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