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