• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = &para;
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 = &para;
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 = &para;
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(&para, 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(&para.vinfo, &vinfo, sizeof(struct vdec_info));
2981 			if (copy_to_user((void *)arg, &para, 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 = &para;
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 = &param;
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(&param,
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(&param,
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(&param,
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