2 * drivers/amlogic/media/stream_input/amports/amstream.c
4 * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
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.
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
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/types.h>
22 #include <linux/init.h>
23 #include <linux/device.h>
24 #include <linux/slab.h>
25 #include <linux/vmalloc.h>
27 #include <linux/amlogic/major.h>
28 #include <linux/sched.h>
29 #include <linux/interrupt.h>
30 #include <linux/delay.h>
31 #include <linux/kthread.h>
33 #include <linux/amlogic/media/video_sink/video.h>
34 #include <linux/amlogic/media/utils/amstream.h>
35 #include <linux/amlogic/media/utils/vformat.h>
36 #include <linux/amlogic/media/utils/aformat.h>
38 #include <linux/amlogic/media/video_sink/video.h>
39 #include <linux/amlogic/media/frame_sync/tsync.h>
40 #include <linux/amlogic/media/frame_sync/ptsserv.h>
41 #include <linux/amlogic/media/frame_sync/timestamp.h>
43 #include <linux/types.h>
44 #include <linux/uaccess.h>
46 /* #include <mach/am_regs.h> */
48 #include <linux/platform_device.h>
49 #include <linux/mutex.h>
50 #include <linux/poll.h>
51 #include <linux/dma-mapping.h>
52 #include <linux/dma-contiguous.h>
53 #include <linux/uaccess.h>
54 #include <linux/clk.h>
55 #if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
56 /* #include <mach/mod_gate.h> */
57 /* #include <mach/power_gate.h> */
59 #include "../amports/streambuf.h"
60 #include "../amports/streambuf_reg.h"
61 #include "../parser/tsdemux.h"
62 #include "../parser/psparser.h"
63 #include "../parser/esparser.h"
64 #include "../../frame_provider/decoder/utils/vdec.h"
66 #include "../parser/rmparser.h"
67 #include "amports_priv.h"
68 #include <linux/amlogic/media/utils/amports_config.h>
69 #include <linux/amlogic/media/frame_sync/tsync_pcr.h>
70 #include "../amports/thread_rw.h"
71 #include <linux/firmware.h>
73 #include <linux/of_fdt.h>
74 #include <linux/libfdt_env.h>
75 #include <linux/of_reserved_mem.h>
76 #include <linux/reset.h>
78 #include <linux/compat.h>
80 #include <linux/amlogic/media/codec_mm/codec_mm.h>
81 #include <linux/amlogic/media/codec_mm/configs.h>
82 #include "../../frame_provider/decoder/utils/firmware.h"
83 #include "../../common/chips/chips.h"
84 #include "../../common/chips/decoder_cpu_ver_info.h"
85 #include "../subtitle/subtitle.h"
86 #include "stream_buffer_base.h"
88 //#define G12A_BRINGUP_DEBUG
90 #define CONFIG_AM_VDEC_REAL //DEBUG_TMP
92 #define DEVICE_NAME "amstream-dev"
93 #define DRIVER_NAME "amstream"
94 #define MODULE_NAME "amstream"
96 #define MAX_AMSTREAM_PORT_NUM ARRAY_SIZE(ports)
97 u32 amstream_port_num
;
100 u32 amstream_audio_reset
= 0;
103 #if MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV
104 #define NO_VDEC2_INIT 1
105 #elif MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD
106 #define NO_VDEC2_INIT IS_MESON_M8M2_CPU
109 #define NO_VDEC2_INIT 1
111 #define DEFAULT_VIDEO_BUFFER_SIZE (1024 * 1024 * 3)
112 #define DEFAULT_VIDEO_BUFFER_SIZE_4K (1024 * 1024 * 6)
113 #define DEFAULT_VIDEO_BUFFER_SIZE_TVP (1024 * 1024 * 10)
114 #define DEFAULT_VIDEO_BUFFER_SIZE_4K_TVP (1024 * 1024 * 15)
117 #define DEFAULT_AUDIO_BUFFER_SIZE (1024*768*2)
118 #define DEFAULT_SUBTITLE_BUFFER_SIZE (1024*256)
120 static int def_4k_vstreambuf_sizeM
=
121 (DEFAULT_VIDEO_BUFFER_SIZE_4K
>> 20);
122 static int def_vstreambuf_sizeM
=
123 (DEFAULT_VIDEO_BUFFER_SIZE
>> 20);
124 static int slow_input
;
126 /* #define DATA_DEBUG */
127 static int use_bufferlevelx10000
= 10000;
128 static int reset_canuse_buferlevel(int level
);
129 static struct platform_device
*amstream_pdev
;
130 struct device
*amports_get_dma_device(void)
132 return &amstream_pdev
->dev
;
134 EXPORT_SYMBOL(amports_get_dma_device
);
137 #include <linux/fs.h>
139 #define DEBUG_FILE_NAME "/sdcard/debug.tmp"
140 static struct file
*debug_filp
;
141 static loff_t debug_file_pos
;
143 void debug_file_write(const char __user
*buf
, size_t count
)
153 if (count
!= vfs_write(debug_filp
, buf
, count
, &debug_file_pos
))
154 pr_err("Failed to write debug file\n");
162 static int amstream_open(struct inode
*inode
, struct file
*file
);
163 static int amstream_release(struct inode
*inode
, struct file
*file
);
164 static long amstream_ioctl(struct file
*file
, unsigned int cmd
, ulong arg
);
166 static long amstream_compat_ioctl
167 (struct file
*file
, unsigned int cmd
, ulong arg
);
169 static ssize_t amstream_vbuf_write
170 (struct file
*file
, const char *buf
, size_t count
, loff_t
*ppos
);
171 static ssize_t amstream_vframe_write
172 (struct file
*file
, const char *buf
, size_t count
, loff_t
*ppos
);
173 static ssize_t amstream_abuf_write
174 (struct file
*file
, const char *buf
, size_t count
, loff_t
*ppos
);
175 static ssize_t amstream_mpts_write
176 (struct file
*file
, const char *buf
, size_t count
, loff_t
*ppos
);
177 static ssize_t amstream_mpps_write
178 (struct file
*file
, const char *buf
, size_t count
, loff_t
*ppos
);
179 static ssize_t amstream_sub_read
180 (struct file
*file
, char *buf
, size_t count
, loff_t
*ppos
);
181 static ssize_t amstream_sub_write
182 (struct file
*file
, const char *buf
, size_t count
, loff_t
*ppos
);
183 static unsigned int amstream_sub_poll
184 (struct file
*file
, poll_table
*wait_table
);
185 static unsigned int amstream_userdata_poll
186 (struct file
*file
, poll_table
*wait_table
);
187 static ssize_t amstream_userdata_read
188 (struct file
*file
, char *buf
, size_t count
, loff_t
*ppos
);
189 static int (*amstream_adec_status
)
190 (struct adec_status
*astatus
);
191 #ifdef CONFIG_AM_VDEC_REAL
192 static ssize_t amstream_mprm_write
193 (struct file
*file
, const char *buf
, size_t count
, loff_t
*ppos
);
196 static const struct file_operations vbuf_fops
= {
197 .owner
= THIS_MODULE
,
198 .open
= amstream_open
,
199 .release
= amstream_release
,
200 .write
= amstream_vbuf_write
,
201 .unlocked_ioctl
= amstream_ioctl
,
203 .compat_ioctl
= amstream_compat_ioctl
,
207 static const struct file_operations vframe_fops
= {
208 .owner
= THIS_MODULE
,
209 .open
= amstream_open
,
210 .release
= amstream_release
,
211 .write
= amstream_vframe_write
,
212 .unlocked_ioctl
= amstream_ioctl
,
214 .compat_ioctl
= amstream_compat_ioctl
,
218 static const struct file_operations abuf_fops
= {
219 .owner
= THIS_MODULE
,
220 .open
= amstream_open
,
221 .release
= amstream_release
,
222 .write
= amstream_abuf_write
,
223 .unlocked_ioctl
= amstream_ioctl
,
225 .compat_ioctl
= amstream_compat_ioctl
,
229 static const struct file_operations mpts_fops
= {
230 .owner
= THIS_MODULE
,
231 .open
= amstream_open
,
232 .release
= amstream_release
,
233 .write
= amstream_mpts_write
,
234 .unlocked_ioctl
= amstream_ioctl
,
236 .compat_ioctl
= amstream_compat_ioctl
,
240 static const struct file_operations mpps_fops
= {
241 .owner
= THIS_MODULE
,
242 .open
= amstream_open
,
243 .release
= amstream_release
,
244 .write
= amstream_mpps_write
,
245 .unlocked_ioctl
= amstream_ioctl
,
247 .compat_ioctl
= amstream_compat_ioctl
,
251 static const struct file_operations mprm_fops
= {
252 .owner
= THIS_MODULE
,
253 .open
= amstream_open
,
254 .release
= amstream_release
,
255 #ifdef CONFIG_AM_VDEC_REAL
256 .write
= amstream_mprm_write
,
258 .unlocked_ioctl
= amstream_ioctl
,
260 .compat_ioctl
= amstream_compat_ioctl
,
264 static const struct file_operations sub_fops
= {
265 .owner
= THIS_MODULE
,
266 .open
= amstream_open
,
267 .release
= amstream_release
,
268 .write
= amstream_sub_write
,
269 .unlocked_ioctl
= amstream_ioctl
,
271 .compat_ioctl
= amstream_compat_ioctl
,
275 static const struct file_operations sub_read_fops
= {
276 .owner
= THIS_MODULE
,
277 .open
= amstream_open
,
278 .release
= amstream_release
,
279 .read
= amstream_sub_read
,
280 .poll
= amstream_sub_poll
,
281 .unlocked_ioctl
= amstream_ioctl
,
283 .compat_ioctl
= amstream_compat_ioctl
,
287 static const struct file_operations userdata_fops
= {
288 .owner
= THIS_MODULE
,
289 .open
= amstream_open
,
290 .release
= amstream_release
,
291 .read
= amstream_userdata_read
,
292 .poll
= amstream_userdata_poll
,
293 .unlocked_ioctl
= amstream_ioctl
,
295 .compat_ioctl
= amstream_compat_ioctl
,
299 static const struct file_operations amstream_fops
= {
300 .owner
= THIS_MODULE
,
301 .open
= amstream_open
,
302 .release
= amstream_release
,
303 .unlocked_ioctl
= amstream_ioctl
,
305 .compat_ioctl
= amstream_compat_ioctl
,
309 /**************************************************/
310 static struct audio_info audio_dec_info
;
311 static struct class *amstream_dev_class
;
312 static DEFINE_MUTEX(amstream_mutex
);
314 atomic_t subdata_ready
= ATOMIC_INIT(0);
316 static int sub_port_inited
;
317 /* wait queue for poll */
318 static wait_queue_head_t amstream_sub_wait
;
319 atomic_t userdata_ready
= ATOMIC_INIT(0);
320 static int userdata_length
;
321 static wait_queue_head_t amstream_userdata_wait
;
322 #define USERDATA_FIFO_NUM 1024
323 static struct userdata_poc_info_t userdata_poc_info
[USERDATA_FIFO_NUM
];
324 static int userdata_poc_ri
, userdata_poc_wi
;
325 static int last_read_wi
;
326 static u32 ud_ready_vdec_flag
;
328 /*bit 1 force dual layer
329 *bit 2 force frame mode
331 static u32 force_dv_mode
;
333 static DEFINE_MUTEX(userdata_mutex
);
335 static struct stream_port_s ports
[] = {
337 .name
= "amstream_vbuf",
338 .type
= PORT_TYPE_ES
| PORT_TYPE_VIDEO
,
341 #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
343 .name
= "amstream_vbuf_sched",
344 .type
= PORT_TYPE_ES
| PORT_TYPE_VIDEO
|
345 PORT_TYPE_DECODER_SCHED
,
349 .name
= "amstream_vframe",
350 .type
= PORT_TYPE_ES
| PORT_TYPE_VIDEO
|
351 PORT_TYPE_FRAME
| PORT_TYPE_DECODER_SCHED
,
352 .fops
= &vframe_fops
,
356 .name
= "amstream_abuf",
357 .type
= PORT_TYPE_ES
| PORT_TYPE_AUDIO
,
361 .name
= "amstream_mpts",
362 .type
= PORT_TYPE_MPTS
| PORT_TYPE_VIDEO
|
363 PORT_TYPE_AUDIO
| PORT_TYPE_SUB
,
366 #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
368 .name
= "amstream_mpts_sched",
369 .type
= PORT_TYPE_MPTS
| PORT_TYPE_VIDEO
|
370 PORT_TYPE_AUDIO
| PORT_TYPE_SUB
|
371 PORT_TYPE_DECODER_SCHED
,
376 .name
= "amstream_mpps",
377 .type
= PORT_TYPE_MPPS
| PORT_TYPE_VIDEO
|
378 PORT_TYPE_AUDIO
| PORT_TYPE_SUB
,
382 .name
= "amstream_rm",
383 .type
= PORT_TYPE_RM
| PORT_TYPE_VIDEO
| PORT_TYPE_AUDIO
,
387 .name
= "amstream_sub",
388 .type
= PORT_TYPE_SUB
,
392 .name
= "amstream_sub_read",
393 .type
= PORT_TYPE_SUB_RD
,
394 .fops
= &sub_read_fops
,
397 .name
= "amstream_userdata",
398 .type
= PORT_TYPE_USERDATA
,
399 .fops
= &userdata_fops
,
402 .name
= "amstream_hevc",
403 .type
= PORT_TYPE_ES
| PORT_TYPE_VIDEO
| PORT_TYPE_HEVC
,
405 .vformat
= VFORMAT_HEVC
,
407 #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
409 .name
= "amstream_hevc_frame",
410 .type
= PORT_TYPE_ES
| PORT_TYPE_VIDEO
| PORT_TYPE_HEVC
|
411 PORT_TYPE_FRAME
| PORT_TYPE_DECODER_SCHED
,
412 .fops
= &vframe_fops
,
413 .vformat
= VFORMAT_HEVC
,
416 .name
= "amstream_hevc_sched",
417 .type
= PORT_TYPE_ES
| PORT_TYPE_VIDEO
| PORT_TYPE_HEVC
|
418 PORT_TYPE_DECODER_SCHED
,
420 .vformat
= VFORMAT_HEVC
,
422 #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
424 .name
= "amstream_dves_avc",
425 .type
= PORT_TYPE_ES
| PORT_TYPE_VIDEO
|
426 PORT_TYPE_DECODER_SCHED
| PORT_TYPE_DUALDEC
,
430 .name
= "amstream_dves_hevc",
431 .type
= PORT_TYPE_ES
| PORT_TYPE_VIDEO
| PORT_TYPE_HEVC
|
432 PORT_TYPE_DECODER_SCHED
| PORT_TYPE_DUALDEC
,
434 .vformat
= VFORMAT_HEVC
,
437 .name
= "amstream_dves_avc_frame",
438 .type
= PORT_TYPE_ES
| PORT_TYPE_VIDEO
| PORT_TYPE_FRAME
|
439 PORT_TYPE_DECODER_SCHED
| PORT_TYPE_DUALDEC
,
440 .fops
= &vframe_fops
,
443 .name
= "amstream_dves_hevc_frame",
444 .type
= PORT_TYPE_ES
| PORT_TYPE_VIDEO
| PORT_TYPE_HEVC
| PORT_TYPE_FRAME
|
445 PORT_TYPE_DECODER_SCHED
| PORT_TYPE_DUALDEC
,
446 .fops
= &vframe_fops
,
447 .vformat
= VFORMAT_HEVC
,
450 .name
= "amstream_dves_av1",
451 .type
= PORT_TYPE_ES
| PORT_TYPE_VIDEO
| PORT_TYPE_HEVC
| PORT_TYPE_FRAME
|
452 PORT_TYPE_DECODER_SCHED
| PORT_TYPE_DUALDEC
,
453 .fops
= &vframe_fops
,
454 .vformat
= VFORMAT_AV1
,
460 static struct stream_buf_s bufs
[BUF_MAX_NUM
] = {
462 .reg_base
= VLD_MEM_VIFIFO_REG_BASE
,
463 .type
= BUF_TYPE_VIDEO
,
465 .buf_size
= DEFAULT_VIDEO_BUFFER_SIZE
,
466 .default_buf_size
= DEFAULT_VIDEO_BUFFER_SIZE
,
467 .first_tstamp
= INVALID_PTS
470 .reg_base
= AIU_MEM_AIFIFO_REG_BASE
,
471 .type
= BUF_TYPE_AUDIO
,
473 .buf_size
= DEFAULT_AUDIO_BUFFER_SIZE
,
474 .default_buf_size
= DEFAULT_AUDIO_BUFFER_SIZE
,
475 .first_tstamp
= INVALID_PTS
479 .type
= BUF_TYPE_SUBTITLE
,
481 .buf_size
= DEFAULT_SUBTITLE_BUFFER_SIZE
,
482 .default_buf_size
= DEFAULT_SUBTITLE_BUFFER_SIZE
,
483 .first_tstamp
= INVALID_PTS
487 .type
= BUF_TYPE_USERDATA
,
490 .first_tstamp
= INVALID_PTS
493 .reg_base
= HEVC_STREAM_REG_BASE
,
494 .type
= BUF_TYPE_HEVC
,
496 .buf_size
= DEFAULT_VIDEO_BUFFER_SIZE_4K
,
497 .default_buf_size
= DEFAULT_VIDEO_BUFFER_SIZE_4K
,
498 .first_tstamp
= INVALID_PTS
502 struct stream_buf_s
*get_buf_by_type(u32 type
)
504 if (PTS_TYPE_VIDEO
== type
)
505 return &bufs
[BUF_TYPE_VIDEO
];
506 if (PTS_TYPE_AUDIO
== type
)
507 return &bufs
[BUF_TYPE_AUDIO
];
508 if (has_hevc_vdec()) {
509 if (PTS_TYPE_HEVC
== type
)
510 return &bufs
[BUF_TYPE_HEVC
];
516 void set_sample_rate_info(int arg
)
518 audio_dec_info
.sample_rate
= arg
;
519 audio_dec_info
.valid
= 1;
522 void set_ch_num_info(int arg
)
524 audio_dec_info
.channels
= arg
;
527 struct audio_info
*get_audio_info(void)
529 return &audio_dec_info
;
531 EXPORT_SYMBOL(get_audio_info
);
533 static void amstream_change_vbufsize(struct port_priv_s
*priv
,
534 struct stream_buf_s
*pvbuf
)
536 if (pvbuf
->buf_start
!= 0 || pvbuf
->ext_buf_addr
!= 0) {
537 pr_info("streambuf is alloced, buf_start 0x%lx, extbuf 0x%lx\n",
538 pvbuf
->buf_start
, pvbuf
->ext_buf_addr
);
541 if (priv
->port
->is_4k
) {
542 pvbuf
->buf_size
= def_4k_vstreambuf_sizeM
* SZ_1M
;
543 if (priv
->vdec
->port_flag
& PORT_FLAG_DRM
)
544 pvbuf
->buf_size
= DEFAULT_VIDEO_BUFFER_SIZE_4K_TVP
;
545 if ((pvbuf
->buf_size
> 30 * SZ_1M
) &&
546 (codec_mm_get_total_size() < 220 * SZ_1M
)) {
547 /*if less than 250M, used 20M for 4K & 265*/
548 pvbuf
->buf_size
= pvbuf
->buf_size
>> 1;
550 } else if (pvbuf
->buf_size
> def_vstreambuf_sizeM
* SZ_1M
) {
551 if (priv
->vdec
->port_flag
& PORT_FLAG_DRM
)
552 pvbuf
->buf_size
= DEFAULT_VIDEO_BUFFER_SIZE_TVP
;
554 pvbuf
->buf_size
= def_vstreambuf_sizeM
* SZ_1M
;
555 if (priv
->vdec
->port_flag
& PORT_FLAG_DRM
)
556 pvbuf
->buf_size
= DEFAULT_VIDEO_BUFFER_SIZE_TVP
;
558 reset_canuse_buferlevel(10000);
561 static bool port_get_inited(struct port_priv_s
*priv
)
563 struct stream_port_s
*port
= priv
->port
;
565 if (port
->type
& PORT_TYPE_VIDEO
) {
566 struct vdec_s
*vdec
= priv
->vdec
;
568 return vdec
? vdec
->port_flag
& PORT_FLAG_INITED
: 0;
571 return port
->flag
& PORT_FLAG_INITED
;
574 static void port_set_inited(struct port_priv_s
*priv
)
576 struct stream_port_s
*port
= priv
->port
;
578 if (port
->type
& PORT_TYPE_VIDEO
) {
579 struct vdec_s
*vdec
= priv
->vdec
;
581 vdec
->port_flag
|= PORT_FLAG_INITED
;
582 port
->flag
|= PORT_FLAG_INITED
;
583 pr_info("vdec->port_flag=0x%x, port_flag=0x%x\n",
584 vdec
->port_flag
, port
->flag
);
586 port
->flag
|= PORT_FLAG_INITED
;
589 static void video_port_release(struct port_priv_s
*priv
,
590 struct stream_buf_s
*pbuf
, int release_num
)
592 struct vdec_s
*vdec
= priv
->vdec
;
593 struct vdec_s
*slave
= NULL
;
598 switch (release_num
) {
601 case 0: /*release all */
615 static int video_port_init(struct port_priv_s
*priv
,
616 struct stream_buf_s
*pbuf
)
619 struct stream_port_s
*port
= priv
->port
;
620 struct vdec_s
*vdec
= priv
->vdec
;
622 if ((vdec
->port_flag
& PORT_FLAG_VFORMAT
) == 0) {
623 pr_err("vformat not set\n");
626 if (vdec_dual(vdec
) && vdec_secure(vdec
) && (vdec
->slave
)) {
627 /*copy drm flags for slave dec.*/
628 vdec
->slave
->port_flag
|= PORT_FLAG_DRM
;
630 if (port
->vformat
== VFORMAT_H264_4K2K
||
631 (priv
->vdec
->sys_info
->height
*
632 priv
->vdec
->sys_info
->width
) > 1920*1088) {
634 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TXLX
635 && port
->vformat
== VFORMAT_H264
) {
636 vdec_poweron(VDEC_HEVC
);
642 if (port
->type
& PORT_TYPE_FRAME
) {
644 (priv
->vdec
->sys_info
->height
*
645 priv
->vdec
->sys_info
->width
) > 1920*1088);
647 pr_err("video_port_init %d, vdec_init failed\n",
652 if (vdec_dual(vdec
)) {
653 if (port
->vformat
== VFORMAT_AV1
) /* av1 dv only single layer */
655 r
= vdec_init(vdec
->slave
,
656 (priv
->vdec
->sys_info
->height
*
657 priv
->vdec
->sys_info
->width
) > 1920*1088);
660 pr_err("video_port_init %d, vdec_init failed\n",
669 amstream_change_vbufsize(priv
, pbuf
);
671 if (has_hevc_vdec()) {
672 if (port
->type
& PORT_TYPE_MPTS
) {
673 if (pbuf
->type
== BUF_TYPE_HEVC
)
674 vdec_poweroff(VDEC_1
);
676 vdec_poweroff(VDEC_HEVC
);
680 /* todo: set path based on port flag */
682 (priv
->vdec
->sys_info
->height
*
683 priv
->vdec
->sys_info
->width
) > 1920*1088);
686 pr_err("video_port_init %d, vdec_init failed\n", __LINE__
);
690 if (vdec_dual(vdec
)) {
691 r
= vdec_init(vdec
->slave
,
692 (priv
->vdec
->sys_info
->height
*
693 priv
->vdec
->sys_info
->width
) > 1920*1088);
695 pr_err("video_port_init %d, vdec_init failed\n", __LINE__
);
703 vdec_release(vdec
->slave
);
711 static void audio_port_release(struct stream_port_s
*port
,
712 struct stream_buf_s
*pbuf
, int release_num
)
714 switch (release_num
) {
717 case 0: /*release all */
720 esparser_release(pbuf
);
723 adec_release(port
->vformat
);
731 amstream_audio_reset
= 0;
735 static int audio_port_reset(struct stream_port_s
*port
,
736 struct stream_buf_s
*pbuf
)
739 mutex_lock(&amstream_mutex
);
740 if ((port
->flag
& PORT_FLAG_AFORMAT
) == 0) {
741 pr_err("aformat not set\n");
742 mutex_unlock(&amstream_mutex
);
746 pr_info("audio port reset, flag:0x%x\n", port
->flag
);
747 if ((port
->flag
& PORT_FLAG_INITED
) == 0) {
748 pr_info("audio port not inited,return\n");
749 mutex_unlock(&amstream_mutex
);
753 pr_info("audio_port_reset begin\n");
754 pts_stop(PTS_TYPE_AUDIO
);
758 r
= stbuf_init(pbuf
, NULL
);
760 mutex_unlock(&amstream_mutex
);
766 audio_port_release(port
, pbuf
, 2);
767 mutex_unlock(&amstream_mutex
);
771 if (port
->type
& PORT_TYPE_ES
)
772 esparser_audio_reset_s(pbuf
);
774 if (port
->type
& PORT_TYPE_MPTS
)
775 tsdemux_audio_reset();
777 if (port
->type
& PORT_TYPE_MPPS
)
778 psparser_audio_reset();
780 #ifdef CONFIG_AM_VDEC_REAL
781 if (port
->type
& PORT_TYPE_RM
)
785 pbuf
->flag
|= BUF_FLAG_IN_USE
;
786 amstream_audio_reset
= 1;
788 r
= pts_start(PTS_TYPE_AUDIO
);
790 //clear audio break flag after reset
791 //tsync_audio_break(0);
793 pr_info("audio_port_reset done\n");
794 mutex_unlock(&amstream_mutex
);
798 static int sub_port_reset(struct stream_port_s
*port
,
799 struct stream_buf_s
*pbuf
)
803 port
->flag
&= (~PORT_FLAG_INITED
);
807 r
= stbuf_init(pbuf
, NULL
);
811 if (port
->type
& PORT_TYPE_MPTS
)
814 if (port
->type
& PORT_TYPE_MPPS
)
815 psparser_sub_reset();
817 if (port
->sid
== 0xffff) { /* es sub */
818 esparser_sub_reset();
819 pbuf
->flag
|= BUF_FLAG_PARSER
;
822 pbuf
->flag
|= BUF_FLAG_IN_USE
;
824 port
->flag
|= PORT_FLAG_INITED
;
829 static int audio_port_init(struct stream_port_s
*port
,
830 struct stream_buf_s
*pbuf
)
834 if ((port
->flag
& PORT_FLAG_AFORMAT
) == 0) {
835 pr_err("aformat not set\n");
839 r
= stbuf_init(pbuf
, NULL
);
844 audio_port_release(port
, pbuf
, 2);
847 if (port
->type
& PORT_TYPE_ES
) {
848 r
= esparser_init(pbuf
, NULL
);
850 audio_port_release(port
, pbuf
, 3);
854 pbuf
->flag
|= BUF_FLAG_IN_USE
;
858 static void sub_port_release(struct stream_port_s
*port
,
859 struct stream_buf_s
*pbuf
)
861 if ((port
->sid
== 0xffff) &&
862 ((port
->type
& (PORT_TYPE_MPPS
| PORT_TYPE_MPTS
)) == 0)) {
864 esparser_release(pbuf
);
870 static int sub_port_init(struct stream_port_s
*port
, struct stream_buf_s
*pbuf
)
873 r
= stbuf_init(pbuf
, NULL
);
876 if ((port
->flag
& PORT_FLAG_SID
) == 0) {
877 pr_err("subtitle id not set\n");
881 if ((port
->sid
== 0xffff) &&
882 ((port
->type
& (PORT_TYPE_MPPS
| PORT_TYPE_MPTS
)) == 0)) {
884 r
= esparser_init(pbuf
, NULL
);
886 sub_port_release(port
, pbuf
);
895 static void amstream_user_buffer_init(void)
897 struct stream_buf_s
*pubuf
= &bufs
[BUF_TYPE_USERDATA
];
900 pubuf
->buf_start
= 0;
907 struct stream_buf_s
*get_vbuf(void)
909 return &bufs
[BUF_TYPE_VIDEO
];
912 EXPORT_SYMBOL(get_vbuf
);
915 static int amstream_port_init(struct port_priv_s
*priv
)
918 struct stream_buf_s
*pvbuf
= &bufs
[BUF_TYPE_VIDEO
];
919 struct stream_buf_s
*pabuf
= &bufs
[BUF_TYPE_AUDIO
];
920 struct stream_buf_s
*psbuf
= &bufs
[BUF_TYPE_SUBTITLE
];
921 struct stream_port_s
*port
= priv
->port
;
922 struct vdec_s
*vdec
= priv
->vdec
;
924 r
= vdec_resource_checking(vdec
);
928 mutex_lock(&amstream_mutex
);
930 if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A
) &&
931 (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2
)) {
932 r
= check_efuse_chip(port
->vformat
);
934 pr_info("No support video format %d.\n", port
->vformat
);
935 mutex_unlock(&amstream_mutex
);
940 /* try to reload the fw.*/
941 r
= video_fw_reload(FW_LOAD_TRY
);
943 pr_err("the firmware reload fail.\n");
947 amstream_user_buffer_init();
949 if (port_get_inited(priv
)) {
950 mutex_unlock(&amstream_mutex
);
954 if ((port
->type
& PORT_TYPE_AUDIO
) &&
955 (port
->flag
& PORT_FLAG_AFORMAT
)) {
956 r
= audio_port_init(port
, pabuf
);
958 pr_err("audio_port_init failed\n");
963 if ((port
->type
& PORT_TYPE_VIDEO
) &&
964 (port
->flag
& PORT_FLAG_VFORMAT
)) {
965 if (vdec_stream_based(vdec
)) {
966 struct stream_buf_ops
*ops
= NULL
;
967 struct parser_args pars
= {
968 .vid
= (port
->flag
& PORT_FLAG_VID
) ? port
->vid
: 0xffff,
969 .aid
= (port
->flag
& PORT_FLAG_AID
) ? port
->aid
: 0xffff,
970 .sid
= (port
->flag
& PORT_FLAG_SID
) ? port
->sid
: 0xffff,
971 .pcrid
= (port
->pcr_inited
== 1) ? port
->pcrid
: 0xffff,
974 if (port
->type
& PORT_TYPE_MPTS
) {
975 ops
= get_tsparser_stbuf_ops();
976 } else if (port
->type
& PORT_TYPE_MPPS
) {
977 ops
= get_psparser_stbuf_ops();
979 ops
= !vdec_single(vdec
) ?
981 get_esparser_stbuf_ops();
983 /* def used stbuf with parser if the feature disable. */
984 if (!is_support_no_parser())
985 ops
= get_esparser_stbuf_ops();
988 r
= stream_buffer_base_init(&vdec
->vbuf
, ops
, &pars
);
990 mutex_unlock(&priv
->mutex
);
991 pr_err("stream buffer base init failed\n");
996 mutex_lock(&priv
->mutex
);
997 r
= video_port_init(priv
, &vdec
->vbuf
);
999 mutex_unlock(&priv
->mutex
);
1000 pr_err("video_port_init failed\n");
1003 mutex_unlock(&priv
->mutex
);
1006 if ((port
->type
& PORT_TYPE_MPTS
) &&
1007 !(port
->flag
& PORT_FLAG_VFORMAT
)) {
1008 r
= tsdemux_init(0xffff,
1009 (port
->flag
& PORT_FLAG_AID
) ? port
->aid
: 0xffff,
1010 (port
->flag
& PORT_FLAG_SID
) ? port
->sid
: 0xffff,
1011 (port
->pcr_inited
== 1) ? port
->pcrid
: 0xffff,
1014 pr_err("tsdemux_init failed\n");
1020 if ((port
->type
& PORT_TYPE_SUB
) && (port
->flag
& PORT_FLAG_SID
)) {
1021 r
= sub_port_init(port
, psbuf
);
1023 pr_err("sub_port_init failed\n");
1028 #ifdef CONFIG_AM_VDEC_REAL
1029 if (port
->type
& PORT_TYPE_RM
) {
1031 (port
->flag
& PORT_FLAG_VID
) ? port
->vid
: 0xffff,
1032 (port
->flag
& PORT_FLAG_AID
) ? port
->aid
: 0xffff);
1035 #if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD */
1036 if (!NO_VDEC2_INIT
) {
1037 if ((port
->type
& PORT_TYPE_VIDEO
)
1038 && (port
->vformat
== VFORMAT_H264_4K2K
))
1039 stbuf_vdec2_init(pvbuf
);
1043 if ((port
->type
& PORT_TYPE_VIDEO
) &&
1044 (vdec
->port_flag
& PORT_FLAG_VFORMAT
))
1045 /* connect vdec at the end after all HW initialization */
1048 tsync_audio_break(0); /* clear audio break */
1049 set_vsync_pts_inc_mode(0); /* clear video inc */
1051 port_set_inited(priv
);
1053 mutex_unlock(&amstream_mutex
);
1055 /*errors follow here */
1058 sub_port_release(port
, psbuf
);
1060 video_port_release(priv
, &priv
->vdec
->vbuf
, 0);
1062 audio_port_release(port
, pabuf
, 0);
1064 mutex_unlock(&amstream_mutex
);
1068 static int amstream_port_release(struct port_priv_s
*priv
)
1070 struct stream_port_s
*port
= priv
->port
;
1071 struct stream_buf_s
*pvbuf
= &priv
->vdec
->vbuf
;
1072 struct stream_buf_s
*pabuf
= &bufs
[BUF_TYPE_AUDIO
];
1073 struct stream_buf_s
*psbuf
= &bufs
[BUF_TYPE_SUBTITLE
];
1075 if ((port
->type
& PORT_TYPE_MPTS
) &&
1076 !(port
->flag
& PORT_FLAG_VFORMAT
)) {
1081 if ((port
->type
& PORT_TYPE_MPPS
) &&
1082 !(port
->flag
& PORT_FLAG_VFORMAT
)) {
1086 if (port
->type
& PORT_TYPE_VIDEO
)
1087 video_port_release(priv
, pvbuf
, 0);
1089 if (port
->type
& PORT_TYPE_AUDIO
)
1090 audio_port_release(port
, pabuf
, 0);
1092 if (port
->type
& PORT_TYPE_SUB
)
1093 sub_port_release(port
, psbuf
);
1095 port
->pcr_inited
= 0;
1097 if (!is_mult_inc(port
->type
) ||
1098 (is_mult_inc(port
->type
) &&
1099 !is_support_no_parser()))
1105 static void amstream_change_avid(struct stream_port_s
*port
)
1107 if (port
->type
& PORT_TYPE_MPTS
) {
1108 tsdemux_change_avid(
1109 (port
->flag
& PORT_FLAG_VID
) ? port
->vid
: 0xffff,
1110 (port
->flag
& PORT_FLAG_AID
) ? port
->aid
: 0xffff);
1113 if (port
->type
& PORT_TYPE_MPPS
) {
1114 psparser_change_avid(
1115 (port
->flag
& PORT_FLAG_VID
) ? port
->vid
: 0xffff,
1116 (port
->flag
& PORT_FLAG_AID
) ? port
->aid
: 0xffff);
1119 #ifdef CONFIG_AM_VDEC_REAL
1120 if (port
->type
& PORT_TYPE_RM
) {
1122 (port
->flag
& PORT_FLAG_VID
) ? port
->vid
: 0xffff,
1123 (port
->flag
& PORT_FLAG_AID
) ? port
->aid
: 0xffff);
1128 static void amstream_change_sid(struct stream_port_s
*port
)
1130 if (port
->type
& PORT_TYPE_MPTS
) {
1132 (port
->flag
& PORT_FLAG_SID
) ? port
->sid
: 0xffff);
1135 if (port
->type
& PORT_TYPE_MPPS
) {
1136 psparser_change_sid(
1137 (port
->flag
& PORT_FLAG_SID
) ? port
->sid
: 0xffff);
1141 /**************************************************/
1142 static ssize_t
amstream_vbuf_write(struct file
*file
, const char *buf
,
1143 size_t count
, loff_t
*ppos
)
1145 struct port_priv_s
*priv
= (struct port_priv_s
*)file
->private_data
;
1146 struct stream_buf_s
*pbuf
= &priv
->vdec
->vbuf
;
1149 if (!(port_get_inited(priv
))) {
1150 r
= amstream_port_init(priv
);
1155 if (priv
->vdec
->port_flag
& PORT_FLAG_DRM
)
1156 r
= drm_write(file
, pbuf
, buf
, count
);
1158 r
= stream_buffer_write(file
, pbuf
, buf
, count
);
1160 pr_info("slow_input: es codec write size %x\n", r
);
1164 debug_file_write(buf
, r
);
1170 static ssize_t
amstream_vframe_write(struct file
*file
, const char *buf
,
1171 size_t count
, loff_t
*ppos
)
1173 struct port_priv_s
*priv
= (struct port_priv_s
*)file
->private_data
;
1175 int wait_max_cnt
= 5;
1177 debug_file_write(buf
, count
);
1180 ret
= vdec_write_vframe(priv
->vdec
, buf
, count
);
1181 if (file
->f_flags
& O_NONBLOCK
) {
1182 break;/*alway return for no block mode.*/
1183 } else if (ret
== -EAGAIN
) {
1185 level
= vdec_input_level(&priv
->vdec
->input
);
1186 if (wait_max_cnt
-- < 0)
1190 } while (ret
== -EAGAIN
);
1194 static ssize_t
amstream_abuf_write(struct file
*file
, const char *buf
,
1195 size_t count
, loff_t
*ppos
)
1197 struct port_priv_s
*priv
= (struct port_priv_s
*)file
->private_data
;
1198 struct stream_port_s
*port
= priv
->port
;
1199 struct stream_buf_s
*pbuf
= &bufs
[BUF_TYPE_AUDIO
];
1202 if (!(port_get_inited(priv
))) {
1203 r
= amstream_port_init(priv
);
1208 if (port
->flag
& PORT_FLAG_DRM
)
1209 r
= drm_write(file
, pbuf
, buf
, count
);
1211 r
= esparser_write(file
, pbuf
, buf
, count
);
1216 static ssize_t
amstream_mpts_write(struct file
*file
, const char *buf
,
1217 size_t count
, loff_t
*ppos
)
1219 struct port_priv_s
*priv
= (struct port_priv_s
*)file
->private_data
;
1220 struct stream_port_s
*port
= priv
->port
;
1221 struct stream_buf_s
*pabuf
= &bufs
[BUF_TYPE_AUDIO
];
1222 struct stream_buf_s
*pvbuf
= &priv
->vdec
->vbuf
;
1225 if (!(port_get_inited(priv
))) {
1226 r
= amstream_port_init(priv
);
1231 debug_file_write(buf
, count
);
1233 if (port
->flag
& PORT_FLAG_DRM
)
1234 r
= drm_tswrite(file
, pvbuf
, pabuf
, buf
, count
);
1236 r
= tsdemux_write(file
, pvbuf
, pabuf
, buf
, count
);
1238 pr_info("slow_input: ts codec write size %x\n", r
);
1244 static ssize_t
amstream_mpps_write(struct file
*file
, const char *buf
,
1245 size_t count
, loff_t
*ppos
)
1247 struct port_priv_s
*priv
= (struct port_priv_s
*)file
->private_data
;
1248 struct stream_buf_s
*pvbuf
= &bufs
[BUF_TYPE_VIDEO
];
1249 struct stream_buf_s
*pabuf
= &bufs
[BUF_TYPE_AUDIO
];
1252 if (!(port_get_inited(priv
))) {
1253 r
= amstream_port_init(priv
);
1257 return psparser_write(file
, pvbuf
, pabuf
, buf
, count
);
1260 #ifdef CONFIG_AM_VDEC_REAL
1261 static ssize_t
amstream_mprm_write(struct file
*file
, const char *buf
,
1262 size_t count
, loff_t
*ppos
)
1264 struct port_priv_s
*priv
= (struct port_priv_s
*)file
->private_data
;
1265 struct stream_buf_s
*pvbuf
= &bufs
[BUF_TYPE_VIDEO
];
1266 struct stream_buf_s
*pabuf
= &bufs
[BUF_TYPE_AUDIO
];
1269 if (!(port_get_inited(priv
))) {
1270 r
= amstream_port_init(priv
);
1274 return rmparser_write(file
, pvbuf
, pabuf
, buf
, count
);
1278 static ssize_t
amstream_sub_read(struct file
*file
, char __user
*buf
,
1279 size_t count
, loff_t
*ppos
)
1281 u32 sub_rp
, sub_wp
, sub_start
, data_size
, res
;
1282 struct stream_buf_s
*s_buf
= &bufs
[BUF_TYPE_SUBTITLE
];
1284 if (sub_port_inited
== 0)
1287 sub_rp
= stbuf_sub_rp_get();
1288 sub_wp
= stbuf_sub_wp_get();
1289 sub_start
= stbuf_sub_start_get();
1291 if (sub_wp
== sub_rp
|| sub_rp
== 0)
1293 /*flush sub buf before read*/
1295 (void*)codec_mm_phys_to_virt(sub_start
),
1298 if (sub_wp
> sub_rp
)
1299 data_size
= sub_wp
- sub_rp
;
1301 data_size
= s_buf
->buf_size
- sub_rp
+ sub_wp
;
1303 if (data_size
> count
)
1306 if (sub_wp
< sub_rp
) {
1307 int first_num
= s_buf
->buf_size
- (sub_rp
- sub_start
);
1309 if (data_size
<= first_num
) {
1310 res
= copy_to_user((void *)buf
,
1311 (void *)(codec_mm_phys_to_virt(sub_rp
)),
1313 stbuf_sub_rp_set(sub_rp
+ data_size
- res
);
1315 return data_size
- res
;
1317 if (first_num
> 0) {
1318 res
= copy_to_user((void *)buf
,
1319 (void *)(codec_mm_phys_to_virt(sub_rp
)),
1321 stbuf_sub_rp_set(sub_rp
+ first_num
-
1324 return first_num
- res
;
1327 res
= copy_to_user((void *)buf
,
1328 (void *)(codec_mm_phys_to_virt(sub_start
)),
1329 data_size
- first_num
);
1331 stbuf_sub_rp_set(sub_start
+ data_size
-
1334 return data_size
- first_num
- res
;
1338 copy_to_user((void *)buf
,
1339 (void *)(codec_mm_phys_to_virt(sub_rp
)),
1342 stbuf_sub_rp_set(sub_rp
+ data_size
- res
);
1344 return data_size
- res
;
1348 static ssize_t
amstream_sub_write(struct file
*file
, const char *buf
,
1349 size_t count
, loff_t
*ppos
)
1351 struct port_priv_s
*priv
= (struct port_priv_s
*)file
->private_data
;
1352 struct stream_buf_s
*pbuf
= &bufs
[BUF_TYPE_SUBTITLE
];
1355 if (!(port_get_inited(priv
))) {
1356 r
= amstream_port_init(priv
);
1360 r
= esparser_write(file
, pbuf
, buf
, count
);
1369 static unsigned int amstream_sub_poll(struct file
*file
,
1370 poll_table
*wait_table
)
1372 poll_wait(file
, &amstream_sub_wait
, wait_table
);
1374 if (atomic_read(&subdata_ready
)) {
1375 atomic_dec(&subdata_ready
);
1376 return POLLOUT
| POLLWRNORM
;
1382 static void set_userdata_poc(struct userdata_poc_info_t poc
)
1384 userdata_poc_info
[userdata_poc_wi
] = poc
;
1386 if (userdata_poc_wi
== USERDATA_FIFO_NUM
)
1387 userdata_poc_wi
= 0;
1389 EXPORT_SYMBOL(set_userdata_poc
);
1391 void init_userdata_fifo(void)
1393 userdata_poc_ri
= 0;
1394 userdata_poc_wi
= 0;
1395 userdata_length
= 0;
1397 EXPORT_SYMBOL(init_userdata_fifo
);
1399 void reset_userdata_fifo(int bInit
)
1401 struct stream_buf_s
*userdata_buf
;
1405 mutex_lock(&userdata_mutex
);
1407 wi
= userdata_poc_wi
;
1408 ri
= userdata_poc_ri
;
1410 userdata_buf
= &bufs
[BUF_TYPE_USERDATA
];
1411 rp
= userdata_buf
->buf_rp
;
1412 wp
= userdata_buf
->buf_wp
;
1415 userdata_buf
->buf_rp
= 0;
1416 userdata_buf
->buf_wp
= 0;
1417 userdata_poc_ri
= 0;
1418 userdata_poc_wi
= 0;
1420 /* just clean fifo buffer */
1421 userdata_buf
->buf_rp
= userdata_buf
->buf_wp
;
1422 userdata_poc_ri
= userdata_poc_wi
;
1424 userdata_length
= 0;
1425 last_read_wi
= userdata_poc_wi
;
1427 mutex_unlock(&userdata_mutex
);
1428 pr_debug("reset_userdata_fifo, bInit=%d, wi=%d, ri=%d, rp=%d, wp=%d\n",
1429 bInit
, wi
, ri
, rp
, wp
);
1431 EXPORT_SYMBOL(reset_userdata_fifo
);
1433 int wakeup_userdata_poll(struct userdata_poc_info_t poc
,
1435 unsigned long start_phyaddr
,
1439 struct stream_buf_s
*userdata_buf
= &bufs
[BUF_TYPE_USERDATA
];
1440 mutex_lock(&userdata_mutex
);
1442 if (data_length
& 0x7)
1443 data_length
= (((data_length
+ 8) >> 3) << 3);
1444 set_userdata_poc(poc
);
1445 userdata_buf
->buf_start
= start_phyaddr
;
1446 userdata_buf
->buf_wp
= wp
;
1447 userdata_buf
->buf_size
= buf_size
;
1448 atomic_set(&userdata_ready
, 1);
1449 userdata_length
+= data_length
;
1450 mutex_unlock(&userdata_mutex
);
1452 wake_up_interruptible(&amstream_userdata_wait
);
1453 return userdata_buf
->buf_rp
;
1455 EXPORT_SYMBOL(wakeup_userdata_poll
);
1458 void amstream_wakeup_userdata_poll(struct vdec_s
*vdec
)
1464 pr_info("Error, not support so many instances(%d) user data push\n",
1469 mutex_lock(&userdata_mutex
);
1470 ud_ready_vdec_flag
|= (1<<vdec_id
);
1472 atomic_set(&userdata_ready
, 1);
1473 mutex_unlock(&userdata_mutex
);
1475 wake_up_interruptible(&amstream_userdata_wait
);
1477 EXPORT_SYMBOL(amstream_wakeup_userdata_poll
);
1479 static unsigned int amstream_userdata_poll(struct file
*file
,
1480 poll_table
*wait_table
)
1482 poll_wait(file
, &amstream_userdata_wait
, wait_table
);
1483 if (atomic_read(&userdata_ready
)) {
1484 atomic_set(&userdata_ready
, 0);
1485 return POLLIN
| POLLRDNORM
;
1490 static ssize_t
amstream_userdata_read(struct file
*file
, char __user
*buf
,
1491 size_t count
, loff_t
*ppos
)
1493 u32 data_size
, res
, retVal
= 0;
1494 u32 buf_wp
, buf_rp
, buf_size
;
1495 unsigned long buf_start
;
1496 struct stream_buf_s
*userdata_buf
= &bufs
[BUF_TYPE_USERDATA
];
1497 #ifdef DEBUG_USER_DATA
1501 mutex_lock(&userdata_mutex
);
1503 if (userdata_poc_ri
!= last_read_wi
) {
1504 /***********************************************
1505 app picks up poc counter wrong from last read user data
1506 for H264. So, we need to recalculate userdata_poc_ri
1507 to the userdata_poc_wi from the last read.
1508 ***********************************************/
1510 pr_info("app pick up poc error: ri = %d, last_wi = %d\n",
1511 userdata_poc_ri
, last_read_wi
);
1513 userdata_poc_ri
= last_read_wi
;
1516 buf_wp
= userdata_buf
->buf_wp
;
1517 buf_rp
= userdata_buf
->buf_rp
;
1518 buf_size
= userdata_buf
->buf_size
;
1519 buf_start
= userdata_buf
->buf_start
;
1520 #ifdef DEBUG_USER_DATA
1521 old_wi
= last_read_wi
;
1523 last_read_wi
= userdata_poc_wi
;
1524 mutex_unlock(&userdata_mutex
);
1526 if (buf_start
== 0 || buf_size
== 0)
1528 if (buf_wp
== buf_rp
)
1530 if (buf_wp
> buf_rp
)
1531 data_size
= buf_wp
- buf_rp
;
1533 data_size
= buf_size
- buf_rp
+ buf_wp
;
1535 if (data_size
> count
)
1537 #ifdef DEBUG_USER_DATA
1538 pr_info("wi:%d ri:%d wp:%d rp:%d size:%d, last_read_wi=%d\n",
1539 userdata_poc_wi
, userdata_poc_ri
,
1540 buf_wp
, buf_rp
, data_size
, old_wi
);
1542 if (buf_wp
< buf_rp
) {
1543 int first_num
= buf_size
- buf_rp
;
1544 if (data_size
<= first_num
) {
1545 res
= copy_to_user((void *)buf
,
1547 buf_start
)), data_size
);
1549 pr_info("p1 read not end res=%d, request=%d\n",
1552 mutex_lock(&userdata_mutex
);
1553 userdata_buf
->buf_rp
+= data_size
- res
;
1554 mutex_unlock(&userdata_mutex
);
1555 retVal
= data_size
- res
;
1557 if (first_num
> 0) {
1558 res
= copy_to_user((void *)buf
,
1560 buf_start
)), first_num
);
1562 pr_info("p2 read not end res=%d, request=%d\n",
1565 res
= copy_to_user((void *)buf
+first_num
,
1566 (void *)(buf_start
),
1567 data_size
- first_num
);
1570 pr_info("p3 read not end res=%d, request=%d\n",
1571 res
, data_size
- first_num
);
1573 mutex_lock(&userdata_mutex
);
1574 userdata_buf
->buf_rp
+= data_size
;
1575 if (userdata_buf
->buf_rp
>= buf_size
)
1576 userdata_buf
->buf_rp
=
1577 userdata_buf
->buf_rp
- buf_size
;
1578 mutex_unlock(&userdata_mutex
);
1583 res
= copy_to_user((void *)buf
,
1584 (void *)((buf_start
)),
1585 data_size
- first_num
);
1586 mutex_lock(&userdata_mutex
);
1587 userdata_buf
->buf_rp
=
1588 data_size
- first_num
- res
;
1589 mutex_unlock(&userdata_mutex
);
1590 retVal
= data_size
- first_num
- res
;
1594 res
= copy_to_user((void *)buf
,
1595 (void *)((buf_rp
+ buf_start
)),
1598 pr_info("p4 read not end res=%d, request=%d\n",
1601 mutex_lock(&userdata_mutex
);
1602 userdata_buf
->buf_rp
+= data_size
- res
;
1603 mutex_unlock(&userdata_mutex
);
1604 retVal
= data_size
- res
;
1609 static int amstream_open(struct inode
*inode
, struct file
*file
)
1612 struct stream_port_s
*s
;
1613 struct stream_port_s
*port
= &ports
[iminor(inode
)];
1614 struct port_priv_s
*priv
;
1616 VDEC_PRINT_FUN_LINENO(__func__
, __LINE__
);
1617 #ifdef G12A_BRINGUP_DEBUG
1618 if (vdec_get_debug_flags() & 0xff0000) {
1619 pr_info("%s force open port %d\n",
1621 ((vdec_get_debug_flags() >> 16) & 0xff) - 1);
1622 port
= &ports
[((vdec_get_debug_flags() >> 16) & 0xff) - 1];
1624 pr_info("%s, port name %s\n", __func__
, port
->name
);
1626 if (iminor(inode
) >= amstream_port_num
)
1629 //pr_err("%s, port name %s\n", __func__, port->name);
1630 //pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid);
1631 mutex_lock(&amstream_mutex
);
1633 if (port
->type
& PORT_TYPE_VIDEO
) {
1634 for (s
= &ports
[0], i
= 0; i
< amstream_port_num
; i
++, s
++) {
1635 if ((!is_mult_inc(s
->type
)) &&
1636 (s
->type
& PORT_TYPE_VIDEO
) &&
1637 (s
->flag
& PORT_FLAG_IN_USE
)) {
1638 mutex_unlock(&amstream_mutex
);
1644 if (!is_support_no_parser()) {
1645 if ((port
->flag
& PORT_FLAG_IN_USE
) &&
1646 ((port
->type
& PORT_TYPE_FRAME
) == 0)) {
1647 mutex_unlock(&amstream_mutex
);
1651 /* force dv frame mode */
1652 if (force_dv_mode
& 0x2) {
1653 port
->type
|= PORT_TYPE_FRAME
;
1654 port
->fops
= &vframe_fops
;
1655 pr_debug("%s, dobly vision force frame mode.\n", __func__
);
1658 /* esplayer stream mode force dv */
1659 if (force_dv_mode
& 0x1)
1660 port
->type
|= PORT_TYPE_DUALDEC
;
1662 /* check other ports conflicts for audio */
1663 for (s
= &ports
[0], i
= 0; i
< amstream_port_num
; i
++, s
++) {
1664 if ((s
->flag
& PORT_FLAG_IN_USE
) &&
1665 ((port
->type
) & (s
->type
) & PORT_TYPE_AUDIO
)) {
1666 mutex_unlock(&amstream_mutex
);
1671 priv
= kzalloc(sizeof(struct port_priv_s
), GFP_KERNEL
);
1673 mutex_unlock(&amstream_mutex
);
1677 mutex_init(&priv
->mutex
);
1681 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M6
) {
1682 /* TODO: mod gate */
1683 /* switch_mod_gate_by_name("demux", 1); */
1684 amports_switch_gate("demux", 1);
1685 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M8
) {
1686 /* TODO: clc gate */
1687 /* CLK_GATE_ON(HIU_PARSER_TOP); */
1688 amports_switch_gate("parser_top", 1);
1691 if (port
->type
& PORT_TYPE_VIDEO
) {
1692 /* TODO: mod gate */
1693 /* switch_mod_gate_by_name("vdec", 1); */
1694 amports_switch_gate("vdec", 1);
1696 if (has_hevc_vdec()) {
1698 (PORT_TYPE_MPTS
| PORT_TYPE_HEVC
))
1699 vdec_poweron(VDEC_HEVC
);
1701 if ((port
->type
& PORT_TYPE_HEVC
) == 0)
1702 vdec_poweron(VDEC_1
);
1704 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M8
)
1705 vdec_poweron(VDEC_1
);
1709 if (port
->type
& PORT_TYPE_AUDIO
) {
1710 /* TODO: mod gate */
1711 /* switch_mod_gate_by_name("audio", 1); */
1712 amports_switch_gate("audio", 1);
1719 port
->pcrid
= 0xffff;
1720 file
->f_op
= port
->fops
;
1721 file
->private_data
= priv
;
1723 port
->flag
= PORT_FLAG_IN_USE
;
1724 port
->pcr_inited
= 0;
1726 debug_filp
= filp_open(DEBUG_FILE_NAME
, O_WRONLY
, 0);
1727 if (IS_ERR(debug_filp
)) {
1728 pr_err("amstream: open debug file failed\n");
1732 mutex_unlock(&amstream_mutex
);
1734 if (port
->type
& PORT_TYPE_VIDEO
) {
1735 priv
->vdec
= vdec_create(port
, NULL
);
1737 if (priv
->vdec
== NULL
) {
1740 pr_err("amstream: vdec creation failed\n");
1743 if (!(port
->type
& PORT_TYPE_FRAME
)) {
1744 if ((port
->type
& PORT_TYPE_DUALDEC
) ||
1745 (vdec_get_debug_flags() & 0x100)) {
1746 priv
->vdec
->slave
= vdec_create(port
, priv
->vdec
);
1748 if (priv
->vdec
->slave
== NULL
) {
1749 vdec_release(priv
->vdec
);
1752 pr_err("amstream: sub vdec creation failed\n");
1762 static int amstream_release(struct inode
*inode
, struct file
*file
)
1764 struct port_priv_s
*priv
= file
->private_data
;
1765 struct stream_port_s
*port
= priv
->port
;
1766 struct vdec_s
*slave
= NULL
;
1767 #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
1770 if (iminor(inode
) >= amstream_port_num
)
1773 mutex_lock(&amstream_mutex
);
1775 if (port_get_inited(priv
))
1776 amstream_port_release(priv
);
1779 #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
1780 port_flag
= priv
->vdec
->port_flag
;
1782 if (priv
->vdec
->slave
)
1783 slave
= priv
->vdec
->slave
;
1784 vdec_release(priv
->vdec
);
1786 vdec_release(slave
);
1790 if ((port
->type
& (PORT_TYPE_AUDIO
| PORT_TYPE_VIDEO
)) ==
1793 struct stream_port_s
*s
;
1795 for (s
= &ports
[0], i
= 0; i
< amstream_port_num
; i
++, s
++) {
1796 if ((s
->flag
& PORT_FLAG_IN_USE
)
1797 && (s
->type
& PORT_TYPE_VIDEO
))
1800 if (i
== amstream_port_num
)
1801 timestamp_firstvpts_set(0);
1804 if (!is_mult_inc(port
->type
) ||
1805 (is_mult_inc(port
->type
) &&
1806 !is_support_no_parser()))
1809 /* timestamp_pcrscr_set(0); */
1813 filp_close(debug_filp
, current
->files
);
1818 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M6
) {
1819 if (port
->type
& PORT_TYPE_VIDEO
) {
1820 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M8
) {
1821 #ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
1822 if (has_hevc_vdec())
1823 vdec_poweroff(VDEC_HEVC
);
1825 vdec_poweroff(VDEC_1
);
1827 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TXLX
1828 && port
->vformat
== VFORMAT_H264
1830 vdec_poweroff(VDEC_HEVC
);
1833 if ((port
->vformat
== VFORMAT_HEVC
1834 || port
->vformat
== VFORMAT_AVS2
1835 || port
->vformat
== VFORMAT_AV1
1836 || port
->vformat
== VFORMAT_VP9
)) {
1837 vdec_poweroff(VDEC_HEVC
);
1839 vdec_poweroff(VDEC_1
);
1843 /* TODO: mod gate */
1844 /* switch_mod_gate_by_name("vdec", 0); */
1845 amports_switch_gate("vdec", 0);
1848 if (port
->type
& PORT_TYPE_AUDIO
) {
1849 /* TODO: mod gate */
1850 /* switch_mod_gate_by_name("audio", 0); */
1851 /* amports_switch_gate("audio", 0); */
1854 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M8
) {
1855 /* TODO: clc gate */
1856 /* CLK_GATE_OFF(HIU_PARSER_TOP); */
1857 amports_switch_gate("parser_top", 0);
1859 /* TODO: mod gate */
1860 /* switch_mod_gate_by_name("demux", 0); */
1861 amports_switch_gate("demux", 0);
1864 mutex_destroy(&priv
->mutex
);
1868 mutex_unlock(&amstream_mutex
);
1872 static long amstream_ioctl_get_version(struct port_priv_s
*priv
,
1875 int version
= (AMSTREAM_IOC_VERSION_FIRST
& 0xffff) << 16
1876 | (AMSTREAM_IOC_VERSION_SECOND
& 0xffff);
1877 put_user(version
, (u32 __user
*)arg
);
1881 static long amstream_ioctl_get(struct port_priv_s
*priv
, ulong arg
)
1883 struct stream_port_s
*this = priv
->port
;
1886 struct am_ioctl_parm parm
;
1889 ((void *)&parm
, (void *)arg
,
1894 case AMSTREAM_GET_SUB_LENGTH
:
1895 if ((this->type
& PORT_TYPE_SUB
) ||
1896 (this->type
& PORT_TYPE_SUB_RD
)) {
1898 struct stream_buf_s
*psbuf
= &bufs
[BUF_TYPE_SUBTITLE
];
1901 sub_wp
= stbuf_sub_wp_get();
1902 sub_rp
= stbuf_sub_rp_get();
1904 if (sub_wp
== sub_rp
)
1906 else if (sub_wp
> sub_rp
)
1907 val
= sub_wp
- sub_rp
;
1909 val
= psbuf
->buf_size
- (sub_rp
- sub_wp
);
1914 case AMSTREAM_GET_UD_LENGTH
:
1915 if (this->type
& PORT_TYPE_USERDATA
) {
1916 parm
.data_32
= userdata_length
;
1917 userdata_length
= 0;
1921 case AMSTREAM_GET_APTS_LOOKUP
:
1922 if (this->type
& PORT_TYPE_AUDIO
) {
1923 u32 pts
= 0, frame_size
, offset
;
1925 offset
= parm
.data_32
;
1926 pts_lookup_offset(PTS_TYPE_AUDIO
, offset
, &pts
,
1931 case AMSTREAM_GET_FIRST_APTS_FLAG
:
1932 if (this->type
& PORT_TYPE_AUDIO
) {
1933 parm
.data_32
= first_pts_checkin_complete(
1937 case AMSTREAM_GET_APTS
:
1938 parm
.data_32
= timestamp_apts_get();
1940 case AMSTREAM_GET_VPTS
:
1941 parm
.data_32
= timestamp_vpts_get();
1943 case AMSTREAM_GET_VPTS_U64
:
1944 parm
.data_64
= timestamp_vpts_get_u64();
1946 case AMSTREAM_GET_APTS_U64
:
1947 parm
.data_64
= timestamp_apts_get_u64();
1949 case AMSTREAM_GET_PCRSCR
:
1950 parm
.data_32
= timestamp_pcrscr_get();
1952 case AMSTREAM_GET_LAST_CHECKIN_APTS
:
1953 parm
.data_32
= get_last_checkin_pts(PTS_TYPE_AUDIO
);
1955 case AMSTREAM_GET_LAST_CHECKIN_VPTS
:
1956 parm
.data_32
= get_last_checkin_pts(PTS_TYPE_VIDEO
);
1958 case AMSTREAM_GET_LAST_CHECKOUT_APTS
:
1959 parm
.data_32
= get_last_checkout_pts(PTS_TYPE_AUDIO
);
1961 case AMSTREAM_GET_LAST_CHECKOUT_VPTS
:
1962 parm
.data_32
= get_last_checkout_pts(PTS_TYPE_VIDEO
);
1964 case AMSTREAM_GET_SUB_NUM
:
1965 parm
.data_32
= psparser_get_sub_found_num();
1967 case AMSTREAM_GET_VIDEO_DELAY_LIMIT_MS
:
1968 parm
.data_32
= bufs
[BUF_TYPE_VIDEO
].max_buffer_delay_ms
;
1970 case AMSTREAM_GET_AUDIO_DELAY_LIMIT_MS
:
1971 parm
.data_32
= bufs
[BUF_TYPE_AUDIO
].max_buffer_delay_ms
;
1973 case AMSTREAM_GET_VIDEO_CUR_DELAY_MS
: {
1976 delay
= calculation_stream_delayed_ms(
1977 PTS_TYPE_VIDEO
, NULL
, NULL
);
1979 parm
.data_32
= delay
;
1985 case AMSTREAM_GET_AUDIO_CUR_DELAY_MS
: {
1988 delay
= calculation_stream_delayed_ms(
1989 PTS_TYPE_AUDIO
, NULL
, NULL
);
1991 parm
.data_32
= delay
;
1996 case AMSTREAM_GET_AUDIO_AVG_BITRATE_BPS
: {
2000 delay
= calculation_stream_delayed_ms(
2001 PTS_TYPE_AUDIO
, NULL
, &avgbps
);
2003 parm
.data_32
= avgbps
;
2008 case AMSTREAM_GET_VIDEO_AVG_BITRATE_BPS
: {
2012 delay
= calculation_stream_delayed_ms(
2013 PTS_TYPE_VIDEO
, NULL
, &avgbps
);
2015 parm
.data_32
= avgbps
;
2020 case AMSTREAM_GET_ION_ID
:
2021 parm
.data_32
= priv
->vdec
->vf_receiver_inst
;
2023 case AMSTREAM_GET_NEED_MORE_DATA
:
2024 parm
.data_32
= vdec_need_more_data(priv
->vdec
);
2026 case AMSTREAM_GET_FREED_HANDLE
:
2027 parm
.data_32
= vdec_input_get_freed_handle(priv
->vdec
);
2033 /* pr_info("parm size:%d\n", sizeof(parm)); */
2035 if (copy_to_user((void *)arg
, &parm
, sizeof(parm
)))
2042 static long amstream_ioctl_set(struct port_priv_s
*priv
, ulong arg
)
2044 struct stream_port_s
*this = priv
->port
;
2045 struct am_ioctl_parm parm
;
2049 ((void *)&parm
, (void *)arg
,
2054 case AMSTREAM_SET_VB_START
:
2055 if ((this->type
& PORT_TYPE_VIDEO
) &&
2056 ((priv
->vdec
->vbuf
.flag
& BUF_FLAG_IN_USE
) == 0)) {
2057 priv
->vdec
->vbuf
.buf_start
= parm
.data_32
;
2061 case AMSTREAM_SET_VB_SIZE
:
2062 if ((this->type
& PORT_TYPE_VIDEO
) &&
2063 ((priv
->vdec
->vbuf
.flag
& BUF_FLAG_IN_USE
) == 0)) {
2064 if (priv
->vdec
->vbuf
.flag
& BUF_FLAG_ALLOC
) {
2065 r
+= stbuf_change_size(
2070 } else if (this->type
& PORT_TYPE_FRAME
) {
2071 /* todo: frame based set max buffer size */
2076 case AMSTREAM_SET_AB_START
:
2077 if ((this->type
& PORT_TYPE_AUDIO
) &&
2078 ((bufs
[BUF_TYPE_AUDIO
].flag
& BUF_FLAG_IN_USE
) == 0))
2079 bufs
[BUF_TYPE_AUDIO
].buf_start
= parm
.data_32
;
2083 case AMSTREAM_SET_AB_SIZE
:
2084 if ((this->type
& PORT_TYPE_AUDIO
) &&
2085 ((bufs
[BUF_TYPE_AUDIO
].flag
& BUF_FLAG_IN_USE
) == 0)) {
2086 if (bufs
[BUF_TYPE_AUDIO
].flag
& BUF_FLAG_ALLOC
) {
2087 r
= stbuf_change_size(
2088 &bufs
[BUF_TYPE_AUDIO
],
2095 case AMSTREAM_SET_VFORMAT
:
2096 if ((this->type
& PORT_TYPE_VIDEO
) &&
2097 (parm
.data_vformat
< VFORMAT_MAX
)) {
2098 this->vformat
= parm
.data_vformat
;
2099 this->flag
|= PORT_FLAG_VFORMAT
;
2101 vdec_set_format(priv
->vdec
, this->vformat
);
2105 case AMSTREAM_SET_AFORMAT
:
2106 if ((this->type
& PORT_TYPE_AUDIO
) &&
2107 (parm
.data_aformat
< AFORMAT_MAX
)) {
2108 memset(&audio_dec_info
, 0,
2109 sizeof(struct audio_info
));
2110 /* for new format,reset the audio info. */
2111 this->aformat
= parm
.data_aformat
;
2112 this->flag
|= PORT_FLAG_AFORMAT
;
2116 case AMSTREAM_SET_VID
:
2117 if (this->type
& PORT_TYPE_VIDEO
) {
2118 this->vid
= parm
.data_32
;
2119 this->flag
|= PORT_FLAG_VID
;
2124 case AMSTREAM_SET_AID
:
2125 if (this->type
& PORT_TYPE_AUDIO
) {
2126 this->aid
= parm
.data_32
;
2127 this->flag
|= PORT_FLAG_AID
;
2129 if (port_get_inited(priv
)) {
2130 //tsync_audio_break(1);
2131 amstream_change_avid(this);
2136 case AMSTREAM_SET_SID
:
2137 if (this->type
& PORT_TYPE_SUB
) {
2138 this->sid
= parm
.data_32
;
2139 this->flag
|= PORT_FLAG_SID
;
2141 if (port_get_inited(priv
))
2142 amstream_change_sid(this);
2147 case AMSTREAM_IOC_PCRID
:
2148 this->pcrid
= parm
.data_32
;
2149 this->pcr_inited
= 1;
2150 pr_err("set pcrid = 0x%x\n", this->pcrid
);
2152 case AMSTREAM_SET_ACHANNEL
:
2153 if (this->type
& PORT_TYPE_AUDIO
) {
2154 this->achanl
= parm
.data_32
;
2155 set_ch_num_info(parm
.data_32
);
2159 case AMSTREAM_SET_SAMPLERATE
:
2160 if (this->type
& PORT_TYPE_AUDIO
) {
2161 this->asamprate
= parm
.data_32
;
2162 set_sample_rate_info(parm
.data_32
);
2166 case AMSTREAM_SET_DATAWIDTH
:
2167 if (this->type
& PORT_TYPE_AUDIO
)
2168 this->adatawidth
= parm
.data_32
;
2172 case AMSTREAM_SET_TSTAMP
:
2173 if ((this->type
& (PORT_TYPE_AUDIO
| PORT_TYPE_VIDEO
)) ==
2174 ((PORT_TYPE_AUDIO
| PORT_TYPE_VIDEO
)))
2176 else if (this->type
& PORT_TYPE_FRAME
)
2177 r
= vdec_set_pts(priv
->vdec
, parm
.data_32
);
2178 else if ((this->type
& PORT_TYPE_VIDEO
) ||
2179 (this->type
& PORT_TYPE_HEVC
)) {
2180 struct stream_buf_s
*vbuf
= &priv
->vdec
->vbuf
;
2181 if (vbuf
->no_parser
) {
2182 pts_checkin_offset(PTS_TYPE_VIDEO
,
2183 vbuf
->stream_offset
, parm
.data_32
);
2185 r
= es_vpts_checkin(vbuf
, parm
.data_32
);
2187 } else if (this->type
& PORT_TYPE_AUDIO
)
2188 r
= es_apts_checkin(&bufs
[BUF_TYPE_AUDIO
],
2191 case AMSTREAM_SET_TSTAMP_US64
:
2192 if ((this->type
& (PORT_TYPE_AUDIO
| PORT_TYPE_VIDEO
)) ==
2193 ((PORT_TYPE_AUDIO
| PORT_TYPE_VIDEO
)))
2196 u64 pts
= parm
.data_64
;
2198 if (this->type
& PORT_TYPE_FRAME
) {
2200 *todo: check upper layer for decoder handler
2201 * life sequence or multi-tasking management
2203 r
= vdec_set_pts64(priv
->vdec
, pts
);
2204 } else if ((this->type
& PORT_TYPE_HEVC
) ||
2205 (this->type
& PORT_TYPE_VIDEO
)) {
2206 r
= es_vpts_checkin_us64(
2207 &priv
->vdec
->vbuf
, pts
);
2208 } else if (this->type
& PORT_TYPE_AUDIO
) {
2209 r
= es_vpts_checkin_us64(
2210 &bufs
[BUF_TYPE_AUDIO
], pts
);
2214 case AMSTREAM_PORT_INIT
:
2215 r
= amstream_port_init(priv
);
2217 case AMSTREAM_SET_TRICKMODE
:
2218 if ((this->type
& PORT_TYPE_VIDEO
) == 0)
2220 r
= vdec_set_trickmode(priv
->vdec
, parm
.data_32
);
2225 case AMSTREAM_AUDIO_RESET
:
2226 if (this->type
& PORT_TYPE_AUDIO
) {
2227 struct stream_buf_s
*pabuf
= &bufs
[BUF_TYPE_AUDIO
];
2229 r
= audio_port_reset(this, pabuf
);
2234 case AMSTREAM_SUB_RESET
:
2235 if (this->type
& PORT_TYPE_SUB
) {
2236 struct stream_buf_s
*psbuf
= &bufs
[BUF_TYPE_SUBTITLE
];
2238 r
= sub_port_reset(this, psbuf
);
2242 case AMSTREAM_DEC_RESET
:
2243 tsync_set_dec_reset();
2245 case AMSTREAM_SET_TS_SKIPBYTE
:
2246 tsdemux_set_skipbyte(parm
.data_32
);
2248 case AMSTREAM_SET_SUB_TYPE
:
2249 sub_type
= parm
.data_32
;
2251 case AMSTREAM_SET_PCRSCR
:
2252 timestamp_pcrscr_set(parm
.data_32
);
2254 case AMSTREAM_SET_DEMUX
:
2255 tsdemux_set_demux(parm
.data_32
);
2257 case AMSTREAM_SET_VIDEO_DELAY_LIMIT_MS
:
2258 priv
->vdec
->vbuf
.max_buffer_delay_ms
= parm
.data_32
;
2260 case AMSTREAM_SET_AUDIO_DELAY_LIMIT_MS
:
2261 bufs
[BUF_TYPE_AUDIO
].max_buffer_delay_ms
= parm
.data_32
;
2263 case AMSTREAM_SET_DRMMODE
:
2264 if (parm
.data_32
== 1) {
2265 pr_debug("set drmmode\n");
2266 this->flag
|= PORT_FLAG_DRM
;
2267 if ((this->type
& PORT_TYPE_VIDEO
) &&
2269 priv
->vdec
->port_flag
|= PORT_FLAG_DRM
;
2271 this->flag
&= (~PORT_FLAG_DRM
);
2272 pr_debug("no drmmode\n");
2275 case AMSTREAM_SET_APTS
: {
2279 if (tsync_get_mode() == TSYNC_MODE_PCRMASTER
)
2280 tsync_pcr_set_apts(pts
);
2282 tsync_set_apts(pts
);
2285 case AMSTREAM_SET_FRAME_BASE_PATH
:
2286 if (is_mult_inc(this->type
) &&
2287 (parm
.frame_base_video_path
< FRAME_BASE_PATH_MAX
)) {
2288 vdec_set_video_path(priv
->vdec
, parm
.data_32
);
2292 case AMSTREAM_SET_EOS
:
2294 vdec_set_eos(priv
->vdec
, parm
.data_32
);
2296 case AMSTREAM_SET_RECEIVE_ID
:
2297 if (is_mult_inc(this->type
))
2298 vdec_set_receive_id(priv
->vdec
, parm
.data_32
);
2302 case AMSTREAM_SET_IS_RESET
:
2304 vdec_set_isreset(priv
->vdec
, parm
.data_32
);
2306 case AMSTREAM_SET_DV_META_WITH_EL
:
2308 vdec_set_dv_metawithel(priv
->vdec
, parm
.data_32
);
2309 if (vdec_dual(priv
->vdec
) && priv
->vdec
->slave
)
2310 vdec_set_dv_metawithel(priv
->vdec
->slave
,
2314 case AMSTREAM_SET_NO_POWERDOWN
:
2315 vdec_set_no_powerdown(parm
.data_32
);
2324 static enum E_ASPECT_RATIO
get_normalized_aspect_ratio(u32 ratio_control
)
2326 enum E_ASPECT_RATIO euAspectRatio
;
2328 ratio_control
= ratio_control
>> DISP_RATIO_ASPECT_RATIO_BIT
;
2330 switch (ratio_control
) {
2333 euAspectRatio
= ASPECT_RATIO_16_9
;
2334 /*pr_info("ASPECT_RATIO_16_9\n");*/
2338 euAspectRatio
= ASPECT_RATIO_4_3
;
2339 /*pr_info("ASPECT_RATIO_4_3\n");*/
2342 euAspectRatio
= ASPECT_UNDEFINED
;
2343 /*pr_info("ASPECT_UNDEFINED and ratio_control = 0x%x\n",
2348 return euAspectRatio
;
2351 static long amstream_ioctl_get_ex(struct port_priv_s
*priv
, ulong arg
)
2353 struct stream_port_s
*this = priv
->port
;
2355 struct am_ioctl_parm_ex parm
;
2358 ((void *)&parm
, (void *)arg
,
2363 case AMSTREAM_GET_EX_VB_STATUS
:
2364 if (this->type
& PORT_TYPE_VIDEO
) {
2365 struct am_ioctl_parm_ex
*p
= &parm
;
2366 struct stream_buf_s
*buf
= NULL
;
2368 mutex_unlock(&amstream_mutex
);
2371 *todo: check upper layer for decoder
2374 if (priv
->vdec
== NULL
) {
2376 mutex_unlock(&amstream_mutex
);
2380 if (this->type
& PORT_TYPE_FRAME
) {
2381 struct vdec_input_status_s status
;
2383 r
= vdec_input_get_status(&priv
->vdec
->input
,
2386 p
->status
.size
= status
.size
;
2387 p
->status
.data_len
= status
.data_len
;
2388 p
->status
.free_len
= status
.free_len
;
2389 p
->status
.read_pointer
=
2390 status
.read_pointer
;
2392 mutex_unlock(&amstream_mutex
);
2396 buf
= &priv
->vdec
->vbuf
;
2397 p
->status
.size
= stbuf_canusesize(buf
);
2398 p
->status
.data_len
= stbuf_level(buf
);
2399 p
->status
.free_len
= stbuf_space(buf
);
2400 p
->status
.read_pointer
= stbuf_rp(buf
);
2401 mutex_unlock(&amstream_mutex
);
2405 case AMSTREAM_GET_EX_AB_STATUS
:
2406 if (this->type
& PORT_TYPE_AUDIO
) {
2407 struct am_ioctl_parm_ex
*p
= &parm
;
2408 struct stream_buf_s
*buf
= &bufs
[BUF_TYPE_AUDIO
];
2411 p
->status
.size
= stbuf_canusesize(buf
);
2412 p
->status
.data_len
= stbuf_level(buf
);
2413 p
->status
.free_len
= stbuf_space(buf
);
2414 p
->status
.read_pointer
= stbuf_rp(buf
);
2419 case AMSTREAM_GET_EX_VDECSTAT
:
2420 if ((this->type
& PORT_TYPE_VIDEO
) == 0) {
2421 pr_err("no video\n");
2424 struct vdec_info vstatus
;
2425 struct am_ioctl_parm_ex
*p
= &parm
;
2427 memset(&vstatus
, 0, sizeof(vstatus
));
2429 mutex_lock(&priv
->mutex
);
2430 if (vdec_status(priv
->vdec
, &vstatus
) == -1) {
2431 mutex_unlock(&priv
->mutex
);
2434 mutex_unlock(&priv
->mutex
);
2436 p
->vstatus
.width
= vstatus
.frame_width
;
2437 p
->vstatus
.height
= vstatus
.frame_height
;
2438 p
->vstatus
.fps
= vstatus
.frame_rate
;
2439 p
->vstatus
.error_count
= vstatus
.error_count
;
2440 p
->vstatus
.status
= vstatus
.status
;
2441 p
->vstatus
.euAspectRatio
=
2442 get_normalized_aspect_ratio(
2443 vstatus
.ratio_control
);
2447 case AMSTREAM_GET_EX_ADECSTAT
:
2448 if ((this->type
& PORT_TYPE_AUDIO
) == 0) {
2449 pr_err("no audio\n");
2452 if (amstream_adec_status
== NULL
) {
2454 *pr_err("no amstream_adec_status\n");
2457 memset(&parm
.astatus
, 0, sizeof(parm
.astatus
));
2459 struct adec_status astatus
;
2460 struct am_ioctl_parm_ex
*p
= &parm
;
2462 amstream_adec_status(&astatus
);
2463 p
->astatus
.channels
= astatus
.channels
;
2464 p
->astatus
.sample_rate
= astatus
.sample_rate
;
2465 p
->astatus
.resolution
= astatus
.resolution
;
2466 p
->astatus
.error_count
= astatus
.error_count
;
2467 p
->astatus
.status
= astatus
.status
;
2471 case AMSTREAM_GET_EX_UD_POC
:
2472 if (this->type
& PORT_TYPE_USERDATA
) {
2473 struct userdata_poc_info_t userdata_poc
=
2474 userdata_poc_info
[userdata_poc_ri
];
2475 memcpy(&parm
.data_userdata_info
,
2477 sizeof(struct userdata_poc_info_t
));
2480 if (userdata_poc_ri
== USERDATA_FIFO_NUM
)
2481 userdata_poc_ri
= 0;
2489 /* pr_info("parm size:%zx\n", sizeof(parm)); */
2491 if (copy_to_user((void *)arg
, &parm
, sizeof(parm
)))
2497 static long amstream_ioctl_set_ex(struct port_priv_s
*priv
, ulong arg
)
2502 static long amstream_ioctl_get_ptr(struct port_priv_s
*priv
, ulong arg
)
2506 struct am_ioctl_parm_ptr parm
;
2509 ((void *)&parm
, (void *)arg
,
2514 case AMSTREAM_GET_PTR_SUB_INFO
:
2516 struct subtitle_info msub_info
[MAX_SUB_NUM
];
2517 struct subtitle_info
*psub_info
[MAX_SUB_NUM
];
2520 for (i
= 0; i
< MAX_SUB_NUM
; i
++)
2521 psub_info
[i
] = &msub_info
[i
];
2523 r
= psparser_get_sub_info(psub_info
);
2526 memcpy(parm
.pdata_sub_info
, msub_info
,
2527 sizeof(struct subtitle_info
)
2536 /* pr_info("parm size:%d\n", sizeof(parm)); */
2538 if (copy_to_user((void *)arg
, &parm
, sizeof(parm
)))
2545 static long amstream_ioctl_set_ptr(struct port_priv_s
*priv
, ulong arg
)
2547 struct stream_port_s
*this = priv
->port
;
2548 struct am_ioctl_parm_ptr parm
;
2552 ((void *)&parm
, (void *)arg
,
2554 pr_err("[%s]%d, arg err\n", __func__
, __LINE__
);
2558 case AMSTREAM_SET_PTR_AUDIO_INFO
:
2559 if ((this->type
& PORT_TYPE_VIDEO
)
2560 || (this->type
& PORT_TYPE_AUDIO
)) {
2561 if (parm
.pdata_audio_info
!= NULL
) {
2563 ((void *)&audio_dec_info
, (void *)parm
.pdata_audio_info
,
2564 sizeof(audio_dec_info
))) {
2565 pr_err("[%s]%d, arg err\n", __func__
, __LINE__
);
2572 case AMSTREAM_SET_PTR_CONFIGS
:
2573 if (this->type
& PORT_TYPE_VIDEO
) {
2574 if (!parm
.pointer
|| (parm
.len
<= 0) ||
2575 (parm
.len
> PAGE_SIZE
)) {
2578 r
= copy_from_user(priv
->vdec
->config
,
2579 parm
.pointer
, parm
.len
);
2583 priv
->vdec
->config_len
= parm
.len
;
2595 static long amstream_do_ioctl_new(struct port_priv_s
*priv
,
2596 unsigned int cmd
, ulong arg
)
2599 struct stream_port_s
*this = priv
->port
;
2602 case AMSTREAM_IOC_GET_VERSION
:
2603 r
= amstream_ioctl_get_version(priv
, arg
);
2605 case AMSTREAM_IOC_GET
:
2606 r
= amstream_ioctl_get(priv
, arg
);
2608 case AMSTREAM_IOC_SET
:
2609 r
= amstream_ioctl_set(priv
, arg
);
2611 case AMSTREAM_IOC_GET_EX
:
2612 r
= amstream_ioctl_get_ex(priv
, arg
);
2614 case AMSTREAM_IOC_SET_EX
:
2615 r
= amstream_ioctl_set_ex(priv
, arg
);
2617 case AMSTREAM_IOC_GET_PTR
:
2618 r
= amstream_ioctl_get_ptr(priv
, arg
);
2620 case AMSTREAM_IOC_SET_PTR
:
2621 r
= amstream_ioctl_set_ptr(priv
, arg
);
2623 case AMSTREAM_IOC_SYSINFO
:
2624 if (this->type
& PORT_TYPE_VIDEO
)
2625 r
= vdec_set_decinfo(priv
->vdec
, (void *)arg
);
2629 case AMSTREAM_IOC_GET_QOSINFO
:
2630 case AMSTREAM_IOC_GET_MVDECINFO
:
2633 u32 struct_size
= 0;
2635 struct vdec_s
*vdec
= NULL
;
2636 struct vframe_counter_s
*tmpbuf
= kmalloc(QOS_FRAME_NUM
*
2637 sizeof(struct vframe_counter_s
),GFP_KERNEL
);
2638 struct av_param_mvdec_t __user
*uarg
= (void *)arg
;
2642 pr_err("kmalloc vframe_counter_s failed!\n");
2646 vdec
= vdec_get_vdec_by_id(vdec_id
);
2653 slots
= vdec_get_frame_vdec(vdec
, tmpbuf
);
2654 if (AMSTREAM_IOC_GET_MVDECINFO
== cmd
)
2655 put_user(slots
, &uarg
->slots
);
2657 if (AMSTREAM_IOC_GET_MVDECINFO
== cmd
) {
2658 if (get_user(vdec_id
, &uarg
->vdec_id
) < 0 ||
2659 get_user(struct_size
, &uarg
->struct_size
) < 0) {
2664 if (copy_to_user((void *)&uarg
->comm
,
2666 sizeof(struct vframe_comm_s
))) {
2671 if (struct_size
== sizeof(struct av_param_mvdec_t_old
)) {//old struct
2672 struct av_param_mvdec_t_old __user
*uarg_old
= (void *)arg
;
2674 for (m
=0; m
<slots
; m
++)
2675 if (copy_to_user((void *)&uarg_old
->minfo
[m
],
2677 sizeof(struct vframe_counter_s_old
))) {
2682 } else if (struct_size
== sizeof(struct av_param_mvdec_t
)) {//new struct
2683 if (copy_to_user((void *)&uarg
->minfo
[0],
2685 slots
*sizeof(struct vframe_counter_s
))) {
2691 pr_err("pass in size %u,old struct size %u,current struct size %u\n",
2692 struct_size
, (u32
)sizeof(struct av_param_mvdec_t_old
),(u32
)sizeof(struct av_param_mvdec_t
));
2693 pr_err("App use another picture size,we haven't support it.\n");
2695 }else { //For compatibility, only copy the qos
2696 struct av_param_qosinfo_t __user
*uarg
= (void *)arg
;
2698 for (i
=0; i
<slots
; i
++)
2699 if (copy_to_user((void *)&uarg
->vframe_qos
[i
],
2701 sizeof(struct vframe_qos_s
))) {
2708 /*Vdec didn't produce item,wait for 10 ms to avoid user application
2709 infinitely calling*/
2710 //msleep(10); let user app handle it.
2715 case AMSTREAM_IOC_GET_AVINFO
:
2717 struct av_param_info_t __user
*uarg
= (void *)arg
;
2718 struct av_info_t av_info
;
2721 if (this->type
& PORT_TYPE_VIDEO
) {
2722 av_info
.first_pic_coming
= get_first_pic_coming();
2723 av_info
.current_fps
= -1;
2724 av_info
.vpts
= timestamp_vpts_get();
2725 av_info
.vpts_err
= tsync_get_vpts_error_num();
2726 av_info
.apts
= timestamp_apts_get();
2727 av_info
.apts_err
= tsync_get_apts_error_num();
2728 av_info
.ts_error
= get_discontinue_counter();
2729 av_info
.first_vpts
= timestamp_firstvpts_get();
2730 av_info
.toggle_frame_count
= get_toggle_frame_count();
2731 delay
= calculation_stream_delayed_ms(
2732 PTS_TYPE_VIDEO
, NULL
, &avgbps
);
2734 av_info
.dec_video_bps
= avgbps
;
2736 av_info
.dec_video_bps
= 0;
2738 if (copy_to_user((void *)&uarg
->av_info
, (void *)&av_info
,
2739 sizeof(struct av_info_t
)))
2751 static long amstream_do_ioctl_old(struct port_priv_s
*priv
,
2752 unsigned int cmd
, ulong arg
)
2754 struct stream_port_s
*this = priv
->port
;
2759 case AMSTREAM_IOC_VB_START
:
2760 if ((this->type
& PORT_TYPE_VIDEO
) &&
2761 ((priv
->vdec
->vbuf
.flag
& BUF_FLAG_IN_USE
) == 0)) {
2762 priv
->vdec
->vbuf
.buf_start
= arg
;
2767 case AMSTREAM_IOC_VB_SIZE
:
2768 if ((this->type
& PORT_TYPE_VIDEO
) &&
2769 ((priv
->vdec
->vbuf
.flag
& BUF_FLAG_IN_USE
) == 0)) {
2770 if (priv
->vdec
->vbuf
.flag
& BUF_FLAG_ALLOC
) {
2771 r
+= stbuf_change_size(
2779 case AMSTREAM_IOC_AB_START
:
2780 if ((this->type
& PORT_TYPE_AUDIO
) &&
2781 ((bufs
[BUF_TYPE_AUDIO
].flag
& BUF_FLAG_IN_USE
) == 0))
2782 bufs
[BUF_TYPE_AUDIO
].buf_start
= arg
;
2787 case AMSTREAM_IOC_AB_SIZE
:
2788 if ((this->type
& PORT_TYPE_AUDIO
) &&
2789 ((bufs
[BUF_TYPE_AUDIO
].flag
& BUF_FLAG_IN_USE
) == 0)) {
2790 if (bufs
[BUF_TYPE_AUDIO
].flag
& BUF_FLAG_ALLOC
) {
2791 r
= stbuf_change_size(
2792 &bufs
[BUF_TYPE_AUDIO
], arg
, false);
2798 case AMSTREAM_IOC_VFORMAT
:
2799 if ((this->type
& PORT_TYPE_VIDEO
) && (arg
< VFORMAT_MAX
)) {
2800 this->vformat
= (enum vformat_e
)arg
;
2801 this->flag
|= PORT_FLAG_VFORMAT
;
2803 vdec_set_format(priv
->vdec
, this->vformat
);
2808 case AMSTREAM_IOC_AFORMAT
:
2809 if ((this->type
& PORT_TYPE_AUDIO
) && (arg
< AFORMAT_MAX
)) {
2810 memset(&audio_dec_info
, 0,
2811 sizeof(struct audio_info
));
2812 /* for new format,reset the audio info. */
2813 this->aformat
= (enum aformat_e
)arg
;
2814 this->flag
|= PORT_FLAG_AFORMAT
;
2819 case AMSTREAM_IOC_VID
:
2820 if (this->type
& PORT_TYPE_VIDEO
) {
2821 this->vid
= (u32
) arg
;
2822 this->flag
|= PORT_FLAG_VID
;
2828 case AMSTREAM_IOC_AID
:
2829 if (this->type
& PORT_TYPE_AUDIO
) {
2830 this->aid
= (u32
) arg
;
2831 this->flag
|= PORT_FLAG_AID
;
2833 if (port_get_inited(priv
)) {
2834 //tsync_audio_break(1);
2835 amstream_change_avid(this);
2841 case AMSTREAM_IOC_SID
:
2842 if (this->type
& PORT_TYPE_SUB
) {
2843 this->sid
= (u32
) arg
;
2844 this->flag
|= PORT_FLAG_SID
;
2846 if (port_get_inited(priv
))
2847 amstream_change_sid(this);
2853 case AMSTREAM_IOC_PCRID
:
2854 this->pcrid
= (u32
) arg
;
2855 this->pcr_inited
= 1;
2856 pr_err("set pcrid = 0x%x\n", this->pcrid
);
2859 case AMSTREAM_IOC_VB_STATUS
:
2860 if (this->type
& PORT_TYPE_VIDEO
) {
2861 struct am_io_param para
;
2862 struct am_io_param
*p
= ¶
;
2863 struct stream_buf_s
*buf
= NULL
;
2865 mutex_lock(&amstream_mutex
);
2868 *todo: check upper layer for decoder
2871 if (priv
->vdec
== NULL
) {
2873 mutex_unlock(&amstream_mutex
);
2877 if (this->type
& PORT_TYPE_FRAME
) {
2878 struct vdec_input_status_s status
;
2880 r
= vdec_input_get_status(&priv
->vdec
->input
,
2883 p
->status
.size
= status
.size
;
2884 p
->status
.data_len
= status
.data_len
;
2885 p
->status
.free_len
= status
.free_len
;
2886 p
->status
.read_pointer
=
2887 status
.read_pointer
;
2888 if (copy_to_user((void *)arg
, p
,
2892 mutex_unlock(&amstream_mutex
);
2896 buf
= &priv
->vdec
->vbuf
;
2897 p
->status
.size
= stbuf_canusesize(buf
);
2898 p
->status
.data_len
= stbuf_level(buf
);
2899 p
->status
.free_len
= stbuf_space(buf
);
2900 p
->status
.read_pointer
= stbuf_rp(buf
);
2901 if (copy_to_user((void *)arg
, p
, sizeof(para
)))
2904 mutex_unlock(&amstream_mutex
);
2910 case AMSTREAM_IOC_AB_STATUS
:
2911 if (this->type
& PORT_TYPE_AUDIO
) {
2912 struct am_io_param para
;
2913 struct am_io_param
*p
= ¶
;
2914 struct stream_buf_s
*buf
= &bufs
[BUF_TYPE_AUDIO
];
2916 p
->status
.size
= stbuf_canusesize(buf
);
2917 p
->status
.data_len
= stbuf_level(buf
);
2918 p
->status
.free_len
= stbuf_space(buf
);
2919 p
->status
.read_pointer
= stbuf_rp(buf
);
2920 if (copy_to_user((void *)arg
, p
, sizeof(para
)))
2927 case AMSTREAM_IOC_SYSINFO
:
2928 if (this->type
& PORT_TYPE_VIDEO
)
2929 r
= vdec_set_decinfo(priv
->vdec
, (void *)arg
);
2934 case AMSTREAM_IOC_ACHANNEL
:
2935 if (this->type
& PORT_TYPE_AUDIO
) {
2936 this->achanl
= (u32
) arg
;
2937 set_ch_num_info((u32
) arg
);
2942 case AMSTREAM_IOC_SAMPLERATE
:
2943 if (this->type
& PORT_TYPE_AUDIO
) {
2944 this->asamprate
= (u32
) arg
;
2945 set_sample_rate_info((u32
) arg
);
2950 case AMSTREAM_IOC_DATAWIDTH
:
2951 if (this->type
& PORT_TYPE_AUDIO
)
2952 this->adatawidth
= (u32
) arg
;
2957 case AMSTREAM_IOC_TSTAMP
:
2958 if ((this->type
& (PORT_TYPE_AUDIO
| PORT_TYPE_VIDEO
)) ==
2959 ((PORT_TYPE_AUDIO
| PORT_TYPE_VIDEO
)))
2961 else if (this->type
& PORT_TYPE_FRAME
)
2962 r
= vdec_set_pts(priv
->vdec
, arg
);
2963 else if ((this->type
& PORT_TYPE_VIDEO
) ||
2964 (this->type
& PORT_TYPE_HEVC
)) {
2965 struct stream_buf_s
*vbuf
= &priv
->vdec
->vbuf
;
2966 if (vbuf
->no_parser
) {
2967 pts_checkin_offset(PTS_TYPE_VIDEO
,
2968 vbuf
->stream_offset
, arg
);
2970 r
= es_vpts_checkin(vbuf
, arg
);
2972 } else if (this->type
& PORT_TYPE_AUDIO
)
2973 r
= es_apts_checkin(&bufs
[BUF_TYPE_AUDIO
], arg
);
2976 case AMSTREAM_IOC_TSTAMP_uS64
:
2977 if ((this->type
& (PORT_TYPE_AUDIO
| PORT_TYPE_VIDEO
)) ==
2978 ((PORT_TYPE_AUDIO
| PORT_TYPE_VIDEO
)))
2984 ((void *)&pts
, (void *)arg
, sizeof(u64
)))
2986 if (this->type
& PORT_TYPE_FRAME
) {
2988 *todo: check upper layer for decoder handler
2989 * life sequence or multi-tasking management
2992 r
= vdec_set_pts64(priv
->vdec
, pts
);
2993 } else if ((this->type
& PORT_TYPE_HEVC
) ||
2994 (this->type
& PORT_TYPE_VIDEO
)) {
2995 r
= es_vpts_checkin_us64(
2996 &priv
->vdec
->vbuf
, pts
);
2997 } else if (this->type
& PORT_TYPE_AUDIO
) {
2998 r
= es_vpts_checkin_us64(
2999 &bufs
[BUF_TYPE_AUDIO
], pts
);
3004 case AMSTREAM_IOC_VDECSTAT
:
3005 if ((this->type
& PORT_TYPE_VIDEO
) == 0)
3008 struct vdec_info vstatus
;
3009 struct am_io_param para
;
3010 struct am_io_param
*p
= ¶
;
3012 memset(&vstatus
, 0, sizeof(vstatus
));
3014 mutex_lock(&priv
->mutex
);
3015 if (vdec_status(priv
->vdec
, &vstatus
) == -1) {
3016 mutex_unlock(&priv
->mutex
);
3019 mutex_unlock(&priv
->mutex
);
3021 p
->vstatus
.width
= vstatus
.frame_width
;
3022 p
->vstatus
.height
= vstatus
.frame_height
;
3023 p
->vstatus
.fps
= vstatus
.frame_rate
;
3024 p
->vstatus
.error_count
= vstatus
.error_count
;
3025 p
->vstatus
.status
= vstatus
.status
;
3026 p
->vstatus
.euAspectRatio
=
3027 get_normalized_aspect_ratio(
3028 vstatus
.ratio_control
);
3030 if (copy_to_user((void *)arg
, p
, sizeof(para
)))
3035 case AMSTREAM_IOC_VDECINFO
:
3036 if ((this->type
& PORT_TYPE_VIDEO
) == 0)
3039 struct vdec_info vinfo
;
3040 struct am_io_info para
;
3042 memset(¶
, 0x0, sizeof(struct am_io_info
));
3044 mutex_lock(&priv
->mutex
);
3045 if (vdec_status(priv
->vdec
, &vinfo
) == -1) {
3046 mutex_unlock(&priv
->mutex
);
3049 mutex_unlock(&priv
->mutex
);
3051 memcpy(¶
.vinfo
, &vinfo
, sizeof(struct vdec_info
));
3052 if (copy_to_user((void *)arg
, ¶
, sizeof(para
)))
3057 case AMSTREAM_IOC_ADECSTAT
:
3058 if ((this->type
& PORT_TYPE_AUDIO
) == 0)
3060 if (amstream_adec_status
== NULL
)
3063 struct adec_status astatus
;
3064 struct am_io_param para
;
3065 struct am_io_param
*p
= ¶
;
3067 amstream_adec_status(&astatus
);
3068 p
->astatus
.channels
= astatus
.channels
;
3069 p
->astatus
.sample_rate
= astatus
.sample_rate
;
3070 p
->astatus
.resolution
= astatus
.resolution
;
3071 p
->astatus
.error_count
= astatus
.error_count
;
3072 p
->astatus
.status
= astatus
.status
;
3073 if (copy_to_user((void *)arg
, p
, sizeof(para
)))
3077 case AMSTREAM_IOC_PORT_INIT
:
3078 r
= amstream_port_init(priv
);
3081 case AMSTREAM_IOC_VDEC_RESET
:
3082 if ((this->type
& PORT_TYPE_VIDEO
) == 0)
3085 if (priv
->vdec
== NULL
)
3088 r
= vdec_reset(priv
->vdec
);
3091 case AMSTREAM_IOC_TRICKMODE
:
3092 if ((this->type
& PORT_TYPE_VIDEO
) == 0)
3094 r
= vdec_set_trickmode(priv
->vdec
, arg
);
3099 case AMSTREAM_IOC_AUDIO_INFO
:
3100 if ((this->type
& PORT_TYPE_VIDEO
)
3101 || (this->type
& PORT_TYPE_AUDIO
)) {
3103 (&audio_dec_info
, (void __user
*)arg
,
3104 sizeof(audio_dec_info
)))
3110 case AMSTREAM_IOC_AUDIO_RESET
:
3111 if (this->type
& PORT_TYPE_AUDIO
) {
3112 struct stream_buf_s
*pabuf
= &bufs
[BUF_TYPE_AUDIO
];
3114 r
= audio_port_reset(this, pabuf
);
3120 case AMSTREAM_IOC_SUB_RESET
:
3121 if (this->type
& PORT_TYPE_SUB
) {
3122 struct stream_buf_s
*psbuf
= &bufs
[BUF_TYPE_SUBTITLE
];
3124 r
= sub_port_reset(this, psbuf
);
3129 case AMSTREAM_IOC_SUB_LENGTH
:
3130 if ((this->type
& PORT_TYPE_SUB
) ||
3131 (this->type
& PORT_TYPE_SUB_RD
)) {
3133 struct stream_buf_s
*psbuf
= &bufs
[BUF_TYPE_SUBTITLE
];
3136 sub_wp
= stbuf_sub_wp_get();
3137 sub_rp
= stbuf_sub_rp_get();
3139 if (sub_wp
== sub_rp
)
3141 else if (sub_wp
> sub_rp
)
3142 val
= sub_wp
- sub_rp
;
3144 val
= psbuf
->buf_size
- (sub_rp
- sub_wp
);
3145 put_user(val
, (int __user
*)arg
);
3150 case AMSTREAM_IOC_UD_LENGTH
:
3151 if (this->type
& PORT_TYPE_USERDATA
) {
3152 /* *((u32 *)arg) = userdata_length; */
3153 put_user(userdata_length
, (unsigned long __user
*)arg
);
3154 userdata_length
= 0;
3159 case AMSTREAM_IOC_UD_POC
:
3160 if (this->type
& PORT_TYPE_USERDATA
) {
3161 /* *((u32 *)arg) = userdata_length; */
3163 #ifdef DEBUG_USER_DATA
3168 mutex_lock(&userdata_mutex
);
3169 if (userdata_poc_wi
!= userdata_poc_ri
) {
3171 ri
= userdata_poc_ri
;
3172 #ifdef DEBUG_USER_DATA
3173 wi
= userdata_poc_wi
;
3176 if (userdata_poc_ri
>= USERDATA_FIFO_NUM
)
3177 userdata_poc_ri
= 0;
3179 mutex_unlock(&userdata_mutex
);
3182 struct userdata_poc_info_t userdata_poc
=
3183 userdata_poc_info
[ri
];
3184 #ifdef DEBUG_USER_DATA
3185 pr_info("read poc: ri=%d, wi=%d, poc=%d, last_wi=%d\n",
3187 userdata_poc
.poc_number
,
3191 copy_to_user((unsigned long __user
*)arg
,
3193 sizeof(struct userdata_poc_info_t
));
3204 case AMSTREAM_IOC_UD_BUF_READ
:
3206 if (this->type
& PORT_TYPE_USERDATA
) {
3207 struct userdata_param_t param
;
3208 struct userdata_param_t
*p_userdata_param
;
3209 struct vdec_s
*vdec
;
3211 p_userdata_param
= ¶m
;
3212 if (copy_from_user(p_userdata_param
,
3214 sizeof(struct userdata_param_t
))) {
3218 mutex_lock(&amstream_mutex
);
3219 vdec
= vdec_get_vdec_by_id(p_userdata_param
->instance_id
);
3221 if (vdec_read_user_data(vdec
,
3222 p_userdata_param
) == 0) {
3224 mutex_unlock(&amstream_mutex
);
3228 if (copy_to_user((void *)arg
,
3230 sizeof(struct userdata_param_t
)))
3234 mutex_unlock(&amstream_mutex
);
3239 case AMSTREAM_IOC_UD_AVAILABLE_VDEC
:
3241 unsigned int ready_vdec
;
3243 mutex_lock(&userdata_mutex
);
3244 ready_vdec
= ud_ready_vdec_flag
;
3245 ud_ready_vdec_flag
= 0;
3246 mutex_unlock(&userdata_mutex
);
3248 put_user(ready_vdec
, (uint32_t __user
*)arg
);
3252 case AMSTREAM_IOC_GET_VDEC_ID
:
3253 if (this->type
& PORT_TYPE_VIDEO
&& priv
->vdec
) {
3254 put_user(priv
->vdec
->id
, (int32_t __user
*)arg
);
3260 case AMSTREAM_IOC_UD_FLUSH_USERDATA
:
3261 if (this->type
& PORT_TYPE_USERDATA
) {
3262 struct vdec_s
*vdec
;
3265 mutex_lock(&amstream_mutex
);
3266 get_user(vdec_id
, (int __user
*)arg
);
3267 vdec
= vdec_get_vdec_by_id(vdec_id
);
3269 vdec_reset_userdata_fifo(vdec
, 0);
3270 pr_info("reset_userdata_fifo for vdec: %d\n", vdec_id
);
3272 mutex_unlock(&amstream_mutex
);
3277 case AMSTREAM_IOC_SET_DEC_RESET
:
3278 tsync_set_dec_reset();
3281 case AMSTREAM_IOC_TS_SKIPBYTE
:
3283 tsdemux_set_skipbyte(arg
);
3288 case AMSTREAM_IOC_SUB_TYPE
:
3289 sub_type
= (int)arg
;
3292 case AMSTREAM_IOC_APTS_LOOKUP
:
3293 if (this->type
& PORT_TYPE_AUDIO
) {
3294 u32 pts
= 0, frame_size
, offset
;
3296 get_user(offset
, (unsigned long __user
*)arg
);
3297 pts_lookup_offset(PTS_TYPE_AUDIO
, offset
, &pts
,
3299 put_user(pts
, (int __user
*)arg
);
3302 case GET_FIRST_APTS_FLAG
:
3303 if (this->type
& PORT_TYPE_AUDIO
) {
3304 put_user(first_pts_checkin_complete(PTS_TYPE_AUDIO
),
3309 case AMSTREAM_IOC_APTS
:
3310 put_user(timestamp_apts_get(), (int __user
*)arg
);
3313 case AMSTREAM_IOC_VPTS
:
3314 put_user(timestamp_vpts_get(), (int __user
*)arg
);
3317 case AMSTREAM_IOC_PCRSCR
:
3318 put_user(timestamp_pcrscr_get(), (int __user
*)arg
);
3321 case AMSTREAM_IOC_SET_PCRSCR
:
3322 timestamp_pcrscr_set(arg
);
3324 case AMSTREAM_IOC_GET_LAST_CHECKIN_APTS
:
3325 put_user(get_last_checkin_pts(PTS_TYPE_AUDIO
), (int *)arg
);
3327 case AMSTREAM_IOC_GET_LAST_CHECKIN_VPTS
:
3328 put_user(get_last_checkin_pts(PTS_TYPE_VIDEO
), (int *)arg
);
3330 case AMSTREAM_IOC_GET_LAST_CHECKOUT_APTS
:
3331 put_user(get_last_checkout_pts(PTS_TYPE_AUDIO
), (int *)arg
);
3333 case AMSTREAM_IOC_GET_LAST_CHECKOUT_VPTS
:
3334 put_user(get_last_checkout_pts(PTS_TYPE_VIDEO
), (int *)arg
);
3336 case AMSTREAM_IOC_SUB_NUM
:
3337 put_user(psparser_get_sub_found_num(), (int *)arg
);
3340 case AMSTREAM_IOC_SUB_INFO
:
3342 struct subtitle_info msub_info
[MAX_SUB_NUM
];
3343 struct subtitle_info
*psub_info
[MAX_SUB_NUM
];
3346 for (i
= 0; i
< MAX_SUB_NUM
; i
++)
3347 psub_info
[i
] = &msub_info
[i
];
3349 r
= psparser_get_sub_info(psub_info
);
3352 if (copy_to_user((void __user
*)arg
, msub_info
,
3353 sizeof(struct subtitle_info
) * MAX_SUB_NUM
))
3358 case AMSTREAM_IOC_SET_DEMUX
:
3359 tsdemux_set_demux((int)arg
);
3361 case AMSTREAM_IOC_SET_VIDEO_DELAY_LIMIT_MS
:
3362 priv
->vdec
->vbuf
.max_buffer_delay_ms
= (int)arg
;
3364 case AMSTREAM_IOC_SET_AUDIO_DELAY_LIMIT_MS
:
3365 bufs
[BUF_TYPE_AUDIO
].max_buffer_delay_ms
= (int)arg
;
3367 case AMSTREAM_IOC_GET_VIDEO_DELAY_LIMIT_MS
:
3368 put_user(priv
->vdec
->vbuf
.max_buffer_delay_ms
, (int *)arg
);
3370 case AMSTREAM_IOC_GET_AUDIO_DELAY_LIMIT_MS
:
3371 put_user(bufs
[BUF_TYPE_AUDIO
].max_buffer_delay_ms
, (int *)arg
);
3373 case AMSTREAM_IOC_GET_VIDEO_CUR_DELAY_MS
: {
3376 delay
= calculation_stream_delayed_ms(
3377 PTS_TYPE_VIDEO
, NULL
, NULL
);
3379 put_user(delay
, (int *)arg
);
3381 put_user(0, (int *)arg
);
3385 case AMSTREAM_IOC_GET_AUDIO_CUR_DELAY_MS
: {
3388 delay
= calculation_stream_delayed_ms(PTS_TYPE_AUDIO
, NULL
,
3391 put_user(delay
, (int *)arg
);
3393 put_user(0, (int *)arg
);
3396 case AMSTREAM_IOC_GET_AUDIO_AVG_BITRATE_BPS
: {
3400 delay
= calculation_stream_delayed_ms(PTS_TYPE_AUDIO
, NULL
,
3403 put_user(avgbps
, (int *)arg
);
3405 put_user(0, (int *)arg
);
3408 case AMSTREAM_IOC_GET_VIDEO_AVG_BITRATE_BPS
: {
3412 delay
= calculation_stream_delayed_ms(PTS_TYPE_VIDEO
, NULL
,
3415 put_user(avgbps
, (int *)arg
);
3417 put_user(0, (int *)arg
);
3420 case AMSTREAM_IOC_SET_DRMMODE
:
3421 if ((u32
) arg
== 1) {
3422 pr_err("set drmmode, input must be secure buffer\n");
3423 this->flag
|= PORT_FLAG_DRM
;
3424 if ((this->type
& PORT_TYPE_VIDEO
) &&
3426 priv
->vdec
->port_flag
|= PORT_FLAG_DRM
;
3427 } else if ((u32
)arg
== 2) {
3428 pr_err("set drmmode, input must be normal buffer\n");
3429 if ((this->type
& PORT_TYPE_VIDEO
) &&
3431 pr_err("vdec port_flag with drmmode\n");
3432 priv
->vdec
->port_flag
|= PORT_FLAG_DRM
;
3435 this->flag
&= (~PORT_FLAG_DRM
);
3436 pr_err("no drmmode\n");
3439 case AMSTREAM_IOC_SET_APTS
: {
3442 if (get_user(pts
, (unsigned long __user
*)arg
)) {
3444 ("Get audio pts from user space fault!\n");
3447 if (tsync_get_mode() == TSYNC_MODE_PCRMASTER
)
3448 tsync_pcr_set_apts(pts
);
3450 tsync_set_apts(pts
);
3453 case AMSTREAM_IOC_SET_CRC
: {
3454 struct usr_crc_info_t crc_info
;
3455 struct vdec_s
*vdec
;
3457 if (copy_from_user(&crc_info
, (void __user
*)arg
,
3458 sizeof(struct usr_crc_info_t
))) {
3462 pr_info("id %d, frame %d, y_crc: %08x, uv_crc: %08x\n", crc_info.id,
3463 crc_info.pic_num, crc_info.y_crc, crc_info.uv_crc);
3465 vdec
= vdec_get_vdec_by_id(crc_info
.id
);
3468 if (vdec
->vfc
.cmp_pool
== NULL
) {
3469 vdec
->vfc
.cmp_pool
=
3470 vmalloc(USER_CMP_POOL_MAX_SIZE
*
3471 sizeof(struct usr_crc_info_t
));
3472 if (vdec
->vfc
.cmp_pool
== NULL
)
3475 if (vdec
->vfc
.usr_cmp_num
>= USER_CMP_POOL_MAX_SIZE
) {
3476 pr_info("warn: could not write any more, max %d",
3477 USER_CMP_POOL_MAX_SIZE
);
3480 memcpy(&vdec
->vfc
.cmp_pool
[vdec
->vfc
.usr_cmp_num
], &crc_info
,
3481 sizeof(struct usr_crc_info_t
));
3482 vdec
->vfc
.usr_cmp_num
++;
3485 case AMSTREAM_IOC_GET_CRC_CMP_RESULT
: {
3487 struct vdec_s
*vdec
;
3489 if (get_user(val
, (int __user
*)arg
)) {
3492 vdec_id
= val
& 0x00ff;
3493 vdec
= vdec_get_vdec_by_id(vdec_id
);
3497 put_user(vdec
->vfc
.usr_cmp_num
, (int *)arg
);
3499 put_user(vdec
->vfc
.usr_cmp_result
, (int *)arg
);
3501 pr_info("amstream get crc32 cmpare num %d result: %d\n",
3502 vdec->vfc.usr_cmp_num, vdec->vfc.usr_cmp_result);
3506 case AMSTREAM_IOC_INIT_EX_STBUF
: {
3507 struct stream_buffer_metainfo parm
;
3508 struct stream_buf_s
*vbuf
= NULL
;
3510 if (priv
->vdec
== NULL
) {
3511 pr_err("init %s, no vdec.\n", __func__
);
3515 vbuf
= &priv
->vdec
->vbuf
;
3517 pr_err("init %s, no stbuf.\n", __func__
);
3521 if (copy_from_user(&parm
, (void __user
*)arg
,
3522 sizeof(struct stream_buffer_metainfo
))) {
3525 stream_buffer_set_ext_buf(vbuf
, parm
.stbuf_start
,
3526 parm
.stbuf_size
, parm
.stbuf_flag
);
3529 case AMSTREAM_IOC_WR_STBUF_META
: {
3530 struct stream_buffer_metainfo meta
;
3531 struct stream_buf_s
*vbuf
= NULL
;
3533 if (priv
->vdec
== NULL
) {
3534 pr_err("write %s, no vdec.\n", __func__
);
3538 vbuf
= &priv
->vdec
->vbuf
;
3540 pr_err("write %s, no stbuf.\n", __func__
);
3544 if (vbuf
->ops
== NULL
) {
3545 pr_err("write %s, no ops.\n", __func__
);
3549 if (copy_from_user(&meta
, (void __user
*)arg
,
3550 sizeof(struct stream_buffer_metainfo
))) {
3553 if (!vbuf
->ext_buf_addr
)
3556 stream_buffer_meta_write(vbuf
, &meta
);
3559 case AMSTREAM_IOC_GET_STBUF_STATUS
: {
3560 struct stream_buffer_status st
;
3561 struct stream_buf_s
*pbuf
= NULL
;
3563 if (priv
->vdec
== NULL
) {
3564 pr_err("get status %s, no vdec.\n", __func__
);
3568 pbuf
= &priv
->vdec
->vbuf
;
3570 pr_err("get status %s, no stbuf.\n", __func__
);
3574 if (pbuf
->ops
== NULL
) {
3575 pr_err("get status %s, no ops.\n", __func__
);
3579 st
.stbuf_start
= pbuf
->ext_buf_addr
;
3580 st
.stbuf_size
= pbuf
->buf_size
;
3581 st
.stbuf_rp
= pbuf
->ops
->get_rp(pbuf
);
3582 st
.stbuf_wp
= pbuf
->ops
->get_wp(pbuf
);
3583 if (copy_to_user((void __user
*)arg
, &st
,
3584 sizeof(struct stream_buffer_status
))) {
3597 static long amstream_do_ioctl(struct port_priv_s
*priv
,
3598 unsigned int cmd
, ulong arg
)
3603 case AMSTREAM_IOC_GET_VERSION
:
3604 case AMSTREAM_IOC_GET
:
3605 case AMSTREAM_IOC_SET
:
3606 case AMSTREAM_IOC_GET_EX
:
3607 case AMSTREAM_IOC_SET_EX
:
3608 case AMSTREAM_IOC_GET_PTR
:
3609 case AMSTREAM_IOC_SET_PTR
:
3610 case AMSTREAM_IOC_SYSINFO
:
3611 case AMSTREAM_IOC_GET_QOSINFO
:
3612 case AMSTREAM_IOC_GET_MVDECINFO
:
3613 case AMSTREAM_IOC_GET_AVINFO
:
3614 r
= amstream_do_ioctl_new(priv
, cmd
, arg
);
3617 r
= amstream_do_ioctl_old(priv
, cmd
, arg
);
3621 pr_err("amstream_do_ioctl error :%lx, %x\n", r
, cmd
);
3625 static long amstream_ioctl(struct file
*file
, unsigned int cmd
, ulong arg
)
3627 struct port_priv_s
*priv
= (struct port_priv_s
*)file
->private_data
;
3628 struct stream_port_s
*this = priv
->port
;
3633 return amstream_do_ioctl(priv
, cmd
, arg
);
3636 #ifdef CONFIG_COMPAT
3637 struct dec_sysinfo32
{
3653 compat_uptr_t param
;
3658 struct am_ioctl_parm_ptr32
{
3660 compat_uptr_t pdata_audio_info
;
3661 compat_uptr_t pdata_sub_info
;
3662 compat_uptr_t pointer
;
3669 static long amstream_ioc_setget_ptr(struct port_priv_s
*priv
,
3670 unsigned int cmd
, struct am_ioctl_parm_ptr32 __user
*arg
)
3672 struct am_ioctl_parm_ptr __user
*data
;
3673 struct am_ioctl_parm_ptr32 param
;
3676 if (copy_from_user(¶m
,
3678 sizeof(struct am_ioctl_parm_ptr32
)))
3681 data
= compat_alloc_user_space(sizeof(*data
));
3682 if (!access_ok(VERIFY_WRITE
, data
, sizeof(*data
)))
3685 if (put_user(param
.cmd
, &data
->cmd
) ||
3686 put_user(compat_ptr(param
.pointer
), &data
->pointer
) ||
3687 put_user(param
.len
, &data
->len
))
3690 ret
= amstream_do_ioctl(priv
, cmd
, (unsigned long)data
);
3697 static long amstream_set_sysinfo(struct port_priv_s
*priv
,
3698 struct dec_sysinfo32 __user
*arg
)
3700 struct dec_sysinfo __user
*data
;
3701 struct dec_sysinfo32 __user
*data32
= arg
;
3703 struct dec_sysinfo32 param
;
3705 if (copy_from_user(¶m
,
3707 sizeof(struct dec_sysinfo32
)))
3710 data
= compat_alloc_user_space(sizeof(*data
));
3711 if (!access_ok(VERIFY_WRITE
, data
, sizeof(*data
)))
3713 if (copy_in_user(data
, data32
, 7 * sizeof(u32
)))
3715 if (put_user(compat_ptr(param
.param
), &data
->param
))
3717 if (copy_in_user(&data
->ratio64
, &data32
->ratio64
,
3718 sizeof(data
->ratio64
)))
3721 ret
= amstream_do_ioctl(priv
, AMSTREAM_IOC_SYSINFO
,
3722 (unsigned long)data
);
3726 if (copy_in_user(&arg
->format
, &data
->format
, 7 * sizeof(u32
)) ||
3727 copy_in_user(&arg
->ratio64
, &data
->ratio64
,
3728 sizeof(arg
->ratio64
)))
3735 struct userdata_param32_t
{
3737 uint32_t instance_id
; /*input, 0~9*/
3738 uint32_t buf_len
; /*input*/
3739 uint32_t data_size
; /*output*/
3740 compat_uptr_t pbuf_addr
; /*input*/
3741 struct userdata_meta_info_t meta_info
; /*output*/
3745 static long amstream_ioc_get_userdata(struct port_priv_s
*priv
,
3746 struct userdata_param32_t __user
*arg
)
3748 struct userdata_param_t __user
*data
;
3749 struct userdata_param32_t __user
*data32
= arg
;
3751 struct userdata_param32_t param
;
3754 if (copy_from_user(¶m
,
3756 sizeof(struct userdata_param32_t
)))
3759 data
= compat_alloc_user_space(sizeof(*data
));
3760 if (!access_ok(VERIFY_WRITE
, data
, sizeof(*data
)))
3763 if (copy_in_user(data
, data32
, 4 * sizeof(u32
)))
3766 if (copy_in_user(&data
->meta_info
, &data32
->meta_info
,
3767 sizeof(data
->meta_info
)))
3770 if (put_user(compat_ptr(param
.pbuf_addr
), &data
->pbuf_addr
))
3773 ret
= amstream_do_ioctl(priv
, AMSTREAM_IOC_UD_BUF_READ
,
3774 (unsigned long)data
);
3778 if (copy_in_user(&data32
->version
, &data
->version
, 4 * sizeof(u32
)) ||
3779 copy_in_user(&data32
->meta_info
, &data
->meta_info
,
3780 sizeof(data32
->meta_info
)))
3787 static long amstream_compat_ioctl(struct file
*file
,
3788 unsigned int cmd
, ulong arg
)
3791 struct port_priv_s
*priv
= (struct port_priv_s
*)file
->private_data
;
3794 case AMSTREAM_IOC_GET_VERSION
:
3795 case AMSTREAM_IOC_GET
:
3796 case AMSTREAM_IOC_SET
:
3797 case AMSTREAM_IOC_GET_EX
:
3798 case AMSTREAM_IOC_SET_EX
:
3799 return amstream_do_ioctl(priv
, cmd
, (ulong
)compat_ptr(arg
));
3800 case AMSTREAM_IOC_GET_PTR
:
3801 case AMSTREAM_IOC_SET_PTR
:
3802 return amstream_ioc_setget_ptr(priv
, cmd
, compat_ptr(arg
));
3803 case AMSTREAM_IOC_SYSINFO
:
3804 return amstream_set_sysinfo(priv
, compat_ptr(arg
));
3805 case AMSTREAM_IOC_UD_BUF_READ
:
3806 return amstream_ioc_get_userdata(priv
, compat_ptr(arg
));
3808 return amstream_do_ioctl(priv
, cmd
, (ulong
)compat_ptr(arg
));
3815 static ssize_t
ports_show(struct class *class, struct class_attribute
*attr
,
3820 struct stream_port_s
*p
= NULL
;
3822 for (i
= 0; i
< amstream_port_num
; i
++) {
3825 pbuf
+= sprintf(pbuf
, "%s\t:\n", p
->name
);
3827 pbuf
+= sprintf(pbuf
, "\ttype:%d( ", p
->type
);
3828 if (p
->type
& PORT_TYPE_VIDEO
)
3829 pbuf
+= sprintf(pbuf
, "%s ", "Video");
3830 if (p
->type
& PORT_TYPE_AUDIO
)
3831 pbuf
+= sprintf(pbuf
, "%s ", "Audio");
3832 if (p
->type
& PORT_TYPE_MPTS
)
3833 pbuf
+= sprintf(pbuf
, "%s ", "TS");
3834 if (p
->type
& PORT_TYPE_MPPS
)
3835 pbuf
+= sprintf(pbuf
, "%s ", "PS");
3836 if (p
->type
& PORT_TYPE_ES
)
3837 pbuf
+= sprintf(pbuf
, "%s ", "ES");
3838 if (p
->type
& PORT_TYPE_RM
)
3839 pbuf
+= sprintf(pbuf
, "%s ", "RM");
3840 if (p
->type
& PORT_TYPE_SUB
)
3841 pbuf
+= sprintf(pbuf
, "%s ", "Subtitle");
3842 if (p
->type
& PORT_TYPE_SUB_RD
)
3843 pbuf
+= sprintf(pbuf
, "%s ", "Subtitle_Read");
3844 if (p
->type
& PORT_TYPE_USERDATA
)
3845 pbuf
+= sprintf(pbuf
, "%s ", "userdata");
3846 pbuf
+= sprintf(pbuf
, ")\n");
3848 pbuf
+= sprintf(pbuf
, "\tflag:%d( ", p
->flag
);
3849 if (p
->flag
& PORT_FLAG_IN_USE
)
3850 pbuf
+= sprintf(pbuf
, "%s ", "Used");
3852 pbuf
+= sprintf(pbuf
, "%s ", "Unused");
3853 if ((p
->type
& PORT_TYPE_VIDEO
) == 0) {
3854 if (p
->flag
& PORT_FLAG_INITED
)
3855 pbuf
+= sprintf(pbuf
, "%s ", "inited");
3857 pbuf
+= sprintf(pbuf
, "%s ", "uninited");
3859 pbuf
+= sprintf(pbuf
, ")\n");
3861 pbuf
+= sprintf(pbuf
, "\tVformat:%d\n",
3862 (p
->flag
& PORT_FLAG_VFORMAT
) ? p
->vformat
: -1);
3863 pbuf
+= sprintf(pbuf
, "\tAformat:%d\n",
3864 (p
->flag
& PORT_FLAG_AFORMAT
) ? p
->aformat
: -1);
3865 pbuf
+= sprintf(pbuf
, "\tVid:%d\n",
3866 (p
->flag
& PORT_FLAG_VID
) ? p
->vid
: -1);
3867 pbuf
+= sprintf(pbuf
, "\tAid:%d\n",
3868 (p
->flag
& PORT_FLAG_AID
) ? p
->aid
: -1);
3869 pbuf
+= sprintf(pbuf
, "\tSid:%d\n",
3870 (p
->flag
& PORT_FLAG_SID
) ? p
->sid
: -1);
3871 pbuf
+= sprintf(pbuf
, "\tPCRid:%d\n",
3872 (p
->pcr_inited
== 1) ? p
->pcrid
: -1);
3873 pbuf
+= sprintf(pbuf
, "\tachannel:%d\n", p
->achanl
);
3874 pbuf
+= sprintf(pbuf
, "\tasamprate:%d\n", p
->asamprate
);
3875 pbuf
+= sprintf(pbuf
, "\tadatawidth:%d\n\n", p
->adatawidth
);
3880 static int show_vbuf_status_cb(struct stream_buf_s
*p
, char *buf
)
3887 pbuf
+= sprintf(pbuf
, "Video-%d buffer:", p
->id
);
3889 pbuf
+= sprintf(pbuf
, "\tflag:%d( ", p
->flag
);
3890 if (p
->flag
& BUF_FLAG_ALLOC
)
3891 pbuf
+= sprintf(pbuf
, "%s ", "Alloc");
3893 pbuf
+= sprintf(pbuf
, "%s ", "Unalloc");
3894 if (p
->flag
& BUF_FLAG_IN_USE
)
3895 pbuf
+= sprintf(pbuf
, "%s ", "Used");
3897 pbuf
+= sprintf(pbuf
, "%s ", "Noused");
3898 if (p
->flag
& BUF_FLAG_PARSER
)
3899 pbuf
+= sprintf(pbuf
, "%s ", "Parser");
3901 pbuf
+= sprintf(pbuf
, "%s ", "noParser");
3902 if (p
->flag
& BUF_FLAG_FIRST_TSTAMP
)
3903 pbuf
+= sprintf(pbuf
, "%s ", "firststamp");
3905 pbuf
+= sprintf(pbuf
, "%s ", "nofirststamp");
3906 pbuf
+= sprintf(pbuf
, ")\n");
3909 pbuf
+= sprintf(pbuf
, "\tbuf addr:%p\n", (void *)p
->buf_start
);
3910 pbuf
+= sprintf(pbuf
, "\tbuf size:%#x\n", p
->buf_size
);
3911 pbuf
+= sprintf(pbuf
, "\tbuf canusesize:%#x\n", p
->canusebuf_size
);
3912 pbuf
+= sprintf(pbuf
, "\tbuf regbase:%#lx\n", p
->reg_base
);
3914 if (p
->reg_base
&& p
->flag
& BUF_FLAG_IN_USE
) {
3915 pbuf
+= sprintf(pbuf
, "\tbuf level:%#x\n",
3917 pbuf
+= sprintf(pbuf
, "\tbuf space:%#x\n",
3919 pbuf
+= sprintf(pbuf
, "\tbuf read pointer:%#x\n",
3922 pbuf
+= sprintf(pbuf
, "\tbuf no used.\n");
3927 static ssize_t
bufs_show(struct class *class, struct class_attribute
*attr
,
3932 struct stream_buf_s
*p
= NULL
;
3933 char buf_type
[][12] = { "Video", "Audio", "Subtitle",
3934 "UserData", "HEVC" };
3936 for (i
= 0; i
< amstream_buf_num
; i
++) {
3943 pbuf
+= sprintf(pbuf
, "%s buffer:", buf_type
[p
->type
]);
3945 pbuf
+= sprintf(pbuf
, "\tflag:%d( ", p
->flag
);
3946 if (p
->flag
& BUF_FLAG_ALLOC
)
3947 pbuf
+= sprintf(pbuf
, "%s ", "Alloc");
3949 pbuf
+= sprintf(pbuf
, "%s ", "Unalloc");
3950 if (p
->flag
& BUF_FLAG_IN_USE
)
3951 pbuf
+= sprintf(pbuf
, "%s ", "Used");
3953 pbuf
+= sprintf(pbuf
, "%s ", "Noused");
3954 if (p
->flag
& BUF_FLAG_PARSER
)
3955 pbuf
+= sprintf(pbuf
, "%s ", "Parser");
3957 pbuf
+= sprintf(pbuf
, "%s ", "noParser");
3958 if (p
->flag
& BUF_FLAG_FIRST_TSTAMP
)
3959 pbuf
+= sprintf(pbuf
, "%s ", "firststamp");
3961 pbuf
+= sprintf(pbuf
, "%s ", "nofirststamp");
3962 pbuf
+= sprintf(pbuf
, ")\n");
3965 pbuf
+= sprintf(pbuf
, "\tbuf addr:%p\n", (void *)p
->buf_start
);
3967 if (p
->type
!= BUF_TYPE_SUBTITLE
) {
3968 pbuf
+= sprintf(pbuf
, "\tbuf size:%#x\n", p
->buf_size
);
3969 pbuf
+= sprintf(pbuf
,
3970 "\tbuf canusesize:%#x\n",
3972 pbuf
+= sprintf(pbuf
,
3973 "\tbuf regbase:%#lx\n", p
->reg_base
);
3975 if (p
->reg_base
&& p
->flag
& BUF_FLAG_IN_USE
) {
3976 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M6
) {
3977 /* TODO: mod gate */
3978 /* switch_mod_gate_by_name("vdec", 1);*/
3979 amports_switch_gate("vdec", 1);
3981 pbuf
+= sprintf(pbuf
, "\tbuf level:%#x\n",
3983 pbuf
+= sprintf(pbuf
, "\tbuf space:%#x\n",
3985 pbuf
+= sprintf(pbuf
,
3986 "\tbuf read pointer:%#x\n",
3988 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M6
) {
3989 /* TODO: mod gate */
3990 /* switch_mod_gate_by_name("vdec", 0);*/
3991 amports_switch_gate("vdec", 0);
3994 pbuf
+= sprintf(pbuf
, "\tbuf no used.\n");
3996 if (p
->type
== BUF_TYPE_USERDATA
) {
3997 pbuf
+= sprintf(pbuf
,
3998 "\tbuf write pointer:%#x\n",
4000 pbuf
+= sprintf(pbuf
,
4001 "\tbuf read pointer:%#x\n",
4005 u32 sub_wp
, sub_rp
, data_size
;
4007 sub_wp
= stbuf_sub_wp_get();
4008 sub_rp
= stbuf_sub_rp_get();
4009 if (sub_wp
>= sub_rp
)
4010 data_size
= sub_wp
- sub_rp
;
4012 data_size
= p
->buf_size
- sub_rp
+ sub_wp
;
4013 pbuf
+= sprintf(pbuf
, "\tbuf size:%#x\n", p
->buf_size
);
4015 sprintf(pbuf
, "\tbuf canusesize:%#x\n",
4018 sprintf(pbuf
, "\tbuf start:%#x\n",
4019 stbuf_sub_start_get());
4020 pbuf
+= sprintf(pbuf
,
4021 "\tbuf write pointer:%#x\n", sub_wp
);
4022 pbuf
+= sprintf(pbuf
,
4023 "\tbuf read pointer:%#x\n", sub_rp
);
4024 pbuf
+= sprintf(pbuf
, "\tbuf level:%#x\n", data_size
);
4027 pbuf
+= sprintf(pbuf
, "\tbuf first_stamp:%#x\n",
4029 pbuf
+= sprintf(pbuf
, "\tbuf wcnt:%#x\n\n", p
->wcnt
);
4030 pbuf
+= sprintf(pbuf
, "\tbuf max_buffer_delay_ms:%dms\n",
4031 p
->max_buffer_delay_ms
);
4033 if (p
->reg_base
&& p
->flag
& BUF_FLAG_IN_USE
) {
4034 int calc_delayms
= 0;
4035 u32 bitrate
= 0, avg_bitrate
= 0;
4037 calc_delayms
= calculation_stream_delayed_ms(
4038 (p
->type
== BUF_TYPE_AUDIO
) ? PTS_TYPE_AUDIO
:
4043 if (calc_delayms
>= 0) {
4044 pbuf
+= sprintf(pbuf
,
4045 "\tbuf current delay:%dms\n",
4047 pbuf
+= sprintf(pbuf
,
4048 "\tbuf bitrate latest:%dbps,avg:%dbps\n",
4049 bitrate
, avg_bitrate
);
4050 pbuf
+= sprintf(pbuf
,
4051 "\tbuf time after last pts:%d ms\n",
4052 calculation_stream_ext_delayed_ms
4053 ((p
->type
== BUF_TYPE_AUDIO
) ? PTS_TYPE_AUDIO
:
4056 pbuf
+= sprintf(pbuf
,
4057 "\tbuf time after last write data :%d ms\n",
4059 p
->last_write_jiffies64
) * 1000 / HZ
);
4062 if (p
->write_thread
) {
4063 pbuf
+= sprintf(pbuf
,
4064 "\twrite thread:%d/%d,fifo %d:%d,passed:%d\n",
4065 threadrw_buffer_level(p
),
4066 threadrw_buffer_size(p
),
4067 threadrw_datafifo_len(p
),
4068 threadrw_freefifo_len(p
),
4069 threadrw_passed_len(p
)
4074 pbuf
+= show_stream_buffer_status(pbuf
, show_vbuf_status_cb
);
4079 static ssize_t
videobufused_show(struct class *class,
4080 struct class_attribute
*attr
, char *buf
)
4083 struct stream_buf_s
*p
= NULL
;
4087 if (p
->flag
& BUF_FLAG_IN_USE
)
4088 pbuf
+= sprintf(pbuf
, "%d ", 1);
4090 pbuf
+= sprintf(pbuf
, "%d ", 0);
4094 static ssize_t
vcodec_profile_show(struct class *class,
4095 struct class_attribute
*attr
, char *buf
)
4097 return vcodec_profile_read(buf
);
4100 static int reset_canuse_buferlevel(int levelx10000
)
4103 struct stream_buf_s
*p
= NULL
;
4105 if (levelx10000
>= 0 && levelx10000
<= 10000)
4106 use_bufferlevelx10000
= levelx10000
;
4108 use_bufferlevelx10000
= 10000;
4109 for (i
= 0; i
< amstream_buf_num
; i
++) {
4111 p
->canusebuf_size
= ((p
->buf_size
/ 1024) *
4112 use_bufferlevelx10000
/ 10000) * 1024;
4113 p
->canusebuf_size
+= 1023;
4114 p
->canusebuf_size
&= ~1023;
4115 if (p
->canusebuf_size
> p
->buf_size
)
4116 p
->canusebuf_size
= p
->buf_size
;
4121 static ssize_t
show_canuse_buferlevel(struct class *class,
4122 struct class_attribute
*attr
, char *buf
)
4124 ssize_t size
= sprintf(buf
,
4125 "use_bufferlevel=%d/10000[=(set range[ 0~10000])=\n",
4126 use_bufferlevelx10000
);
4130 static ssize_t
store_canuse_buferlevel(struct class *class,
4131 struct class_attribute
*attr
,
4132 const char *buf
, size_t size
)
4137 /*ret = sscanf(buf, "%d", &val);*/
4138 ret
= kstrtoint(buf
, 0, &val
);
4143 reset_canuse_buferlevel(val
);
4147 static ssize_t
store_maxdelay(struct class *class,
4148 struct class_attribute
*attr
,
4149 const char *buf
, size_t size
)
4155 /*ret = sscanf(buf, "%d", &val);*/
4156 ret
= kstrtoint(buf
, 0, &val
);
4159 for (i
= 0; i
< amstream_buf_num
; i
++)
4160 bufs
[i
].max_buffer_delay_ms
= val
;
4164 static ssize_t
show_maxdelay(struct class *class,
4165 struct class_attribute
*attr
,
4170 size
+= sprintf(buf
, "%dms video max buffered data delay ms\n",
4171 bufs
[0].max_buffer_delay_ms
);
4172 size
+= sprintf(buf
, "%dms audio max buffered data delay ms\n",
4173 bufs
[1].max_buffer_delay_ms
);
4177 static ssize_t
audio_path_store(struct class *class,
4178 struct class_attribute
*attr
,
4179 const char *buf
, size_t size
)
4181 unsigned int val
= 0;
4184 struct stream_buf_s
*pabuf
= &bufs
[BUF_TYPE_AUDIO
];
4185 struct stream_port_s
*this;
4186 ret
= kstrtoint(buf
, 0, &val
);
4191 for (i
= 0; i
< MAX_AMSTREAM_PORT_NUM
; i
++) {
4192 if (strcmp(ports
[i
].name
, "amstream_mpts") == 0 ||
4193 strcmp(ports
[i
].name
, "amstream_mpts_sched") == 0) {
4195 if ((this->flag
& PORT_FLAG_AFORMAT
) != 0) {
4196 pr_info("audio_port_reset %s\n", ports
[i
].name
);
4197 audio_port_reset(this, pabuf
);
4204 ssize_t
dump_stream_show(struct class *class,
4205 struct class_attribute
*attr
, char *buf
)
4209 p_buf
+= sprintf(p_buf
, "\nmdkir -p /data/tmp -m 777;setenforce 0;\n\n");
4210 p_buf
+= sprintf(p_buf
, "video:\n\t echo 0 > /sys/class/amstream/dump_stream;\n");
4211 p_buf
+= sprintf(p_buf
, "hevc :\n\t echo 4 > /sys/class/amstream/dump_stream;\n");
4216 #define DUMP_STREAM_FILE "/data/tmp/dump_stream.h264"
4217 ssize_t
dump_stream_store(struct class *class,
4218 struct class_attribute
*attr
,
4219 const char *buf
, size_t size
)
4221 struct stream_buf_s
*p_buf
;
4222 int ret
= 0, id
= 0;
4223 unsigned int stride
, remain
, level
, vmap_size
;
4226 unsigned long offset
;
4228 mm_segment_t old_fs
;
4231 ret
= sscanf(buf
, "%d", &id
);
4233 pr_info("paser buf id fail, default id = 0\n");
4236 if (id
!= BUF_TYPE_VIDEO
&& id
!= BUF_TYPE_HEVC
) {
4237 pr_info("buf id out of range, max %d, id %d, set default id 0\n", BUF_MAX_NUM
- 1, id
);
4240 p_buf
= get_stream_buffer(id
);
4242 pr_info("get buf fail, id %d\n", id
);
4245 if ((!p_buf
->buf_size
) || (p_buf
->is_secure
) || (!(p_buf
->flag
& BUF_FLAG_IN_USE
))) {
4246 pr_info("buf size %d, is_secure %d, in_use %d, it can not dump\n",
4247 p_buf
->buf_size
, p_buf
->is_secure
, (p_buf
->flag
& BUF_FLAG_IN_USE
));
4251 level
= stbuf_level(p_buf
);
4252 if (!level
|| level
> p_buf
->buf_size
) {
4253 pr_info("stream buf level %d, buf size %d, error return\n", level
, p_buf
->buf_size
);
4257 fp
= filp_open(DUMP_STREAM_FILE
, O_CREAT
| O_RDWR
, 0666);
4260 pr_info("create dump stream file failed\n");
4264 offset
= p_buf
->buf_start
;
4269 pr_info("create file success, it will dump from addr 0x%lx, size 0x%x\n", offset
, remain
);
4270 while (remain
> 0) {
4271 if (remain
> stride
)
4278 stbuf_vaddr
= codec_mm_vmap(offset
, vmap_size
);
4279 if (stbuf_vaddr
== NULL
) {
4281 pr_info("vmap fail change vmap stide size 0x%x\n", stride
);
4284 codec_mm_dma_flush(stbuf_vaddr
, vmap_size
, DMA_FROM_DEVICE
);
4288 write_size
= vfs_write(fp
, stbuf_vaddr
, vmap_size
, &fpos
);
4289 if (write_size
< vmap_size
) {
4290 write_size
+= vfs_write(fp
, stbuf_vaddr
+ write_size
, vmap_size
- write_size
, &fpos
);
4291 pr_info("fail write retry, total %d, write %d\n", vmap_size
, write_size
);
4292 if (write_size
< vmap_size
) {
4293 pr_info("retry fail, interrupt dump stream, break\n");
4299 pr_info("vmap_size 0x%x dump size 0x%x\n", vmap_size
, write_size
);
4301 offset
+= vmap_size
;
4302 remain
-= vmap_size
;
4303 codec_mm_unmap_phyaddr(stbuf_vaddr
);
4306 filp_close(fp
, current
->files
);
4307 pr_info("dump stream buf end\n");
4315 static struct class_attribute amstream_class_attrs
[] = {
4318 __ATTR_RO(vcodec_profile
),
4319 __ATTR_RO(videobufused
),
4320 __ATTR(canuse_buferlevel
, S_IRUGO
| S_IWUSR
| S_IWGRP
,
4321 show_canuse_buferlevel
, store_canuse_buferlevel
),
4322 __ATTR(max_buffer_delay_ms
, S_IRUGO
| S_IWUSR
| S_IWGRP
, show_maxdelay
,
4324 __ATTR(reset_audio_port
, S_IRUGO
| S_IWUSR
| S_IWGRP
,
4325 NULL
, audio_path_store
),
4326 __ATTR(dump_stream
, S_IRUGO
| S_IWUSR
| S_IWGRP
,
4327 dump_stream_show
, dump_stream_store
),
4331 static struct class amstream_class
= {
4333 .class_attrs
= amstream_class_attrs
,
4336 int amstream_request_firmware_from_sys(const char *file_name
,
4337 char *buf
, int size
)
4339 const struct firmware
*firmware
;
4341 struct device
*micro_dev
;
4343 pr_info("try load %s ...", file_name
);
4344 micro_dev
= device_create(&amstream_class
,
4345 NULL
, MKDEV(AMSTREAM_MAJOR
, 100),
4347 if (micro_dev
== NULL
) {
4348 pr_err("device_create failed =%d\n", err
);
4351 err
= request_firmware(&firmware
, file_name
, micro_dev
);
4353 pr_err("can't load the %s,err=%d\n", file_name
, err
);
4356 if (firmware
->size
> size
) {
4357 pr_err("not enough memory size for audiodsp code\n");
4362 memcpy(buf
, (char *)firmware
->data
, firmware
->size
);
4363 /*mb(); don't need it*/
4364 pr_err("load mcode size=%zd\n mcode name %s\n", firmware
->size
,
4366 err
= firmware
->size
;
4368 release_firmware(firmware
);
4370 device_destroy(&amstream_class
, MKDEV(AMSTREAM_MAJOR
, 100));
4374 int videobufused_show_fun(const char *trigger
, int id
, char *sbuf
, int size
)
4377 void *buf
, *getbuf
= NULL
;
4378 if (size
< PAGE_SIZE
) {
4379 getbuf
= (void *)__get_free_page(GFP_KERNEL
);
4389 ret
= videobufused_show(NULL
, NULL
, buf
);
4394 if (ret
> 0 && getbuf
!= NULL
) {
4395 ret
= min_t(int, ret
, size
);
4396 strncpy(sbuf
, buf
, ret
);
4399 free_page((unsigned long)getbuf
);
4403 static struct mconfig amports_configs
[] = {
4404 MC_PI32("def_4k_vstreambuf_sizeM", &def_4k_vstreambuf_sizeM
),
4405 MC_PI32("def_vstreambuf_sizeM", &def_vstreambuf_sizeM
),
4406 MC_PI32("slow_input", &slow_input
),
4407 MC_FUN_ID("videobufused", videobufused_show_fun
, NULL
, 0),
4412 /*static struct resource memobj;*/
4413 static int amstream_probe(struct platform_device
*pdev
)
4417 struct stream_port_s
*st
;
4419 pr_err("Amlogic A/V streaming port init\n");
4421 amstream_port_num
= MAX_AMSTREAM_PORT_NUM
;
4422 amstream_buf_num
= BUF_MAX_NUM
;
4424 * r = of_reserved_mem_device_init(&pdev->dev);
4426 * pr_info("of probe done");
4432 r
= class_register(&amstream_class
);
4434 pr_err("amstream class create fail.\n");
4438 r
= astream_dev_register();
4442 r
= register_chrdev(AMSTREAM_MAJOR
, "amstream", &amstream_fops
);
4444 pr_err("Can't allocate major for amstreaming device\n");
4449 amstream_dev_class
= class_create(THIS_MODULE
, DEVICE_NAME
);
4451 for (st
= &ports
[0], i
= 0; i
< amstream_port_num
; i
++, st
++) {
4452 st
->class_dev
= device_create(amstream_dev_class
, NULL
,
4453 MKDEV(AMSTREAM_MAJOR
, i
), NULL
,
4457 amstream_adec_status
= NULL
;
4458 if (tsdemux_class_register() != 0) {
4462 tsdemux_tsync_func_init();
4463 init_waitqueue_head(&amstream_sub_wait
);
4464 init_waitqueue_head(&amstream_userdata_wait
);
4465 reset_canuse_buferlevel(10000);
4466 amstream_pdev
= pdev
;
4467 amports_clock_gate_init(&amstream_pdev
->dev
);
4469 /*prealloc fetch buf to avoid no continue buffer later...*/
4471 REG_PATH_CONFIGS("media.amports", amports_configs
);
4473 /* poweroff the decode core because dos can not be reset when reboot */
4474 if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_G12A
)
4481 * tsdemux_class_unregister();
4484 for (st
= &ports
[0], i
= 0; i
< amstream_port_num
; i
++, st
++)
4485 device_destroy(amstream_dev_class
, MKDEV(AMSTREAM_MAJOR
, i
));
4486 class_destroy(amstream_dev_class
);
4488 unregister_chrdev(AMSTREAM_MAJOR
, "amstream");
4490 astream_dev_unregister();
4494 static int amstream_remove(struct platform_device
*pdev
)
4497 struct stream_port_s
*st
;
4499 if (bufs
[BUF_TYPE_AUDIO
].flag
& BUF_FLAG_ALLOC
)
4500 stbuf_change_size(&bufs
[BUF_TYPE_AUDIO
], 0, false);
4501 stbuf_fetch_release();
4502 tsdemux_class_unregister();
4503 for (st
= &ports
[0], i
= 0; i
< amstream_port_num
; i
++, st
++)
4504 device_destroy(amstream_dev_class
, MKDEV(AMSTREAM_MAJOR
, i
));
4506 class_destroy(amstream_dev_class
);
4508 unregister_chrdev(AMSTREAM_MAJOR
, "amstream");
4510 class_unregister(&amstream_class
);
4512 astream_dev_unregister();
4514 amstream_adec_status
= NULL
;
4516 pr_err("Amlogic A/V streaming port release\n");
4521 void set_adec_func(int (*adec_func
)(struct adec_status
*))
4523 amstream_adec_status
= adec_func
;
4526 void wakeup_sub_poll(void)
4528 atomic_inc(&subdata_ready
);
4529 wake_up_interruptible(&amstream_sub_wait
);
4532 int get_sub_type(void)
4537 u32
get_audio_reset(void)
4539 return amstream_audio_reset
;
4542 /*get pes buffers */
4544 struct stream_buf_s
*get_stream_buffer(int id
)
4546 if (id
>= BUF_MAX_NUM
)
4550 EXPORT_SYMBOL(get_stream_buffer
);
4551 static const struct of_device_id amlogic_mesonstream_dt_match
[] = {
4553 .compatible
= "amlogic, codec, streambuf",
4558 static struct platform_driver amstream_driver
= {
4559 .probe
= amstream_probe
,
4560 .remove
= amstream_remove
,
4562 .owner
= THIS_MODULE
,
4563 .name
= "mesonstream",
4564 .of_match_table
= amlogic_mesonstream_dt_match
,
4568 static int __init
amstream_module_init(void)
4570 if (platform_driver_register(&amstream_driver
)) {
4571 pr_err("failed to register amstream module\n");
4575 if (subtitle_init()) {
4576 pr_err("failed to init subtitle\n");
4583 static void __exit
amstream_module_exit(void)
4585 platform_driver_unregister(&amstream_driver
);
4589 module_init(amstream_module_init
);
4590 module_exit(amstream_module_exit
);
4592 module_param(force_dv_mode
, uint
, 0664);
4593 MODULE_PARM_DESC(force_dv_mode
,
4594 "\n force_dv_mode \n");
4596 module_param(def_4k_vstreambuf_sizeM
, uint
, 0664);
4597 MODULE_PARM_DESC(def_4k_vstreambuf_sizeM
,
4598 "\nDefault video Stream buf size for 4K MByptes\n");
4600 module_param(def_vstreambuf_sizeM
, uint
, 0664);
4601 MODULE_PARM_DESC(def_vstreambuf_sizeM
,
4602 "\nDefault video Stream buf size for < 1080p MByptes\n");
4604 module_param(slow_input
, uint
, 0664);
4605 MODULE_PARM_DESC(slow_input
, "\n amstream slow_input\n");
4607 MODULE_DESCRIPTION("AMLOGIC streaming port driver");
4608 MODULE_LICENSE("GPL");
4609 MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>");