summaryrefslogtreecommitdiff
path: root/drivers/stream_input/amports/amstream.c (plain)
blob: dbca2770b1468162b68b31c88891479c38c1131a
1/*
2 * drivers/amlogic/media/stream_input/amports/amstream.c
3 *
4 * Copyright (C) 2016 Amlogic, Inc. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 */
17#define DEBUG
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/types.h>
21#include <linux/fs.h>
22#include <linux/init.h>
23#include <linux/device.h>
24#include <linux/slab.h>
25#include <linux/vmalloc.h>
26#include <linux/mm.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>
32
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>
37
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>
42
43#include <linux/types.h>
44#include <linux/uaccess.h>
45#include <linux/io.h>
46/* #include <mach/am_regs.h> */
47
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> */
58#endif
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"
65#include "adec.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>
72#include <linux/of.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>
77#ifdef CONFIG_COMPAT
78#include <linux/compat.h>
79#endif
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"
87
88//#define G12A_BRINGUP_DEBUG
89
90#define CONFIG_AM_VDEC_REAL //DEBUG_TMP
91
92#define DEVICE_NAME "amstream-dev"
93#define DRIVER_NAME "amstream"
94#define MODULE_NAME "amstream"
95
96#define MAX_AMSTREAM_PORT_NUM ARRAY_SIZE(ports)
97u32 amstream_port_num;
98u32 amstream_buf_num;
99
100u32 amstream_audio_reset = 0;
101
102#if 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
107#endif
108#endif
109#define NO_VDEC2_INIT 1
110
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)
115
116
117#define DEFAULT_AUDIO_BUFFER_SIZE (1024*768*2)
118#define DEFAULT_SUBTITLE_BUFFER_SIZE (1024*256)
119
120static int def_4k_vstreambuf_sizeM =
121 (DEFAULT_VIDEO_BUFFER_SIZE_4K >> 20);
122static int def_vstreambuf_sizeM =
123 (DEFAULT_VIDEO_BUFFER_SIZE >> 20);
124static int slow_input;
125
126/* #define DATA_DEBUG */
127static int use_bufferlevelx10000 = 10000;
128static int reset_canuse_buferlevel(int level);
129static struct platform_device *amstream_pdev;
130struct device *amports_get_dma_device(void)
131{
132 return &amstream_pdev->dev;
133}
134EXPORT_SYMBOL(amports_get_dma_device);
135
136#ifdef DATA_DEBUG
137#include <linux/fs.h>
138
139#define DEBUG_FILE_NAME "/sdcard/debug.tmp"
140static struct file *debug_filp;
141static loff_t debug_file_pos;
142
143void debug_file_write(const char __user *buf, size_t count)
144{
145 mm_segment_t old_fs;
146
147 if (!debug_filp)
148 return;
149
150 old_fs = get_fs();
151 set_fs(KERNEL_DS);
152
153 if (count != vfs_write(debug_filp, buf, count, &debug_file_pos))
154 pr_err("Failed to write debug file\n");
155
156 set_fs(old_fs);
157}
158#endif
159
160
161
162static int amstream_open(struct inode *inode, struct file *file);
163static int amstream_release(struct inode *inode, struct file *file);
164static long amstream_ioctl(struct file *file, unsigned int cmd, ulong arg);
165#ifdef CONFIG_COMPAT
166static long amstream_compat_ioctl
167 (struct file *file, unsigned int cmd, ulong arg);
168#endif
169static ssize_t amstream_vbuf_write
170(struct file *file, const char *buf, size_t count, loff_t *ppos);
171static ssize_t amstream_vframe_write
172(struct file *file, const char *buf, size_t count, loff_t *ppos);
173static ssize_t amstream_abuf_write
174(struct file *file, const char *buf, size_t count, loff_t *ppos);
175static ssize_t amstream_mpts_write
176(struct file *file, const char *buf, size_t count, loff_t *ppos);
177static ssize_t amstream_mpps_write
178(struct file *file, const char *buf, size_t count, loff_t *ppos);
179static ssize_t amstream_sub_read
180(struct file *file, char *buf, size_t count, loff_t *ppos);
181static ssize_t amstream_sub_write
182(struct file *file, const char *buf, size_t count, loff_t *ppos);
183static unsigned int amstream_sub_poll
184(struct file *file, poll_table *wait_table);
185static unsigned int amstream_userdata_poll
186(struct file *file, poll_table *wait_table);
187static ssize_t amstream_userdata_read
188(struct file *file, char *buf, size_t count, loff_t *ppos);
189static int (*amstream_adec_status)
190(struct adec_status *astatus);
191#ifdef CONFIG_AM_VDEC_REAL
192static ssize_t amstream_mprm_write
193(struct file *file, const char *buf, size_t count, loff_t *ppos);
194#endif
195
196static 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,
202#ifdef CONFIG_COMPAT
203 .compat_ioctl = amstream_compat_ioctl,
204#endif
205};
206
207static 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,
213#ifdef CONFIG_COMPAT
214 .compat_ioctl = amstream_compat_ioctl,
215#endif
216};
217
218static 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,
224#ifdef CONFIG_COMPAT
225 .compat_ioctl = amstream_compat_ioctl,
226#endif
227};
228
229static 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,
235#ifdef CONFIG_COMPAT
236 .compat_ioctl = amstream_compat_ioctl,
237#endif
238};
239
240static 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,
246#ifdef CONFIG_COMPAT
247 .compat_ioctl = amstream_compat_ioctl,
248#endif
249};
250
251static 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,
257#endif
258 .unlocked_ioctl = amstream_ioctl,
259#ifdef CONFIG_COMPAT
260 .compat_ioctl = amstream_compat_ioctl,
261#endif
262};
263
264static 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,
270#ifdef CONFIG_COMPAT
271 .compat_ioctl = amstream_compat_ioctl,
272#endif
273};
274
275static 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,
282#ifdef CONFIG_COMPAT
283 .compat_ioctl = amstream_compat_ioctl,
284#endif
285};
286
287static 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,
294#ifdef CONFIG_COMPAT
295 .compat_ioctl = amstream_compat_ioctl,
296#endif
297};
298
299static const struct file_operations amstream_fops = {
300 .owner = THIS_MODULE,
301 .open = amstream_open,
302 .release = amstream_release,
303 .unlocked_ioctl = amstream_ioctl,
304#ifdef CONFIG_COMPAT
305 .compat_ioctl = amstream_compat_ioctl,
306#endif
307};
308
309/**************************************************/
310static struct audio_info audio_dec_info;
311static struct class *amstream_dev_class;
312static DEFINE_MUTEX(amstream_mutex);
313
314atomic_t subdata_ready = ATOMIC_INIT(0);
315static int sub_type;
316static int sub_port_inited;
317/* wait queue for poll */
318static wait_queue_head_t amstream_sub_wait;
319atomic_t userdata_ready = ATOMIC_INIT(0);
320static int userdata_length;
321static wait_queue_head_t amstream_userdata_wait;
322#define USERDATA_FIFO_NUM 1024
323static struct userdata_poc_info_t userdata_poc_info[USERDATA_FIFO_NUM];
324static int userdata_poc_ri, userdata_poc_wi;
325static int last_read_wi;
326static u32 ud_ready_vdec_flag;
327
328/*bit 1 force dual layer
329 *bit 2 force frame mode
330 */
331static u32 force_dv_mode;
332
333static DEFINE_MUTEX(userdata_mutex);
334
335static struct stream_port_s ports[] = {
336 {
337 .name = "amstream_vbuf",
338 .type = PORT_TYPE_ES | PORT_TYPE_VIDEO,
339 .fops = &vbuf_fops,
340 },
341#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
342 {
343 .name = "amstream_vbuf_sched",
344 .type = PORT_TYPE_ES | PORT_TYPE_VIDEO |
345 PORT_TYPE_DECODER_SCHED,
346 .fops = &vbuf_fops,
347 },
348 {
349 .name = "amstream_vframe",
350 .type = PORT_TYPE_ES | PORT_TYPE_VIDEO |
351 PORT_TYPE_FRAME | PORT_TYPE_DECODER_SCHED,
352 .fops = &vframe_fops,
353 },
354#endif
355 {
356 .name = "amstream_abuf",
357 .type = PORT_TYPE_ES | PORT_TYPE_AUDIO,
358 .fops = &abuf_fops,
359 },
360 {
361 .name = "amstream_mpts",
362 .type = PORT_TYPE_MPTS | PORT_TYPE_VIDEO |
363 PORT_TYPE_AUDIO | PORT_TYPE_SUB,
364 .fops = &mpts_fops,
365 },
366#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
367 {
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,
372 .fops = &mpts_fops,
373 },
374#endif
375 {
376 .name = "amstream_mpps",
377 .type = PORT_TYPE_MPPS | PORT_TYPE_VIDEO |
378 PORT_TYPE_AUDIO | PORT_TYPE_SUB,
379 .fops = &mpps_fops,
380 },
381 {
382 .name = "amstream_rm",
383 .type = PORT_TYPE_RM | PORT_TYPE_VIDEO | PORT_TYPE_AUDIO,
384 .fops = &mprm_fops,
385 },
386 {
387 .name = "amstream_sub",
388 .type = PORT_TYPE_SUB,
389 .fops = &sub_fops,
390 },
391 {
392 .name = "amstream_sub_read",
393 .type = PORT_TYPE_SUB_RD,
394 .fops = &sub_read_fops,
395 },
396 {
397 .name = "amstream_userdata",
398 .type = PORT_TYPE_USERDATA,
399 .fops = &userdata_fops,
400 },
401 {
402 .name = "amstream_hevc",
403 .type = PORT_TYPE_ES | PORT_TYPE_VIDEO | PORT_TYPE_HEVC,
404 .fops = &vbuf_fops,
405 .vformat = VFORMAT_HEVC,
406 },
407#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
408 {
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,
414 },
415 {
416 .name = "amstream_hevc_sched",
417 .type = PORT_TYPE_ES | PORT_TYPE_VIDEO | PORT_TYPE_HEVC |
418 PORT_TYPE_DECODER_SCHED,
419 .fops = &vbuf_fops,
420 .vformat = VFORMAT_HEVC,
421 },
422#ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_DOLBYVISION
423 {
424 .name = "amstream_dves_avc",
425 .type = PORT_TYPE_ES | PORT_TYPE_VIDEO |
426 PORT_TYPE_DECODER_SCHED | PORT_TYPE_DUALDEC,
427 .fops = &vbuf_fops,
428 },
429 {
430 .name = "amstream_dves_hevc",
431 .type = PORT_TYPE_ES | PORT_TYPE_VIDEO | PORT_TYPE_HEVC |
432 PORT_TYPE_DECODER_SCHED | PORT_TYPE_DUALDEC,
433 .fops = &vbuf_fops,
434 .vformat = VFORMAT_HEVC,
435 },
436 {
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,
441 },
442 {
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,
448 },
449 {
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,
455 },
456#endif
457#endif
458};
459
460static struct stream_buf_s bufs[BUF_MAX_NUM] = {
461 {
462 .reg_base = VLD_MEM_VIFIFO_REG_BASE,
463 .type = BUF_TYPE_VIDEO,
464 .buf_start = 0,
465 .buf_size = DEFAULT_VIDEO_BUFFER_SIZE,
466 .default_buf_size = DEFAULT_VIDEO_BUFFER_SIZE,
467 .first_tstamp = INVALID_PTS
468 },
469 {
470 .reg_base = AIU_MEM_AIFIFO_REG_BASE,
471 .type = BUF_TYPE_AUDIO,
472 .buf_start = 0,
473 .buf_size = DEFAULT_AUDIO_BUFFER_SIZE,
474 .default_buf_size = DEFAULT_AUDIO_BUFFER_SIZE,
475 .first_tstamp = INVALID_PTS
476 },
477 {
478 .reg_base = 0,
479 .type = BUF_TYPE_SUBTITLE,
480 .buf_start = 0,
481 .buf_size = DEFAULT_SUBTITLE_BUFFER_SIZE,
482 .default_buf_size = DEFAULT_SUBTITLE_BUFFER_SIZE,
483 .first_tstamp = INVALID_PTS
484 },
485 {
486 .reg_base = 0,
487 .type = BUF_TYPE_USERDATA,
488 .buf_start = 0,
489 .buf_size = 0,
490 .first_tstamp = INVALID_PTS
491 },
492 {
493 .reg_base = HEVC_STREAM_REG_BASE,
494 .type = BUF_TYPE_HEVC,
495 .buf_start = 0,
496 .buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K,
497 .default_buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K,
498 .first_tstamp = INVALID_PTS
499 },
500};
501
502struct stream_buf_s *get_buf_by_type(u32 type)
503{
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];
511 }
512
513 return NULL;
514}
515
516void set_sample_rate_info(int arg)
517{
518 audio_dec_info.sample_rate = arg;
519 audio_dec_info.valid = 1;
520}
521
522void set_ch_num_info(int arg)
523{
524 audio_dec_info.channels = arg;
525}
526
527struct audio_info *get_audio_info(void)
528{
529 return &audio_dec_info;
530}
531EXPORT_SYMBOL(get_audio_info);
532
533static void amstream_change_vbufsize(struct port_priv_s *priv,
534 struct stream_buf_s *pvbuf)
535{
536 if (pvbuf->buf_start != 0) {
537 pr_info("streambuf is alloced before\n");
538 return;
539 }
540 if (priv->port->is_4k) {
541 pvbuf->buf_size = def_4k_vstreambuf_sizeM * SZ_1M;
542 if (priv->vdec->port_flag & PORT_FLAG_DRM)
543 pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_4K_TVP;
544 if ((pvbuf->buf_size > 30 * SZ_1M) &&
545 (codec_mm_get_total_size() < 220 * SZ_1M)) {
546 /*if less than 250M, used 20M for 4K & 265*/
547 pvbuf->buf_size = pvbuf->buf_size >> 1;
548 }
549 } else if (pvbuf->buf_size > def_vstreambuf_sizeM * SZ_1M) {
550 if (priv->vdec->port_flag & PORT_FLAG_DRM)
551 pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_TVP;
552 } else {
553 pvbuf->buf_size = def_vstreambuf_sizeM * SZ_1M;
554 if (priv->vdec->port_flag & PORT_FLAG_DRM)
555 pvbuf->buf_size = DEFAULT_VIDEO_BUFFER_SIZE_TVP;
556 }
557 reset_canuse_buferlevel(10000);
558}
559
560static bool port_get_inited(struct port_priv_s *priv)
561{
562 struct stream_port_s *port = priv->port;
563
564 if (port->type & PORT_TYPE_VIDEO) {
565 struct vdec_s *vdec = priv->vdec;
566
567 return vdec ? vdec->port_flag & PORT_FLAG_INITED : 0;
568 }
569
570 return port->flag & PORT_FLAG_INITED;
571}
572
573static void port_set_inited(struct port_priv_s *priv)
574{
575 struct stream_port_s *port = priv->port;
576
577 if (port->type & PORT_TYPE_VIDEO) {
578 struct vdec_s *vdec = priv->vdec;
579
580 vdec->port_flag |= PORT_FLAG_INITED;
581 port->flag |= PORT_FLAG_INITED;
582 pr_info("vdec->port_flag=0x%x, port_flag=0x%x\n",
583 vdec->port_flag, port->flag);
584 } else
585 port->flag |= PORT_FLAG_INITED;
586}
587
588static void video_port_release(struct port_priv_s *priv,
589 struct stream_buf_s *pbuf, int release_num)
590{
591 struct vdec_s *vdec = priv->vdec;
592 struct vdec_s *slave = NULL;
593
594 if (!vdec)
595 return;
596
597 switch (release_num) {
598 default:
599 /*fallthrough*/
600 case 0: /*release all */
601 case 3:
602 if (vdec->slave)
603 slave = vdec->slave;
604 vdec_release(vdec);
605 if (slave)
606 vdec_release(slave);
607 priv->vdec = NULL;
608 /*fallthrough*/
609 case 1:
610 ;
611 }
612}
613
614static int video_port_init(struct port_priv_s *priv,
615 struct stream_buf_s *pbuf)
616{
617 int r;
618 struct stream_port_s *port = priv->port;
619 struct vdec_s *vdec = priv->vdec;
620
621 if ((vdec->port_flag & PORT_FLAG_VFORMAT) == 0) {
622 pr_err("vformat not set\n");
623 return -EPERM;
624 }
625 if (vdec_dual(vdec) && vdec_secure(vdec) && (vdec->slave)) {
626 /*copy drm flags for slave dec.*/
627 vdec->slave->port_flag |= PORT_FLAG_DRM;
628 }
629 if (port->vformat == VFORMAT_H264_4K2K ||
630 (priv->vdec->sys_info->height *
631 priv->vdec->sys_info->width) > 1920*1088) {
632 port->is_4k = true;
633 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TXLX
634 && port->vformat == VFORMAT_H264) {
635 vdec_poweron(VDEC_HEVC);
636 }
637 } else {
638 port->is_4k = false;
639 }
640
641 if (port->type & PORT_TYPE_FRAME) {
642 r = vdec_init(vdec,
643 (priv->vdec->sys_info->height *
644 priv->vdec->sys_info->width) > 1920*1088);
645 if (r < 0) {
646 pr_err("video_port_init %d, vdec_init failed\n",
647 __LINE__);
648 return r;
649 }
650#if 0
651 if (vdec_dual(vdec)) {
652 if (port->vformat == VFORMAT_AV1) /* av1 dv only single layer */
653 return 0;
654 r = vdec_init(vdec->slave,
655 (priv->vdec->sys_info->height *
656 priv->vdec->sys_info->width) > 1920*1088);
657 if (r < 0) {
658 vdec_release(vdec);
659 pr_err("video_port_init %d, vdec_init failed\n",
660 __LINE__);
661 return r;
662 }
663 }
664#endif
665 return 0;
666 }
667
668 amstream_change_vbufsize(priv, pbuf);
669
670 if (has_hevc_vdec()) {
671 if (port->type & PORT_TYPE_MPTS) {
672 if (pbuf->type == BUF_TYPE_HEVC)
673 vdec_poweroff(VDEC_1);
674 else
675 vdec_poweroff(VDEC_HEVC);
676 }
677 }
678
679 /* todo: set path based on port flag */
680 r = vdec_init(vdec,
681 (priv->vdec->sys_info->height *
682 priv->vdec->sys_info->width) > 1920*1088);
683
684 if (r < 0) {
685 pr_err("video_port_init %d, vdec_init failed\n", __LINE__);
686 goto err;
687 }
688
689 if (vdec_dual(vdec)) {
690 r = vdec_init(vdec->slave,
691 (priv->vdec->sys_info->height *
692 priv->vdec->sys_info->width) > 1920*1088);
693 if (r < 0) {
694 pr_err("video_port_init %d, vdec_init failed\n", __LINE__);
695 goto err;
696 }
697 }
698
699 return 0;
700err:
701 if (vdec->slave)
702 vdec_release(vdec->slave);
703 if (vdec)
704 vdec_release(vdec);
705 priv->vdec = NULL;
706
707 return r;
708}
709
710static void audio_port_release(struct stream_port_s *port,
711 struct stream_buf_s *pbuf, int release_num)
712{
713 switch (release_num) {
714 default:
715 /*fallthrough*/
716 case 0: /*release all */
717 /*fallthrough*/
718 case 4:
719 esparser_release(pbuf);
720 /*fallthrough*/
721 case 3:
722 adec_release(port->vformat);
723 /*fallthrough*/
724 case 2:
725 stbuf_release(pbuf);
726 /*fallthrough*/
727 case 1:
728 ;
729 }
730 amstream_audio_reset = 0;
731 return;
732}
733
734static int audio_port_reset(struct stream_port_s *port,
735 struct stream_buf_s *pbuf)
736{
737 int r;
738 mutex_lock(&amstream_mutex);
739 if ((port->flag & PORT_FLAG_AFORMAT) == 0) {
740 pr_err("aformat not set\n");
741 mutex_unlock(&amstream_mutex);
742 return 0;
743 }
744
745 pr_info("audio port reset, flag:0x%x\n", port->flag);
746 if ((port->flag & PORT_FLAG_INITED) == 0) {
747 pr_info("audio port not inited,return\n");
748 mutex_unlock(&amstream_mutex);
749 return 0;
750 }
751
752 pr_info("audio_port_reset begin\n");
753 pts_stop(PTS_TYPE_AUDIO);
754
755 stbuf_release(pbuf);
756
757 r = stbuf_init(pbuf, NULL);
758 if (r < 0) {
759 mutex_unlock(&amstream_mutex);
760 return r;
761 }
762
763 r = adec_init(port);
764 if (r < 0) {
765 audio_port_release(port, pbuf, 2);
766 mutex_unlock(&amstream_mutex);
767 return r;
768 }
769
770 if (port->type & PORT_TYPE_ES)
771 esparser_audio_reset_s(pbuf);
772
773 if (port->type & PORT_TYPE_MPTS)
774 tsdemux_audio_reset();
775
776 if (port->type & PORT_TYPE_MPPS)
777 psparser_audio_reset();
778
779#ifdef CONFIG_AM_VDEC_REAL
780 if (port->type & PORT_TYPE_RM)
781 rm_audio_reset();
782#endif
783
784 pbuf->flag |= BUF_FLAG_IN_USE;
785 amstream_audio_reset = 1;
786
787 r = pts_start(PTS_TYPE_AUDIO);
788
789 //clear audio break flag after reset
790 //tsync_audio_break(0);
791
792 pr_info("audio_port_reset done\n");
793 mutex_unlock(&amstream_mutex);
794 return r;
795}
796
797static int sub_port_reset(struct stream_port_s *port,
798 struct stream_buf_s *pbuf)
799{
800 int r;
801
802 port->flag &= (~PORT_FLAG_INITED);
803
804 stbuf_release(pbuf);
805
806 r = stbuf_init(pbuf, NULL);
807 if (r < 0)
808 return r;
809
810 if (port->type & PORT_TYPE_MPTS)
811 tsdemux_sub_reset();
812
813 if (port->type & PORT_TYPE_MPPS)
814 psparser_sub_reset();
815
816 if (port->sid == 0xffff) { /* es sub */
817 esparser_sub_reset();
818 pbuf->flag |= BUF_FLAG_PARSER;
819 }
820
821 pbuf->flag |= BUF_FLAG_IN_USE;
822
823 port->flag |= PORT_FLAG_INITED;
824
825 return 0;
826}
827
828static int audio_port_init(struct stream_port_s *port,
829 struct stream_buf_s *pbuf)
830{
831 int r;
832
833 if ((port->flag & PORT_FLAG_AFORMAT) == 0) {
834 pr_err("aformat not set\n");
835 return 0;
836 }
837
838 r = stbuf_init(pbuf, NULL);
839 if (r < 0)
840 return r;
841 r = adec_init(port);
842 if (r < 0) {
843 audio_port_release(port, pbuf, 2);
844 return r;
845 }
846 if (port->type & PORT_TYPE_ES) {
847 r = esparser_init(pbuf, NULL);
848 if (r < 0) {
849 audio_port_release(port, pbuf, 3);
850 return r;
851 }
852 }
853 pbuf->flag |= BUF_FLAG_IN_USE;
854 return 0;
855}
856
857static void sub_port_release(struct stream_port_s *port,
858 struct stream_buf_s *pbuf)
859{
860 if ((port->sid == 0xffff) &&
861 ((port->type & (PORT_TYPE_MPPS | PORT_TYPE_MPTS)) == 0)) {
862 /* this is es sub */
863 esparser_release(pbuf);
864 }
865 stbuf_release(pbuf);
866 sub_port_inited = 0;
867}
868
869static int sub_port_init(struct stream_port_s *port, struct stream_buf_s *pbuf)
870{
871 int r;
872 r = stbuf_init(pbuf, NULL);
873 if (r < 0)
874 return r;
875 if ((port->flag & PORT_FLAG_SID) == 0) {
876 pr_err("subtitle id not set\n");
877 return 0;
878 }
879
880 if ((port->sid == 0xffff) &&
881 ((port->type & (PORT_TYPE_MPPS | PORT_TYPE_MPTS)) == 0)) {
882 /* es sub */
883 r = esparser_init(pbuf, NULL);
884 if (r < 0) {
885 sub_port_release(port, pbuf);
886 return r;
887 }
888 }
889
890 sub_port_inited = 1;
891 return 0;
892}
893
894static void amstream_user_buffer_init(void)
895{
896 struct stream_buf_s *pubuf = &bufs[BUF_TYPE_USERDATA];
897
898 pubuf->buf_size = 0;
899 pubuf->buf_start = 0;
900 pubuf->buf_wp = 0;
901 pubuf->buf_rp = 0;
902}
903
904#if 1
905/*DDD*/
906struct stream_buf_s *get_vbuf(void)
907{
908 return &bufs[BUF_TYPE_VIDEO];
909}
910
911EXPORT_SYMBOL(get_vbuf);
912#endif
913
914static int amstream_port_init(struct port_priv_s *priv)
915{
916 int r = 0;
917 struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO];
918 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
919 struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
920 struct stream_port_s *port = priv->port;
921 struct vdec_s *vdec = priv->vdec;
922
923 mutex_lock(&amstream_mutex);
924
925 if ((get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_G12A) &&
926 (get_cpu_major_id() < AM_MESON_CPU_MAJOR_ID_SC2)) {
927 r = check_efuse_chip(port->vformat);
928 if (r) {
929 pr_info("No support video format %d.\n", port->vformat);
930 mutex_unlock(&amstream_mutex);
931 return 0;
932 }
933 }
934
935 /* try to reload the fw.*/
936 r = video_fw_reload(FW_LOAD_TRY);
937 if (r)
938 pr_err("the firmware reload fail.\n");
939
940 stbuf_fetch_init();
941
942 amstream_user_buffer_init();
943
944 if (port_get_inited(priv)) {
945 mutex_unlock(&amstream_mutex);
946 return 0;
947 }
948
949 if ((port->type & PORT_TYPE_AUDIO) &&
950 (port->flag & PORT_FLAG_AFORMAT)) {
951 r = audio_port_init(port, pabuf);
952 if (r < 0) {
953 pr_err("audio_port_init failed\n");
954 goto error1;
955 }
956 }
957
958 if ((port->type & PORT_TYPE_VIDEO) &&
959 (port->flag & PORT_FLAG_VFORMAT)) {
960 if (vdec_stream_based(vdec)) {
961 struct stream_buf_ops *ops = NULL;
962 struct parser_args pars = {
963 .vid = (port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
964 .aid = (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff,
965 .sid = (port->flag & PORT_FLAG_SID) ? port->sid : 0xffff,
966 .pcrid = (port->pcr_inited == 1) ? port->pcrid : 0xffff,
967 };
968
969 if (port->type & PORT_TYPE_MPTS) {
970 ops = get_tsparser_stbuf_ops();
971 } else if (port->type & PORT_TYPE_MPPS) {
972 ops = get_psparser_stbuf_ops();
973 } else {
974 ops = !vdec_single(vdec) ?
975 get_stbuf_ops() :
976 get_esparser_stbuf_ops();
977
978 /* def used stbuf with parser if the feature disable. */
979 if (!is_support_no_parser())
980 ops = get_esparser_stbuf_ops();
981 }
982
983 r = stream_buffer_base_init(&vdec->vbuf, ops, &pars);
984 if (r) {
985 mutex_unlock(&priv->mutex);
986 pr_err("stream buffer base init failed\n");
987 goto error2;
988 }
989 }
990
991 mutex_lock(&priv->mutex);
992 r = video_port_init(priv, &vdec->vbuf);
993 if (r < 0) {
994 mutex_unlock(&priv->mutex);
995 pr_err("video_port_init failed\n");
996 goto error2;
997 }
998 mutex_unlock(&priv->mutex);
999 }
1000
1001 if ((port->type & PORT_TYPE_MPTS) &&
1002 !(port->flag & PORT_FLAG_VFORMAT)) {
1003 r = tsdemux_init(0xffff,
1004 (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff,
1005 (port->flag & PORT_FLAG_SID) ? port->sid : 0xffff,
1006 (port->pcr_inited == 1) ? port->pcrid : 0xffff,
1007 0, vdec);
1008 if (r < 0) {
1009 pr_err("tsdemux_init failed\n");
1010 goto error4;
1011 }
1012 tsync_pcr_start();
1013 }
1014
1015 if ((port->type & PORT_TYPE_SUB) && (port->flag & PORT_FLAG_SID)) {
1016 r = sub_port_init(port, psbuf);
1017 if (r < 0) {
1018 pr_err("sub_port_init failed\n");
1019 goto error3;
1020 }
1021 }
1022
1023#ifdef CONFIG_AM_VDEC_REAL
1024 if (port->type & PORT_TYPE_RM) {
1025 rm_set_vasid(
1026 (port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
1027 (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff);
1028 }
1029#endif
1030#if 1 /* MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6TVD */
1031 if (!NO_VDEC2_INIT) {
1032 if ((port->type & PORT_TYPE_VIDEO)
1033 && (port->vformat == VFORMAT_H264_4K2K))
1034 stbuf_vdec2_init(pvbuf);
1035 }
1036#endif
1037
1038 if ((port->type & PORT_TYPE_VIDEO) &&
1039 (vdec->port_flag & PORT_FLAG_VFORMAT))
1040 /* connect vdec at the end after all HW initialization */
1041 vdec_connect(vdec);
1042
1043 tsync_audio_break(0); /* clear audio break */
1044 set_vsync_pts_inc_mode(0); /* clear video inc */
1045
1046 port_set_inited(priv);
1047
1048 mutex_unlock(&amstream_mutex);
1049 return 0;
1050 /*errors follow here */
1051
1052error4:
1053 sub_port_release(port, psbuf);
1054error3:
1055 video_port_release(priv, &priv->vdec->vbuf, 0);
1056error2:
1057 audio_port_release(port, pabuf, 0);
1058error1:
1059 mutex_unlock(&amstream_mutex);
1060 return r;
1061}
1062
1063static int amstream_port_release(struct port_priv_s *priv)
1064{
1065 struct stream_port_s *port = priv->port;
1066 struct stream_buf_s *pvbuf = &priv->vdec->vbuf;
1067 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
1068 struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
1069
1070 if ((port->type & PORT_TYPE_MPTS) &&
1071 !(port->flag & PORT_FLAG_VFORMAT)) {
1072 tsync_pcr_stop();
1073 tsdemux_release();
1074 }
1075
1076 if ((port->type & PORT_TYPE_MPPS) &&
1077 !(port->flag & PORT_FLAG_VFORMAT)) {
1078 psparser_release();
1079 }
1080
1081 if (port->type & PORT_TYPE_VIDEO)
1082 video_port_release(priv, pvbuf, 0);
1083
1084 if (port->type & PORT_TYPE_AUDIO)
1085 audio_port_release(port, pabuf, 0);
1086
1087 if (port->type & PORT_TYPE_SUB)
1088 sub_port_release(port, psbuf);
1089
1090 port->pcr_inited = 0;
1091 port->flag = 0;
1092 return 0;
1093}
1094
1095static void amstream_change_avid(struct stream_port_s *port)
1096{
1097 if (port->type & PORT_TYPE_MPTS) {
1098 tsdemux_change_avid(
1099 (port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
1100 (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff);
1101 }
1102
1103 if (port->type & PORT_TYPE_MPPS) {
1104 psparser_change_avid(
1105 (port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
1106 (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff);
1107 }
1108
1109#ifdef CONFIG_AM_VDEC_REAL
1110 if (port->type & PORT_TYPE_RM) {
1111 rm_set_vasid(
1112 (port->flag & PORT_FLAG_VID) ? port->vid : 0xffff,
1113 (port->flag & PORT_FLAG_AID) ? port->aid : 0xffff);
1114 }
1115#endif
1116}
1117
1118static void amstream_change_sid(struct stream_port_s *port)
1119{
1120 if (port->type & PORT_TYPE_MPTS) {
1121 tsdemux_change_sid(
1122 (port->flag & PORT_FLAG_SID) ? port->sid : 0xffff);
1123 }
1124
1125 if (port->type & PORT_TYPE_MPPS) {
1126 psparser_change_sid(
1127 (port->flag & PORT_FLAG_SID) ? port->sid : 0xffff);
1128 }
1129}
1130
1131/**************************************************/
1132static ssize_t amstream_vbuf_write(struct file *file, const char *buf,
1133 size_t count, loff_t *ppos)
1134{
1135 struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
1136 struct stream_buf_s *pbuf = &priv->vdec->vbuf;
1137 int r;
1138
1139 if (!(port_get_inited(priv))) {
1140 r = amstream_port_init(priv);
1141 if (r < 0)
1142 return r;
1143 }
1144
1145 if (priv->vdec->port_flag & PORT_FLAG_DRM)
1146 r = drm_write(file, pbuf, buf, count);
1147 else
1148 r = stream_buffer_write(file, pbuf, buf, count);
1149 if (slow_input) {
1150 pr_info("slow_input: es codec write size %x\n", r);
1151 msleep(3000);
1152 }
1153#ifdef DATA_DEBUG
1154 debug_file_write(buf, r);
1155#endif
1156
1157 return r;
1158}
1159
1160static ssize_t amstream_vframe_write(struct file *file, const char *buf,
1161 size_t count, loff_t *ppos)
1162{
1163 struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
1164 ssize_t ret;
1165 int wait_max_cnt = 5;
1166#ifdef DATA_DEBUG
1167 debug_file_write(buf, count);
1168#endif
1169 do {
1170 ret = vdec_write_vframe(priv->vdec, buf, count);
1171 if (file->f_flags & O_NONBLOCK) {
1172 break;/*alway return for no block mode.*/
1173 } else if (ret == -EAGAIN) {
1174 int level;
1175 level = vdec_input_level(&priv->vdec->input);
1176 if (wait_max_cnt-- < 0)
1177 break;
1178 msleep(20);
1179 }
1180 } while (ret == -EAGAIN);
1181 return ret;
1182}
1183
1184static ssize_t amstream_abuf_write(struct file *file, const char *buf,
1185 size_t count, loff_t *ppos)
1186{
1187 struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
1188 struct stream_port_s *port = priv->port;
1189 struct stream_buf_s *pbuf = &bufs[BUF_TYPE_AUDIO];
1190 int r;
1191
1192 if (!(port_get_inited(priv))) {
1193 r = amstream_port_init(priv);
1194 if (r < 0)
1195 return r;
1196 }
1197
1198 if (port->flag & PORT_FLAG_DRM)
1199 r = drm_write(file, pbuf, buf, count);
1200 else
1201 r = esparser_write(file, pbuf, buf, count);
1202
1203 return r;
1204}
1205
1206static ssize_t amstream_mpts_write(struct file *file, const char *buf,
1207 size_t count, loff_t *ppos)
1208{
1209 struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
1210 struct stream_port_s *port = priv->port;
1211 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
1212 struct stream_buf_s *pvbuf = &priv->vdec->vbuf;
1213 int r = 0;
1214
1215 if (!(port_get_inited(priv))) {
1216 r = amstream_port_init(priv);
1217 if (r < 0)
1218 return r;
1219 }
1220#ifdef DATA_DEBUG
1221 debug_file_write(buf, count);
1222#endif
1223 if (port->flag & PORT_FLAG_DRM)
1224 r = drm_tswrite(file, pvbuf, pabuf, buf, count);
1225 else
1226 r = tsdemux_write(file, pvbuf, pabuf, buf, count);
1227 if (slow_input) {
1228 pr_info("slow_input: ts codec write size %x\n", r);
1229 msleep(3000);
1230 }
1231 return r;
1232}
1233
1234static ssize_t amstream_mpps_write(struct file *file, const char *buf,
1235 size_t count, loff_t *ppos)
1236{
1237 struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
1238 struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO];
1239 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
1240 int r;
1241
1242 if (!(port_get_inited(priv))) {
1243 r = amstream_port_init(priv);
1244 if (r < 0)
1245 return r;
1246 }
1247 return psparser_write(file, pvbuf, pabuf, buf, count);
1248}
1249
1250#ifdef CONFIG_AM_VDEC_REAL
1251static ssize_t amstream_mprm_write(struct file *file, const char *buf,
1252 size_t count, loff_t *ppos)
1253{
1254 struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
1255 struct stream_buf_s *pvbuf = &bufs[BUF_TYPE_VIDEO];
1256 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
1257 int r;
1258
1259 if (!(port_get_inited(priv))) {
1260 r = amstream_port_init(priv);
1261 if (r < 0)
1262 return r;
1263 }
1264 return rmparser_write(file, pvbuf, pabuf, buf, count);
1265}
1266#endif
1267
1268static ssize_t amstream_sub_read(struct file *file, char __user *buf,
1269 size_t count, loff_t *ppos)
1270{
1271 u32 sub_rp, sub_wp, sub_start, data_size, res;
1272 struct stream_buf_s *s_buf = &bufs[BUF_TYPE_SUBTITLE];
1273
1274 if (sub_port_inited == 0)
1275 return 0;
1276
1277 sub_rp = stbuf_sub_rp_get();
1278 sub_wp = stbuf_sub_wp_get();
1279 sub_start = stbuf_sub_start_get();
1280
1281 if (sub_wp == sub_rp || sub_rp == 0)
1282 return 0;
1283 /*flush sub buf before read*/
1284 codec_mm_dma_flush(
1285 (void*)codec_mm_phys_to_virt(sub_start),
1286 stbuf_size(s_buf),
1287 DMA_FROM_DEVICE);
1288 if (sub_wp > sub_rp)
1289 data_size = sub_wp - sub_rp;
1290 else
1291 data_size = s_buf->buf_size - sub_rp + sub_wp;
1292
1293 if (data_size > count)
1294 data_size = count;
1295
1296 if (sub_wp < sub_rp) {
1297 int first_num = s_buf->buf_size - (sub_rp - sub_start);
1298
1299 if (data_size <= first_num) {
1300 res = copy_to_user((void *)buf,
1301 (void *)(codec_mm_phys_to_virt(sub_rp)),
1302 data_size);
1303 stbuf_sub_rp_set(sub_rp + data_size - res);
1304
1305 return data_size - res;
1306 } else {
1307 if (first_num > 0) {
1308 res = copy_to_user((void *)buf,
1309 (void *)(codec_mm_phys_to_virt(sub_rp)),
1310 first_num);
1311 stbuf_sub_rp_set(sub_rp + first_num -
1312 res);
1313
1314 return first_num - res;
1315 }
1316
1317 res = copy_to_user((void *)buf,
1318 (void *)(codec_mm_phys_to_virt(sub_start)),
1319 data_size - first_num);
1320
1321 stbuf_sub_rp_set(sub_start + data_size -
1322 first_num - res);
1323
1324 return data_size - first_num - res;
1325 }
1326 } else {
1327 res =
1328 copy_to_user((void *)buf,
1329 (void *)(codec_mm_phys_to_virt(sub_rp)),
1330 data_size);
1331
1332 stbuf_sub_rp_set(sub_rp + data_size - res);
1333
1334 return data_size - res;
1335 }
1336}
1337
1338static ssize_t amstream_sub_write(struct file *file, const char *buf,
1339 size_t count, loff_t *ppos)
1340{
1341 struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
1342 struct stream_buf_s *pbuf = &bufs[BUF_TYPE_SUBTITLE];
1343 int r;
1344
1345 if (!(port_get_inited(priv))) {
1346 r = amstream_port_init(priv);
1347 if (r < 0)
1348 return r;
1349 }
1350 r = esparser_write(file, pbuf, buf, count);
1351 if (r < 0)
1352 return r;
1353
1354 wakeup_sub_poll();
1355
1356 return r;
1357}
1358
1359static unsigned int amstream_sub_poll(struct file *file,
1360 poll_table *wait_table)
1361{
1362 poll_wait(file, &amstream_sub_wait, wait_table);
1363
1364 if (atomic_read(&subdata_ready)) {
1365 atomic_dec(&subdata_ready);
1366 return POLLOUT | POLLWRNORM;
1367 }
1368
1369 return 0;
1370}
1371
1372static void set_userdata_poc(struct userdata_poc_info_t poc)
1373{
1374 userdata_poc_info[userdata_poc_wi] = poc;
1375 userdata_poc_wi++;
1376 if (userdata_poc_wi == USERDATA_FIFO_NUM)
1377 userdata_poc_wi = 0;
1378}
1379EXPORT_SYMBOL(set_userdata_poc);
1380
1381void init_userdata_fifo(void)
1382{
1383 userdata_poc_ri = 0;
1384 userdata_poc_wi = 0;
1385 userdata_length = 0;
1386}
1387EXPORT_SYMBOL(init_userdata_fifo);
1388
1389void reset_userdata_fifo(int bInit)
1390{
1391 struct stream_buf_s *userdata_buf;
1392 int wi, ri;
1393 u32 rp, wp;
1394
1395 mutex_lock(&userdata_mutex);
1396
1397 wi = userdata_poc_wi;
1398 ri = userdata_poc_ri;
1399
1400 userdata_buf = &bufs[BUF_TYPE_USERDATA];
1401 rp = userdata_buf->buf_rp;
1402 wp = userdata_buf->buf_wp;
1403 if (bInit) {
1404 /* decoder reset */
1405 userdata_buf->buf_rp = 0;
1406 userdata_buf->buf_wp = 0;
1407 userdata_poc_ri = 0;
1408 userdata_poc_wi = 0;
1409 } else {
1410 /* just clean fifo buffer */
1411 userdata_buf->buf_rp = userdata_buf->buf_wp;
1412 userdata_poc_ri = userdata_poc_wi;
1413 }
1414 userdata_length = 0;
1415 last_read_wi = userdata_poc_wi;
1416
1417 mutex_unlock(&userdata_mutex);
1418 pr_debug("reset_userdata_fifo, bInit=%d, wi=%d, ri=%d, rp=%d, wp=%d\n",
1419 bInit, wi, ri, rp, wp);
1420}
1421EXPORT_SYMBOL(reset_userdata_fifo);
1422
1423int wakeup_userdata_poll(struct userdata_poc_info_t poc,
1424 int wp,
1425 unsigned long start_phyaddr,
1426 int buf_size,
1427 int data_length)
1428{
1429 struct stream_buf_s *userdata_buf = &bufs[BUF_TYPE_USERDATA];
1430 mutex_lock(&userdata_mutex);
1431
1432 if (data_length & 0x7)
1433 data_length = (((data_length + 8) >> 3) << 3);
1434 set_userdata_poc(poc);
1435 userdata_buf->buf_start = start_phyaddr;
1436 userdata_buf->buf_wp = wp;
1437 userdata_buf->buf_size = buf_size;
1438 atomic_set(&userdata_ready, 1);
1439 userdata_length += data_length;
1440 mutex_unlock(&userdata_mutex);
1441
1442 wake_up_interruptible(&amstream_userdata_wait);
1443 return userdata_buf->buf_rp;
1444}
1445EXPORT_SYMBOL(wakeup_userdata_poll);
1446
1447
1448void amstream_wakeup_userdata_poll(struct vdec_s *vdec)
1449{
1450 int vdec_id;
1451
1452 vdec_id = vdec->id;
1453 if (vdec_id > 31) {
1454 pr_info("Error, not support so many instances(%d) user data push\n",
1455 vdec_id);
1456 return;
1457 }
1458
1459 mutex_lock(&userdata_mutex);
1460 ud_ready_vdec_flag |= (1<<vdec_id);
1461
1462 atomic_set(&userdata_ready, 1);
1463 mutex_unlock(&userdata_mutex);
1464
1465 wake_up_interruptible(&amstream_userdata_wait);
1466}
1467EXPORT_SYMBOL(amstream_wakeup_userdata_poll);
1468
1469static unsigned int amstream_userdata_poll(struct file *file,
1470 poll_table *wait_table)
1471{
1472 poll_wait(file, &amstream_userdata_wait, wait_table);
1473 if (atomic_read(&userdata_ready)) {
1474 atomic_set(&userdata_ready, 0);
1475 return POLLIN | POLLRDNORM;
1476 }
1477 return 0;
1478}
1479
1480static ssize_t amstream_userdata_read(struct file *file, char __user *buf,
1481 size_t count, loff_t *ppos)
1482{
1483 u32 data_size, res, retVal = 0;
1484 u32 buf_wp, buf_rp, buf_size;
1485 unsigned long buf_start;
1486 struct stream_buf_s *userdata_buf = &bufs[BUF_TYPE_USERDATA];
1487#ifdef DEBUG_USER_DATA
1488 int old_wi;
1489#endif
1490
1491 mutex_lock(&userdata_mutex);
1492
1493 if (userdata_poc_ri != last_read_wi) {
1494 /***********************************************
1495 app picks up poc counter wrong from last read user data
1496 for H264. So, we need to recalculate userdata_poc_ri
1497 to the userdata_poc_wi from the last read.
1498 ***********************************************/
1499#if 0
1500 pr_info("app pick up poc error: ri = %d, last_wi = %d\n",
1501 userdata_poc_ri, last_read_wi);
1502#endif
1503 userdata_poc_ri = last_read_wi;
1504 }
1505
1506 buf_wp = userdata_buf->buf_wp;
1507 buf_rp = userdata_buf->buf_rp;
1508 buf_size = userdata_buf->buf_size;
1509 buf_start = userdata_buf->buf_start;
1510#ifdef DEBUG_USER_DATA
1511 old_wi = last_read_wi;
1512#endif
1513 last_read_wi = userdata_poc_wi;
1514 mutex_unlock(&userdata_mutex);
1515
1516 if (buf_start == 0 || buf_size == 0)
1517 return 0;
1518 if (buf_wp == buf_rp)
1519 return 0;
1520 if (buf_wp > buf_rp)
1521 data_size = buf_wp - buf_rp;
1522 else
1523 data_size = buf_size - buf_rp + buf_wp;
1524
1525 if (data_size > count)
1526 data_size = count;
1527#ifdef DEBUG_USER_DATA
1528 pr_info("wi:%d ri:%d wp:%d rp:%d size:%d, last_read_wi=%d\n",
1529 userdata_poc_wi, userdata_poc_ri,
1530 buf_wp, buf_rp, data_size, old_wi);
1531#endif
1532 if (buf_wp < buf_rp) {
1533 int first_num = buf_size - buf_rp;
1534 if (data_size <= first_num) {
1535 res = copy_to_user((void *)buf,
1536 (void *)((buf_rp +
1537 buf_start)), data_size);
1538 if (res)
1539 pr_info("p1 read not end res=%d, request=%d\n",
1540 res, data_size);
1541
1542 mutex_lock(&userdata_mutex);
1543 userdata_buf->buf_rp += data_size - res;
1544 mutex_unlock(&userdata_mutex);
1545 retVal = data_size - res;
1546 } else {
1547 if (first_num > 0) {
1548 res = copy_to_user((void *)buf,
1549 (void *)((buf_rp +
1550 buf_start)), first_num);
1551 if (res)
1552 pr_info("p2 read not end res=%d, request=%d\n",
1553 res, first_num);
1554
1555 res = copy_to_user((void *)buf+first_num,
1556 (void *)(buf_start),
1557 data_size - first_num);
1558
1559 if (res)
1560 pr_info("p3 read not end res=%d, request=%d\n",
1561 res, data_size - first_num);
1562
1563 mutex_lock(&userdata_mutex);
1564 userdata_buf->buf_rp += data_size;
1565 if (userdata_buf->buf_rp >= buf_size)
1566 userdata_buf->buf_rp =
1567 userdata_buf->buf_rp - buf_size;
1568 mutex_unlock(&userdata_mutex);
1569
1570 retVal = data_size;
1571 } else {
1572 /* first_num == 0*/
1573 res = copy_to_user((void *)buf,
1574 (void *)((buf_start)),
1575 data_size - first_num);
1576 mutex_lock(&userdata_mutex);
1577 userdata_buf->buf_rp =
1578 data_size - first_num - res;
1579 mutex_unlock(&userdata_mutex);
1580 retVal = data_size - first_num - res;
1581 }
1582 }
1583 } else {
1584 res = copy_to_user((void *)buf,
1585 (void *)((buf_rp + buf_start)),
1586 data_size);
1587 if (res)
1588 pr_info("p4 read not end res=%d, request=%d\n",
1589 res, data_size);
1590
1591 mutex_lock(&userdata_mutex);
1592 userdata_buf->buf_rp += data_size - res;
1593 mutex_unlock(&userdata_mutex);
1594 retVal = data_size - res;
1595 }
1596 return retVal;
1597}
1598
1599static int amstream_open(struct inode *inode, struct file *file)
1600{
1601 s32 i;
1602 struct stream_port_s *s;
1603 struct stream_port_s *port = &ports[iminor(inode)];
1604 struct port_priv_s *priv;
1605 VDEC_PRINT_FUN_LINENO(__func__, __LINE__);
1606#ifdef G12A_BRINGUP_DEBUG
1607 if (vdec_get_debug_flags() & 0xff0000) {
1608 pr_info("%s force open port %d\n",
1609 __func__,
1610 ((vdec_get_debug_flags() >> 16) & 0xff) - 1);
1611 port = &ports[((vdec_get_debug_flags() >> 16) & 0xff) - 1];
1612 }
1613 pr_info("%s, port name %s\n", __func__, port->name);
1614#endif
1615 if (iminor(inode) >= amstream_port_num)
1616 return -ENODEV;
1617
1618 //pr_err("%s, port name %s\n", __func__, port->name);
1619 //pr_err("%s [pid=%d,tgid=%d]\n", __func__, current->pid, current->tgid);
1620 mutex_lock(&amstream_mutex);
1621
1622 if (port->type & PORT_TYPE_VIDEO) {
1623 for (s = &ports[0], i = 0; i < amstream_port_num; i++, s++) {
1624 if ((!is_mult_inc(s->type)) &&
1625 (s->type & PORT_TYPE_VIDEO) &&
1626 (s->flag & PORT_FLAG_IN_USE)) {
1627 mutex_unlock(&amstream_mutex);
1628 return -EBUSY;
1629 }
1630 }
1631 }
1632
1633 if (!is_support_no_parser()) {
1634 if ((port->flag & PORT_FLAG_IN_USE) &&
1635 ((port->type & PORT_TYPE_FRAME) == 0)) {
1636 mutex_unlock(&amstream_mutex);
1637 return -EBUSY;
1638 }
1639 }
1640 /* force dv frame mode */
1641 if ((force_dv_mode & 0x2) &&
1642 (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SC2)) {
1643 port->type |= PORT_TYPE_FRAME;
1644 port->fops = &vframe_fops;
1645 pr_debug("%s, dobly vision force frame mode.\n", __func__);
1646 }
1647
1648 /* esplayer stream mode force dv */
1649 if (force_dv_mode & 0x1)
1650 port->type |= PORT_TYPE_DUALDEC;
1651
1652 /* check other ports conflicts for audio */
1653 for (s = &ports[0], i = 0; i < amstream_port_num; i++, s++) {
1654 if ((s->flag & PORT_FLAG_IN_USE) &&
1655 ((port->type) & (s->type) & PORT_TYPE_AUDIO)) {
1656 mutex_unlock(&amstream_mutex);
1657 return -EBUSY;
1658 }
1659 }
1660
1661 priv = kzalloc(sizeof(struct port_priv_s), GFP_KERNEL);
1662 if (priv == NULL) {
1663 mutex_unlock(&amstream_mutex);
1664 return -ENOMEM;
1665 }
1666
1667 mutex_init(&priv->mutex);
1668
1669 priv->port = port;
1670
1671 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M6) {
1672 /* TODO: mod gate */
1673 /* switch_mod_gate_by_name("demux", 1); */
1674 amports_switch_gate("demux", 1);
1675 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M8) {
1676 /* TODO: clc gate */
1677 /* CLK_GATE_ON(HIU_PARSER_TOP); */
1678 amports_switch_gate("parser_top", 1);
1679 }
1680
1681 if (port->type & PORT_TYPE_VIDEO) {
1682 /* TODO: mod gate */
1683 /* switch_mod_gate_by_name("vdec", 1); */
1684 amports_switch_gate("vdec", 1);
1685
1686 if (has_hevc_vdec()) {
1687 if (port->type &
1688 (PORT_TYPE_MPTS | PORT_TYPE_HEVC))
1689 vdec_poweron(VDEC_HEVC);
1690
1691 if ((port->type & PORT_TYPE_HEVC) == 0)
1692 vdec_poweron(VDEC_1);
1693 } else {
1694 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M8)
1695 vdec_poweron(VDEC_1);
1696 }
1697 }
1698
1699 if (port->type & PORT_TYPE_AUDIO) {
1700 /* TODO: mod gate */
1701 /* switch_mod_gate_by_name("audio", 1); */
1702 amports_switch_gate("audio", 1);
1703 }
1704 }
1705
1706 port->vid = 0;
1707 port->aid = 0;
1708 port->sid = 0;
1709 port->pcrid = 0xffff;
1710 file->f_op = port->fops;
1711 file->private_data = priv;
1712
1713 port->flag = PORT_FLAG_IN_USE;
1714 port->pcr_inited = 0;
1715#ifdef DATA_DEBUG
1716 debug_filp = filp_open(DEBUG_FILE_NAME, O_WRONLY, 0);
1717 if (IS_ERR(debug_filp)) {
1718 pr_err("amstream: open debug file failed\n");
1719 debug_filp = NULL;
1720 }
1721#endif
1722 mutex_unlock(&amstream_mutex);
1723
1724 if (port->type & PORT_TYPE_VIDEO) {
1725 priv->vdec = vdec_create(port, NULL);
1726
1727 if (priv->vdec == NULL) {
1728 port->flag = 0;
1729 kfree(priv);
1730 pr_err("amstream: vdec creation failed\n");
1731 return -ENOMEM;
1732 }
1733 if (!(port->type & PORT_TYPE_FRAME)) {
1734 if ((port->type & PORT_TYPE_DUALDEC) ||
1735 (vdec_get_debug_flags() & 0x100)) {
1736 priv->vdec->slave = vdec_create(port, priv->vdec);
1737
1738 if (priv->vdec->slave == NULL) {
1739 vdec_release(priv->vdec);
1740 port->flag = 0;
1741 kfree(priv);
1742 pr_err("amstream: sub vdec creation failed\n");
1743 return -ENOMEM;
1744 }
1745 }
1746 }
1747 }
1748
1749 return 0;
1750}
1751
1752static int amstream_release(struct inode *inode, struct file *file)
1753{
1754 struct port_priv_s *priv = file->private_data;
1755 struct stream_port_s *port = priv->port;
1756 struct vdec_s *slave = NULL;
1757#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
1758 u32 port_flag = 0;
1759#endif
1760
1761 if (iminor(inode) >= amstream_port_num)
1762 return -ENODEV;
1763
1764 mutex_lock(&amstream_mutex);
1765
1766 if (port_get_inited(priv))
1767 amstream_port_release(priv);
1768
1769 if (priv->vdec) {
1770#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
1771 port_flag = priv->vdec->port_flag;
1772#endif
1773 if (priv->vdec->slave)
1774 slave = priv->vdec->slave;
1775 vdec_release(priv->vdec);
1776 if (slave)
1777 vdec_release(slave);
1778 priv->vdec = NULL;
1779 }
1780
1781 if ((port->type & (PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)) ==
1782 PORT_TYPE_AUDIO) {
1783 s32 i;
1784 struct stream_port_s *s;
1785
1786 for (s = &ports[0], i = 0; i < amstream_port_num; i++, s++) {
1787 if ((s->flag & PORT_FLAG_IN_USE)
1788 && (s->type & PORT_TYPE_VIDEO))
1789 break;
1790 }
1791 if (i == amstream_port_num)
1792 timestamp_firstvpts_set(0);
1793 }
1794 port->flag = 0;
1795
1796 /* timestamp_pcrscr_set(0); */
1797
1798#ifdef DATA_DEBUG
1799 if (debug_filp) {
1800 filp_close(debug_filp, current->files);
1801 debug_filp = NULL;
1802 debug_file_pos = 0;
1803 }
1804#endif
1805 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M6) {
1806 if (port->type & PORT_TYPE_VIDEO) {
1807 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M8) {
1808#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
1809 if (has_hevc_vdec())
1810 vdec_poweroff(VDEC_HEVC);
1811
1812 vdec_poweroff(VDEC_1);
1813#else
1814 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_TXLX
1815 && port->vformat == VFORMAT_H264
1816 && port->is_4k) {
1817 vdec_poweroff(VDEC_HEVC);
1818 }
1819
1820 if ((port->vformat == VFORMAT_HEVC
1821 || port->vformat == VFORMAT_AVS2
1822 || port->vformat == VFORMAT_AV1
1823 || port->vformat == VFORMAT_VP9)) {
1824 vdec_poweroff(VDEC_HEVC);
1825 } else {
1826 vdec_poweroff(VDEC_1);
1827 }
1828#endif
1829 }
1830 /* TODO: mod gate */
1831 /* switch_mod_gate_by_name("vdec", 0); */
1832 amports_switch_gate("vdec", 0);
1833 }
1834
1835 if (port->type & PORT_TYPE_AUDIO) {
1836 /* TODO: mod gate */
1837 /* switch_mod_gate_by_name("audio", 0); */
1838 /* amports_switch_gate("audio", 0); */
1839 }
1840
1841 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M8) {
1842 /* TODO: clc gate */
1843 /* CLK_GATE_OFF(HIU_PARSER_TOP); */
1844 amports_switch_gate("parser_top", 0);
1845 }
1846 /* TODO: mod gate */
1847 /* switch_mod_gate_by_name("demux", 0); */
1848 amports_switch_gate("demux", 0);
1849 }
1850
1851 mutex_destroy(&priv->mutex);
1852
1853 kfree(priv);
1854
1855 mutex_unlock(&amstream_mutex);
1856 return 0;
1857}
1858
1859static long amstream_ioctl_get_version(struct port_priv_s *priv,
1860 ulong arg)
1861{
1862 int version = (AMSTREAM_IOC_VERSION_FIRST & 0xffff) << 16
1863 | (AMSTREAM_IOC_VERSION_SECOND & 0xffff);
1864 put_user(version, (u32 __user *)arg);
1865
1866 return 0;
1867}
1868static long amstream_ioctl_get(struct port_priv_s *priv, ulong arg)
1869{
1870 struct stream_port_s *this = priv->port;
1871 long r = 0;
1872
1873 struct am_ioctl_parm parm;
1874
1875 if (copy_from_user
1876 ((void *)&parm, (void *)arg,
1877 sizeof(parm)))
1878 r = -EFAULT;
1879
1880 switch (parm.cmd) {
1881 case AMSTREAM_GET_SUB_LENGTH:
1882 if ((this->type & PORT_TYPE_SUB) ||
1883 (this->type & PORT_TYPE_SUB_RD)) {
1884 u32 sub_wp, sub_rp;
1885 struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
1886 int val;
1887
1888 sub_wp = stbuf_sub_wp_get();
1889 sub_rp = stbuf_sub_rp_get();
1890
1891 if (sub_wp == sub_rp)
1892 val = 0;
1893 else if (sub_wp > sub_rp)
1894 val = sub_wp - sub_rp;
1895 else
1896 val = psbuf->buf_size - (sub_rp - sub_wp);
1897 parm.data_32 = val;
1898 } else
1899 r = -EINVAL;
1900 break;
1901 case AMSTREAM_GET_UD_LENGTH:
1902 if (this->type & PORT_TYPE_USERDATA) {
1903 parm.data_32 = userdata_length;
1904 userdata_length = 0;
1905 } else
1906 r = -EINVAL;
1907 break;
1908 case AMSTREAM_GET_APTS_LOOKUP:
1909 if (this->type & PORT_TYPE_AUDIO) {
1910 u32 pts = 0, frame_size, offset;
1911
1912 offset = parm.data_32;
1913 pts_lookup_offset(PTS_TYPE_AUDIO, offset, &pts,
1914 &frame_size, 300);
1915 parm.data_32 = pts;
1916 }
1917 break;
1918 case AMSTREAM_GET_FIRST_APTS_FLAG:
1919 if (this->type & PORT_TYPE_AUDIO) {
1920 parm.data_32 = first_pts_checkin_complete(
1921 PTS_TYPE_AUDIO);
1922 }
1923 break;
1924 case AMSTREAM_GET_APTS:
1925 parm.data_32 = timestamp_apts_get();
1926 break;
1927 case AMSTREAM_GET_VPTS:
1928 parm.data_32 = timestamp_vpts_get();
1929 break;
1930 case AMSTREAM_GET_VPTS_U64:
1931 parm.data_64 = timestamp_vpts_get_u64();
1932 break;
1933 case AMSTREAM_GET_APTS_U64:
1934 parm.data_64 = timestamp_apts_get_u64();
1935 break;
1936 case AMSTREAM_GET_PCRSCR:
1937 parm.data_32 = timestamp_pcrscr_get();
1938 break;
1939 case AMSTREAM_GET_LAST_CHECKIN_APTS:
1940 parm.data_32 = get_last_checkin_pts(PTS_TYPE_AUDIO);
1941 break;
1942 case AMSTREAM_GET_LAST_CHECKIN_VPTS:
1943 parm.data_32 = get_last_checkin_pts(PTS_TYPE_VIDEO);
1944 break;
1945 case AMSTREAM_GET_LAST_CHECKOUT_APTS:
1946 parm.data_32 = get_last_checkout_pts(PTS_TYPE_AUDIO);
1947 break;
1948 case AMSTREAM_GET_LAST_CHECKOUT_VPTS:
1949 parm.data_32 = get_last_checkout_pts(PTS_TYPE_VIDEO);
1950 break;
1951 case AMSTREAM_GET_SUB_NUM:
1952 parm.data_32 = psparser_get_sub_found_num();
1953 break;
1954 case AMSTREAM_GET_VIDEO_DELAY_LIMIT_MS:
1955 parm.data_32 = bufs[BUF_TYPE_VIDEO].max_buffer_delay_ms;
1956 break;
1957 case AMSTREAM_GET_AUDIO_DELAY_LIMIT_MS:
1958 parm.data_32 = bufs[BUF_TYPE_AUDIO].max_buffer_delay_ms;
1959 break;
1960 case AMSTREAM_GET_VIDEO_CUR_DELAY_MS: {
1961 int delay;
1962
1963 delay = calculation_stream_delayed_ms(
1964 PTS_TYPE_VIDEO, NULL, NULL);
1965 if (delay >= 0)
1966 parm.data_32 = delay;
1967 else
1968 parm.data_32 = 0;
1969 }
1970 break;
1971
1972 case AMSTREAM_GET_AUDIO_CUR_DELAY_MS: {
1973 int delay;
1974
1975 delay = calculation_stream_delayed_ms(
1976 PTS_TYPE_AUDIO, NULL, NULL);
1977 if (delay >= 0)
1978 parm.data_32 = delay;
1979 else
1980 parm.data_32 = 0;
1981 }
1982 break;
1983 case AMSTREAM_GET_AUDIO_AVG_BITRATE_BPS: {
1984 int delay;
1985 u32 avgbps;
1986
1987 delay = calculation_stream_delayed_ms(
1988 PTS_TYPE_AUDIO, NULL, &avgbps);
1989 if (delay >= 0)
1990 parm.data_32 = avgbps;
1991 else
1992 parm.data_32 = 0;
1993 }
1994 break;
1995 case AMSTREAM_GET_VIDEO_AVG_BITRATE_BPS: {
1996 int delay;
1997 u32 avgbps;
1998
1999 delay = calculation_stream_delayed_ms(
2000 PTS_TYPE_VIDEO, NULL, &avgbps);
2001 if (delay >= 0)
2002 parm.data_32 = avgbps;
2003 else
2004 parm.data_32 = 0;
2005 }
2006 break;
2007 case AMSTREAM_GET_ION_ID:
2008 parm.data_32 = priv->vdec->vf_receiver_inst;
2009 break;
2010 case AMSTREAM_GET_NEED_MORE_DATA:
2011 parm.data_32 = vdec_need_more_data(priv->vdec);
2012 break;
2013 case AMSTREAM_GET_FREED_HANDLE:
2014 parm.data_32 = vdec_input_get_freed_handle(priv->vdec);
2015 break;
2016 default:
2017 r = -ENOIOCTLCMD;
2018 break;
2019 }
2020 /* pr_info("parm size:%d\n", sizeof(parm)); */
2021 if (r == 0) {
2022 if (copy_to_user((void *)arg, &parm, sizeof(parm)))
2023 r = -EFAULT;
2024 }
2025
2026 return r;
2027
2028}
2029static long amstream_ioctl_set(struct port_priv_s *priv, ulong arg)
2030{
2031 struct stream_port_s *this = priv->port;
2032 struct am_ioctl_parm parm;
2033 long r = 0;
2034
2035 if (copy_from_user
2036 ((void *)&parm, (void *)arg,
2037 sizeof(parm)))
2038 r = -EFAULT;
2039
2040 switch (parm.cmd) {
2041 case AMSTREAM_SET_VB_START:
2042 if ((this->type & PORT_TYPE_VIDEO) &&
2043 ((priv->vdec->vbuf.flag & BUF_FLAG_IN_USE) == 0)) {
2044 priv->vdec->vbuf.buf_start = parm.data_32;
2045 } else
2046 r = -EINVAL;
2047 break;
2048 case AMSTREAM_SET_VB_SIZE:
2049 if ((this->type & PORT_TYPE_VIDEO) &&
2050 ((priv->vdec->vbuf.flag & BUF_FLAG_IN_USE) == 0)) {
2051 if (priv->vdec->vbuf.flag & BUF_FLAG_ALLOC) {
2052 r += stbuf_change_size(
2053 &priv->vdec->vbuf,
2054 parm.data_32,
2055 false);
2056 }
2057 } else if (this->type & PORT_TYPE_FRAME) {
2058 /* todo: frame based set max buffer size */
2059 r = 0;
2060 } else
2061 r = -EINVAL;
2062 break;
2063 case AMSTREAM_SET_AB_START:
2064 if ((this->type & PORT_TYPE_AUDIO) &&
2065 ((bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_IN_USE) == 0))
2066 bufs[BUF_TYPE_AUDIO].buf_start = parm.data_32;
2067 else
2068 r = -EINVAL;
2069 break;
2070 case AMSTREAM_SET_AB_SIZE:
2071 if ((this->type & PORT_TYPE_AUDIO) &&
2072 ((bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_IN_USE) == 0)) {
2073 if (bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_ALLOC) {
2074 r = stbuf_change_size(
2075 &bufs[BUF_TYPE_AUDIO],
2076 parm.data_32,
2077 false);
2078 }
2079 } else
2080 r = -EINVAL;
2081 break;
2082 case AMSTREAM_SET_VFORMAT:
2083 if ((this->type & PORT_TYPE_VIDEO) &&
2084 (parm.data_vformat < VFORMAT_MAX)) {
2085 this->vformat = parm.data_vformat;
2086 this->flag |= PORT_FLAG_VFORMAT;
2087
2088 vdec_set_format(priv->vdec, this->vformat);
2089 } else
2090 r = -EINVAL;
2091 break;
2092 case AMSTREAM_SET_AFORMAT:
2093 if ((this->type & PORT_TYPE_AUDIO) &&
2094 (parm.data_aformat < AFORMAT_MAX)) {
2095 memset(&audio_dec_info, 0,
2096 sizeof(struct audio_info));
2097 /* for new format,reset the audio info. */
2098 this->aformat = parm.data_aformat;
2099 this->flag |= PORT_FLAG_AFORMAT;
2100 } else
2101 r = -EINVAL;
2102 break;
2103 case AMSTREAM_SET_VID:
2104 if (this->type & PORT_TYPE_VIDEO) {
2105 this->vid = parm.data_32;
2106 this->flag |= PORT_FLAG_VID;
2107 } else
2108 r = -EINVAL;
2109
2110 break;
2111 case AMSTREAM_SET_AID:
2112 if (this->type & PORT_TYPE_AUDIO) {
2113 this->aid = parm.data_32;
2114 this->flag |= PORT_FLAG_AID;
2115
2116 if (port_get_inited(priv)) {
2117 //tsync_audio_break(1);
2118 amstream_change_avid(this);
2119 }
2120 } else
2121 r = -EINVAL;
2122 break;
2123 case AMSTREAM_SET_SID:
2124 if (this->type & PORT_TYPE_SUB) {
2125 this->sid = parm.data_32;
2126 this->flag |= PORT_FLAG_SID;
2127
2128 if (port_get_inited(priv))
2129 amstream_change_sid(this);
2130 } else
2131 r = -EINVAL;
2132
2133 break;
2134 case AMSTREAM_IOC_PCRID:
2135 this->pcrid = parm.data_32;
2136 this->pcr_inited = 1;
2137 pr_err("set pcrid = 0x%x\n", this->pcrid);
2138 break;
2139 case AMSTREAM_SET_ACHANNEL:
2140 if (this->type & PORT_TYPE_AUDIO) {
2141 this->achanl = parm.data_32;
2142 set_ch_num_info(parm.data_32);
2143 } else
2144 r = -EINVAL;
2145 break;
2146 case AMSTREAM_SET_SAMPLERATE:
2147 if (this->type & PORT_TYPE_AUDIO) {
2148 this->asamprate = parm.data_32;
2149 set_sample_rate_info(parm.data_32);
2150 } else
2151 r = -EINVAL;
2152 break;
2153 case AMSTREAM_SET_DATAWIDTH:
2154 if (this->type & PORT_TYPE_AUDIO)
2155 this->adatawidth = parm.data_32;
2156 else
2157 r = -EINVAL;
2158 break;
2159 case AMSTREAM_SET_TSTAMP:
2160 if ((this->type & (PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)) ==
2161 ((PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)))
2162 r = -EINVAL;
2163 else if (this->type & PORT_TYPE_FRAME)
2164 r = vdec_set_pts(priv->vdec, parm.data_32);
2165 else if ((this->type & PORT_TYPE_VIDEO) ||
2166 (this->type & PORT_TYPE_HEVC))
2167 r = es_vpts_checkin(&priv->vdec->vbuf,
2168 parm.data_32);
2169 else if (this->type & PORT_TYPE_AUDIO)
2170 r = es_apts_checkin(&bufs[BUF_TYPE_AUDIO],
2171 parm.data_32);
2172 break;
2173 case AMSTREAM_SET_TSTAMP_US64:
2174 if ((this->type & (PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)) ==
2175 ((PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)))
2176 r = -EINVAL;
2177 else {
2178 u64 pts = parm.data_64;
2179
2180 if (this->type & PORT_TYPE_FRAME) {
2181 /*
2182 *todo: check upper layer for decoder handler
2183 * life sequence or multi-tasking management
2184 */
2185 r = vdec_set_pts64(priv->vdec, pts);
2186 } else if ((this->type & PORT_TYPE_HEVC) ||
2187 (this->type & PORT_TYPE_VIDEO)) {
2188 r = es_vpts_checkin_us64(
2189 &priv->vdec->vbuf, pts);
2190 } else if (this->type & PORT_TYPE_AUDIO) {
2191 r = es_vpts_checkin_us64(
2192 &bufs[BUF_TYPE_AUDIO], pts);
2193 }
2194 }
2195 break;
2196 case AMSTREAM_PORT_INIT:
2197 r = amstream_port_init(priv);
2198 break;
2199 case AMSTREAM_SET_TRICKMODE:
2200 if ((this->type & PORT_TYPE_VIDEO) == 0)
2201 return -EINVAL;
2202 r = vdec_set_trickmode(priv->vdec, parm.data_32);
2203 if (r == -1)
2204 return -ENODEV;
2205 break;
2206
2207 case AMSTREAM_AUDIO_RESET:
2208 if (this->type & PORT_TYPE_AUDIO) {
2209 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
2210
2211 r = audio_port_reset(this, pabuf);
2212 } else
2213 r = -EINVAL;
2214
2215 break;
2216 case AMSTREAM_SUB_RESET:
2217 if (this->type & PORT_TYPE_SUB) {
2218 struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
2219
2220 r = sub_port_reset(this, psbuf);
2221 } else
2222 r = -EINVAL;
2223 break;
2224 case AMSTREAM_DEC_RESET:
2225 tsync_set_dec_reset();
2226 break;
2227 case AMSTREAM_SET_TS_SKIPBYTE:
2228 tsdemux_set_skipbyte(parm.data_32);
2229 break;
2230 case AMSTREAM_SET_SUB_TYPE:
2231 sub_type = parm.data_32;
2232 break;
2233 case AMSTREAM_SET_PCRSCR:
2234 timestamp_pcrscr_set(parm.data_32);
2235 break;
2236 case AMSTREAM_SET_DEMUX:
2237 tsdemux_set_demux(parm.data_32);
2238 break;
2239 case AMSTREAM_SET_VIDEO_DELAY_LIMIT_MS:
2240 priv->vdec->vbuf.max_buffer_delay_ms = parm.data_32;
2241 break;
2242 case AMSTREAM_SET_AUDIO_DELAY_LIMIT_MS:
2243 bufs[BUF_TYPE_AUDIO].max_buffer_delay_ms = parm.data_32;
2244 break;
2245 case AMSTREAM_SET_DRMMODE:
2246 if (parm.data_32 == 1) {
2247 pr_debug("set drmmode\n");
2248 this->flag |= PORT_FLAG_DRM;
2249 if ((this->type & PORT_TYPE_VIDEO) &&
2250 (priv->vdec))
2251 priv->vdec->port_flag |= PORT_FLAG_DRM;
2252 } else {
2253 this->flag &= (~PORT_FLAG_DRM);
2254 pr_debug("no drmmode\n");
2255 }
2256 break;
2257 case AMSTREAM_SET_APTS: {
2258 unsigned int pts;
2259
2260 pts = parm.data_32;
2261 if (tsync_get_mode() == TSYNC_MODE_PCRMASTER)
2262 tsync_pcr_set_apts(pts);
2263 else
2264 tsync_set_apts(pts);
2265 break;
2266 }
2267 case AMSTREAM_SET_FRAME_BASE_PATH:
2268 if (is_mult_inc(this->type) &&
2269 (parm.frame_base_video_path < FRAME_BASE_PATH_MAX)) {
2270 vdec_set_video_path(priv->vdec, parm.data_32);
2271 } else
2272 r = -EINVAL;
2273 break;
2274 case AMSTREAM_SET_EOS:
2275 if (priv->vdec)
2276 vdec_set_eos(priv->vdec, parm.data_32);
2277 break;
2278 case AMSTREAM_SET_RECEIVE_ID:
2279 if (is_mult_inc(this->type))
2280 vdec_set_receive_id(priv->vdec, parm.data_32);
2281 else
2282 r = -EINVAL;
2283 break;
2284 case AMSTREAM_SET_IS_RESET:
2285 if (priv->vdec)
2286 vdec_set_isreset(priv->vdec, parm.data_32);
2287 break;
2288 case AMSTREAM_SET_DV_META_WITH_EL:
2289 if (priv->vdec) {
2290 vdec_set_dv_metawithel(priv->vdec, parm.data_32);
2291 if (vdec_dual(priv->vdec) && priv->vdec->slave)
2292 vdec_set_dv_metawithel(priv->vdec->slave,
2293 parm.data_32);
2294 }
2295 break;
2296 case AMSTREAM_SET_NO_POWERDOWN:
2297 vdec_set_no_powerdown(parm.data_32);
2298 break;
2299 default:
2300 r = -ENOIOCTLCMD;
2301 break;
2302 }
2303 return r;
2304}
2305
2306static enum E_ASPECT_RATIO get_normalized_aspect_ratio(u32 ratio_control)
2307{
2308 enum E_ASPECT_RATIO euAspectRatio;
2309
2310 ratio_control = ratio_control >> DISP_RATIO_ASPECT_RATIO_BIT;
2311
2312 switch (ratio_control) {
2313 case 0x8c:
2314 case 0x90:
2315 euAspectRatio = ASPECT_RATIO_16_9;
2316 /*pr_info("ASPECT_RATIO_16_9\n");*/
2317 break;
2318 case 0xbb:
2319 case 0xc0:
2320 euAspectRatio = ASPECT_RATIO_4_3;
2321 /*pr_info("ASPECT_RATIO_4_3\n");*/
2322 break;
2323 default:
2324 euAspectRatio = ASPECT_UNDEFINED;
2325 /*pr_info("ASPECT_UNDEFINED and ratio_control = 0x%x\n",
2326 ratio_control);*/
2327 break;
2328 }
2329
2330 return euAspectRatio;
2331}
2332
2333static long amstream_ioctl_get_ex(struct port_priv_s *priv, ulong arg)
2334{
2335 struct stream_port_s *this = priv->port;
2336 long r = 0;
2337 struct am_ioctl_parm_ex parm;
2338
2339 if (copy_from_user
2340 ((void *)&parm, (void *)arg,
2341 sizeof(parm)))
2342 r = -EFAULT;
2343
2344 switch (parm.cmd) {
2345 case AMSTREAM_GET_EX_VB_STATUS:
2346 if (this->type & PORT_TYPE_VIDEO) {
2347 struct am_ioctl_parm_ex *p = &parm;
2348 struct stream_buf_s *buf = NULL;
2349
2350 mutex_unlock(&amstream_mutex);
2351
2352 /*
2353 *todo: check upper layer for decoder
2354 * handler lifecycle
2355 */
2356 if (priv->vdec == NULL) {
2357 r = -EINVAL;
2358 mutex_unlock(&amstream_mutex);
2359 break;
2360 }
2361
2362 if (this->type & PORT_TYPE_FRAME) {
2363 struct vdec_input_status_s status;
2364
2365 r = vdec_input_get_status(&priv->vdec->input,
2366 &status);
2367 if (r == 0) {
2368 p->status.size = status.size;
2369 p->status.data_len = status.data_len;
2370 p->status.free_len = status.free_len;
2371 p->status.read_pointer =
2372 status.read_pointer;
2373 }
2374 mutex_unlock(&amstream_mutex);
2375 break;
2376 }
2377
2378 buf = &priv->vdec->vbuf;
2379 p->status.size = stbuf_canusesize(buf);
2380 p->status.data_len = stbuf_level(buf);
2381 p->status.free_len = stbuf_space(buf);
2382 p->status.read_pointer = stbuf_rp(buf);
2383 mutex_unlock(&amstream_mutex);
2384 } else
2385 r = -EINVAL;
2386 break;
2387 case AMSTREAM_GET_EX_AB_STATUS:
2388 if (this->type & PORT_TYPE_AUDIO) {
2389 struct am_ioctl_parm_ex *p = &parm;
2390 struct stream_buf_s *buf = &bufs[BUF_TYPE_AUDIO];
2391
2392
2393 p->status.size = stbuf_canusesize(buf);
2394 p->status.data_len = stbuf_level(buf);
2395 p->status.free_len = stbuf_space(buf);
2396 p->status.read_pointer = stbuf_rp(buf);
2397
2398 } else
2399 r = -EINVAL;
2400 break;
2401 case AMSTREAM_GET_EX_VDECSTAT:
2402 if ((this->type & PORT_TYPE_VIDEO) == 0) {
2403 pr_err("no video\n");
2404 return -EINVAL;
2405 } else {
2406 struct vdec_info vstatus;
2407 struct am_ioctl_parm_ex *p = &parm;
2408
2409 memset(&vstatus, 0, sizeof(vstatus));
2410
2411 mutex_lock(&priv->mutex);
2412 if (vdec_status(priv->vdec, &vstatus) == -1) {
2413 mutex_unlock(&priv->mutex);
2414 return -ENODEV;
2415 }
2416 mutex_unlock(&priv->mutex);
2417
2418 p->vstatus.width = vstatus.frame_width;
2419 p->vstatus.height = vstatus.frame_height;
2420 p->vstatus.fps = vstatus.frame_rate;
2421 p->vstatus.error_count = vstatus.error_count;
2422 p->vstatus.status = vstatus.status;
2423 p->vstatus.euAspectRatio =
2424 get_normalized_aspect_ratio(
2425 vstatus.ratio_control);
2426
2427 }
2428 break;
2429 case AMSTREAM_GET_EX_ADECSTAT:
2430 if ((this->type & PORT_TYPE_AUDIO) == 0) {
2431 pr_err("no audio\n");
2432 return -EINVAL;
2433 }
2434 if (amstream_adec_status == NULL) {
2435 /*
2436 *pr_err("no amstream_adec_status\n");
2437 *return -ENODEV;
2438 */
2439 memset(&parm.astatus, 0, sizeof(parm.astatus));
2440 } else {
2441 struct adec_status astatus;
2442 struct am_ioctl_parm_ex *p = &parm;
2443
2444 amstream_adec_status(&astatus);
2445 p->astatus.channels = astatus.channels;
2446 p->astatus.sample_rate = astatus.sample_rate;
2447 p->astatus.resolution = astatus.resolution;
2448 p->astatus.error_count = astatus.error_count;
2449 p->astatus.status = astatus.status;
2450 }
2451 break;
2452
2453 case AMSTREAM_GET_EX_UD_POC:
2454 if (this->type & PORT_TYPE_USERDATA) {
2455 struct userdata_poc_info_t userdata_poc =
2456 userdata_poc_info[userdata_poc_ri];
2457 memcpy(&parm.data_userdata_info,
2458 &userdata_poc,
2459 sizeof(struct userdata_poc_info_t));
2460
2461 userdata_poc_ri++;
2462 if (userdata_poc_ri == USERDATA_FIFO_NUM)
2463 userdata_poc_ri = 0;
2464 } else
2465 r = -EINVAL;
2466 break;
2467 default:
2468 r = -ENOIOCTLCMD;
2469 break;
2470 }
2471 /* pr_info("parm size:%zx\n", sizeof(parm)); */
2472 if (r == 0) {
2473 if (copy_to_user((void *)arg, &parm, sizeof(parm)))
2474 r = -EFAULT;
2475 }
2476 return r;
2477
2478}
2479static long amstream_ioctl_set_ex(struct port_priv_s *priv, ulong arg)
2480{
2481 long r = 0;
2482 return r;
2483}
2484static long amstream_ioctl_get_ptr(struct port_priv_s *priv, ulong arg)
2485{
2486 long r = 0;
2487
2488 struct am_ioctl_parm_ptr parm;
2489
2490 if (copy_from_user
2491 ((void *)&parm, (void *)arg,
2492 sizeof(parm)))
2493 return -EFAULT;
2494
2495 switch (parm.cmd) {
2496 case AMSTREAM_GET_PTR_SUB_INFO:
2497 {
2498 struct subtitle_info msub_info[MAX_SUB_NUM];
2499 struct subtitle_info *psub_info[MAX_SUB_NUM];
2500 int i;
2501
2502 for (i = 0; i < MAX_SUB_NUM; i++)
2503 psub_info[i] = &msub_info[i];
2504
2505 r = psparser_get_sub_info(psub_info);
2506
2507 if (r == 0) {
2508 memcpy(parm.pdata_sub_info, msub_info,
2509 sizeof(struct subtitle_info)
2510 * MAX_SUB_NUM);
2511 }
2512 }
2513 break;
2514 default:
2515 r = -ENOIOCTLCMD;
2516 break;
2517 }
2518 /* pr_info("parm size:%d\n", sizeof(parm)); */
2519 if (r == 0) {
2520 if (copy_to_user((void *)arg, &parm, sizeof(parm)))
2521 r = -EFAULT;
2522 }
2523
2524 return r;
2525
2526}
2527static long amstream_ioctl_set_ptr(struct port_priv_s *priv, ulong arg)
2528{
2529 struct stream_port_s *this = priv->port;
2530 struct am_ioctl_parm_ptr parm;
2531 long r = 0;
2532
2533 if (copy_from_user
2534 ((void *)&parm, (void *)arg,
2535 sizeof(parm))) {
2536 pr_err("[%s]%d, arg err\n", __func__, __LINE__);
2537 r = -EFAULT;
2538 }
2539 switch (parm.cmd) {
2540 case AMSTREAM_SET_PTR_AUDIO_INFO:
2541 if ((this->type & PORT_TYPE_VIDEO)
2542 || (this->type & PORT_TYPE_AUDIO)) {
2543 if (parm.pdata_audio_info != NULL) {
2544 if (copy_from_user
2545 ((void *)&audio_dec_info, (void *)parm.pdata_audio_info,
2546 sizeof(audio_dec_info))) {
2547 pr_err("[%s]%d, arg err\n", __func__, __LINE__);
2548 r = -EFAULT;
2549 }
2550 }
2551 } else
2552 r = -EINVAL;
2553 break;
2554 case AMSTREAM_SET_PTR_CONFIGS:
2555 if (this->type & PORT_TYPE_VIDEO) {
2556 if (!parm.pointer || (parm.len <= 0) ||
2557 (parm.len > PAGE_SIZE)) {
2558 r = -EINVAL;
2559 } else {
2560 r = copy_from_user(priv->vdec->config,
2561 parm.pointer, parm.len);
2562 if (r)
2563 r = -EINVAL;
2564 else
2565 priv->vdec->config_len = parm.len;
2566 }
2567 } else
2568 r = -EINVAL;
2569 break;
2570 case AMSTREAM_SET_PTR_HDR10P_DATA:
2571 if ((this->type & PORT_TYPE_VIDEO) && (this->type & PORT_TYPE_FRAME)) {
2572 if (!parm.pointer || (parm.len <= 0) ||
2573 (parm.len > PAGE_SIZE)) {
2574 r = -EINVAL;
2575 } else {
2576 r = copy_from_user(priv->vdec->hdr10p_data_buf,
2577 parm.pointer, parm.len);
2578 if (r) {
2579 priv->vdec->hdr10p_data_size = 0;
2580 priv->vdec->hdr10p_data_valid = false;
2581 r = -EINVAL;
2582 } else {
2583 priv->vdec->hdr10p_data_size = parm.len;
2584 priv->vdec->hdr10p_data_valid = true;
2585 }
2586 }
2587 } else
2588 r = -EINVAL;
2589 break;
2590 default:
2591 r = -ENOIOCTLCMD;
2592 break;
2593 }
2594 return r;
2595}
2596
2597static long amstream_do_ioctl_new(struct port_priv_s *priv,
2598 unsigned int cmd, ulong arg)
2599{
2600 long r = 0;
2601 struct stream_port_s *this = priv->port;
2602
2603 switch (cmd) {
2604 case AMSTREAM_IOC_GET_VERSION:
2605 r = amstream_ioctl_get_version(priv, arg);
2606 break;
2607 case AMSTREAM_IOC_GET:
2608 r = amstream_ioctl_get(priv, arg);
2609 break;
2610 case AMSTREAM_IOC_SET:
2611 r = amstream_ioctl_set(priv, arg);
2612 break;
2613 case AMSTREAM_IOC_GET_EX:
2614 r = amstream_ioctl_get_ex(priv, arg);
2615 break;
2616 case AMSTREAM_IOC_SET_EX:
2617 r = amstream_ioctl_set_ex(priv, arg);
2618 break;
2619 case AMSTREAM_IOC_GET_PTR:
2620 r = amstream_ioctl_get_ptr(priv, arg);
2621 break;
2622 case AMSTREAM_IOC_SET_PTR:
2623 r = amstream_ioctl_set_ptr(priv, arg);
2624 break;
2625 case AMSTREAM_IOC_SYSINFO:
2626 if (this->type & PORT_TYPE_VIDEO)
2627 r = vdec_set_decinfo(priv->vdec, (void *)arg);
2628 else
2629 r = -EINVAL;
2630 break;
2631 case AMSTREAM_IOC_GET_QOSINFO:
2632 case AMSTREAM_IOC_GET_MVDECINFO:
2633 {
2634 u32 slots = 0;
2635 u32 struct_size = 0;
2636 int vdec_id = 0;
2637 struct vdec_s *vdec = NULL;
2638 struct vframe_counter_s tmpbuf[QOS_FRAME_NUM] = {0};
2639 struct av_param_mvdec_t __user *uarg = (void *)arg;
2640
2641 if (AMSTREAM_IOC_GET_MVDECINFO == cmd) {
2642 if (get_user(vdec_id, &uarg->vdec_id) < 0
2643 || get_user(struct_size, &uarg->struct_size) < 0) {
2644 r = -EFAULT;
2645 break;
2646 }
2647 if (struct_size != sizeof(struct av_param_mvdec_t)) {
2648 pr_err("pass in size %u != expected size %u\n",
2649 struct_size, (u32)sizeof(struct av_param_mvdec_t));
2650 pr_err("App using old structue,we will support it.\n");
2651 //Here will add the compatibility for old structure when
2652 //current struecture be substituded by newer structure.
2653 //msleep(1000); let app handle it.
2654 break;
2655 }
2656 }
2657 vdec = vdec_get_vdec_by_id(vdec_id);
2658 if (!vdec) {
2659 r = 0;
2660 break;
2661 }
2662
2663 slots = vdec_get_frame_vdec(vdec, tmpbuf);
2664 if (AMSTREAM_IOC_GET_MVDECINFO == cmd)
2665 put_user(slots, &uarg->slots);
2666 if (slots) {
2667 if (AMSTREAM_IOC_GET_MVDECINFO == cmd) {
2668 if (copy_to_user((void *)&uarg->comm,
2669 &vdec->mvfrm->comm,
2670 sizeof(struct vframe_comm_s))) {
2671 r = -EFAULT;
2672 break;
2673 }
2674 if (copy_to_user((void *)&uarg->minfo[0],
2675 tmpbuf,
2676 slots*sizeof(struct vframe_counter_s))) {
2677 r = -EFAULT;
2678 kfree(tmpbuf);
2679 break;
2680 }
2681 }else { //For compatibility, only copy the qos
2682 struct av_param_qosinfo_t __user *uarg = (void *)arg;
2683 int i;
2684 for (i=0; i<slots; i++)
2685 if (copy_to_user((void *)&uarg->vframe_qos[i],
2686 &tmpbuf[i].qos,
2687 sizeof(struct vframe_qos_s))) {
2688 r = -EFAULT;
2689 break;
2690 }
2691 }
2692 } else {
2693 /*Vdec didn't produce item,wait for 10 ms to avoid user application
2694 infinitely calling*/
2695 //msleep(10); let user app handle it.
2696 }
2697 }
2698 break;
2699 case AMSTREAM_IOC_GET_AVINFO:
2700 {
2701 struct av_param_info_t __user *uarg = (void *)arg;
2702 struct av_info_t av_info;
2703 int delay;
2704 u32 avgbps;
2705 if (this->type & PORT_TYPE_VIDEO) {
2706 av_info.first_pic_coming = get_first_pic_coming();
2707 av_info.current_fps = -1;
2708 av_info.vpts = timestamp_vpts_get();
2709 av_info.vpts_err = tsync_get_vpts_error_num();
2710 av_info.apts = timestamp_apts_get();
2711 av_info.apts_err = tsync_get_apts_error_num();
2712 av_info.ts_error = get_discontinue_counter();
2713 av_info.first_vpts = timestamp_firstvpts_get();
2714 av_info.toggle_frame_count = get_toggle_frame_count();
2715 delay = calculation_stream_delayed_ms(
2716 PTS_TYPE_VIDEO, NULL, &avgbps);
2717 if (delay >= 0)
2718 av_info.dec_video_bps = avgbps;
2719 else
2720 av_info.dec_video_bps = 0;
2721 }
2722 if (copy_to_user((void *)&uarg->av_info, (void *)&av_info,
2723 sizeof(struct av_info_t)))
2724 r = -EFAULT;
2725 }
2726 break;
2727 default:
2728 r = -ENOIOCTLCMD;
2729 break;
2730 }
2731
2732 return r;
2733}
2734
2735static long amstream_do_ioctl_old(struct port_priv_s *priv,
2736 unsigned int cmd, ulong arg)
2737{
2738 struct stream_port_s *this = priv->port;
2739 long r = 0;
2740
2741 switch (cmd) {
2742
2743 case AMSTREAM_IOC_VB_START:
2744 if ((this->type & PORT_TYPE_VIDEO) &&
2745 ((priv->vdec->vbuf.flag & BUF_FLAG_IN_USE) == 0)) {
2746 priv->vdec->vbuf.buf_start = arg;
2747 } else
2748 r = -EINVAL;
2749 break;
2750
2751 case AMSTREAM_IOC_VB_SIZE:
2752 if ((this->type & PORT_TYPE_VIDEO) &&
2753 ((priv->vdec->vbuf.flag & BUF_FLAG_IN_USE) == 0)) {
2754 if (priv->vdec->vbuf.flag & BUF_FLAG_ALLOC) {
2755 r += stbuf_change_size(
2756 &priv->vdec->vbuf,
2757 arg, false);
2758 }
2759 } else
2760 r = -EINVAL;
2761 break;
2762
2763 case AMSTREAM_IOC_AB_START:
2764 if ((this->type & PORT_TYPE_AUDIO) &&
2765 ((bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_IN_USE) == 0))
2766 bufs[BUF_TYPE_AUDIO].buf_start = arg;
2767 else
2768 r = -EINVAL;
2769 break;
2770
2771 case AMSTREAM_IOC_AB_SIZE:
2772 if ((this->type & PORT_TYPE_AUDIO) &&
2773 ((bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_IN_USE) == 0)) {
2774 if (bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_ALLOC) {
2775 r = stbuf_change_size(
2776 &bufs[BUF_TYPE_AUDIO], arg, false);
2777 }
2778 } else
2779 r = -EINVAL;
2780 break;
2781
2782 case AMSTREAM_IOC_VFORMAT:
2783 if ((this->type & PORT_TYPE_VIDEO) && (arg < VFORMAT_MAX)) {
2784 this->vformat = (enum vformat_e)arg;
2785 this->flag |= PORT_FLAG_VFORMAT;
2786
2787 vdec_set_format(priv->vdec, this->vformat);
2788 } else
2789 r = -EINVAL;
2790 break;
2791
2792 case AMSTREAM_IOC_AFORMAT:
2793 if ((this->type & PORT_TYPE_AUDIO) && (arg < AFORMAT_MAX)) {
2794 memset(&audio_dec_info, 0,
2795 sizeof(struct audio_info));
2796 /* for new format,reset the audio info. */
2797 this->aformat = (enum aformat_e)arg;
2798 this->flag |= PORT_FLAG_AFORMAT;
2799 } else
2800 r = -EINVAL;
2801 break;
2802
2803 case AMSTREAM_IOC_VID:
2804 if (this->type & PORT_TYPE_VIDEO) {
2805 this->vid = (u32) arg;
2806 this->flag |= PORT_FLAG_VID;
2807 } else
2808 r = -EINVAL;
2809
2810 break;
2811
2812 case AMSTREAM_IOC_AID:
2813 if (this->type & PORT_TYPE_AUDIO) {
2814 this->aid = (u32) arg;
2815 this->flag |= PORT_FLAG_AID;
2816
2817 if (port_get_inited(priv)) {
2818 //tsync_audio_break(1);
2819 amstream_change_avid(this);
2820 }
2821 } else
2822 r = -EINVAL;
2823 break;
2824
2825 case AMSTREAM_IOC_SID:
2826 if (this->type & PORT_TYPE_SUB) {
2827 this->sid = (u32) arg;
2828 this->flag |= PORT_FLAG_SID;
2829
2830 if (port_get_inited(priv))
2831 amstream_change_sid(this);
2832 } else
2833 r = -EINVAL;
2834
2835 break;
2836
2837 case AMSTREAM_IOC_PCRID:
2838 this->pcrid = (u32) arg;
2839 this->pcr_inited = 1;
2840 pr_err("set pcrid = 0x%x\n", this->pcrid);
2841 break;
2842
2843 case AMSTREAM_IOC_VB_STATUS:
2844 if (this->type & PORT_TYPE_VIDEO) {
2845 struct am_io_param para;
2846 struct am_io_param *p = &para;
2847 struct stream_buf_s *buf = NULL;
2848
2849 mutex_lock(&amstream_mutex);
2850
2851 /*
2852 *todo: check upper layer for decoder
2853 * handler lifecycle
2854 */
2855 if (priv->vdec == NULL) {
2856 r = -EINVAL;
2857 mutex_unlock(&amstream_mutex);
2858 break;
2859 }
2860
2861 if (this->type & PORT_TYPE_FRAME) {
2862 struct vdec_input_status_s status;
2863
2864 r = vdec_input_get_status(&priv->vdec->input,
2865 &status);
2866 if (r == 0) {
2867 p->status.size = status.size;
2868 p->status.data_len = status.data_len;
2869 p->status.free_len = status.free_len;
2870 p->status.read_pointer =
2871 status.read_pointer;
2872 if (copy_to_user((void *)arg, p,
2873 sizeof(para)))
2874 r = -EFAULT;
2875 }
2876 mutex_unlock(&amstream_mutex);
2877 break;
2878 }
2879
2880 buf = &priv->vdec->vbuf;
2881 p->status.size = stbuf_canusesize(buf);
2882 p->status.data_len = stbuf_level(buf);
2883 p->status.free_len = stbuf_space(buf);
2884 p->status.read_pointer = stbuf_rp(buf);
2885 if (copy_to_user((void *)arg, p, sizeof(para)))
2886 r = -EFAULT;
2887
2888 mutex_unlock(&amstream_mutex);
2889 return r;
2890 }
2891 r = -EINVAL;
2892 break;
2893
2894 case AMSTREAM_IOC_AB_STATUS:
2895 if (this->type & PORT_TYPE_AUDIO) {
2896 struct am_io_param para;
2897 struct am_io_param *p = &para;
2898 struct stream_buf_s *buf = &bufs[BUF_TYPE_AUDIO];
2899
2900 p->status.size = stbuf_canusesize(buf);
2901 p->status.data_len = stbuf_level(buf);
2902 p->status.free_len = stbuf_space(buf);
2903 p->status.read_pointer = stbuf_rp(buf);
2904 if (copy_to_user((void *)arg, p, sizeof(para)))
2905 r = -EFAULT;
2906 return r;
2907 }
2908 r = -EINVAL;
2909 break;
2910
2911 case AMSTREAM_IOC_SYSINFO:
2912 if (this->type & PORT_TYPE_VIDEO)
2913 r = vdec_set_decinfo(priv->vdec, (void *)arg);
2914 else
2915 r = -EINVAL;
2916 break;
2917
2918 case AMSTREAM_IOC_ACHANNEL:
2919 if (this->type & PORT_TYPE_AUDIO) {
2920 this->achanl = (u32) arg;
2921 set_ch_num_info((u32) arg);
2922 } else
2923 r = -EINVAL;
2924 break;
2925
2926 case AMSTREAM_IOC_SAMPLERATE:
2927 if (this->type & PORT_TYPE_AUDIO) {
2928 this->asamprate = (u32) arg;
2929 set_sample_rate_info((u32) arg);
2930 } else
2931 r = -EINVAL;
2932 break;
2933
2934 case AMSTREAM_IOC_DATAWIDTH:
2935 if (this->type & PORT_TYPE_AUDIO)
2936 this->adatawidth = (u32) arg;
2937 else
2938 r = -EINVAL;
2939 break;
2940
2941 case AMSTREAM_IOC_TSTAMP:
2942 if ((this->type & (PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)) ==
2943 ((PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)))
2944 r = -EINVAL;
2945 else if (this->type & PORT_TYPE_FRAME)
2946 r = vdec_set_pts(priv->vdec, arg);
2947 else if ((this->type & PORT_TYPE_VIDEO) ||
2948 (this->type & PORT_TYPE_HEVC))
2949 r = es_vpts_checkin(&priv->vdec->vbuf, arg);
2950 else if (this->type & PORT_TYPE_AUDIO)
2951 r = es_apts_checkin(&bufs[BUF_TYPE_AUDIO], arg);
2952 break;
2953
2954 case AMSTREAM_IOC_TSTAMP_uS64:
2955 if ((this->type & (PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)) ==
2956 ((PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)))
2957 r = -EINVAL;
2958 else {
2959 u64 pts;
2960
2961 if (copy_from_user
2962 ((void *)&pts, (void *)arg, sizeof(u64)))
2963 return -EFAULT;
2964 if (this->type & PORT_TYPE_FRAME) {
2965 /*
2966 *todo: check upper layer for decoder handler
2967 * life sequence or multi-tasking management
2968 */
2969 if (priv->vdec)
2970 r = vdec_set_pts64(priv->vdec, pts);
2971 } else if ((this->type & PORT_TYPE_HEVC) ||
2972 (this->type & PORT_TYPE_VIDEO)) {
2973 r = es_vpts_checkin_us64(
2974 &priv->vdec->vbuf, pts);
2975 } else if (this->type & PORT_TYPE_AUDIO) {
2976 r = es_vpts_checkin_us64(
2977 &bufs[BUF_TYPE_AUDIO], pts);
2978 }
2979 }
2980 break;
2981
2982 case AMSTREAM_IOC_VDECSTAT:
2983 if ((this->type & PORT_TYPE_VIDEO) == 0)
2984 return -EINVAL;
2985 {
2986 struct vdec_info vstatus;
2987 struct am_io_param para;
2988 struct am_io_param *p = &para;
2989
2990 memset(&vstatus, 0, sizeof(vstatus));
2991
2992 mutex_lock(&priv->mutex);
2993 if (vdec_status(priv->vdec, &vstatus) == -1) {
2994 mutex_unlock(&priv->mutex);
2995 return -ENODEV;
2996 }
2997 mutex_unlock(&priv->mutex);
2998
2999 p->vstatus.width = vstatus.frame_width;
3000 p->vstatus.height = vstatus.frame_height;
3001 p->vstatus.fps = vstatus.frame_rate;
3002 p->vstatus.error_count = vstatus.error_count;
3003 p->vstatus.status = vstatus.status;
3004 p->vstatus.euAspectRatio =
3005 get_normalized_aspect_ratio(
3006 vstatus.ratio_control);
3007
3008 if (copy_to_user((void *)arg, p, sizeof(para)))
3009 r = -EFAULT;
3010 return r;
3011 }
3012
3013 case AMSTREAM_IOC_VDECINFO:
3014 if ((this->type & PORT_TYPE_VIDEO) == 0)
3015 return -EINVAL;
3016 {
3017 struct vdec_info vinfo;
3018 struct am_io_info para;
3019
3020 memset(&para, 0x0, sizeof(struct am_io_info));
3021
3022 mutex_lock(&priv->mutex);
3023 if (vdec_status(priv->vdec, &vinfo) == -1) {
3024 mutex_unlock(&priv->mutex);
3025 return -ENODEV;
3026 }
3027 mutex_unlock(&priv->mutex);
3028
3029 memcpy(&para.vinfo, &vinfo, sizeof(struct vdec_info));
3030 if (copy_to_user((void *)arg, &para, sizeof(para)))
3031 r = -EFAULT;
3032 return r;
3033 }
3034
3035 case AMSTREAM_IOC_ADECSTAT:
3036 if ((this->type & PORT_TYPE_AUDIO) == 0)
3037 return -EINVAL;
3038 if (amstream_adec_status == NULL)
3039 return -ENODEV;
3040 else {
3041 struct adec_status astatus;
3042 struct am_io_param para;
3043 struct am_io_param *p = &para;
3044
3045 amstream_adec_status(&astatus);
3046 p->astatus.channels = astatus.channels;
3047 p->astatus.sample_rate = astatus.sample_rate;
3048 p->astatus.resolution = astatus.resolution;
3049 p->astatus.error_count = astatus.error_count;
3050 p->astatus.status = astatus.status;
3051 if (copy_to_user((void *)arg, p, sizeof(para)))
3052 r = -EFAULT;
3053 return r;
3054 }
3055 case AMSTREAM_IOC_PORT_INIT:
3056 r = amstream_port_init(priv);
3057 break;
3058
3059 case AMSTREAM_IOC_VDEC_RESET:
3060 if ((this->type & PORT_TYPE_VIDEO) == 0)
3061 return -EINVAL;
3062
3063 if (priv->vdec == NULL)
3064 return -ENODEV;
3065
3066 r = vdec_reset(priv->vdec);
3067 break;
3068
3069 case AMSTREAM_IOC_TRICKMODE:
3070 if ((this->type & PORT_TYPE_VIDEO) == 0)
3071 return -EINVAL;
3072 r = vdec_set_trickmode(priv->vdec, arg);
3073 if (r == -1)
3074 return -ENODEV;
3075 break;
3076
3077 case AMSTREAM_IOC_AUDIO_INFO:
3078 if ((this->type & PORT_TYPE_VIDEO)
3079 || (this->type & PORT_TYPE_AUDIO)) {
3080 if (copy_from_user
3081 (&audio_dec_info, (void __user *)arg,
3082 sizeof(audio_dec_info)))
3083 r = -EFAULT;
3084 } else
3085 r = -EINVAL;
3086 break;
3087
3088 case AMSTREAM_IOC_AUDIO_RESET:
3089 if (this->type & PORT_TYPE_AUDIO) {
3090 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
3091
3092 r = audio_port_reset(this, pabuf);
3093 } else
3094 r = -EINVAL;
3095
3096 break;
3097
3098 case AMSTREAM_IOC_SUB_RESET:
3099 if (this->type & PORT_TYPE_SUB) {
3100 struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
3101
3102 r = sub_port_reset(this, psbuf);
3103 } else
3104 r = -EINVAL;
3105 break;
3106
3107 case AMSTREAM_IOC_SUB_LENGTH:
3108 if ((this->type & PORT_TYPE_SUB) ||
3109 (this->type & PORT_TYPE_SUB_RD)) {
3110 u32 sub_wp, sub_rp;
3111 struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
3112 int val;
3113
3114 sub_wp = stbuf_sub_wp_get();
3115 sub_rp = stbuf_sub_rp_get();
3116
3117 if (sub_wp == sub_rp)
3118 val = 0;
3119 else if (sub_wp > sub_rp)
3120 val = sub_wp - sub_rp;
3121 else
3122 val = psbuf->buf_size - (sub_rp - sub_wp);
3123 put_user(val, (int __user *)arg);
3124 } else
3125 r = -EINVAL;
3126 break;
3127
3128 case AMSTREAM_IOC_UD_LENGTH:
3129 if (this->type & PORT_TYPE_USERDATA) {
3130 /* *((u32 *)arg) = userdata_length; */
3131 put_user(userdata_length, (unsigned long __user *)arg);
3132 userdata_length = 0;
3133 } else
3134 r = -EINVAL;
3135 break;
3136
3137 case AMSTREAM_IOC_UD_POC:
3138 if (this->type & PORT_TYPE_USERDATA) {
3139 /* *((u32 *)arg) = userdata_length; */
3140 int ri;
3141#ifdef DEBUG_USER_DATA
3142 int wi;
3143#endif
3144 int bDataAvail = 0;
3145
3146 mutex_lock(&userdata_mutex);
3147 if (userdata_poc_wi != userdata_poc_ri) {
3148 bDataAvail = 1;
3149 ri = userdata_poc_ri;
3150#ifdef DEBUG_USER_DATA
3151 wi = userdata_poc_wi;
3152#endif
3153 userdata_poc_ri++;
3154 if (userdata_poc_ri >= USERDATA_FIFO_NUM)
3155 userdata_poc_ri = 0;
3156 }
3157 mutex_unlock(&userdata_mutex);
3158 if (bDataAvail) {
3159 int res;
3160 struct userdata_poc_info_t userdata_poc =
3161 userdata_poc_info[ri];
3162#ifdef DEBUG_USER_DATA
3163 pr_info("read poc: ri=%d, wi=%d, poc=%d, last_wi=%d\n",
3164 ri, wi,
3165 userdata_poc.poc_number,
3166 last_read_wi);
3167#endif
3168 res =
3169 copy_to_user((unsigned long __user *)arg,
3170 &userdata_poc,
3171 sizeof(struct userdata_poc_info_t));
3172 if (res < 0)
3173 r = -EFAULT;
3174 } else {
3175 r = -EFAULT;
3176 }
3177 } else {
3178 r = -EINVAL;
3179 }
3180 break;
3181
3182 case AMSTREAM_IOC_UD_BUF_READ:
3183 {
3184 if (this->type & PORT_TYPE_USERDATA) {
3185 struct userdata_param_t param;
3186 struct userdata_param_t *p_userdata_param;
3187 struct vdec_s *vdec;
3188
3189 p_userdata_param = &param;
3190 if (copy_from_user(p_userdata_param,
3191 (void __user *)arg,
3192 sizeof(struct userdata_param_t))) {
3193 r = -EFAULT;
3194 break;
3195 }
3196 mutex_lock(&amstream_mutex);
3197 vdec = vdec_get_vdec_by_id(p_userdata_param->instance_id);
3198 if (vdec) {
3199 if (vdec_read_user_data(vdec,
3200 p_userdata_param) == 0) {
3201 r = -EFAULT;
3202 mutex_unlock(&amstream_mutex);
3203 break;
3204 }
3205
3206 if (copy_to_user((void *)arg,
3207 p_userdata_param,
3208 sizeof(struct userdata_param_t)))
3209 r = -EFAULT;
3210 } else
3211 r = -EINVAL;
3212 mutex_unlock(&amstream_mutex);
3213 }
3214 }
3215 break;
3216
3217 case AMSTREAM_IOC_UD_AVAILABLE_VDEC:
3218 {
3219 unsigned int ready_vdec;
3220
3221 mutex_lock(&userdata_mutex);
3222 ready_vdec = ud_ready_vdec_flag;
3223 ud_ready_vdec_flag = 0;
3224 mutex_unlock(&userdata_mutex);
3225
3226 put_user(ready_vdec, (uint32_t __user *)arg);
3227 }
3228 break;
3229
3230 case AMSTREAM_IOC_GET_VDEC_ID:
3231 if (this->type & PORT_TYPE_VIDEO && priv->vdec) {
3232 put_user(priv->vdec->id, (int32_t __user *)arg);
3233 } else
3234 r = -EINVAL;
3235 break;
3236
3237
3238 case AMSTREAM_IOC_UD_FLUSH_USERDATA:
3239 if (this->type & PORT_TYPE_USERDATA) {
3240 struct vdec_s *vdec;
3241 int vdec_id;
3242
3243 mutex_lock(&amstream_mutex);
3244 get_user(vdec_id, (int __user *)arg);
3245 vdec = vdec_get_vdec_by_id(vdec_id);
3246 if (vdec) {
3247 vdec_reset_userdata_fifo(vdec, 0);
3248 pr_info("reset_userdata_fifo for vdec: %d\n", vdec_id);
3249 }
3250 mutex_unlock(&amstream_mutex);
3251 } else
3252 r = -EINVAL;
3253 break;
3254
3255 case AMSTREAM_IOC_SET_DEC_RESET:
3256 tsync_set_dec_reset();
3257 break;
3258
3259 case AMSTREAM_IOC_TS_SKIPBYTE:
3260 if ((int)arg >= 0)
3261 tsdemux_set_skipbyte(arg);
3262 else
3263 r = -EINVAL;
3264 break;
3265
3266 case AMSTREAM_IOC_SUB_TYPE:
3267 sub_type = (int)arg;
3268 break;
3269
3270 case AMSTREAM_IOC_APTS_LOOKUP:
3271 if (this->type & PORT_TYPE_AUDIO) {
3272 u32 pts = 0, frame_size, offset;
3273
3274 get_user(offset, (unsigned long __user *)arg);
3275 pts_lookup_offset(PTS_TYPE_AUDIO, offset, &pts,
3276 &frame_size, 300);
3277 put_user(pts, (int __user *)arg);
3278 }
3279 return 0;
3280 case GET_FIRST_APTS_FLAG:
3281 if (this->type & PORT_TYPE_AUDIO) {
3282 put_user(first_pts_checkin_complete(PTS_TYPE_AUDIO),
3283 (int __user *)arg);
3284 }
3285 break;
3286
3287 case AMSTREAM_IOC_APTS:
3288 put_user(timestamp_apts_get(), (int __user *)arg);
3289 break;
3290
3291 case AMSTREAM_IOC_VPTS:
3292 put_user(timestamp_vpts_get(), (int __user *)arg);
3293 break;
3294
3295 case AMSTREAM_IOC_PCRSCR:
3296 put_user(timestamp_pcrscr_get(), (int __user *)arg);
3297 break;
3298
3299 case AMSTREAM_IOC_SET_PCRSCR:
3300 timestamp_pcrscr_set(arg);
3301 break;
3302 case AMSTREAM_IOC_GET_LAST_CHECKIN_APTS:
3303 put_user(get_last_checkin_pts(PTS_TYPE_AUDIO), (int *)arg);
3304 break;
3305 case AMSTREAM_IOC_GET_LAST_CHECKIN_VPTS:
3306 put_user(get_last_checkin_pts(PTS_TYPE_VIDEO), (int *)arg);
3307 break;
3308 case AMSTREAM_IOC_GET_LAST_CHECKOUT_APTS:
3309 put_user(get_last_checkout_pts(PTS_TYPE_AUDIO), (int *)arg);
3310 break;
3311 case AMSTREAM_IOC_GET_LAST_CHECKOUT_VPTS:
3312 put_user(get_last_checkout_pts(PTS_TYPE_VIDEO), (int *)arg);
3313 break;
3314 case AMSTREAM_IOC_SUB_NUM:
3315 put_user(psparser_get_sub_found_num(), (int *)arg);
3316 break;
3317
3318 case AMSTREAM_IOC_SUB_INFO:
3319 if (arg > 0) {
3320 struct subtitle_info msub_info[MAX_SUB_NUM];
3321 struct subtitle_info *psub_info[MAX_SUB_NUM];
3322 int i;
3323
3324 for (i = 0; i < MAX_SUB_NUM; i++)
3325 psub_info[i] = &msub_info[i];
3326
3327 r = psparser_get_sub_info(psub_info);
3328
3329 if (r == 0) {
3330 if (copy_to_user((void __user *)arg, msub_info,
3331 sizeof(struct subtitle_info) * MAX_SUB_NUM))
3332 r = -EFAULT;
3333 }
3334 }
3335 break;
3336 case AMSTREAM_IOC_SET_DEMUX:
3337 tsdemux_set_demux((int)arg);
3338 break;
3339 case AMSTREAM_IOC_SET_VIDEO_DELAY_LIMIT_MS:
3340 priv->vdec->vbuf.max_buffer_delay_ms = (int)arg;
3341 break;
3342 case AMSTREAM_IOC_SET_AUDIO_DELAY_LIMIT_MS:
3343 bufs[BUF_TYPE_AUDIO].max_buffer_delay_ms = (int)arg;
3344 break;
3345 case AMSTREAM_IOC_GET_VIDEO_DELAY_LIMIT_MS:
3346 put_user(priv->vdec->vbuf.max_buffer_delay_ms, (int *)arg);
3347 break;
3348 case AMSTREAM_IOC_GET_AUDIO_DELAY_LIMIT_MS:
3349 put_user(bufs[BUF_TYPE_AUDIO].max_buffer_delay_ms, (int *)arg);
3350 break;
3351 case AMSTREAM_IOC_GET_VIDEO_CUR_DELAY_MS: {
3352 int delay;
3353
3354 delay = calculation_stream_delayed_ms(
3355 PTS_TYPE_VIDEO, NULL, NULL);
3356 if (delay >= 0)
3357 put_user(delay, (int *)arg);
3358 else
3359 put_user(0, (int *)arg);
3360 }
3361 break;
3362
3363 case AMSTREAM_IOC_GET_AUDIO_CUR_DELAY_MS: {
3364 int delay;
3365
3366 delay = calculation_stream_delayed_ms(PTS_TYPE_AUDIO, NULL,
3367 NULL);
3368 if (delay >= 0)
3369 put_user(delay, (int *)arg);
3370 else
3371 put_user(0, (int *)arg);
3372 }
3373 break;
3374 case AMSTREAM_IOC_GET_AUDIO_AVG_BITRATE_BPS: {
3375 int delay;
3376 u32 avgbps;
3377
3378 delay = calculation_stream_delayed_ms(PTS_TYPE_AUDIO, NULL,
3379 &avgbps);
3380 if (delay >= 0)
3381 put_user(avgbps, (int *)arg);
3382 else
3383 put_user(0, (int *)arg);
3384 break;
3385 }
3386 case AMSTREAM_IOC_GET_VIDEO_AVG_BITRATE_BPS: {
3387 int delay;
3388 u32 avgbps;
3389
3390 delay = calculation_stream_delayed_ms(PTS_TYPE_VIDEO, NULL,
3391 &avgbps);
3392 if (delay >= 0)
3393 put_user(avgbps, (int *)arg);
3394 else
3395 put_user(0, (int *)arg);
3396 break;
3397 }
3398 case AMSTREAM_IOC_SET_DRMMODE:
3399 if ((u32) arg == 1) {
3400 pr_err("set drmmode, input must be secure buffer\n");
3401 this->flag |= PORT_FLAG_DRM;
3402 if ((this->type & PORT_TYPE_VIDEO) &&
3403 (priv->vdec))
3404 priv->vdec->port_flag |= PORT_FLAG_DRM;
3405 } else if ((u32)arg == 2) {
3406 pr_err("set drmmode, input must be normal buffer\n");
3407 if ((this->type & PORT_TYPE_VIDEO) &&
3408 (priv->vdec)) {
3409 pr_err("vdec port_flag with drmmode\n");
3410 priv->vdec->port_flag |= PORT_FLAG_DRM;
3411 }
3412 } else {
3413 this->flag &= (~PORT_FLAG_DRM);
3414 pr_err("no drmmode\n");
3415 }
3416 break;
3417 case AMSTREAM_IOC_SET_APTS: {
3418 unsigned long pts;
3419
3420 if (get_user(pts, (unsigned long __user *)arg)) {
3421 pr_err
3422 ("Get audio pts from user space fault!\n");
3423 return -EFAULT;
3424 }
3425 if (tsync_get_mode() == TSYNC_MODE_PCRMASTER)
3426 tsync_pcr_set_apts(pts);
3427 else
3428 tsync_set_apts(pts);
3429 break;
3430 }
3431 case AMSTREAM_IOC_SET_CRC: {
3432 struct usr_crc_info_t crc_info;
3433 struct vdec_s *vdec;
3434
3435 if (copy_from_user(&crc_info, (void __user *)arg,
3436 sizeof(struct usr_crc_info_t))) {
3437 return -EFAULT;
3438 }
3439 /*
3440 pr_info("id %d, frame %d, y_crc: %08x, uv_crc: %08x\n", crc_info.id,
3441 crc_info.pic_num, crc_info.y_crc, crc_info.uv_crc);
3442 */
3443 vdec = vdec_get_vdec_by_id(crc_info.id);
3444 if (vdec == NULL)
3445 return -ENODEV;
3446 if (vdec->vfc.cmp_pool == NULL) {
3447 vdec->vfc.cmp_pool =
3448 vmalloc(USER_CMP_POOL_MAX_SIZE *
3449 sizeof(struct usr_crc_info_t));
3450 if (vdec->vfc.cmp_pool == NULL)
3451 return -ENOMEM;
3452 }
3453 if (vdec->vfc.usr_cmp_num >= USER_CMP_POOL_MAX_SIZE) {
3454 pr_info("warn: could not write any more, max %d",
3455 USER_CMP_POOL_MAX_SIZE);
3456 return -EFAULT;
3457 }
3458 memcpy(&vdec->vfc.cmp_pool[vdec->vfc.usr_cmp_num], &crc_info,
3459 sizeof(struct usr_crc_info_t));
3460 vdec->vfc.usr_cmp_num++;
3461 break;
3462 }
3463 case AMSTREAM_IOC_GET_CRC_CMP_RESULT: {
3464 int val, vdec_id;
3465 struct vdec_s *vdec;
3466
3467 if (get_user(val, (int __user *)arg)) {
3468 return -EFAULT;
3469 }
3470 vdec_id = val & 0x00ff;
3471 vdec = vdec_get_vdec_by_id(vdec_id);
3472 if (vdec == NULL)
3473 return -ENODEV;
3474 if (val & 0xff00)
3475 put_user(vdec->vfc.usr_cmp_num, (int *)arg);
3476 else
3477 put_user(vdec->vfc.usr_cmp_result, (int *)arg);
3478 /*
3479 pr_info("amstream get crc32 cmpare num %d result: %d\n",
3480 vdec->vfc.usr_cmp_num, vdec->vfc.usr_cmp_result);
3481 */
3482 break;
3483 }
3484 case AMSTREAM_IOC_INIT_EX_STBUF: {
3485 struct stream_buffer_metainfo parm;
3486 struct stream_buf_s *vbuf = &priv->vdec->vbuf;
3487
3488 if (copy_from_user(&parm, (void __user *)arg,
3489 sizeof(struct stream_buffer_metainfo))) {
3490 return -EFAULT;
3491 }
3492 stream_buffer_set_ext_buf(vbuf, parm.stbuf_start,
3493 parm.stbuf_size, parm.stbuf_flag);
3494 break;
3495 }
3496 case AMSTREAM_IOC_WR_STBUF_META: {
3497 struct stream_buffer_metainfo meta;
3498 struct stream_buf_s *vbuf = &priv->vdec->vbuf;
3499
3500 if (copy_from_user(&meta, (void __user *)arg,
3501 sizeof(struct stream_buffer_metainfo))) {
3502 return -EFAULT;
3503 }
3504 if (!vbuf->ext_buf_addr)
3505 return -ENODEV;
3506
3507 stream_buffer_meta_write(vbuf, &meta);
3508 break;
3509 }
3510 case AMSTREAM_IOC_GET_STBUF_STATUS: {
3511 struct stream_buffer_status st;
3512 struct stream_buf_s *pbuf = &priv->vdec->vbuf;
3513
3514 st.stbuf_start = pbuf->ext_buf_addr;
3515 st.stbuf_size = pbuf->buf_size;
3516 st.stbuf_rp = pbuf->ops->get_rp(pbuf);
3517 st.stbuf_wp = pbuf->ops->get_wp(pbuf);
3518 if (copy_to_user((void __user *)arg, &st,
3519 sizeof(struct stream_buffer_status))) {
3520 return -EFAULT;
3521 }
3522 break;
3523 }
3524 default:
3525 r = -ENOIOCTLCMD;
3526 break;
3527 }
3528
3529 return r;
3530}
3531
3532static long amstream_do_ioctl(struct port_priv_s *priv,
3533 unsigned int cmd, ulong arg)
3534{
3535 long r = 0;
3536
3537 switch (cmd) {
3538 case AMSTREAM_IOC_GET_VERSION:
3539 case AMSTREAM_IOC_GET:
3540 case AMSTREAM_IOC_SET:
3541 case AMSTREAM_IOC_GET_EX:
3542 case AMSTREAM_IOC_SET_EX:
3543 case AMSTREAM_IOC_GET_PTR:
3544 case AMSTREAM_IOC_SET_PTR:
3545 case AMSTREAM_IOC_SYSINFO:
3546 case AMSTREAM_IOC_GET_QOSINFO:
3547 case AMSTREAM_IOC_GET_MVDECINFO:
3548 case AMSTREAM_IOC_GET_AVINFO:
3549 r = amstream_do_ioctl_new(priv, cmd, arg);
3550 break;
3551 default:
3552 r = amstream_do_ioctl_old(priv, cmd, arg);
3553 break;
3554 }
3555 if (r != 0)
3556 pr_err("amstream_do_ioctl error :%lx, %x\n", r, cmd);
3557
3558 return r;
3559}
3560static long amstream_ioctl(struct file *file, unsigned int cmd, ulong arg)
3561{
3562 struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
3563 struct stream_port_s *this = priv->port;
3564
3565 if (!this)
3566 return -ENODEV;
3567
3568 return amstream_do_ioctl(priv, cmd, arg);
3569}
3570
3571#ifdef CONFIG_COMPAT
3572struct dec_sysinfo32 {
3573
3574 u32 format;
3575
3576 u32 width;
3577
3578 u32 height;
3579
3580 u32 rate;
3581
3582 u32 extra;
3583
3584 u32 status;
3585
3586 u32 ratio;
3587
3588 compat_uptr_t param;
3589
3590 u64 ratio64;
3591};
3592
3593struct am_ioctl_parm_ptr32 {
3594 union {
3595 compat_uptr_t pdata_audio_info;
3596 compat_uptr_t pdata_sub_info;
3597 compat_uptr_t pointer;
3598 char data[8];
3599 };
3600 u32 cmd;
3601 u32 len;
3602};
3603
3604static long amstream_ioc_setget_ptr(struct port_priv_s *priv,
3605 unsigned int cmd, struct am_ioctl_parm_ptr32 __user *arg)
3606{
3607 struct am_ioctl_parm_ptr __user *data;
3608 struct am_ioctl_parm_ptr32 param;
3609 int ret;
3610
3611 if (copy_from_user(&param,
3612 (void __user *)arg,
3613 sizeof(struct am_ioctl_parm_ptr32)))
3614 return -EFAULT;
3615
3616 data = compat_alloc_user_space(sizeof(*data));
3617 if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
3618 return -EFAULT;
3619
3620 if (put_user(param.cmd, &data->cmd) ||
3621 put_user(compat_ptr(param.pointer), &data->pointer) ||
3622 put_user(param.len, &data->len))
3623 return -EFAULT;
3624
3625 ret = amstream_do_ioctl(priv, cmd, (unsigned long)data);
3626 if (ret < 0)
3627 return ret;
3628 return 0;
3629
3630}
3631
3632static long amstream_set_sysinfo(struct port_priv_s *priv,
3633 struct dec_sysinfo32 __user *arg)
3634{
3635 struct dec_sysinfo __user *data;
3636 struct dec_sysinfo32 __user *data32 = arg;
3637 int ret;
3638 struct dec_sysinfo32 param;
3639
3640 if (copy_from_user(&param,
3641 (void __user *)arg,
3642 sizeof(struct dec_sysinfo32)))
3643 return -EFAULT;
3644
3645 data = compat_alloc_user_space(sizeof(*data));
3646 if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
3647 return -EFAULT;
3648 if (copy_in_user(data, data32, 7 * sizeof(u32)))
3649 return -EFAULT;
3650 if (put_user(compat_ptr(param.param), &data->param))
3651 return -EFAULT;
3652 if (copy_in_user(&data->ratio64, &data32->ratio64,
3653 sizeof(data->ratio64)))
3654 return -EFAULT;
3655
3656 ret = amstream_do_ioctl(priv, AMSTREAM_IOC_SYSINFO,
3657 (unsigned long)data);
3658 if (ret < 0)
3659 return ret;
3660
3661 if (copy_in_user(&arg->format, &data->format, 7 * sizeof(u32)) ||
3662 copy_in_user(&arg->ratio64, &data->ratio64,
3663 sizeof(arg->ratio64)))
3664 return -EFAULT;
3665
3666 return 0;
3667}
3668
3669
3670struct userdata_param32_t {
3671 uint32_t version;
3672 uint32_t instance_id; /*input, 0~9*/
3673 uint32_t buf_len; /*input*/
3674 uint32_t data_size; /*output*/
3675 compat_uptr_t pbuf_addr; /*input*/
3676 struct userdata_meta_info_t meta_info; /*output*/
3677};
3678
3679
3680static long amstream_ioc_get_userdata(struct port_priv_s *priv,
3681 struct userdata_param32_t __user *arg)
3682{
3683 struct userdata_param_t __user *data;
3684 struct userdata_param32_t __user *data32 = arg;
3685 int ret;
3686 struct userdata_param32_t param;
3687
3688
3689 if (copy_from_user(&param,
3690 (void __user *)arg,
3691 sizeof(struct userdata_param32_t)))
3692 return -EFAULT;
3693
3694 data = compat_alloc_user_space(sizeof(*data));
3695 if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
3696 return -EFAULT;
3697
3698 if (copy_in_user(data, data32, 4 * sizeof(u32)))
3699 return -EFAULT;
3700
3701 if (copy_in_user(&data->meta_info, &data32->meta_info,
3702 sizeof(data->meta_info)))
3703 return -EFAULT;
3704
3705 if (put_user(compat_ptr(param.pbuf_addr), &data->pbuf_addr))
3706 return -EFAULT;
3707
3708 ret = amstream_do_ioctl(priv, AMSTREAM_IOC_UD_BUF_READ,
3709 (unsigned long)data);
3710 if (ret < 0)
3711 return ret;
3712
3713 if (copy_in_user(&data32->version, &data->version, 4 * sizeof(u32)) ||
3714 copy_in_user(&data32->meta_info, &data->meta_info,
3715 sizeof(data32->meta_info)))
3716 return -EFAULT;
3717
3718 return 0;
3719}
3720
3721
3722static long amstream_compat_ioctl(struct file *file,
3723 unsigned int cmd, ulong arg)
3724{
3725 s32 r = 0;
3726 struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
3727
3728 switch (cmd) {
3729 case AMSTREAM_IOC_GET_VERSION:
3730 case AMSTREAM_IOC_GET:
3731 case AMSTREAM_IOC_SET:
3732 case AMSTREAM_IOC_GET_EX:
3733 case AMSTREAM_IOC_SET_EX:
3734 return amstream_do_ioctl(priv, cmd, (ulong)compat_ptr(arg));
3735 case AMSTREAM_IOC_GET_PTR:
3736 case AMSTREAM_IOC_SET_PTR:
3737 return amstream_ioc_setget_ptr(priv, cmd, compat_ptr(arg));
3738 case AMSTREAM_IOC_SYSINFO:
3739 return amstream_set_sysinfo(priv, compat_ptr(arg));
3740 case AMSTREAM_IOC_UD_BUF_READ:
3741 return amstream_ioc_get_userdata(priv, compat_ptr(arg));
3742 default:
3743 return amstream_do_ioctl(priv, cmd, (ulong)compat_ptr(arg));
3744 }
3745
3746 return r;
3747}
3748#endif
3749
3750static ssize_t ports_show(struct class *class, struct class_attribute *attr,
3751 char *buf)
3752{
3753 int i;
3754 char *pbuf = buf;
3755 struct stream_port_s *p = NULL;
3756
3757 for (i = 0; i < amstream_port_num; i++) {
3758 p = &ports[i];
3759 /*name */
3760 pbuf += sprintf(pbuf, "%s\t:\n", p->name);
3761 /*type */
3762 pbuf += sprintf(pbuf, "\ttype:%d( ", p->type);
3763 if (p->type & PORT_TYPE_VIDEO)
3764 pbuf += sprintf(pbuf, "%s ", "Video");
3765 if (p->type & PORT_TYPE_AUDIO)
3766 pbuf += sprintf(pbuf, "%s ", "Audio");
3767 if (p->type & PORT_TYPE_MPTS)
3768 pbuf += sprintf(pbuf, "%s ", "TS");
3769 if (p->type & PORT_TYPE_MPPS)
3770 pbuf += sprintf(pbuf, "%s ", "PS");
3771 if (p->type & PORT_TYPE_ES)
3772 pbuf += sprintf(pbuf, "%s ", "ES");
3773 if (p->type & PORT_TYPE_RM)
3774 pbuf += sprintf(pbuf, "%s ", "RM");
3775 if (p->type & PORT_TYPE_SUB)
3776 pbuf += sprintf(pbuf, "%s ", "Subtitle");
3777 if (p->type & PORT_TYPE_SUB_RD)
3778 pbuf += sprintf(pbuf, "%s ", "Subtitle_Read");
3779 if (p->type & PORT_TYPE_USERDATA)
3780 pbuf += sprintf(pbuf, "%s ", "userdata");
3781 pbuf += sprintf(pbuf, ")\n");
3782 /*flag */
3783 pbuf += sprintf(pbuf, "\tflag:%d( ", p->flag);
3784 if (p->flag & PORT_FLAG_IN_USE)
3785 pbuf += sprintf(pbuf, "%s ", "Used");
3786 else
3787 pbuf += sprintf(pbuf, "%s ", "Unused");
3788 if ((p->type & PORT_TYPE_VIDEO) == 0) {
3789 if (p->flag & PORT_FLAG_INITED)
3790 pbuf += sprintf(pbuf, "%s ", "inited");
3791 else
3792 pbuf += sprintf(pbuf, "%s ", "uninited");
3793 }
3794 pbuf += sprintf(pbuf, ")\n");
3795 /*others */
3796 pbuf += sprintf(pbuf, "\tVformat:%d\n",
3797 (p->flag & PORT_FLAG_VFORMAT) ? p->vformat : -1);
3798 pbuf += sprintf(pbuf, "\tAformat:%d\n",
3799 (p->flag & PORT_FLAG_AFORMAT) ? p->aformat : -1);
3800 pbuf += sprintf(pbuf, "\tVid:%d\n",
3801 (p->flag & PORT_FLAG_VID) ? p->vid : -1);
3802 pbuf += sprintf(pbuf, "\tAid:%d\n",
3803 (p->flag & PORT_FLAG_AID) ? p->aid : -1);
3804 pbuf += sprintf(pbuf, "\tSid:%d\n",
3805 (p->flag & PORT_FLAG_SID) ? p->sid : -1);
3806 pbuf += sprintf(pbuf, "\tPCRid:%d\n",
3807 (p->pcr_inited == 1) ? p->pcrid : -1);
3808 pbuf += sprintf(pbuf, "\tachannel:%d\n", p->achanl);
3809 pbuf += sprintf(pbuf, "\tasamprate:%d\n", p->asamprate);
3810 pbuf += sprintf(pbuf, "\tadatawidth:%d\n\n", p->adatawidth);
3811 }
3812 return pbuf - buf;
3813}
3814
3815static int show_vbuf_status_cb(struct stream_buf_s *p, char *buf)
3816{
3817 char *pbuf = buf;
3818
3819 if (!p->buf_start)
3820 return 0;
3821 /*type */
3822 pbuf += sprintf(pbuf, "Video-%d buffer:", p->id);
3823 /*flag */
3824 pbuf += sprintf(pbuf, "\tflag:%d( ", p->flag);
3825 if (p->flag & BUF_FLAG_ALLOC)
3826 pbuf += sprintf(pbuf, "%s ", "Alloc");
3827 else
3828 pbuf += sprintf(pbuf, "%s ", "Unalloc");
3829 if (p->flag & BUF_FLAG_IN_USE)
3830 pbuf += sprintf(pbuf, "%s ", "Used");
3831 else
3832 pbuf += sprintf(pbuf, "%s ", "Noused");
3833 if (p->flag & BUF_FLAG_PARSER)
3834 pbuf += sprintf(pbuf, "%s ", "Parser");
3835 else
3836 pbuf += sprintf(pbuf, "%s ", "noParser");
3837 if (p->flag & BUF_FLAG_FIRST_TSTAMP)
3838 pbuf += sprintf(pbuf, "%s ", "firststamp");
3839 else
3840 pbuf += sprintf(pbuf, "%s ", "nofirststamp");
3841 pbuf += sprintf(pbuf, ")\n");
3842
3843 /*buf stats */
3844 pbuf += sprintf(pbuf, "\tbuf addr:%p\n", (void *)p->buf_start);
3845 pbuf += sprintf(pbuf, "\tbuf size:%#x\n", p->buf_size);
3846 pbuf += sprintf(pbuf, "\tbuf canusesize:%#x\n", p->canusebuf_size);
3847 pbuf += sprintf(pbuf, "\tbuf regbase:%#lx\n", p->reg_base);
3848
3849 if (p->reg_base && p->flag & BUF_FLAG_IN_USE) {
3850 pbuf += sprintf(pbuf, "\tbuf level:%#x\n",
3851 stbuf_level(p));
3852 pbuf += sprintf(pbuf, "\tbuf space:%#x\n",
3853 stbuf_space(p));
3854 pbuf += sprintf(pbuf, "\tbuf read pointer:%#x\n",
3855 stbuf_rp(p));
3856 } else
3857 pbuf += sprintf(pbuf, "\tbuf no used.\n");
3858
3859 return pbuf - buf;
3860}
3861
3862static ssize_t bufs_show(struct class *class, struct class_attribute *attr,
3863 char *buf)
3864{
3865 int i;
3866 char *pbuf = buf;
3867 struct stream_buf_s *p = NULL;
3868 char buf_type[][12] = { "Video", "Audio", "Subtitle",
3869 "UserData", "HEVC" };
3870
3871 for (i = 0; i < amstream_buf_num; i++) {
3872 p = &bufs[i];
3873
3874 if (!p->buf_start)
3875 continue;
3876
3877 /*type */
3878 pbuf += sprintf(pbuf, "%s buffer:", buf_type[p->type]);
3879 /*flag */
3880 pbuf += sprintf(pbuf, "\tflag:%d( ", p->flag);
3881 if (p->flag & BUF_FLAG_ALLOC)
3882 pbuf += sprintf(pbuf, "%s ", "Alloc");
3883 else
3884 pbuf += sprintf(pbuf, "%s ", "Unalloc");
3885 if (p->flag & BUF_FLAG_IN_USE)
3886 pbuf += sprintf(pbuf, "%s ", "Used");
3887 else
3888 pbuf += sprintf(pbuf, "%s ", "Noused");
3889 if (p->flag & BUF_FLAG_PARSER)
3890 pbuf += sprintf(pbuf, "%s ", "Parser");
3891 else
3892 pbuf += sprintf(pbuf, "%s ", "noParser");
3893 if (p->flag & BUF_FLAG_FIRST_TSTAMP)
3894 pbuf += sprintf(pbuf, "%s ", "firststamp");
3895 else
3896 pbuf += sprintf(pbuf, "%s ", "nofirststamp");
3897 pbuf += sprintf(pbuf, ")\n");
3898 /*buf stats */
3899
3900 pbuf += sprintf(pbuf, "\tbuf addr:%p\n", (void *)p->buf_start);
3901
3902 if (p->type != BUF_TYPE_SUBTITLE) {
3903 pbuf += sprintf(pbuf, "\tbuf size:%#x\n", p->buf_size);
3904 pbuf += sprintf(pbuf,
3905 "\tbuf canusesize:%#x\n",
3906 p->canusebuf_size);
3907 pbuf += sprintf(pbuf,
3908 "\tbuf regbase:%#lx\n", p->reg_base);
3909
3910 if (p->reg_base && p->flag & BUF_FLAG_IN_USE) {
3911 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M6) {
3912 /* TODO: mod gate */
3913 /* switch_mod_gate_by_name("vdec", 1);*/
3914 amports_switch_gate("vdec", 1);
3915 }
3916 pbuf += sprintf(pbuf, "\tbuf level:%#x\n",
3917 stbuf_level(p));
3918 pbuf += sprintf(pbuf, "\tbuf space:%#x\n",
3919 stbuf_space(p));
3920 pbuf += sprintf(pbuf,
3921 "\tbuf read pointer:%#x\n",
3922 stbuf_rp(p));
3923 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M6) {
3924 /* TODO: mod gate */
3925 /* switch_mod_gate_by_name("vdec", 0);*/
3926 amports_switch_gate("vdec", 0);
3927 }
3928 } else
3929 pbuf += sprintf(pbuf, "\tbuf no used.\n");
3930
3931 if (p->type == BUF_TYPE_USERDATA) {
3932 pbuf += sprintf(pbuf,
3933 "\tbuf write pointer:%#x\n",
3934 p->buf_wp);
3935 pbuf += sprintf(pbuf,
3936 "\tbuf read pointer:%#x\n",
3937 p->buf_rp);
3938 }
3939 } else {
3940 u32 sub_wp, sub_rp, data_size;
3941
3942 sub_wp = stbuf_sub_wp_get();
3943 sub_rp = stbuf_sub_rp_get();
3944 if (sub_wp >= sub_rp)
3945 data_size = sub_wp - sub_rp;
3946 else
3947 data_size = p->buf_size - sub_rp + sub_wp;
3948 pbuf += sprintf(pbuf, "\tbuf size:%#x\n", p->buf_size);
3949 pbuf +=
3950 sprintf(pbuf, "\tbuf canusesize:%#x\n",
3951 p->canusebuf_size);
3952 pbuf +=
3953 sprintf(pbuf, "\tbuf start:%#x\n",
3954 stbuf_sub_start_get());
3955 pbuf += sprintf(pbuf,
3956 "\tbuf write pointer:%#x\n", sub_wp);
3957 pbuf += sprintf(pbuf,
3958 "\tbuf read pointer:%#x\n", sub_rp);
3959 pbuf += sprintf(pbuf, "\tbuf level:%#x\n", data_size);
3960 }
3961
3962 pbuf += sprintf(pbuf, "\tbuf first_stamp:%#x\n",
3963 p->first_tstamp);
3964 pbuf += sprintf(pbuf, "\tbuf wcnt:%#x\n\n", p->wcnt);
3965 pbuf += sprintf(pbuf, "\tbuf max_buffer_delay_ms:%dms\n",
3966 p->max_buffer_delay_ms);
3967
3968 if (p->reg_base && p->flag & BUF_FLAG_IN_USE) {
3969 int calc_delayms = 0;
3970 u32 bitrate = 0, avg_bitrate = 0;
3971
3972 calc_delayms = calculation_stream_delayed_ms(
3973 (p->type == BUF_TYPE_AUDIO) ? PTS_TYPE_AUDIO :
3974 PTS_TYPE_VIDEO,
3975 &bitrate,
3976 &avg_bitrate);
3977
3978 if (calc_delayms >= 0) {
3979 pbuf += sprintf(pbuf,
3980 "\tbuf current delay:%dms\n",
3981 calc_delayms);
3982 pbuf += sprintf(pbuf,
3983 "\tbuf bitrate latest:%dbps,avg:%dbps\n",
3984 bitrate, avg_bitrate);
3985 pbuf += sprintf(pbuf,
3986 "\tbuf time after last pts:%d ms\n",
3987 calculation_stream_ext_delayed_ms
3988 ((p->type == BUF_TYPE_AUDIO) ? PTS_TYPE_AUDIO :
3989 PTS_TYPE_VIDEO));
3990
3991 pbuf += sprintf(pbuf,
3992 "\tbuf time after last write data :%d ms\n",
3993 (int)(jiffies_64 -
3994 p->last_write_jiffies64) * 1000 / HZ);
3995 }
3996 }
3997 if (p->write_thread) {
3998 pbuf += sprintf(pbuf,
3999 "\twrite thread:%d/%d,fifo %d:%d,passed:%d\n",
4000 threadrw_buffer_level(p),
4001 threadrw_buffer_size(p),
4002 threadrw_datafifo_len(p),
4003 threadrw_freefifo_len(p),
4004 threadrw_passed_len(p)
4005 );
4006 }
4007 }
4008
4009 pbuf += show_stream_buffer_status(pbuf, show_vbuf_status_cb);
4010
4011 return pbuf - buf;
4012}
4013
4014static ssize_t videobufused_show(struct class *class,
4015 struct class_attribute *attr, char *buf)
4016{
4017 char *pbuf = buf;
4018 struct stream_buf_s *p = NULL;
4019
4020 p = &bufs[0];
4021
4022 if (p->flag & BUF_FLAG_IN_USE)
4023 pbuf += sprintf(pbuf, "%d ", 1);
4024 else
4025 pbuf += sprintf(pbuf, "%d ", 0);
4026 return 1;
4027}
4028
4029static ssize_t vcodec_profile_show(struct class *class,
4030 struct class_attribute *attr, char *buf)
4031{
4032 return vcodec_profile_read(buf);
4033}
4034
4035static int reset_canuse_buferlevel(int levelx10000)
4036{
4037 int i;
4038 struct stream_buf_s *p = NULL;
4039
4040 if (levelx10000 >= 0 && levelx10000 <= 10000)
4041 use_bufferlevelx10000 = levelx10000;
4042 else
4043 use_bufferlevelx10000 = 10000;
4044 for (i = 0; i < amstream_buf_num; i++) {
4045 p = &bufs[i];
4046 p->canusebuf_size = ((p->buf_size / 1024) *
4047 use_bufferlevelx10000 / 10000) * 1024;
4048 p->canusebuf_size += 1023;
4049 p->canusebuf_size &= ~1023;
4050 if (p->canusebuf_size > p->buf_size)
4051 p->canusebuf_size = p->buf_size;
4052 }
4053 return 0;
4054}
4055
4056static ssize_t show_canuse_buferlevel(struct class *class,
4057 struct class_attribute *attr, char *buf)
4058{
4059 ssize_t size = sprintf(buf,
4060 "use_bufferlevel=%d/10000[=(set range[ 0~10000])=\n",
4061 use_bufferlevelx10000);
4062 return size;
4063}
4064
4065static ssize_t store_canuse_buferlevel(struct class *class,
4066 struct class_attribute *attr,
4067 const char *buf, size_t size)
4068{
4069 unsigned int val;
4070 ssize_t ret;
4071
4072 /*ret = sscanf(buf, "%d", &val);*/
4073 ret = kstrtoint(buf, 0, &val);
4074
4075 if (ret != 0)
4076 return -EINVAL;
4077 val = val;
4078 reset_canuse_buferlevel(val);
4079 return size;
4080}
4081
4082static ssize_t store_maxdelay(struct class *class,
4083 struct class_attribute *attr,
4084 const char *buf, size_t size)
4085{
4086 unsigned int val;
4087 ssize_t ret;
4088 int i;
4089
4090 /*ret = sscanf(buf, "%d", &val);*/
4091 ret = kstrtoint(buf, 0, &val);
4092 if (ret != 0)
4093 return -EINVAL;
4094 for (i = 0; i < amstream_buf_num; i++)
4095 bufs[i].max_buffer_delay_ms = val;
4096 return size;
4097}
4098
4099static ssize_t show_maxdelay(struct class *class,
4100 struct class_attribute *attr,
4101 char *buf)
4102{
4103 ssize_t size = 0;
4104
4105 size += sprintf(buf, "%dms video max buffered data delay ms\n",
4106 bufs[0].max_buffer_delay_ms);
4107 size += sprintf(buf, "%dms audio max buffered data delay ms\n",
4108 bufs[1].max_buffer_delay_ms);
4109 return size;
4110}
4111
4112static ssize_t audio_path_store(struct class *class,
4113 struct class_attribute *attr,
4114 const char *buf, size_t size)
4115{
4116 unsigned int val = 0;
4117 int i;
4118 ssize_t ret;
4119 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
4120 struct stream_port_s *this;
4121 ret = kstrtoint(buf, 0, &val);
4122 if (ret != 0)
4123 return -EINVAL;
4124 if (val != 1)
4125 return -EINVAL;
4126 for (i = 0; i < MAX_AMSTREAM_PORT_NUM; i++) {
4127 if (strcmp(ports[i].name, "amstream_mpts") == 0 ||
4128 strcmp(ports[i].name, "amstream_mpts_sched") == 0) {
4129 this = &ports[i];
4130 if ((this->flag & PORT_FLAG_AFORMAT) != 0) {
4131 pr_info("audio_port_reset %s\n", ports[i].name);
4132 audio_port_reset(this, pabuf);
4133 }
4134 }
4135 }
4136 return size;
4137}
4138
4139ssize_t dump_stream_show(struct class *class,
4140 struct class_attribute *attr, char *buf)
4141{
4142 char *p_buf = buf;
4143
4144 p_buf += sprintf(p_buf, "\nmdkir -p /data/tmp -m 777;setenforce 0;\n\n");
4145 p_buf += sprintf(p_buf, "video:\n\t echo 0 > /sys/class/amstream/dump_stream;\n");
4146 p_buf += sprintf(p_buf, "hevc :\n\t echo 4 > /sys/class/amstream/dump_stream;\n");
4147
4148 return p_buf - buf;
4149}
4150
4151#define DUMP_STREAM_FILE "/data/tmp/dump_stream.h264"
4152ssize_t dump_stream_store(struct class *class,
4153 struct class_attribute *attr,
4154 const char *buf, size_t size)
4155{
4156 struct stream_buf_s *p_buf;
4157 int ret = 0, id = 0;
4158 unsigned int stride, remain, level, vmap_size;
4159 int write_size;
4160 void *stbuf_vaddr;
4161 unsigned long offset;
4162 struct file *fp;
4163 mm_segment_t old_fs;
4164 loff_t fpos;
4165
4166 ret = sscanf(buf, "%d", &id);
4167 if (ret < 0) {
4168 pr_info("paser buf id fail, default id = 0\n");
4169 id = 0;
4170 }
4171 if (id != BUF_TYPE_VIDEO && id != BUF_TYPE_HEVC) {
4172 pr_info("buf id out of range, max %d, id %d, set default id 0\n", BUF_MAX_NUM - 1, id);
4173 id = 0;
4174 }
4175 p_buf = get_stream_buffer(id);
4176 if (!p_buf) {
4177 pr_info("get buf fail, id %d\n", id);
4178 return size;
4179 }
4180 if ((!p_buf->buf_size) || (p_buf->is_secure) || (!(p_buf->flag & BUF_FLAG_IN_USE))) {
4181 pr_info("buf size %d, is_secure %d, in_use %d, it can not dump\n",
4182 p_buf->buf_size, p_buf->is_secure, (p_buf->flag & BUF_FLAG_IN_USE));
4183 return size;
4184 }
4185
4186 level = stbuf_level(p_buf);
4187 if (!level || level > p_buf->buf_size) {
4188 pr_info("stream buf level %d, buf size %d, error return\n", level, p_buf->buf_size);
4189 return size;
4190 }
4191
4192 fp = filp_open(DUMP_STREAM_FILE, O_CREAT | O_RDWR, 0666);
4193 if (IS_ERR(fp)) {
4194 fp = NULL;
4195 pr_info("create dump stream file failed\n");
4196 return size;
4197 }
4198
4199 offset = p_buf->buf_start;
4200 remain = level;
4201 stride = SZ_1M;
4202 vmap_size = 0;
4203 fpos = 0;
4204 pr_info("create file success, it will dump from addr 0x%lx, size 0x%x\n", offset, remain);
4205 while (remain > 0) {
4206 if (remain > stride)
4207 vmap_size = stride;
4208 else {
4209 stride = remain;
4210 vmap_size = stride;
4211 }
4212
4213 stbuf_vaddr = codec_mm_vmap(offset, vmap_size);
4214 if (stbuf_vaddr == NULL) {
4215 stride >>= 1;
4216 pr_info("vmap fail change vmap stide size 0x%x\n", stride);
4217 continue;
4218 }
4219 codec_mm_dma_flush(stbuf_vaddr, vmap_size, DMA_FROM_DEVICE);
4220
4221 old_fs = get_fs();
4222 set_fs(KERNEL_DS);
4223 write_size = vfs_write(fp, stbuf_vaddr, vmap_size, &fpos);
4224 if (write_size < vmap_size) {
4225 write_size += vfs_write(fp, stbuf_vaddr + write_size, vmap_size - write_size, &fpos);
4226 pr_info("fail write retry, total %d, write %d\n", vmap_size, write_size);
4227 if (write_size < vmap_size) {
4228 pr_info("retry fail, interrupt dump stream, break\n");
4229 break;
4230 }
4231 }
4232 set_fs(old_fs);
4233 vfs_fsync(fp, 0);
4234 pr_info("vmap_size 0x%x dump size 0x%x\n", vmap_size, write_size);
4235
4236 offset += vmap_size;
4237 remain -= vmap_size;
4238 codec_mm_unmap_phyaddr(stbuf_vaddr);
4239 }
4240
4241 filp_close(fp, current->files);
4242 pr_info("dump stream buf end\n");
4243
4244 return size;
4245}
4246
4247
4248
4249
4250static struct class_attribute amstream_class_attrs[] = {
4251 __ATTR_RO(ports),
4252 __ATTR_RO(bufs),
4253 __ATTR_RO(vcodec_profile),
4254 __ATTR_RO(videobufused),
4255 __ATTR(canuse_buferlevel, S_IRUGO | S_IWUSR | S_IWGRP,
4256 show_canuse_buferlevel, store_canuse_buferlevel),
4257 __ATTR(max_buffer_delay_ms, S_IRUGO | S_IWUSR | S_IWGRP, show_maxdelay,
4258 store_maxdelay),
4259 __ATTR(reset_audio_port, S_IRUGO | S_IWUSR | S_IWGRP,
4260 NULL, audio_path_store),
4261 __ATTR(dump_stream, S_IRUGO | S_IWUSR | S_IWGRP,
4262 dump_stream_show, dump_stream_store),
4263 __ATTR_NULL
4264};
4265
4266static struct class amstream_class = {
4267 .name = "amstream",
4268 .class_attrs = amstream_class_attrs,
4269};
4270
4271int amstream_request_firmware_from_sys(const char *file_name,
4272 char *buf, int size)
4273{
4274 const struct firmware *firmware;
4275 int err = 0;
4276 struct device *micro_dev;
4277
4278 pr_info("try load %s ...", file_name);
4279 micro_dev = device_create(&amstream_class,
4280 NULL, MKDEV(AMSTREAM_MAJOR, 100),
4281 NULL, "videodec");
4282 if (micro_dev == NULL) {
4283 pr_err("device_create failed =%d\n", err);
4284 return -1;
4285 }
4286 err = request_firmware(&firmware, file_name, micro_dev);
4287 if (err < 0) {
4288 pr_err("can't load the %s,err=%d\n", file_name, err);
4289 goto error1;
4290 }
4291 if (firmware->size > size) {
4292 pr_err("not enough memory size for audiodsp code\n");
4293 err = -ENOMEM;
4294 goto release;
4295 }
4296
4297 memcpy(buf, (char *)firmware->data, firmware->size);
4298 /*mb(); don't need it*/
4299 pr_err("load mcode size=%zd\n mcode name %s\n", firmware->size,
4300 file_name);
4301 err = firmware->size;
4302release:
4303 release_firmware(firmware);
4304error1:
4305 device_destroy(&amstream_class, MKDEV(AMSTREAM_MAJOR, 100));
4306 return err;
4307}
4308
4309int videobufused_show_fun(const char *trigger, int id, char *sbuf, int size)
4310{
4311 int ret = -1;
4312 void *buf, *getbuf = NULL;
4313 if (size < PAGE_SIZE) {
4314 getbuf = (void *)__get_free_page(GFP_KERNEL);
4315 if (!getbuf)
4316 return -ENOMEM;
4317 buf = getbuf;
4318 } else {
4319 buf = sbuf;
4320 }
4321
4322 switch (id) {
4323 case 0:
4324 ret = videobufused_show(NULL, NULL , buf);
4325 break;
4326 default:
4327 ret = -1;
4328 }
4329 if (ret > 0 && getbuf != NULL) {
4330 ret = min_t(int, ret, size);
4331 strncpy(sbuf, buf, ret);
4332 }
4333 if (getbuf != NULL)
4334 free_page((unsigned long)getbuf);
4335 return ret;
4336}
4337
4338static struct mconfig amports_configs[] = {
4339 MC_PI32("def_4k_vstreambuf_sizeM", &def_4k_vstreambuf_sizeM),
4340 MC_PI32("def_vstreambuf_sizeM", &def_vstreambuf_sizeM),
4341 MC_PI32("slow_input", &slow_input),
4342 MC_FUN_ID("videobufused", videobufused_show_fun, NULL, 0),
4343};
4344
4345
4346
4347/*static struct resource memobj;*/
4348static int amstream_probe(struct platform_device *pdev)
4349{
4350 int i;
4351 int r;
4352 struct stream_port_s *st;
4353
4354 pr_err("Amlogic A/V streaming port init\n");
4355
4356 amstream_port_num = MAX_AMSTREAM_PORT_NUM;
4357 amstream_buf_num = BUF_MAX_NUM;
4358/*
4359 * r = of_reserved_mem_device_init(&pdev->dev);
4360 * if (r == 0)
4361 * pr_info("of probe done");
4362 * else {
4363 * r = -ENOMEM;
4364 * return r;
4365 * }
4366 */
4367 r = class_register(&amstream_class);
4368 if (r) {
4369 pr_err("amstream class create fail.\n");
4370 return r;
4371 }
4372
4373 r = astream_dev_register();
4374 if (r)
4375 return r;
4376
4377 r = register_chrdev(AMSTREAM_MAJOR, "amstream", &amstream_fops);
4378 if (r < 0) {
4379 pr_err("Can't allocate major for amstreaming device\n");
4380
4381 goto error2;
4382 }
4383
4384 amstream_dev_class = class_create(THIS_MODULE, DEVICE_NAME);
4385
4386 for (st = &ports[0], i = 0; i < amstream_port_num; i++, st++) {
4387 st->class_dev = device_create(amstream_dev_class, NULL,
4388 MKDEV(AMSTREAM_MAJOR, i), NULL,
4389 ports[i].name);
4390 }
4391
4392 amstream_adec_status = NULL;
4393 if (tsdemux_class_register() != 0) {
4394 r = (-EIO);
4395 goto error3;
4396 }
4397 tsdemux_tsync_func_init();
4398 init_waitqueue_head(&amstream_sub_wait);
4399 init_waitqueue_head(&amstream_userdata_wait);
4400 reset_canuse_buferlevel(10000);
4401 amstream_pdev = pdev;
4402 amports_clock_gate_init(&amstream_pdev->dev);
4403
4404 /*prealloc fetch buf to avoid no continue buffer later...*/
4405 stbuf_fetch_init();
4406 REG_PATH_CONFIGS("media.amports", amports_configs);
4407
4408 /* poweroff the decode core because dos can not be reset when reboot */
4409 if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_G12A)
4410 vdec_power_reset();
4411
4412 return 0;
4413
4414 /*
4415 * error4:
4416 * tsdemux_class_unregister();
4417 */
4418error3:
4419 for (st = &ports[0], i = 0; i < amstream_port_num; i++, st++)
4420 device_destroy(amstream_dev_class, MKDEV(AMSTREAM_MAJOR, i));
4421 class_destroy(amstream_dev_class);
4422error2:
4423 unregister_chrdev(AMSTREAM_MAJOR, "amstream");
4424 /* error1: */
4425 astream_dev_unregister();
4426 return r;
4427}
4428
4429static int amstream_remove(struct platform_device *pdev)
4430{
4431 int i;
4432 struct stream_port_s *st;
4433
4434 if (bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_ALLOC)
4435 stbuf_change_size(&bufs[BUF_TYPE_AUDIO], 0, false);
4436 stbuf_fetch_release();
4437 tsdemux_class_unregister();
4438 for (st = &ports[0], i = 0; i < amstream_port_num; i++, st++)
4439 device_destroy(amstream_dev_class, MKDEV(AMSTREAM_MAJOR, i));
4440
4441 class_destroy(amstream_dev_class);
4442
4443 unregister_chrdev(AMSTREAM_MAJOR, "amstream");
4444
4445 class_unregister(&amstream_class);
4446
4447 astream_dev_unregister();
4448
4449 amstream_adec_status = NULL;
4450
4451 pr_err("Amlogic A/V streaming port release\n");
4452
4453 return 0;
4454}
4455
4456void set_adec_func(int (*adec_func)(struct adec_status *))
4457{
4458 amstream_adec_status = adec_func;
4459}
4460
4461void wakeup_sub_poll(void)
4462{
4463 atomic_inc(&subdata_ready);
4464 wake_up_interruptible(&amstream_sub_wait);
4465}
4466
4467int get_sub_type(void)
4468{
4469 return sub_type;
4470}
4471
4472u32 get_audio_reset(void)
4473{
4474 return amstream_audio_reset;
4475}
4476
4477/*get pes buffers */
4478
4479struct stream_buf_s *get_stream_buffer(int id)
4480{
4481 if (id >= BUF_MAX_NUM)
4482 return 0;
4483 return &bufs[id];
4484}
4485EXPORT_SYMBOL(get_stream_buffer);
4486static const struct of_device_id amlogic_mesonstream_dt_match[] = {
4487 {
4488 .compatible = "amlogic, codec, streambuf",
4489 },
4490 {},
4491};
4492
4493static struct platform_driver amstream_driver = {
4494 .probe = amstream_probe,
4495 .remove = amstream_remove,
4496 .driver = {
4497 .owner = THIS_MODULE,
4498 .name = "mesonstream",
4499 .of_match_table = amlogic_mesonstream_dt_match,
4500 }
4501};
4502
4503static int __init amstream_module_init(void)
4504{
4505 if (platform_driver_register(&amstream_driver)) {
4506 pr_err("failed to register amstream module\n");
4507 return -ENODEV;
4508 }
4509
4510 if (subtitle_init()) {
4511 pr_err("failed to init subtitle\n");
4512 return -ENODEV;
4513 }
4514
4515 return 0;
4516}
4517
4518static void __exit amstream_module_exit(void)
4519{
4520 platform_driver_unregister(&amstream_driver);
4521 subtitle_exit();
4522}
4523
4524module_init(amstream_module_init);
4525module_exit(amstream_module_exit);
4526
4527module_param(force_dv_mode, uint, 0664);
4528MODULE_PARM_DESC(force_dv_mode,
4529 "\n force_dv_mode \n");
4530
4531module_param(def_4k_vstreambuf_sizeM, uint, 0664);
4532MODULE_PARM_DESC(def_4k_vstreambuf_sizeM,
4533 "\nDefault video Stream buf size for 4K MByptes\n");
4534
4535module_param(def_vstreambuf_sizeM, uint, 0664);
4536MODULE_PARM_DESC(def_vstreambuf_sizeM,
4537 "\nDefault video Stream buf size for < 1080p MByptes\n");
4538
4539module_param(slow_input, uint, 0664);
4540MODULE_PARM_DESC(slow_input, "\n amstream slow_input\n");
4541
4542MODULE_DESCRIPTION("AMLOGIC streaming port driver");
4543MODULE_LICENSE("GPL");
4544MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>");
4545