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