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