summaryrefslogtreecommitdiff
path: root/drivers/stream_input/amports/amstream.c (plain)
blob: b204dc6968aabdeb8ee773aefec9f19fb71d2f5c
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 default:
2571 r = -ENOIOCTLCMD;
2572 break;
2573 }
2574 return r;
2575}
2576
2577static long amstream_do_ioctl_new(struct port_priv_s *priv,
2578 unsigned int cmd, ulong arg)
2579{
2580 long r = 0;
2581 struct stream_port_s *this = priv->port;
2582
2583 switch (cmd) {
2584 case AMSTREAM_IOC_GET_VERSION:
2585 r = amstream_ioctl_get_version(priv, arg);
2586 break;
2587 case AMSTREAM_IOC_GET:
2588 r = amstream_ioctl_get(priv, arg);
2589 break;
2590 case AMSTREAM_IOC_SET:
2591 r = amstream_ioctl_set(priv, arg);
2592 break;
2593 case AMSTREAM_IOC_GET_EX:
2594 r = amstream_ioctl_get_ex(priv, arg);
2595 break;
2596 case AMSTREAM_IOC_SET_EX:
2597 r = amstream_ioctl_set_ex(priv, arg);
2598 break;
2599 case AMSTREAM_IOC_GET_PTR:
2600 r = amstream_ioctl_get_ptr(priv, arg);
2601 break;
2602 case AMSTREAM_IOC_SET_PTR:
2603 r = amstream_ioctl_set_ptr(priv, arg);
2604 break;
2605 case AMSTREAM_IOC_SYSINFO:
2606 if (this->type & PORT_TYPE_VIDEO)
2607 r = vdec_set_decinfo(priv->vdec, (void *)arg);
2608 else
2609 r = -EINVAL;
2610 break;
2611 case AMSTREAM_IOC_GET_QOSINFO:
2612 case AMSTREAM_IOC_GET_MVDECINFO:
2613 {
2614 u32 slots = 0;
2615 u32 struct_size = 0;
2616 int vdec_id = 0;
2617 struct vdec_s *vdec = NULL;
2618 struct vframe_counter_s tmpbuf[QOS_FRAME_NUM] = {0};
2619 struct av_param_mvdec_t __user *uarg = (void *)arg;
2620
2621 if (AMSTREAM_IOC_GET_MVDECINFO == cmd) {
2622 if (get_user(vdec_id, &uarg->vdec_id) < 0
2623 || get_user(struct_size, &uarg->struct_size) < 0) {
2624 r = -EFAULT;
2625 break;
2626 }
2627 if (struct_size != sizeof(struct av_param_mvdec_t)) {
2628 pr_err("pass in size %u != expected size %u\n",
2629 struct_size, (u32)sizeof(struct av_param_mvdec_t));
2630 pr_err("App using old structue,we will support it.\n");
2631 //Here will add the compatibility for old structure when
2632 //current struecture be substituded by newer structure.
2633 //msleep(1000); let app handle it.
2634 break;
2635 }
2636 }
2637 vdec = vdec_get_vdec_by_id(vdec_id);
2638 if (!vdec) {
2639 r = 0;
2640 break;
2641 }
2642
2643 slots = vdec_get_frame_vdec(vdec, tmpbuf);
2644 if (AMSTREAM_IOC_GET_MVDECINFO == cmd)
2645 put_user(slots, &uarg->slots);
2646 if (slots) {
2647 if (AMSTREAM_IOC_GET_MVDECINFO == cmd) {
2648 if (copy_to_user((void *)&uarg->comm,
2649 &vdec->mvfrm->comm,
2650 sizeof(struct vframe_comm_s))) {
2651 r = -EFAULT;
2652 break;
2653 }
2654 if (copy_to_user((void *)&uarg->minfo[0],
2655 tmpbuf,
2656 slots*sizeof(struct vframe_counter_s))) {
2657 r = -EFAULT;
2658 kfree(tmpbuf);
2659 break;
2660 }
2661 }else { //For compatibility, only copy the qos
2662 struct av_param_qosinfo_t __user *uarg = (void *)arg;
2663 int i;
2664 for (i=0; i<slots; i++)
2665 if (copy_to_user((void *)&uarg->vframe_qos[i],
2666 &tmpbuf[i].qos,
2667 sizeof(struct vframe_qos_s))) {
2668 r = -EFAULT;
2669 break;
2670 }
2671 }
2672 } else {
2673 /*Vdec didn't produce item,wait for 10 ms to avoid user application
2674 infinitely calling*/
2675 //msleep(10); let user app handle it.
2676 }
2677 }
2678 break;
2679 case AMSTREAM_IOC_GET_AVINFO:
2680 {
2681 struct av_param_info_t __user *uarg = (void *)arg;
2682 struct av_info_t av_info;
2683 int delay;
2684 u32 avgbps;
2685 if (this->type & PORT_TYPE_VIDEO) {
2686 av_info.first_pic_coming = get_first_pic_coming();
2687 av_info.current_fps = -1;
2688 av_info.vpts = timestamp_vpts_get();
2689 av_info.vpts_err = tsync_get_vpts_error_num();
2690 av_info.apts = timestamp_apts_get();
2691 av_info.apts_err = tsync_get_apts_error_num();
2692 av_info.ts_error = get_discontinue_counter();
2693 av_info.first_vpts = timestamp_firstvpts_get();
2694 av_info.toggle_frame_count = get_toggle_frame_count();
2695 delay = calculation_stream_delayed_ms(
2696 PTS_TYPE_VIDEO, NULL, &avgbps);
2697 if (delay >= 0)
2698 av_info.dec_video_bps = avgbps;
2699 else
2700 av_info.dec_video_bps = 0;
2701 }
2702 if (copy_to_user((void *)&uarg->av_info, (void *)&av_info,
2703 sizeof(struct av_info_t)))
2704 r = -EFAULT;
2705 }
2706 break;
2707 default:
2708 r = -ENOIOCTLCMD;
2709 break;
2710 }
2711
2712 return r;
2713}
2714
2715static long amstream_do_ioctl_old(struct port_priv_s *priv,
2716 unsigned int cmd, ulong arg)
2717{
2718 struct stream_port_s *this = priv->port;
2719 long r = 0;
2720
2721 switch (cmd) {
2722
2723 case AMSTREAM_IOC_VB_START:
2724 if ((this->type & PORT_TYPE_VIDEO) &&
2725 ((priv->vdec->vbuf.flag & BUF_FLAG_IN_USE) == 0)) {
2726 priv->vdec->vbuf.buf_start = arg;
2727 } else
2728 r = -EINVAL;
2729 break;
2730
2731 case AMSTREAM_IOC_VB_SIZE:
2732 if ((this->type & PORT_TYPE_VIDEO) &&
2733 ((priv->vdec->vbuf.flag & BUF_FLAG_IN_USE) == 0)) {
2734 if (priv->vdec->vbuf.flag & BUF_FLAG_ALLOC) {
2735 r += stbuf_change_size(
2736 &priv->vdec->vbuf,
2737 arg, false);
2738 }
2739 } else
2740 r = -EINVAL;
2741 break;
2742
2743 case AMSTREAM_IOC_AB_START:
2744 if ((this->type & PORT_TYPE_AUDIO) &&
2745 ((bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_IN_USE) == 0))
2746 bufs[BUF_TYPE_AUDIO].buf_start = arg;
2747 else
2748 r = -EINVAL;
2749 break;
2750
2751 case AMSTREAM_IOC_AB_SIZE:
2752 if ((this->type & PORT_TYPE_AUDIO) &&
2753 ((bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_IN_USE) == 0)) {
2754 if (bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_ALLOC) {
2755 r = stbuf_change_size(
2756 &bufs[BUF_TYPE_AUDIO], arg, false);
2757 }
2758 } else
2759 r = -EINVAL;
2760 break;
2761
2762 case AMSTREAM_IOC_VFORMAT:
2763 if ((this->type & PORT_TYPE_VIDEO) && (arg < VFORMAT_MAX)) {
2764 this->vformat = (enum vformat_e)arg;
2765 this->flag |= PORT_FLAG_VFORMAT;
2766
2767 vdec_set_format(priv->vdec, this->vformat);
2768 } else
2769 r = -EINVAL;
2770 break;
2771
2772 case AMSTREAM_IOC_AFORMAT:
2773 if ((this->type & PORT_TYPE_AUDIO) && (arg < AFORMAT_MAX)) {
2774 memset(&audio_dec_info, 0,
2775 sizeof(struct audio_info));
2776 /* for new format,reset the audio info. */
2777 this->aformat = (enum aformat_e)arg;
2778 this->flag |= PORT_FLAG_AFORMAT;
2779 } else
2780 r = -EINVAL;
2781 break;
2782
2783 case AMSTREAM_IOC_VID:
2784 if (this->type & PORT_TYPE_VIDEO) {
2785 this->vid = (u32) arg;
2786 this->flag |= PORT_FLAG_VID;
2787 } else
2788 r = -EINVAL;
2789
2790 break;
2791
2792 case AMSTREAM_IOC_AID:
2793 if (this->type & PORT_TYPE_AUDIO) {
2794 this->aid = (u32) arg;
2795 this->flag |= PORT_FLAG_AID;
2796
2797 if (port_get_inited(priv)) {
2798 //tsync_audio_break(1);
2799 amstream_change_avid(this);
2800 }
2801 } else
2802 r = -EINVAL;
2803 break;
2804
2805 case AMSTREAM_IOC_SID:
2806 if (this->type & PORT_TYPE_SUB) {
2807 this->sid = (u32) arg;
2808 this->flag |= PORT_FLAG_SID;
2809
2810 if (port_get_inited(priv))
2811 amstream_change_sid(this);
2812 } else
2813 r = -EINVAL;
2814
2815 break;
2816
2817 case AMSTREAM_IOC_PCRID:
2818 this->pcrid = (u32) arg;
2819 this->pcr_inited = 1;
2820 pr_err("set pcrid = 0x%x\n", this->pcrid);
2821 break;
2822
2823 case AMSTREAM_IOC_VB_STATUS:
2824 if (this->type & PORT_TYPE_VIDEO) {
2825 struct am_io_param para;
2826 struct am_io_param *p = &para;
2827 struct stream_buf_s *buf = NULL;
2828
2829 mutex_lock(&amstream_mutex);
2830
2831 /*
2832 *todo: check upper layer for decoder
2833 * handler lifecycle
2834 */
2835 if (priv->vdec == NULL) {
2836 r = -EINVAL;
2837 mutex_unlock(&amstream_mutex);
2838 break;
2839 }
2840
2841 if (this->type & PORT_TYPE_FRAME) {
2842 struct vdec_input_status_s status;
2843
2844 r = vdec_input_get_status(&priv->vdec->input,
2845 &status);
2846 if (r == 0) {
2847 p->status.size = status.size;
2848 p->status.data_len = status.data_len;
2849 p->status.free_len = status.free_len;
2850 p->status.read_pointer =
2851 status.read_pointer;
2852 if (copy_to_user((void *)arg, p,
2853 sizeof(para)))
2854 r = -EFAULT;
2855 }
2856 mutex_unlock(&amstream_mutex);
2857 break;
2858 }
2859
2860 buf = &priv->vdec->vbuf;
2861 p->status.size = stbuf_canusesize(buf);
2862 p->status.data_len = stbuf_level(buf);
2863 p->status.free_len = stbuf_space(buf);
2864 p->status.read_pointer = stbuf_rp(buf);
2865 if (copy_to_user((void *)arg, p, sizeof(para)))
2866 r = -EFAULT;
2867
2868 mutex_unlock(&amstream_mutex);
2869 return r;
2870 }
2871 r = -EINVAL;
2872 break;
2873
2874 case AMSTREAM_IOC_AB_STATUS:
2875 if (this->type & PORT_TYPE_AUDIO) {
2876 struct am_io_param para;
2877 struct am_io_param *p = &para;
2878 struct stream_buf_s *buf = &bufs[BUF_TYPE_AUDIO];
2879
2880 p->status.size = stbuf_canusesize(buf);
2881 p->status.data_len = stbuf_level(buf);
2882 p->status.free_len = stbuf_space(buf);
2883 p->status.read_pointer = stbuf_rp(buf);
2884 if (copy_to_user((void *)arg, p, sizeof(para)))
2885 r = -EFAULT;
2886 return r;
2887 }
2888 r = -EINVAL;
2889 break;
2890
2891 case AMSTREAM_IOC_SYSINFO:
2892 if (this->type & PORT_TYPE_VIDEO)
2893 r = vdec_set_decinfo(priv->vdec, (void *)arg);
2894 else
2895 r = -EINVAL;
2896 break;
2897
2898 case AMSTREAM_IOC_ACHANNEL:
2899 if (this->type & PORT_TYPE_AUDIO) {
2900 this->achanl = (u32) arg;
2901 set_ch_num_info((u32) arg);
2902 } else
2903 r = -EINVAL;
2904 break;
2905
2906 case AMSTREAM_IOC_SAMPLERATE:
2907 if (this->type & PORT_TYPE_AUDIO) {
2908 this->asamprate = (u32) arg;
2909 set_sample_rate_info((u32) arg);
2910 } else
2911 r = -EINVAL;
2912 break;
2913
2914 case AMSTREAM_IOC_DATAWIDTH:
2915 if (this->type & PORT_TYPE_AUDIO)
2916 this->adatawidth = (u32) arg;
2917 else
2918 r = -EINVAL;
2919 break;
2920
2921 case AMSTREAM_IOC_TSTAMP:
2922 if ((this->type & (PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)) ==
2923 ((PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)))
2924 r = -EINVAL;
2925 else if (this->type & PORT_TYPE_FRAME)
2926 r = vdec_set_pts(priv->vdec, arg);
2927 else if ((this->type & PORT_TYPE_VIDEO) ||
2928 (this->type & PORT_TYPE_HEVC))
2929 r = es_vpts_checkin(&priv->vdec->vbuf, arg);
2930 else if (this->type & PORT_TYPE_AUDIO)
2931 r = es_apts_checkin(&bufs[BUF_TYPE_AUDIO], arg);
2932 break;
2933
2934 case AMSTREAM_IOC_TSTAMP_uS64:
2935 if ((this->type & (PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)) ==
2936 ((PORT_TYPE_AUDIO | PORT_TYPE_VIDEO)))
2937 r = -EINVAL;
2938 else {
2939 u64 pts;
2940
2941 if (copy_from_user
2942 ((void *)&pts, (void *)arg, sizeof(u64)))
2943 return -EFAULT;
2944 if (this->type & PORT_TYPE_FRAME) {
2945 /*
2946 *todo: check upper layer for decoder handler
2947 * life sequence or multi-tasking management
2948 */
2949 if (priv->vdec)
2950 r = vdec_set_pts64(priv->vdec, pts);
2951 } else if ((this->type & PORT_TYPE_HEVC) ||
2952 (this->type & PORT_TYPE_VIDEO)) {
2953 r = es_vpts_checkin_us64(
2954 &priv->vdec->vbuf, pts);
2955 } else if (this->type & PORT_TYPE_AUDIO) {
2956 r = es_vpts_checkin_us64(
2957 &bufs[BUF_TYPE_AUDIO], pts);
2958 }
2959 }
2960 break;
2961
2962 case AMSTREAM_IOC_VDECSTAT:
2963 if ((this->type & PORT_TYPE_VIDEO) == 0)
2964 return -EINVAL;
2965 {
2966 struct vdec_info vstatus;
2967 struct am_io_param para;
2968 struct am_io_param *p = &para;
2969
2970 memset(&vstatus, 0, sizeof(vstatus));
2971
2972 mutex_lock(&priv->mutex);
2973 if (vdec_status(priv->vdec, &vstatus) == -1) {
2974 mutex_unlock(&priv->mutex);
2975 return -ENODEV;
2976 }
2977 mutex_unlock(&priv->mutex);
2978
2979 p->vstatus.width = vstatus.frame_width;
2980 p->vstatus.height = vstatus.frame_height;
2981 p->vstatus.fps = vstatus.frame_rate;
2982 p->vstatus.error_count = vstatus.error_count;
2983 p->vstatus.status = vstatus.status;
2984 p->vstatus.euAspectRatio =
2985 get_normalized_aspect_ratio(
2986 vstatus.ratio_control);
2987
2988 if (copy_to_user((void *)arg, p, sizeof(para)))
2989 r = -EFAULT;
2990 return r;
2991 }
2992
2993 case AMSTREAM_IOC_VDECINFO:
2994 if ((this->type & PORT_TYPE_VIDEO) == 0)
2995 return -EINVAL;
2996 {
2997 struct vdec_info vinfo;
2998 struct am_io_info para;
2999
3000 memset(&para, 0x0, sizeof(struct am_io_info));
3001
3002 mutex_lock(&priv->mutex);
3003 if (vdec_status(priv->vdec, &vinfo) == -1) {
3004 mutex_unlock(&priv->mutex);
3005 return -ENODEV;
3006 }
3007 mutex_unlock(&priv->mutex);
3008
3009 memcpy(&para.vinfo, &vinfo, sizeof(struct vdec_info));
3010 if (copy_to_user((void *)arg, &para, sizeof(para)))
3011 r = -EFAULT;
3012 return r;
3013 }
3014
3015 case AMSTREAM_IOC_ADECSTAT:
3016 if ((this->type & PORT_TYPE_AUDIO) == 0)
3017 return -EINVAL;
3018 if (amstream_adec_status == NULL)
3019 return -ENODEV;
3020 else {
3021 struct adec_status astatus;
3022 struct am_io_param para;
3023 struct am_io_param *p = &para;
3024
3025 amstream_adec_status(&astatus);
3026 p->astatus.channels = astatus.channels;
3027 p->astatus.sample_rate = astatus.sample_rate;
3028 p->astatus.resolution = astatus.resolution;
3029 p->astatus.error_count = astatus.error_count;
3030 p->astatus.status = astatus.status;
3031 if (copy_to_user((void *)arg, p, sizeof(para)))
3032 r = -EFAULT;
3033 return r;
3034 }
3035 case AMSTREAM_IOC_PORT_INIT:
3036 r = amstream_port_init(priv);
3037 break;
3038
3039 case AMSTREAM_IOC_VDEC_RESET:
3040 if ((this->type & PORT_TYPE_VIDEO) == 0)
3041 return -EINVAL;
3042
3043 if (priv->vdec == NULL)
3044 return -ENODEV;
3045
3046 r = vdec_reset(priv->vdec);
3047 break;
3048
3049 case AMSTREAM_IOC_TRICKMODE:
3050 if ((this->type & PORT_TYPE_VIDEO) == 0)
3051 return -EINVAL;
3052 r = vdec_set_trickmode(priv->vdec, arg);
3053 if (r == -1)
3054 return -ENODEV;
3055 break;
3056
3057 case AMSTREAM_IOC_AUDIO_INFO:
3058 if ((this->type & PORT_TYPE_VIDEO)
3059 || (this->type & PORT_TYPE_AUDIO)) {
3060 if (copy_from_user
3061 (&audio_dec_info, (void __user *)arg,
3062 sizeof(audio_dec_info)))
3063 r = -EFAULT;
3064 } else
3065 r = -EINVAL;
3066 break;
3067
3068 case AMSTREAM_IOC_AUDIO_RESET:
3069 if (this->type & PORT_TYPE_AUDIO) {
3070 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
3071
3072 r = audio_port_reset(this, pabuf);
3073 } else
3074 r = -EINVAL;
3075
3076 break;
3077
3078 case AMSTREAM_IOC_SUB_RESET:
3079 if (this->type & PORT_TYPE_SUB) {
3080 struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
3081
3082 r = sub_port_reset(this, psbuf);
3083 } else
3084 r = -EINVAL;
3085 break;
3086
3087 case AMSTREAM_IOC_SUB_LENGTH:
3088 if ((this->type & PORT_TYPE_SUB) ||
3089 (this->type & PORT_TYPE_SUB_RD)) {
3090 u32 sub_wp, sub_rp;
3091 struct stream_buf_s *psbuf = &bufs[BUF_TYPE_SUBTITLE];
3092 int val;
3093
3094 sub_wp = stbuf_sub_wp_get();
3095 sub_rp = stbuf_sub_rp_get();
3096
3097 if (sub_wp == sub_rp)
3098 val = 0;
3099 else if (sub_wp > sub_rp)
3100 val = sub_wp - sub_rp;
3101 else
3102 val = psbuf->buf_size - (sub_rp - sub_wp);
3103 put_user(val, (int __user *)arg);
3104 } else
3105 r = -EINVAL;
3106 break;
3107
3108 case AMSTREAM_IOC_UD_LENGTH:
3109 if (this->type & PORT_TYPE_USERDATA) {
3110 /* *((u32 *)arg) = userdata_length; */
3111 put_user(userdata_length, (unsigned long __user *)arg);
3112 userdata_length = 0;
3113 } else
3114 r = -EINVAL;
3115 break;
3116
3117 case AMSTREAM_IOC_UD_POC:
3118 if (this->type & PORT_TYPE_USERDATA) {
3119 /* *((u32 *)arg) = userdata_length; */
3120 int ri;
3121#ifdef DEBUG_USER_DATA
3122 int wi;
3123#endif
3124 int bDataAvail = 0;
3125
3126 mutex_lock(&userdata_mutex);
3127 if (userdata_poc_wi != userdata_poc_ri) {
3128 bDataAvail = 1;
3129 ri = userdata_poc_ri;
3130#ifdef DEBUG_USER_DATA
3131 wi = userdata_poc_wi;
3132#endif
3133 userdata_poc_ri++;
3134 if (userdata_poc_ri >= USERDATA_FIFO_NUM)
3135 userdata_poc_ri = 0;
3136 }
3137 mutex_unlock(&userdata_mutex);
3138 if (bDataAvail) {
3139 int res;
3140 struct userdata_poc_info_t userdata_poc =
3141 userdata_poc_info[ri];
3142#ifdef DEBUG_USER_DATA
3143 pr_info("read poc: ri=%d, wi=%d, poc=%d, last_wi=%d\n",
3144 ri, wi,
3145 userdata_poc.poc_number,
3146 last_read_wi);
3147#endif
3148 res =
3149 copy_to_user((unsigned long __user *)arg,
3150 &userdata_poc,
3151 sizeof(struct userdata_poc_info_t));
3152 if (res < 0)
3153 r = -EFAULT;
3154 } else {
3155 r = -EFAULT;
3156 }
3157 } else {
3158 r = -EINVAL;
3159 }
3160 break;
3161
3162 case AMSTREAM_IOC_UD_BUF_READ:
3163 {
3164 if (this->type & PORT_TYPE_USERDATA) {
3165 struct userdata_param_t param;
3166 struct userdata_param_t *p_userdata_param;
3167 struct vdec_s *vdec;
3168
3169 p_userdata_param = &param;
3170 if (copy_from_user(p_userdata_param,
3171 (void __user *)arg,
3172 sizeof(struct userdata_param_t))) {
3173 r = -EFAULT;
3174 break;
3175 }
3176 mutex_lock(&amstream_mutex);
3177 vdec = vdec_get_vdec_by_id(p_userdata_param->instance_id);
3178 if (vdec) {
3179 if (vdec_read_user_data(vdec,
3180 p_userdata_param) == 0) {
3181 r = -EFAULT;
3182 mutex_unlock(&amstream_mutex);
3183 break;
3184 }
3185
3186 if (copy_to_user((void *)arg,
3187 p_userdata_param,
3188 sizeof(struct userdata_param_t)))
3189 r = -EFAULT;
3190 } else
3191 r = -EINVAL;
3192 mutex_unlock(&amstream_mutex);
3193 }
3194 }
3195 break;
3196
3197 case AMSTREAM_IOC_UD_AVAILABLE_VDEC:
3198 {
3199 unsigned int ready_vdec;
3200
3201 mutex_lock(&userdata_mutex);
3202 ready_vdec = ud_ready_vdec_flag;
3203 ud_ready_vdec_flag = 0;
3204 mutex_unlock(&userdata_mutex);
3205
3206 put_user(ready_vdec, (uint32_t __user *)arg);
3207 }
3208 break;
3209
3210 case AMSTREAM_IOC_GET_VDEC_ID:
3211 if (this->type & PORT_TYPE_VIDEO && priv->vdec) {
3212 put_user(priv->vdec->id, (int32_t __user *)arg);
3213 } else
3214 r = -EINVAL;
3215 break;
3216
3217
3218 case AMSTREAM_IOC_UD_FLUSH_USERDATA:
3219 if (this->type & PORT_TYPE_USERDATA) {
3220 struct vdec_s *vdec;
3221 int vdec_id;
3222
3223 mutex_lock(&amstream_mutex);
3224 get_user(vdec_id, (int __user *)arg);
3225 vdec = vdec_get_vdec_by_id(vdec_id);
3226 if (vdec) {
3227 vdec_reset_userdata_fifo(vdec, 0);
3228 pr_info("reset_userdata_fifo for vdec: %d\n", vdec_id);
3229 }
3230 mutex_unlock(&amstream_mutex);
3231 } else
3232 r = -EINVAL;
3233 break;
3234
3235 case AMSTREAM_IOC_SET_DEC_RESET:
3236 tsync_set_dec_reset();
3237 break;
3238
3239 case AMSTREAM_IOC_TS_SKIPBYTE:
3240 if ((int)arg >= 0)
3241 tsdemux_set_skipbyte(arg);
3242 else
3243 r = -EINVAL;
3244 break;
3245
3246 case AMSTREAM_IOC_SUB_TYPE:
3247 sub_type = (int)arg;
3248 break;
3249
3250 case AMSTREAM_IOC_APTS_LOOKUP:
3251 if (this->type & PORT_TYPE_AUDIO) {
3252 u32 pts = 0, frame_size, offset;
3253
3254 get_user(offset, (unsigned long __user *)arg);
3255 pts_lookup_offset(PTS_TYPE_AUDIO, offset, &pts,
3256 &frame_size, 300);
3257 put_user(pts, (int __user *)arg);
3258 }
3259 return 0;
3260 case GET_FIRST_APTS_FLAG:
3261 if (this->type & PORT_TYPE_AUDIO) {
3262 put_user(first_pts_checkin_complete(PTS_TYPE_AUDIO),
3263 (int __user *)arg);
3264 }
3265 break;
3266
3267 case AMSTREAM_IOC_APTS:
3268 put_user(timestamp_apts_get(), (int __user *)arg);
3269 break;
3270
3271 case AMSTREAM_IOC_VPTS:
3272 put_user(timestamp_vpts_get(), (int __user *)arg);
3273 break;
3274
3275 case AMSTREAM_IOC_PCRSCR:
3276 put_user(timestamp_pcrscr_get(), (int __user *)arg);
3277 break;
3278
3279 case AMSTREAM_IOC_SET_PCRSCR:
3280 timestamp_pcrscr_set(arg);
3281 break;
3282 case AMSTREAM_IOC_GET_LAST_CHECKIN_APTS:
3283 put_user(get_last_checkin_pts(PTS_TYPE_AUDIO), (int *)arg);
3284 break;
3285 case AMSTREAM_IOC_GET_LAST_CHECKIN_VPTS:
3286 put_user(get_last_checkin_pts(PTS_TYPE_VIDEO), (int *)arg);
3287 break;
3288 case AMSTREAM_IOC_GET_LAST_CHECKOUT_APTS:
3289 put_user(get_last_checkout_pts(PTS_TYPE_AUDIO), (int *)arg);
3290 break;
3291 case AMSTREAM_IOC_GET_LAST_CHECKOUT_VPTS:
3292 put_user(get_last_checkout_pts(PTS_TYPE_VIDEO), (int *)arg);
3293 break;
3294 case AMSTREAM_IOC_SUB_NUM:
3295 put_user(psparser_get_sub_found_num(), (int *)arg);
3296 break;
3297
3298 case AMSTREAM_IOC_SUB_INFO:
3299 if (arg > 0) {
3300 struct subtitle_info msub_info[MAX_SUB_NUM];
3301 struct subtitle_info *psub_info[MAX_SUB_NUM];
3302 int i;
3303
3304 for (i = 0; i < MAX_SUB_NUM; i++)
3305 psub_info[i] = &msub_info[i];
3306
3307 r = psparser_get_sub_info(psub_info);
3308
3309 if (r == 0) {
3310 if (copy_to_user((void __user *)arg, msub_info,
3311 sizeof(struct subtitle_info) * MAX_SUB_NUM))
3312 r = -EFAULT;
3313 }
3314 }
3315 break;
3316 case AMSTREAM_IOC_SET_DEMUX:
3317 tsdemux_set_demux((int)arg);
3318 break;
3319 case AMSTREAM_IOC_SET_VIDEO_DELAY_LIMIT_MS:
3320 priv->vdec->vbuf.max_buffer_delay_ms = (int)arg;
3321 break;
3322 case AMSTREAM_IOC_SET_AUDIO_DELAY_LIMIT_MS:
3323 bufs[BUF_TYPE_AUDIO].max_buffer_delay_ms = (int)arg;
3324 break;
3325 case AMSTREAM_IOC_GET_VIDEO_DELAY_LIMIT_MS:
3326 put_user(priv->vdec->vbuf.max_buffer_delay_ms, (int *)arg);
3327 break;
3328 case AMSTREAM_IOC_GET_AUDIO_DELAY_LIMIT_MS:
3329 put_user(bufs[BUF_TYPE_AUDIO].max_buffer_delay_ms, (int *)arg);
3330 break;
3331 case AMSTREAM_IOC_GET_VIDEO_CUR_DELAY_MS: {
3332 int delay;
3333
3334 delay = calculation_stream_delayed_ms(
3335 PTS_TYPE_VIDEO, NULL, NULL);
3336 if (delay >= 0)
3337 put_user(delay, (int *)arg);
3338 else
3339 put_user(0, (int *)arg);
3340 }
3341 break;
3342
3343 case AMSTREAM_IOC_GET_AUDIO_CUR_DELAY_MS: {
3344 int delay;
3345
3346 delay = calculation_stream_delayed_ms(PTS_TYPE_AUDIO, NULL,
3347 NULL);
3348 if (delay >= 0)
3349 put_user(delay, (int *)arg);
3350 else
3351 put_user(0, (int *)arg);
3352 }
3353 break;
3354 case AMSTREAM_IOC_GET_AUDIO_AVG_BITRATE_BPS: {
3355 int delay;
3356 u32 avgbps;
3357
3358 delay = calculation_stream_delayed_ms(PTS_TYPE_AUDIO, NULL,
3359 &avgbps);
3360 if (delay >= 0)
3361 put_user(avgbps, (int *)arg);
3362 else
3363 put_user(0, (int *)arg);
3364 break;
3365 }
3366 case AMSTREAM_IOC_GET_VIDEO_AVG_BITRATE_BPS: {
3367 int delay;
3368 u32 avgbps;
3369
3370 delay = calculation_stream_delayed_ms(PTS_TYPE_VIDEO, NULL,
3371 &avgbps);
3372 if (delay >= 0)
3373 put_user(avgbps, (int *)arg);
3374 else
3375 put_user(0, (int *)arg);
3376 break;
3377 }
3378 case AMSTREAM_IOC_SET_DRMMODE:
3379 if ((u32) arg == 1) {
3380 pr_err("set drmmode, input must be secure buffer\n");
3381 this->flag |= PORT_FLAG_DRM;
3382 if ((this->type & PORT_TYPE_VIDEO) &&
3383 (priv->vdec))
3384 priv->vdec->port_flag |= PORT_FLAG_DRM;
3385 } else if ((u32)arg == 2) {
3386 pr_err("set drmmode, input must be normal buffer\n");
3387 if ((this->type & PORT_TYPE_VIDEO) &&
3388 (priv->vdec)) {
3389 pr_err("vdec port_flag with drmmode\n");
3390 priv->vdec->port_flag |= PORT_FLAG_DRM;
3391 }
3392 } else {
3393 this->flag &= (~PORT_FLAG_DRM);
3394 pr_err("no drmmode\n");
3395 }
3396 break;
3397 case AMSTREAM_IOC_SET_APTS: {
3398 unsigned long pts;
3399
3400 if (get_user(pts, (unsigned long __user *)arg)) {
3401 pr_err
3402 ("Get audio pts from user space fault!\n");
3403 return -EFAULT;
3404 }
3405 if (tsync_get_mode() == TSYNC_MODE_PCRMASTER)
3406 tsync_pcr_set_apts(pts);
3407 else
3408 tsync_set_apts(pts);
3409 break;
3410 }
3411 case AMSTREAM_IOC_SET_CRC: {
3412 struct usr_crc_info_t crc_info;
3413 struct vdec_s *vdec;
3414
3415 if (copy_from_user(&crc_info, (void __user *)arg,
3416 sizeof(struct usr_crc_info_t))) {
3417 return -EFAULT;
3418 }
3419 /*
3420 pr_info("id %d, frame %d, y_crc: %08x, uv_crc: %08x\n", crc_info.id,
3421 crc_info.pic_num, crc_info.y_crc, crc_info.uv_crc);
3422 */
3423 vdec = vdec_get_vdec_by_id(crc_info.id);
3424 if (vdec == NULL)
3425 return -ENODEV;
3426 if (vdec->vfc.cmp_pool == NULL) {
3427 vdec->vfc.cmp_pool =
3428 vmalloc(USER_CMP_POOL_MAX_SIZE *
3429 sizeof(struct usr_crc_info_t));
3430 if (vdec->vfc.cmp_pool == NULL)
3431 return -ENOMEM;
3432 }
3433 if (vdec->vfc.usr_cmp_num >= USER_CMP_POOL_MAX_SIZE) {
3434 pr_info("warn: could not write any more, max %d",
3435 USER_CMP_POOL_MAX_SIZE);
3436 return -EFAULT;
3437 }
3438 memcpy(&vdec->vfc.cmp_pool[vdec->vfc.usr_cmp_num], &crc_info,
3439 sizeof(struct usr_crc_info_t));
3440 vdec->vfc.usr_cmp_num++;
3441 break;
3442 }
3443 case AMSTREAM_IOC_GET_CRC_CMP_RESULT: {
3444 int val, vdec_id;
3445 struct vdec_s *vdec;
3446
3447 if (get_user(val, (int __user *)arg)) {
3448 return -EFAULT;
3449 }
3450 vdec_id = val & 0x00ff;
3451 vdec = vdec_get_vdec_by_id(vdec_id);
3452 if (vdec == NULL)
3453 return -ENODEV;
3454 if (val & 0xff00)
3455 put_user(vdec->vfc.usr_cmp_num, (int *)arg);
3456 else
3457 put_user(vdec->vfc.usr_cmp_result, (int *)arg);
3458 /*
3459 pr_info("amstream get crc32 cmpare num %d result: %d\n",
3460 vdec->vfc.usr_cmp_num, vdec->vfc.usr_cmp_result);
3461 */
3462 break;
3463 }
3464 case AMSTREAM_IOC_INIT_EX_STBUF: {
3465 struct stream_buffer_metainfo parm;
3466 struct stream_buf_s *vbuf = &priv->vdec->vbuf;
3467
3468 if (copy_from_user(&parm, (void __user *)arg,
3469 sizeof(struct stream_buffer_metainfo))) {
3470 return -EFAULT;
3471 }
3472 stream_buffer_set_ext_buf(vbuf, parm.stbuf_start,
3473 parm.stbuf_size, parm.stbuf_flag);
3474 break;
3475 }
3476 case AMSTREAM_IOC_WR_STBUF_META: {
3477 struct stream_buffer_metainfo meta;
3478 struct stream_buf_s *vbuf = &priv->vdec->vbuf;
3479
3480 if (copy_from_user(&meta, (void __user *)arg,
3481 sizeof(struct stream_buffer_metainfo))) {
3482 return -EFAULT;
3483 }
3484 if (!vbuf->ext_buf_addr)
3485 return -ENODEV;
3486
3487 stream_buffer_meta_write(vbuf, &meta);
3488 break;
3489 }
3490 case AMSTREAM_IOC_GET_STBUF_STATUS: {
3491 struct stream_buffer_status st;
3492 struct stream_buf_s *pbuf = &priv->vdec->vbuf;
3493
3494 st.stbuf_start = pbuf->ext_buf_addr;
3495 st.stbuf_size = pbuf->buf_size;
3496 st.stbuf_rp = pbuf->ops->get_rp(pbuf);
3497 st.stbuf_wp = pbuf->ops->get_wp(pbuf);
3498 if (copy_to_user((void __user *)arg, &st,
3499 sizeof(struct stream_buffer_status))) {
3500 return -EFAULT;
3501 }
3502 break;
3503 }
3504 default:
3505 r = -ENOIOCTLCMD;
3506 break;
3507 }
3508
3509 return r;
3510}
3511
3512static long amstream_do_ioctl(struct port_priv_s *priv,
3513 unsigned int cmd, ulong arg)
3514{
3515 long r = 0;
3516
3517 switch (cmd) {
3518 case AMSTREAM_IOC_GET_VERSION:
3519 case AMSTREAM_IOC_GET:
3520 case AMSTREAM_IOC_SET:
3521 case AMSTREAM_IOC_GET_EX:
3522 case AMSTREAM_IOC_SET_EX:
3523 case AMSTREAM_IOC_GET_PTR:
3524 case AMSTREAM_IOC_SET_PTR:
3525 case AMSTREAM_IOC_SYSINFO:
3526 case AMSTREAM_IOC_GET_QOSINFO:
3527 case AMSTREAM_IOC_GET_MVDECINFO:
3528 case AMSTREAM_IOC_GET_AVINFO:
3529 r = amstream_do_ioctl_new(priv, cmd, arg);
3530 break;
3531 default:
3532 r = amstream_do_ioctl_old(priv, cmd, arg);
3533 break;
3534 }
3535 if (r != 0)
3536 pr_err("amstream_do_ioctl error :%lx, %x\n", r, cmd);
3537
3538 return r;
3539}
3540static long amstream_ioctl(struct file *file, unsigned int cmd, ulong arg)
3541{
3542 struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
3543 struct stream_port_s *this = priv->port;
3544
3545 if (!this)
3546 return -ENODEV;
3547
3548 return amstream_do_ioctl(priv, cmd, arg);
3549}
3550
3551#ifdef CONFIG_COMPAT
3552struct dec_sysinfo32 {
3553
3554 u32 format;
3555
3556 u32 width;
3557
3558 u32 height;
3559
3560 u32 rate;
3561
3562 u32 extra;
3563
3564 u32 status;
3565
3566 u32 ratio;
3567
3568 compat_uptr_t param;
3569
3570 u64 ratio64;
3571};
3572
3573struct am_ioctl_parm_ptr32 {
3574 union {
3575 compat_uptr_t pdata_audio_info;
3576 compat_uptr_t pdata_sub_info;
3577 compat_uptr_t pointer;
3578 char data[8];
3579 };
3580 u32 cmd;
3581 u32 len;
3582};
3583
3584static long amstream_ioc_setget_ptr(struct port_priv_s *priv,
3585 unsigned int cmd, struct am_ioctl_parm_ptr32 __user *arg)
3586{
3587 struct am_ioctl_parm_ptr __user *data;
3588 struct am_ioctl_parm_ptr32 param;
3589 int ret;
3590
3591 if (copy_from_user(&param,
3592 (void __user *)arg,
3593 sizeof(struct am_ioctl_parm_ptr32)))
3594 return -EFAULT;
3595
3596 data = compat_alloc_user_space(sizeof(*data));
3597 if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
3598 return -EFAULT;
3599
3600 if (put_user(param.cmd, &data->cmd) ||
3601 put_user(compat_ptr(param.pointer), &data->pointer) ||
3602 put_user(param.len, &data->len))
3603 return -EFAULT;
3604
3605 ret = amstream_do_ioctl(priv, cmd, (unsigned long)data);
3606 if (ret < 0)
3607 return ret;
3608 return 0;
3609
3610}
3611
3612static long amstream_set_sysinfo(struct port_priv_s *priv,
3613 struct dec_sysinfo32 __user *arg)
3614{
3615 struct dec_sysinfo __user *data;
3616 struct dec_sysinfo32 __user *data32 = arg;
3617 int ret;
3618 struct dec_sysinfo32 param;
3619
3620 if (copy_from_user(&param,
3621 (void __user *)arg,
3622 sizeof(struct dec_sysinfo32)))
3623 return -EFAULT;
3624
3625 data = compat_alloc_user_space(sizeof(*data));
3626 if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
3627 return -EFAULT;
3628 if (copy_in_user(data, data32, 7 * sizeof(u32)))
3629 return -EFAULT;
3630 if (put_user(compat_ptr(param.param), &data->param))
3631 return -EFAULT;
3632 if (copy_in_user(&data->ratio64, &data32->ratio64,
3633 sizeof(data->ratio64)))
3634 return -EFAULT;
3635
3636 ret = amstream_do_ioctl(priv, AMSTREAM_IOC_SYSINFO,
3637 (unsigned long)data);
3638 if (ret < 0)
3639 return ret;
3640
3641 if (copy_in_user(&arg->format, &data->format, 7 * sizeof(u32)) ||
3642 copy_in_user(&arg->ratio64, &data->ratio64,
3643 sizeof(arg->ratio64)))
3644 return -EFAULT;
3645
3646 return 0;
3647}
3648
3649
3650struct userdata_param32_t {
3651 uint32_t version;
3652 uint32_t instance_id; /*input, 0~9*/
3653 uint32_t buf_len; /*input*/
3654 uint32_t data_size; /*output*/
3655 compat_uptr_t pbuf_addr; /*input*/
3656 struct userdata_meta_info_t meta_info; /*output*/
3657};
3658
3659
3660static long amstream_ioc_get_userdata(struct port_priv_s *priv,
3661 struct userdata_param32_t __user *arg)
3662{
3663 struct userdata_param_t __user *data;
3664 struct userdata_param32_t __user *data32 = arg;
3665 int ret;
3666 struct userdata_param32_t param;
3667
3668
3669 if (copy_from_user(&param,
3670 (void __user *)arg,
3671 sizeof(struct userdata_param32_t)))
3672 return -EFAULT;
3673
3674 data = compat_alloc_user_space(sizeof(*data));
3675 if (!access_ok(VERIFY_WRITE, data, sizeof(*data)))
3676 return -EFAULT;
3677
3678 if (copy_in_user(data, data32, 4 * sizeof(u32)))
3679 return -EFAULT;
3680
3681 if (copy_in_user(&data->meta_info, &data32->meta_info,
3682 sizeof(data->meta_info)))
3683 return -EFAULT;
3684
3685 if (put_user(compat_ptr(param.pbuf_addr), &data->pbuf_addr))
3686 return -EFAULT;
3687
3688 ret = amstream_do_ioctl(priv, AMSTREAM_IOC_UD_BUF_READ,
3689 (unsigned long)data);
3690 if (ret < 0)
3691 return ret;
3692
3693 if (copy_in_user(&data32->version, &data->version, 4 * sizeof(u32)) ||
3694 copy_in_user(&data32->meta_info, &data->meta_info,
3695 sizeof(data32->meta_info)))
3696 return -EFAULT;
3697
3698 return 0;
3699}
3700
3701
3702static long amstream_compat_ioctl(struct file *file,
3703 unsigned int cmd, ulong arg)
3704{
3705 s32 r = 0;
3706 struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
3707
3708 switch (cmd) {
3709 case AMSTREAM_IOC_GET_VERSION:
3710 case AMSTREAM_IOC_GET:
3711 case AMSTREAM_IOC_SET:
3712 case AMSTREAM_IOC_GET_EX:
3713 case AMSTREAM_IOC_SET_EX:
3714 return amstream_do_ioctl(priv, cmd, (ulong)compat_ptr(arg));
3715 case AMSTREAM_IOC_GET_PTR:
3716 case AMSTREAM_IOC_SET_PTR:
3717 return amstream_ioc_setget_ptr(priv, cmd, compat_ptr(arg));
3718 case AMSTREAM_IOC_SYSINFO:
3719 return amstream_set_sysinfo(priv, compat_ptr(arg));
3720 case AMSTREAM_IOC_UD_BUF_READ:
3721 return amstream_ioc_get_userdata(priv, compat_ptr(arg));
3722 default:
3723 return amstream_do_ioctl(priv, cmd, (ulong)compat_ptr(arg));
3724 }
3725
3726 return r;
3727}
3728#endif
3729
3730static ssize_t ports_show(struct class *class, struct class_attribute *attr,
3731 char *buf)
3732{
3733 int i;
3734 char *pbuf = buf;
3735 struct stream_port_s *p = NULL;
3736
3737 for (i = 0; i < amstream_port_num; i++) {
3738 p = &ports[i];
3739 /*name */
3740 pbuf += sprintf(pbuf, "%s\t:\n", p->name);
3741 /*type */
3742 pbuf += sprintf(pbuf, "\ttype:%d( ", p->type);
3743 if (p->type & PORT_TYPE_VIDEO)
3744 pbuf += sprintf(pbuf, "%s ", "Video");
3745 if (p->type & PORT_TYPE_AUDIO)
3746 pbuf += sprintf(pbuf, "%s ", "Audio");
3747 if (p->type & PORT_TYPE_MPTS)
3748 pbuf += sprintf(pbuf, "%s ", "TS");
3749 if (p->type & PORT_TYPE_MPPS)
3750 pbuf += sprintf(pbuf, "%s ", "PS");
3751 if (p->type & PORT_TYPE_ES)
3752 pbuf += sprintf(pbuf, "%s ", "ES");
3753 if (p->type & PORT_TYPE_RM)
3754 pbuf += sprintf(pbuf, "%s ", "RM");
3755 if (p->type & PORT_TYPE_SUB)
3756 pbuf += sprintf(pbuf, "%s ", "Subtitle");
3757 if (p->type & PORT_TYPE_SUB_RD)
3758 pbuf += sprintf(pbuf, "%s ", "Subtitle_Read");
3759 if (p->type & PORT_TYPE_USERDATA)
3760 pbuf += sprintf(pbuf, "%s ", "userdata");
3761 pbuf += sprintf(pbuf, ")\n");
3762 /*flag */
3763 pbuf += sprintf(pbuf, "\tflag:%d( ", p->flag);
3764 if (p->flag & PORT_FLAG_IN_USE)
3765 pbuf += sprintf(pbuf, "%s ", "Used");
3766 else
3767 pbuf += sprintf(pbuf, "%s ", "Unused");
3768 if ((p->type & PORT_TYPE_VIDEO) == 0) {
3769 if (p->flag & PORT_FLAG_INITED)
3770 pbuf += sprintf(pbuf, "%s ", "inited");
3771 else
3772 pbuf += sprintf(pbuf, "%s ", "uninited");
3773 }
3774 pbuf += sprintf(pbuf, ")\n");
3775 /*others */
3776 pbuf += sprintf(pbuf, "\tVformat:%d\n",
3777 (p->flag & PORT_FLAG_VFORMAT) ? p->vformat : -1);
3778 pbuf += sprintf(pbuf, "\tAformat:%d\n",
3779 (p->flag & PORT_FLAG_AFORMAT) ? p->aformat : -1);
3780 pbuf += sprintf(pbuf, "\tVid:%d\n",
3781 (p->flag & PORT_FLAG_VID) ? p->vid : -1);
3782 pbuf += sprintf(pbuf, "\tAid:%d\n",
3783 (p->flag & PORT_FLAG_AID) ? p->aid : -1);
3784 pbuf += sprintf(pbuf, "\tSid:%d\n",
3785 (p->flag & PORT_FLAG_SID) ? p->sid : -1);
3786 pbuf += sprintf(pbuf, "\tPCRid:%d\n",
3787 (p->pcr_inited == 1) ? p->pcrid : -1);
3788 pbuf += sprintf(pbuf, "\tachannel:%d\n", p->achanl);
3789 pbuf += sprintf(pbuf, "\tasamprate:%d\n", p->asamprate);
3790 pbuf += sprintf(pbuf, "\tadatawidth:%d\n\n", p->adatawidth);
3791 }
3792 return pbuf - buf;
3793}
3794
3795static int show_vbuf_status_cb(struct stream_buf_s *p, char *buf)
3796{
3797 char *pbuf = buf;
3798
3799 if (!p->buf_start)
3800 return 0;
3801 /*type */
3802 pbuf += sprintf(pbuf, "Video-%d buffer:", p->id);
3803 /*flag */
3804 pbuf += sprintf(pbuf, "\tflag:%d( ", p->flag);
3805 if (p->flag & BUF_FLAG_ALLOC)
3806 pbuf += sprintf(pbuf, "%s ", "Alloc");
3807 else
3808 pbuf += sprintf(pbuf, "%s ", "Unalloc");
3809 if (p->flag & BUF_FLAG_IN_USE)
3810 pbuf += sprintf(pbuf, "%s ", "Used");
3811 else
3812 pbuf += sprintf(pbuf, "%s ", "Noused");
3813 if (p->flag & BUF_FLAG_PARSER)
3814 pbuf += sprintf(pbuf, "%s ", "Parser");
3815 else
3816 pbuf += sprintf(pbuf, "%s ", "noParser");
3817 if (p->flag & BUF_FLAG_FIRST_TSTAMP)
3818 pbuf += sprintf(pbuf, "%s ", "firststamp");
3819 else
3820 pbuf += sprintf(pbuf, "%s ", "nofirststamp");
3821 pbuf += sprintf(pbuf, ")\n");
3822
3823 /*buf stats */
3824 pbuf += sprintf(pbuf, "\tbuf addr:%p\n", (void *)p->buf_start);
3825 pbuf += sprintf(pbuf, "\tbuf size:%#x\n", p->buf_size);
3826 pbuf += sprintf(pbuf, "\tbuf canusesize:%#x\n", p->canusebuf_size);
3827 pbuf += sprintf(pbuf, "\tbuf regbase:%#lx\n", p->reg_base);
3828
3829 if (p->reg_base && p->flag & BUF_FLAG_IN_USE) {
3830 pbuf += sprintf(pbuf, "\tbuf level:%#x\n",
3831 stbuf_level(p));
3832 pbuf += sprintf(pbuf, "\tbuf space:%#x\n",
3833 stbuf_space(p));
3834 pbuf += sprintf(pbuf, "\tbuf read pointer:%#x\n",
3835 stbuf_rp(p));
3836 } else
3837 pbuf += sprintf(pbuf, "\tbuf no used.\n");
3838
3839 return pbuf - buf;
3840}
3841
3842static ssize_t bufs_show(struct class *class, struct class_attribute *attr,
3843 char *buf)
3844{
3845 int i;
3846 char *pbuf = buf;
3847 struct stream_buf_s *p = NULL;
3848 char buf_type[][12] = { "Video", "Audio", "Subtitle",
3849 "UserData", "HEVC" };
3850
3851 for (i = 0; i < amstream_buf_num; i++) {
3852 p = &bufs[i];
3853
3854 if (!p->buf_start)
3855 continue;
3856
3857 /*type */
3858 pbuf += sprintf(pbuf, "%s buffer:", buf_type[p->type]);
3859 /*flag */
3860 pbuf += sprintf(pbuf, "\tflag:%d( ", p->flag);
3861 if (p->flag & BUF_FLAG_ALLOC)
3862 pbuf += sprintf(pbuf, "%s ", "Alloc");
3863 else
3864 pbuf += sprintf(pbuf, "%s ", "Unalloc");
3865 if (p->flag & BUF_FLAG_IN_USE)
3866 pbuf += sprintf(pbuf, "%s ", "Used");
3867 else
3868 pbuf += sprintf(pbuf, "%s ", "Noused");
3869 if (p->flag & BUF_FLAG_PARSER)
3870 pbuf += sprintf(pbuf, "%s ", "Parser");
3871 else
3872 pbuf += sprintf(pbuf, "%s ", "noParser");
3873 if (p->flag & BUF_FLAG_FIRST_TSTAMP)
3874 pbuf += sprintf(pbuf, "%s ", "firststamp");
3875 else
3876 pbuf += sprintf(pbuf, "%s ", "nofirststamp");
3877 pbuf += sprintf(pbuf, ")\n");
3878 /*buf stats */
3879
3880 pbuf += sprintf(pbuf, "\tbuf addr:%p\n", (void *)p->buf_start);
3881
3882 if (p->type != BUF_TYPE_SUBTITLE) {
3883 pbuf += sprintf(pbuf, "\tbuf size:%#x\n", p->buf_size);
3884 pbuf += sprintf(pbuf,
3885 "\tbuf canusesize:%#x\n",
3886 p->canusebuf_size);
3887 pbuf += sprintf(pbuf,
3888 "\tbuf regbase:%#lx\n", p->reg_base);
3889
3890 if (p->reg_base && p->flag & BUF_FLAG_IN_USE) {
3891 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M6) {
3892 /* TODO: mod gate */
3893 /* switch_mod_gate_by_name("vdec", 1);*/
3894 amports_switch_gate("vdec", 1);
3895 }
3896 pbuf += sprintf(pbuf, "\tbuf level:%#x\n",
3897 stbuf_level(p));
3898 pbuf += sprintf(pbuf, "\tbuf space:%#x\n",
3899 stbuf_space(p));
3900 pbuf += sprintf(pbuf,
3901 "\tbuf read pointer:%#x\n",
3902 stbuf_rp(p));
3903 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_M6) {
3904 /* TODO: mod gate */
3905 /* switch_mod_gate_by_name("vdec", 0);*/
3906 amports_switch_gate("vdec", 0);
3907 }
3908 } else
3909 pbuf += sprintf(pbuf, "\tbuf no used.\n");
3910
3911 if (p->type == BUF_TYPE_USERDATA) {
3912 pbuf += sprintf(pbuf,
3913 "\tbuf write pointer:%#x\n",
3914 p->buf_wp);
3915 pbuf += sprintf(pbuf,
3916 "\tbuf read pointer:%#x\n",
3917 p->buf_rp);
3918 }
3919 } else {
3920 u32 sub_wp, sub_rp, data_size;
3921
3922 sub_wp = stbuf_sub_wp_get();
3923 sub_rp = stbuf_sub_rp_get();
3924 if (sub_wp >= sub_rp)
3925 data_size = sub_wp - sub_rp;
3926 else
3927 data_size = p->buf_size - sub_rp + sub_wp;
3928 pbuf += sprintf(pbuf, "\tbuf size:%#x\n", p->buf_size);
3929 pbuf +=
3930 sprintf(pbuf, "\tbuf canusesize:%#x\n",
3931 p->canusebuf_size);
3932 pbuf +=
3933 sprintf(pbuf, "\tbuf start:%#x\n",
3934 stbuf_sub_start_get());
3935 pbuf += sprintf(pbuf,
3936 "\tbuf write pointer:%#x\n", sub_wp);
3937 pbuf += sprintf(pbuf,
3938 "\tbuf read pointer:%#x\n", sub_rp);
3939 pbuf += sprintf(pbuf, "\tbuf level:%#x\n", data_size);
3940 }
3941
3942 pbuf += sprintf(pbuf, "\tbuf first_stamp:%#x\n",
3943 p->first_tstamp);
3944 pbuf += sprintf(pbuf, "\tbuf wcnt:%#x\n\n", p->wcnt);
3945 pbuf += sprintf(pbuf, "\tbuf max_buffer_delay_ms:%dms\n",
3946 p->max_buffer_delay_ms);
3947
3948 if (p->reg_base && p->flag & BUF_FLAG_IN_USE) {
3949 int calc_delayms = 0;
3950 u32 bitrate = 0, avg_bitrate = 0;
3951
3952 calc_delayms = calculation_stream_delayed_ms(
3953 (p->type == BUF_TYPE_AUDIO) ? PTS_TYPE_AUDIO :
3954 PTS_TYPE_VIDEO,
3955 &bitrate,
3956 &avg_bitrate);
3957
3958 if (calc_delayms >= 0) {
3959 pbuf += sprintf(pbuf,
3960 "\tbuf current delay:%dms\n",
3961 calc_delayms);
3962 pbuf += sprintf(pbuf,
3963 "\tbuf bitrate latest:%dbps,avg:%dbps\n",
3964 bitrate, avg_bitrate);
3965 pbuf += sprintf(pbuf,
3966 "\tbuf time after last pts:%d ms\n",
3967 calculation_stream_ext_delayed_ms
3968 ((p->type == BUF_TYPE_AUDIO) ? PTS_TYPE_AUDIO :
3969 PTS_TYPE_VIDEO));
3970
3971 pbuf += sprintf(pbuf,
3972 "\tbuf time after last write data :%d ms\n",
3973 (int)(jiffies_64 -
3974 p->last_write_jiffies64) * 1000 / HZ);
3975 }
3976 }
3977 if (p->write_thread) {
3978 pbuf += sprintf(pbuf,
3979 "\twrite thread:%d/%d,fifo %d:%d,passed:%d\n",
3980 threadrw_buffer_level(p),
3981 threadrw_buffer_size(p),
3982 threadrw_datafifo_len(p),
3983 threadrw_freefifo_len(p),
3984 threadrw_passed_len(p)
3985 );
3986 }
3987 }
3988
3989 pbuf += show_stream_buffer_status(pbuf, show_vbuf_status_cb);
3990
3991 return pbuf - buf;
3992}
3993
3994static ssize_t videobufused_show(struct class *class,
3995 struct class_attribute *attr, char *buf)
3996{
3997 char *pbuf = buf;
3998 struct stream_buf_s *p = NULL;
3999
4000 p = &bufs[0];
4001
4002 if (p->flag & BUF_FLAG_IN_USE)
4003 pbuf += sprintf(pbuf, "%d ", 1);
4004 else
4005 pbuf += sprintf(pbuf, "%d ", 0);
4006 return 1;
4007}
4008
4009static ssize_t vcodec_profile_show(struct class *class,
4010 struct class_attribute *attr, char *buf)
4011{
4012 return vcodec_profile_read(buf);
4013}
4014
4015static int reset_canuse_buferlevel(int levelx10000)
4016{
4017 int i;
4018 struct stream_buf_s *p = NULL;
4019
4020 if (levelx10000 >= 0 && levelx10000 <= 10000)
4021 use_bufferlevelx10000 = levelx10000;
4022 else
4023 use_bufferlevelx10000 = 10000;
4024 for (i = 0; i < amstream_buf_num; i++) {
4025 p = &bufs[i];
4026 p->canusebuf_size = ((p->buf_size / 1024) *
4027 use_bufferlevelx10000 / 10000) * 1024;
4028 p->canusebuf_size += 1023;
4029 p->canusebuf_size &= ~1023;
4030 if (p->canusebuf_size > p->buf_size)
4031 p->canusebuf_size = p->buf_size;
4032 }
4033 return 0;
4034}
4035
4036static ssize_t show_canuse_buferlevel(struct class *class,
4037 struct class_attribute *attr, char *buf)
4038{
4039 ssize_t size = sprintf(buf,
4040 "use_bufferlevel=%d/10000[=(set range[ 0~10000])=\n",
4041 use_bufferlevelx10000);
4042 return size;
4043}
4044
4045static ssize_t store_canuse_buferlevel(struct class *class,
4046 struct class_attribute *attr,
4047 const char *buf, size_t size)
4048{
4049 unsigned int val;
4050 ssize_t ret;
4051
4052 /*ret = sscanf(buf, "%d", &val);*/
4053 ret = kstrtoint(buf, 0, &val);
4054
4055 if (ret != 0)
4056 return -EINVAL;
4057 val = val;
4058 reset_canuse_buferlevel(val);
4059 return size;
4060}
4061
4062static ssize_t store_maxdelay(struct class *class,
4063 struct class_attribute *attr,
4064 const char *buf, size_t size)
4065{
4066 unsigned int val;
4067 ssize_t ret;
4068 int i;
4069
4070 /*ret = sscanf(buf, "%d", &val);*/
4071 ret = kstrtoint(buf, 0, &val);
4072 if (ret != 0)
4073 return -EINVAL;
4074 for (i = 0; i < amstream_buf_num; i++)
4075 bufs[i].max_buffer_delay_ms = val;
4076 return size;
4077}
4078
4079static ssize_t show_maxdelay(struct class *class,
4080 struct class_attribute *attr,
4081 char *buf)
4082{
4083 ssize_t size = 0;
4084
4085 size += sprintf(buf, "%dms video max buffered data delay ms\n",
4086 bufs[0].max_buffer_delay_ms);
4087 size += sprintf(buf, "%dms audio max buffered data delay ms\n",
4088 bufs[1].max_buffer_delay_ms);
4089 return size;
4090}
4091
4092static ssize_t audio_path_store(struct class *class,
4093 struct class_attribute *attr,
4094 const char *buf, size_t size)
4095{
4096 unsigned int val = 0;
4097 int i;
4098 ssize_t ret;
4099 struct stream_buf_s *pabuf = &bufs[BUF_TYPE_AUDIO];
4100 struct stream_port_s *this;
4101 ret = kstrtoint(buf, 0, &val);
4102 if (ret != 0)
4103 return -EINVAL;
4104 if (val != 1)
4105 return -EINVAL;
4106 for (i = 0; i < MAX_AMSTREAM_PORT_NUM; i++) {
4107 if (strcmp(ports[i].name, "amstream_mpts") == 0 ||
4108 strcmp(ports[i].name, "amstream_mpts_sched") == 0) {
4109 this = &ports[i];
4110 if ((this->flag & PORT_FLAG_AFORMAT) != 0) {
4111 pr_info("audio_port_reset %s\n", ports[i].name);
4112 audio_port_reset(this, pabuf);
4113 }
4114 }
4115 }
4116 return size;
4117}
4118
4119ssize_t dump_stream_show(struct class *class,
4120 struct class_attribute *attr, char *buf)
4121{
4122 char *p_buf = buf;
4123
4124 p_buf += sprintf(p_buf, "\nmdkir -p /data/tmp -m 777;setenforce 0;\n\n");
4125 p_buf += sprintf(p_buf, "video:\n\t echo 0 > /sys/class/amstream/dump_stream;\n");
4126 p_buf += sprintf(p_buf, "hevc :\n\t echo 4 > /sys/class/amstream/dump_stream;\n");
4127
4128 return p_buf - buf;
4129}
4130
4131#define DUMP_STREAM_FILE "/data/tmp/dump_stream.h264"
4132ssize_t dump_stream_store(struct class *class,
4133 struct class_attribute *attr,
4134 const char *buf, size_t size)
4135{
4136 struct stream_buf_s *p_buf;
4137 int ret = 0, id = 0;
4138 unsigned int stride, remain, level, vmap_size;
4139 int write_size;
4140 void *stbuf_vaddr;
4141 unsigned long offset;
4142 struct file *fp;
4143 mm_segment_t old_fs;
4144 loff_t fpos;
4145
4146 ret = sscanf(buf, "%d", &id);
4147 if (ret < 0) {
4148 pr_info("paser buf id fail, default id = 0\n");
4149 id = 0;
4150 }
4151 if (id != BUF_TYPE_VIDEO && id != BUF_TYPE_HEVC) {
4152 pr_info("buf id out of range, max %d, id %d, set default id 0\n", BUF_MAX_NUM - 1, id);
4153 id = 0;
4154 }
4155 p_buf = get_stream_buffer(id);
4156 if (!p_buf) {
4157 pr_info("get buf fail, id %d\n", id);
4158 return size;
4159 }
4160 if ((!p_buf->buf_size) || (p_buf->is_secure) || (!(p_buf->flag & BUF_FLAG_IN_USE))) {
4161 pr_info("buf size %d, is_secure %d, in_use %d, it can not dump\n",
4162 p_buf->buf_size, p_buf->is_secure, (p_buf->flag & BUF_FLAG_IN_USE));
4163 return size;
4164 }
4165
4166 level = stbuf_level(p_buf);
4167 if (!level || level > p_buf->buf_size) {
4168 pr_info("stream buf level %d, buf size %d, error return\n", level, p_buf->buf_size);
4169 return size;
4170 }
4171
4172 fp = filp_open(DUMP_STREAM_FILE, O_CREAT | O_RDWR, 0666);
4173 if (IS_ERR(fp)) {
4174 fp = NULL;
4175 pr_info("create dump stream file failed\n");
4176 return size;
4177 }
4178
4179 offset = p_buf->buf_start;
4180 remain = level;
4181 stride = SZ_1M;
4182 vmap_size = 0;
4183 fpos = 0;
4184 pr_info("create file success, it will dump from addr 0x%lx, size 0x%x\n", offset, remain);
4185 while (remain > 0) {
4186 if (remain > stride)
4187 vmap_size = stride;
4188 else {
4189 stride = remain;
4190 vmap_size = stride;
4191 }
4192
4193 stbuf_vaddr = codec_mm_vmap(offset, vmap_size);
4194 if (stbuf_vaddr == NULL) {
4195 stride >>= 1;
4196 pr_info("vmap fail change vmap stide size 0x%x\n", stride);
4197 continue;
4198 }
4199 codec_mm_dma_flush(stbuf_vaddr, vmap_size, DMA_FROM_DEVICE);
4200
4201 old_fs = get_fs();
4202 set_fs(KERNEL_DS);
4203 write_size = vfs_write(fp, stbuf_vaddr, vmap_size, &fpos);
4204 if (write_size < vmap_size) {
4205 write_size += vfs_write(fp, stbuf_vaddr + write_size, vmap_size - write_size, &fpos);
4206 pr_info("fail write retry, total %d, write %d\n", vmap_size, write_size);
4207 if (write_size < vmap_size) {
4208 pr_info("retry fail, interrupt dump stream, break\n");
4209 break;
4210 }
4211 }
4212 set_fs(old_fs);
4213 vfs_fsync(fp, 0);
4214 pr_info("vmap_size 0x%x dump size 0x%x\n", vmap_size, write_size);
4215
4216 offset += vmap_size;
4217 remain -= vmap_size;
4218 codec_mm_unmap_phyaddr(stbuf_vaddr);
4219 }
4220
4221 filp_close(fp, current->files);
4222 pr_info("dump stream buf end\n");
4223
4224 return size;
4225}
4226
4227
4228
4229
4230static struct class_attribute amstream_class_attrs[] = {
4231 __ATTR_RO(ports),
4232 __ATTR_RO(bufs),
4233 __ATTR_RO(vcodec_profile),
4234 __ATTR_RO(videobufused),
4235 __ATTR(canuse_buferlevel, S_IRUGO | S_IWUSR | S_IWGRP,
4236 show_canuse_buferlevel, store_canuse_buferlevel),
4237 __ATTR(max_buffer_delay_ms, S_IRUGO | S_IWUSR | S_IWGRP, show_maxdelay,
4238 store_maxdelay),
4239 __ATTR(reset_audio_port, S_IRUGO | S_IWUSR | S_IWGRP,
4240 NULL, audio_path_store),
4241 __ATTR(dump_stream, S_IRUGO | S_IWUSR | S_IWGRP,
4242 dump_stream_show, dump_stream_store),
4243 __ATTR_NULL
4244};
4245
4246static struct class amstream_class = {
4247 .name = "amstream",
4248 .class_attrs = amstream_class_attrs,
4249};
4250
4251int amstream_request_firmware_from_sys(const char *file_name,
4252 char *buf, int size)
4253{
4254 const struct firmware *firmware;
4255 int err = 0;
4256 struct device *micro_dev;
4257
4258 pr_info("try load %s ...", file_name);
4259 micro_dev = device_create(&amstream_class,
4260 NULL, MKDEV(AMSTREAM_MAJOR, 100),
4261 NULL, "videodec");
4262 if (micro_dev == NULL) {
4263 pr_err("device_create failed =%d\n", err);
4264 return -1;
4265 }
4266 err = request_firmware(&firmware, file_name, micro_dev);
4267 if (err < 0) {
4268 pr_err("can't load the %s,err=%d\n", file_name, err);
4269 goto error1;
4270 }
4271 if (firmware->size > size) {
4272 pr_err("not enough memory size for audiodsp code\n");
4273 err = -ENOMEM;
4274 goto release;
4275 }
4276
4277 memcpy(buf, (char *)firmware->data, firmware->size);
4278 /*mb(); don't need it*/
4279 pr_err("load mcode size=%zd\n mcode name %s\n", firmware->size,
4280 file_name);
4281 err = firmware->size;
4282release:
4283 release_firmware(firmware);
4284error1:
4285 device_destroy(&amstream_class, MKDEV(AMSTREAM_MAJOR, 100));
4286 return err;
4287}
4288
4289int videobufused_show_fun(const char *trigger, int id, char *sbuf, int size)
4290{
4291 int ret = -1;
4292 void *buf, *getbuf = NULL;
4293 if (size < PAGE_SIZE) {
4294 getbuf = (void *)__get_free_page(GFP_KERNEL);
4295 if (!getbuf)
4296 return -ENOMEM;
4297 buf = getbuf;
4298 } else {
4299 buf = sbuf;
4300 }
4301
4302 switch (id) {
4303 case 0:
4304 ret = videobufused_show(NULL, NULL , buf);
4305 break;
4306 default:
4307 ret = -1;
4308 }
4309 if (ret > 0 && getbuf != NULL) {
4310 ret = min_t(int, ret, size);
4311 strncpy(sbuf, buf, ret);
4312 }
4313 if (getbuf != NULL)
4314 free_page((unsigned long)getbuf);
4315 return ret;
4316}
4317
4318static struct mconfig amports_configs[] = {
4319 MC_PI32("def_4k_vstreambuf_sizeM", &def_4k_vstreambuf_sizeM),
4320 MC_PI32("def_vstreambuf_sizeM", &def_vstreambuf_sizeM),
4321 MC_PI32("slow_input", &slow_input),
4322 MC_FUN_ID("videobufused", videobufused_show_fun, NULL, 0),
4323};
4324
4325
4326
4327/*static struct resource memobj;*/
4328static int amstream_probe(struct platform_device *pdev)
4329{
4330 int i;
4331 int r;
4332 struct stream_port_s *st;
4333
4334 pr_err("Amlogic A/V streaming port init\n");
4335
4336 amstream_port_num = MAX_AMSTREAM_PORT_NUM;
4337 amstream_buf_num = BUF_MAX_NUM;
4338/*
4339 * r = of_reserved_mem_device_init(&pdev->dev);
4340 * if (r == 0)
4341 * pr_info("of probe done");
4342 * else {
4343 * r = -ENOMEM;
4344 * return r;
4345 * }
4346 */
4347 r = class_register(&amstream_class);
4348 if (r) {
4349 pr_err("amstream class create fail.\n");
4350 return r;
4351 }
4352
4353 r = astream_dev_register();
4354 if (r)
4355 return r;
4356
4357 r = register_chrdev(AMSTREAM_MAJOR, "amstream", &amstream_fops);
4358 if (r < 0) {
4359 pr_err("Can't allocate major for amstreaming device\n");
4360
4361 goto error2;
4362 }
4363
4364 amstream_dev_class = class_create(THIS_MODULE, DEVICE_NAME);
4365
4366 for (st = &ports[0], i = 0; i < amstream_port_num; i++, st++) {
4367 st->class_dev = device_create(amstream_dev_class, NULL,
4368 MKDEV(AMSTREAM_MAJOR, i), NULL,
4369 ports[i].name);
4370 }
4371
4372 amstream_adec_status = NULL;
4373 if (tsdemux_class_register() != 0) {
4374 r = (-EIO);
4375 goto error3;
4376 }
4377 tsdemux_tsync_func_init();
4378 init_waitqueue_head(&amstream_sub_wait);
4379 init_waitqueue_head(&amstream_userdata_wait);
4380 reset_canuse_buferlevel(10000);
4381 amstream_pdev = pdev;
4382 amports_clock_gate_init(&amstream_pdev->dev);
4383
4384 /*prealloc fetch buf to avoid no continue buffer later...*/
4385 stbuf_fetch_init();
4386 REG_PATH_CONFIGS("media.amports", amports_configs);
4387
4388 /* poweroff the decode core because dos can not be reset when reboot */
4389 if (get_cpu_major_id() == AM_MESON_CPU_MAJOR_ID_G12A)
4390 vdec_power_reset();
4391
4392 return 0;
4393
4394 /*
4395 * error4:
4396 * tsdemux_class_unregister();
4397 */
4398error3:
4399 for (st = &ports[0], i = 0; i < amstream_port_num; i++, st++)
4400 device_destroy(amstream_dev_class, MKDEV(AMSTREAM_MAJOR, i));
4401 class_destroy(amstream_dev_class);
4402error2:
4403 unregister_chrdev(AMSTREAM_MAJOR, "amstream");
4404 /* error1: */
4405 astream_dev_unregister();
4406 return r;
4407}
4408
4409static int amstream_remove(struct platform_device *pdev)
4410{
4411 int i;
4412 struct stream_port_s *st;
4413
4414 if (bufs[BUF_TYPE_AUDIO].flag & BUF_FLAG_ALLOC)
4415 stbuf_change_size(&bufs[BUF_TYPE_AUDIO], 0, false);
4416 stbuf_fetch_release();
4417 tsdemux_class_unregister();
4418 for (st = &ports[0], i = 0; i < amstream_port_num; i++, st++)
4419 device_destroy(amstream_dev_class, MKDEV(AMSTREAM_MAJOR, i));
4420
4421 class_destroy(amstream_dev_class);
4422
4423 unregister_chrdev(AMSTREAM_MAJOR, "amstream");
4424
4425 class_unregister(&amstream_class);
4426
4427 astream_dev_unregister();
4428
4429 amstream_adec_status = NULL;
4430
4431 pr_err("Amlogic A/V streaming port release\n");
4432
4433 return 0;
4434}
4435
4436void set_adec_func(int (*adec_func)(struct adec_status *))
4437{
4438 amstream_adec_status = adec_func;
4439}
4440
4441void wakeup_sub_poll(void)
4442{
4443 atomic_inc(&subdata_ready);
4444 wake_up_interruptible(&amstream_sub_wait);
4445}
4446
4447int get_sub_type(void)
4448{
4449 return sub_type;
4450}
4451
4452u32 get_audio_reset(void)
4453{
4454 return amstream_audio_reset;
4455}
4456
4457/*get pes buffers */
4458
4459struct stream_buf_s *get_stream_buffer(int id)
4460{
4461 if (id >= BUF_MAX_NUM)
4462 return 0;
4463 return &bufs[id];
4464}
4465EXPORT_SYMBOL(get_stream_buffer);
4466static const struct of_device_id amlogic_mesonstream_dt_match[] = {
4467 {
4468 .compatible = "amlogic, codec, streambuf",
4469 },
4470 {},
4471};
4472
4473static struct platform_driver amstream_driver = {
4474 .probe = amstream_probe,
4475 .remove = amstream_remove,
4476 .driver = {
4477 .owner = THIS_MODULE,
4478 .name = "mesonstream",
4479 .of_match_table = amlogic_mesonstream_dt_match,
4480 }
4481};
4482
4483static int __init amstream_module_init(void)
4484{
4485 if (platform_driver_register(&amstream_driver)) {
4486 pr_err("failed to register amstream module\n");
4487 return -ENODEV;
4488 }
4489
4490 if (subtitle_init()) {
4491 pr_err("failed to init subtitle\n");
4492 return -ENODEV;
4493 }
4494
4495 return 0;
4496}
4497
4498static void __exit amstream_module_exit(void)
4499{
4500 platform_driver_unregister(&amstream_driver);
4501 subtitle_exit();
4502}
4503
4504module_init(amstream_module_init);
4505module_exit(amstream_module_exit);
4506
4507module_param(force_dv_mode, uint, 0664);
4508MODULE_PARM_DESC(force_dv_mode,
4509 "\n force_dv_mode \n");
4510
4511module_param(def_4k_vstreambuf_sizeM, uint, 0664);
4512MODULE_PARM_DESC(def_4k_vstreambuf_sizeM,
4513 "\nDefault video Stream buf size for 4K MByptes\n");
4514
4515module_param(def_vstreambuf_sizeM, uint, 0664);
4516MODULE_PARM_DESC(def_vstreambuf_sizeM,
4517 "\nDefault video Stream buf size for < 1080p MByptes\n");
4518
4519module_param(slow_input, uint, 0664);
4520MODULE_PARM_DESC(slow_input, "\n amstream slow_input\n");
4521
4522MODULE_DESCRIPTION("AMLOGIC streaming port driver");
4523MODULE_LICENSE("GPL");
4524MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>");
4525