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