• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * drivers/amlogic/media/stream_input/parser/tsdemux.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 
18 #include <linux/kernel.h>
19 #include <linux/types.h>
20 #include <linux/errno.h>
21 #include <linux/interrupt.h>
22 #include <linux/wait.h>
23 #include <linux/sched.h>
24 #include <linux/fs.h>
25 #include <linux/dma-mapping.h>
26 #include <linux/amlogic/media/frame_sync/ptsserv.h>
27 #include <linux/amlogic/media/frame_sync/tsync.h>
28 #include <linux/amlogic/media/utils/amstream.h>
29 #include <linux/amlogic/media/vfm/vframe_provider.h>
30 #include <linux/device.h>
31 #include <linux/delay.h>
32 
33 #include <linux/uaccess.h>
34 /* #include <mach/am_regs.h> */
35 #include <linux/clk.h>
36 /* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
37 /* #include <mach/mod_gate.h> */
38 /* #endif */
39 
40 #include "../../frame_provider/decoder/utils/vdec.h"
41 #include <linux/amlogic/media/utils/vdec_reg.h>
42 #include "../amports/streambuf_reg.h"
43 #include "../amports/streambuf.h"
44 #include <linux/amlogic/media/utils/amports_config.h>
45 #include <linux/amlogic/media/frame_sync/tsync_pcr.h>
46 
47 #include "tsdemux.h"
48 #include <linux/reset.h>
49 #include "../amports/amports_priv.h"
50 
51 #define MAX_DRM_PACKAGE_SIZE 0x500000
52 
53 
54 static const char tsdemux_fetch_id[] = "tsdemux-fetch-id";
55 static const char tsdemux_irq_id[] = "tsdemux-irq-id";
56 
57 static u32 curr_pcr_num = 0xffff;
58 static u32 curr_vid_id = 0xffff;
59 static u32 curr_aud_id = 0xffff;
60 static u32 curr_sub_id = 0xffff;
61 static u32 curr_pcr_id = 0xffff;
62 
63 static DECLARE_WAIT_QUEUE_HEAD(wq);
64 static u32 fetch_done;
65 static u32 discontinued_counter;
66 static u32 first_pcr;
67 static u8 pcrscr_valid;
68 static u8 pcraudio_valid;
69 static u8 pcrvideo_valid;
70 static u8 pcr_init_flag;
71 
72 static int demux_skipbyte;
73 
74 static struct tsdemux_ops *demux_ops;
75 static DEFINE_SPINLOCK(demux_ops_lock);
76 
enable_demux_driver(void)77 static int enable_demux_driver(void)
78 {
79 	return demux_ops ? 1 : 0;
80 }
81 
tsdemux_set_ops(struct tsdemux_ops * ops)82 void tsdemux_set_ops(struct tsdemux_ops *ops)
83 {
84 	unsigned long flags;
85 
86 	spin_lock_irqsave(&demux_ops_lock, flags);
87 	demux_ops = ops;
88 	spin_unlock_irqrestore(&demux_ops_lock, flags);
89 }
90 EXPORT_SYMBOL(tsdemux_set_ops);
91 
tsdemux_set_reset_flag_ext(void)92 int tsdemux_set_reset_flag_ext(void)
93 {
94 	int r = 0;
95 
96 	if (demux_ops && demux_ops->set_reset_flag)
97 		r = demux_ops->set_reset_flag();
98 
99 	return r;
100 }
101 
tsdemux_set_reset_flag(void)102 int tsdemux_set_reset_flag(void)
103 {
104 	unsigned long flags;
105 	int r;
106 
107 	spin_lock_irqsave(&demux_ops_lock, flags);
108 	r = tsdemux_set_reset_flag_ext();
109 	spin_unlock_irqrestore(&demux_ops_lock, flags);
110 
111 	return r;
112 }
113 
tsdemux_reset(void)114 static int tsdemux_reset(void)
115 {
116 	unsigned long flags;
117 	int r = 0;
118 
119 	spin_lock_irqsave(&demux_ops_lock, flags);
120 	if (demux_ops && demux_ops->reset) {
121 		tsdemux_set_reset_flag_ext();
122 		r = demux_ops->reset();
123 	}
124 	spin_unlock_irqrestore(&demux_ops_lock, flags);
125 
126 	return r;
127 }
128 
tsdemux_request_irq(irq_handler_t handler,void * data)129 static int tsdemux_request_irq(irq_handler_t handler, void *data)
130 {
131 	unsigned long flags;
132 	int r = 0;
133 
134 	spin_lock_irqsave(&demux_ops_lock, flags);
135 	if (demux_ops && demux_ops->request_irq)
136 		r = demux_ops->request_irq(handler, data);
137 	spin_unlock_irqrestore(&demux_ops_lock, flags);
138 
139 	return r;
140 }
141 
tsdemux_free_irq(void)142 static int tsdemux_free_irq(void)
143 {
144 	unsigned long flags;
145 	int r = 0;
146 
147 	spin_lock_irqsave(&demux_ops_lock, flags);
148 	if (demux_ops && demux_ops->free_irq)
149 		r = demux_ops->free_irq();
150 	spin_unlock_irqrestore(&demux_ops_lock, flags);
151 
152 	return r;
153 }
154 
tsdemux_set_vid(int vpid)155 static int tsdemux_set_vid(int vpid)
156 {
157 	unsigned long flags;
158 	int r = 0;
159 
160 	spin_lock_irqsave(&demux_ops_lock, flags);
161 	if (demux_ops && demux_ops->set_vid)
162 		r = demux_ops->set_vid(vpid);
163 	spin_unlock_irqrestore(&demux_ops_lock, flags);
164 
165 	return r;
166 }
167 
tsdemux_set_aid(int apid)168 static int tsdemux_set_aid(int apid)
169 {
170 	unsigned long flags;
171 	int r = 0;
172 
173 	spin_lock_irqsave(&demux_ops_lock, flags);
174 	if (demux_ops && demux_ops->set_aid)
175 		r = demux_ops->set_aid(apid);
176 	spin_unlock_irqrestore(&demux_ops_lock, flags);
177 
178 	return r;
179 }
180 
tsdemux_set_sid(int spid)181 static int tsdemux_set_sid(int spid)
182 {
183 	unsigned long flags;
184 	int r = 0;
185 
186 	spin_lock_irqsave(&demux_ops_lock, flags);
187 	if (demux_ops && demux_ops->set_sid)
188 		r = demux_ops->set_sid(spid);
189 	spin_unlock_irqrestore(&demux_ops_lock, flags);
190 
191 	return r;
192 }
193 
tsdemux_set_pcrid(int pcrpid)194 static int tsdemux_set_pcrid(int pcrpid)
195 {
196 	unsigned long flags;
197 	int r = 0;
198 
199 	spin_lock_irqsave(&demux_ops_lock, flags);
200 	if (demux_ops && demux_ops->set_pcrid)
201 		r = demux_ops->set_pcrid(pcrpid);
202 	spin_unlock_irqrestore(&demux_ops_lock, flags);
203 
204 	return r;
205 }
206 
tsdemux_set_skip_byte(int skipbyte)207 static int tsdemux_set_skip_byte(int skipbyte)
208 {
209 	unsigned long flags;
210 	int r = 0;
211 
212 	spin_lock_irqsave(&demux_ops_lock, flags);
213 	if (demux_ops && demux_ops->set_skipbyte)
214 		r = demux_ops->set_skipbyte(skipbyte);
215 	spin_unlock_irqrestore(&demux_ops_lock, flags);
216 
217 	return r;
218 }
219 
tsdemux_config(void)220 static int tsdemux_config(void)
221 {
222 	return 0;
223 }
224 
225 static void tsdemux_pcr_set(unsigned int pcr);
226 /*TODO irq*/
227 /* bit 15 ---------------*/
228 /* bit 12 --VIDEO_PTS[32]*/
229 /* bit 0  ---------------*/
230 /*Read the 13th bit of STB_PTS_DTS_STATUS register
231 correspond to the highest bit of video pts*/
tsdemux_isr(int irq,void * dev_id)232 static irqreturn_t tsdemux_isr(int irq, void *dev_id)
233 {
234 	u32 int_status = 0;
235 	int id = (long)dev_id;
236 
237 	if (!enable_demux_driver()) {
238 		int_status = READ_DEMUX_REG(STB_INT_STATUS);
239 	} else {
240 		if (id == 0)
241 			int_status = READ_DEMUX_REG(STB_INT_STATUS);
242 		else if (id == 1)
243 			int_status = READ_DEMUX_REG(STB_INT_STATUS_2);
244 		else if (id == 2)
245 			int_status = READ_DEMUX_REG(STB_INT_STATUS_3);
246 	}
247 
248 	if (int_status & (1 << NEW_PDTS_READY)) {
249 		if (!enable_demux_driver()) {
250 			u32 pdts_status = READ_DEMUX_REG(STB_PTS_DTS_STATUS);
251 			u64 vpts;
252 
253 			vpts = READ_MPEG_REG(VIDEO_PTS_DEMUX);
254 			vpts &= 0x00000000FFFFFFFF;
255 			if (pdts_status & 0x1000) {
256 				vpts = vpts | (1LL<<32);
257 			}
258 
259 			if (pdts_status & (1 << VIDEO_PTS_READY))
260 				pts_checkin_wrptr_pts33(PTS_TYPE_VIDEO,
261 					READ_DEMUX_REG(VIDEO_PDTS_WR_PTR),
262 					vpts);
263 
264 			if (pdts_status & (1 << AUDIO_PTS_READY))
265 				pts_checkin_wrptr(PTS_TYPE_AUDIO,
266 					READ_DEMUX_REG(AUDIO_PDTS_WR_PTR),
267 					READ_DEMUX_REG(AUDIO_PTS_DEMUX));
268 
269 			WRITE_DEMUX_REG(STB_PTS_DTS_STATUS, pdts_status);
270 		} else {
271 #define DMX_READ_REG(i, r)\
272 	((i) ? ((i == 1) ? READ_DEMUX_REG(r##_2) : \
273 		READ_DEMUX_REG(r##_3)) : READ_DEMUX_REG(r))
274 			u64 vpts;
275 			u32 pdts_status = DMX_READ_REG(id, STB_PTS_DTS_STATUS);
276 			vpts = DMX_READ_REG(id, VIDEO_PTS_DEMUX);
277 			vpts &= 0x00000000FFFFFFFF;
278 			if (pdts_status & 0x1000) {
279 				vpts = vpts | (1LL<<32);
280 			}
281 
282 			if (pdts_status & (1 << VIDEO_PTS_READY))
283 				pts_checkin_wrptr_pts33(PTS_TYPE_VIDEO,
284 					DMX_READ_REG(id, VIDEO_PDTS_WR_PTR),
285 					vpts);
286 
287 			if (pdts_status & (1 << AUDIO_PTS_READY))
288 				pts_checkin_wrptr(PTS_TYPE_AUDIO,
289 					DMX_READ_REG(id, AUDIO_PDTS_WR_PTR),
290 					DMX_READ_REG(id, AUDIO_PTS_DEMUX));
291 
292 			if (id == 1)
293 				WRITE_DEMUX_REG(STB_PTS_DTS_STATUS_2,
294 							pdts_status);
295 			else if (id == 2)
296 				WRITE_DEMUX_REG(STB_PTS_DTS_STATUS_3,
297 							pdts_status);
298 			else
299 				WRITE_DEMUX_REG(STB_PTS_DTS_STATUS,
300 							pdts_status);
301 		}
302 	}
303 	if (int_status & (1 << DIS_CONTINUITY_PACKET)) {
304 		discontinued_counter++;
305 		/* pr_info("discontinued counter=%d\n",discontinued_counter); */
306 	}
307 	if (int_status & (1 << SUB_PES_READY)) {
308 		/* TODO: put data to somewhere */
309 		/* pr_info("subtitle pes ready\n"); */
310 		wakeup_sub_poll();
311 	}
312 	if (int_status & (1<<PCR_READY)) {
313 		unsigned int pcr_pts = 0xffffffff;
314 		pcr_pts = DMX_READ_REG(id, PCR_DEMUX);
315 		tsdemux_pcr_set(pcr_pts);
316 	}
317 
318 	if (!enable_demux_driver())
319 		WRITE_DEMUX_REG(STB_INT_STATUS, int_status);
320 
321 	return IRQ_HANDLED;
322 }
323 
parser_isr(int irq,void * dev_id)324 static irqreturn_t parser_isr(int irq, void *dev_id)
325 {
326 	u32 int_status = READ_PARSER_REG(PARSER_INT_STATUS);
327 
328 	WRITE_PARSER_REG(PARSER_INT_STATUS, int_status);
329 
330 	if (int_status & PARSER_INTSTAT_FETCH_CMD) {
331 		fetch_done = 1;
332 
333 		wake_up_interruptible(&wq);
334 	}
335 
336 	return IRQ_HANDLED;
337 }
338 
_tsdemux_write(const char __user * buf,size_t count,int isphybuf)339 static ssize_t _tsdemux_write(const char __user *buf, size_t count,
340 							  int isphybuf)
341 {
342 	size_t r = count;
343 	const char __user *p = buf;
344 	u32 len;
345 	int ret;
346 	dma_addr_t dma_addr = 0;
347 
348 	if (r > 0) {
349 		if (isphybuf)
350 			len = count;
351 		else {
352 			len = min_t(size_t, r, FETCHBUF_SIZE);
353 			if (copy_from_user(fetchbuf, p, len))
354 				return -EFAULT;
355 
356 			dma_addr =
357 				dma_map_single(amports_get_dma_device(),
358 						fetchbuf,
359 						FETCHBUF_SIZE, DMA_TO_DEVICE);
360 			if (dma_mapping_error(amports_get_dma_device(),
361 						dma_addr))
362 				return -EFAULT;
363 
364 
365 		}
366 
367 		fetch_done = 0;
368 
369 		wmb();		/* Ensure fetchbuf  contents visible */
370 
371 		if (isphybuf) {
372 			u32 buf_32 = (unsigned long)buf & 0xffffffff;
373 			WRITE_PARSER_REG(PARSER_FETCH_ADDR, buf_32);
374 		} else {
375 			WRITE_PARSER_REG(PARSER_FETCH_ADDR, dma_addr);
376 			dma_unmap_single(amports_get_dma_device(), dma_addr,
377 					FETCHBUF_SIZE, DMA_TO_DEVICE);
378 		}
379 
380 		WRITE_PARSER_REG(PARSER_FETCH_CMD, (7 << FETCH_ENDIAN) | len);
381 
382 
383 		ret =
384 			wait_event_interruptible_timeout(wq, fetch_done != 0,
385 					HZ / 2);
386 		if (ret == 0) {
387 			WRITE_PARSER_REG(PARSER_FETCH_CMD, 0);
388 			pr_info("write timeout, retry\n");
389 			return -EAGAIN;
390 		} else if (ret < 0)
391 			return -ERESTARTSYS;
392 
393 		p += len;
394 		r -= len;
395 	}
396 
397 	return count - r;
398 }
399 
400 #define PCR_EN                     12
401 
reset_pcr_regs(void)402 static int reset_pcr_regs(void)
403 {
404 	u32 pcr_num;
405 	u32 pcr_regs = 0;
406 
407 	if (curr_pcr_id >= 0x1FFF)
408 		return 0;
409 	/* set paramater to fetch pcr */
410 	pcr_num = 0;
411 	if (curr_pcr_id == curr_vid_id)
412 		pcr_num = 0;
413 	else if (curr_pcr_id == curr_aud_id)
414 		pcr_num = 1;
415 	else if (curr_pcr_id == curr_sub_id)
416 		pcr_num = 2;
417 	else
418 		pcr_num = 3;
419 	if (pcr_num != curr_pcr_num) {
420 		u32 clk_unit = 0;
421 		u32 clk_81 = 0;
422 		struct clk *clk;
423 		//clk = clk_get(NULL,"clk81");
424 		clk= devm_clk_get(amports_get_dma_device(),"clk_81");
425 		if (IS_ERR(clk) || clk == 0) {
426 			pr_info("[%s:%d] error clock\n", __func__, __LINE__);
427 			return 0;
428 		}
429 		clk_81 = clk_get_rate(clk);
430 		clk_unit = clk_81 / 90000;
431 		pr_info("[%s:%d] clk_81 = %x clk_unit =%x\n", __func__,
432 				__LINE__, clk_81, clk_unit);
433 		pcr_regs = 1 << PCR_EN | clk_unit;
434 		pr_info("[tsdemux_init] the set pcr_regs =%x\n", pcr_regs);
435 		if (READ_DEMUX_REG(TS_HIU_CTL_2) & 0x80) {
436 			WRITE_DEMUX_REG(PCR90K_CTL_2, pcr_regs);
437 			WRITE_DEMUX_REG(ASSIGN_PID_NUMBER_2, pcr_num);
438 			pr_info("[tsdemux_init] To use device 2,pcr_num=%d\n",
439 					pcr_num);
440 			pr_info("tsdemux_init] the read  pcr_regs= %x\n",
441 				READ_DEMUX_REG(PCR90K_CTL_2));
442 		} else if (READ_DEMUX_REG(TS_HIU_CTL_3) & 0x80) {
443 			WRITE_DEMUX_REG(PCR90K_CTL_3, pcr_regs);
444 			WRITE_DEMUX_REG(ASSIGN_PID_NUMBER_3, pcr_num);
445 			pr_info("[tsdemux_init] To use device 3,pcr_num=%d\n",
446 					pcr_num);
447 			pr_info("tsdemux_init] the read  pcr_regs= %x\n",
448 				READ_DEMUX_REG(PCR90K_CTL_3));
449 		} else {
450 			WRITE_DEMUX_REG(PCR90K_CTL, pcr_regs);
451 			WRITE_DEMUX_REG(ASSIGN_PID_NUMBER, pcr_num);
452 			pr_info("[tsdemux_init] To use device 1,pcr_num=%d\n",
453 					pcr_num);
454 			pr_info("tsdemux_init] the read  pcr_regs= %x\n",
455 				READ_DEMUX_REG(PCR90K_CTL));
456 		}
457 		curr_pcr_num = pcr_num;
458 	}
459 	return 1;
460 }
461 
tsdemux_init(u32 vid,u32 aid,u32 sid,u32 pcrid,bool is_hevc,struct vdec_s * vdec)462 s32 tsdemux_init(u32 vid, u32 aid, u32 sid, u32 pcrid, bool is_hevc,
463 		struct vdec_s *vdec)
464 {
465 	s32 r;
466 	u32 parser_sub_start_ptr;
467 	u32 parser_sub_end_ptr;
468 	u32 parser_sub_rp;
469 	pcrvideo_valid = 0;
470 	pcraudio_valid = 0;
471 	pcr_init_flag = 0;
472 
473 	/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
474 	/*TODO clk */
475 	/*
476 	 *switch_mod_gate_by_type(MOD_DEMUX, 1);
477 	 */
478 	/* #endif */
479 
480 	amports_switch_gate("demux", 1);
481 
482 	parser_sub_start_ptr = READ_PARSER_REG(PARSER_SUB_START_PTR);
483 	parser_sub_end_ptr = READ_PARSER_REG(PARSER_SUB_END_PTR);
484 	parser_sub_rp = READ_PARSER_REG(PARSER_SUB_RP);
485 
486 	WRITE_RESET_REG(RESET1_REGISTER, RESET_PARSER);
487 
488 	if (enable_demux_driver()) {
489 		tsdemux_reset();
490 	} else {
491 		WRITE_RESET_REG(RESET1_REGISTER, RESET_PARSER | RESET_DEMUXSTB);
492 
493 		WRITE_DEMUX_REG(STB_TOP_CONFIG, 0);
494 		WRITE_DEMUX_REG(DEMUX_CONTROL, 0);
495 	}
496 
497 	/* set PID filter */
498 	pr_info
499 		("tsdemux video_pid = 0x%x, audio_pid = 0x%x,",
500 		 vid, aid);
501 	pr_info
502 		("sub_pid = 0x%x, pcrid = 0x%x\n",
503 		 sid, pcrid);
504 
505 	if (!enable_demux_driver()) {
506 		WRITE_DEMUX_REG(FM_WR_DATA,
507 				(((vid < 0x1fff)
508 					? (vid & 0x1fff) | (VIDEO_PACKET << 13)
509 					: 0xffff) << 16)
510 				| ((aid < 0x1fff)
511 					? (aid & 0x1fff) | (AUDIO_PACKET << 13)
512 					: 0xffff));
513 		WRITE_DEMUX_REG(FM_WR_ADDR, 0x8000);
514 		while (READ_DEMUX_REG(FM_WR_ADDR) & 0x8000)
515 			;
516 
517 		WRITE_DEMUX_REG(FM_WR_DATA,
518 				(((sid < 0x1fff)
519 					? (sid & 0x1fff) | (SUB_PACKET << 13)
520 					: 0xffff) << 16)
521 				| 0xffff);
522 		WRITE_DEMUX_REG(FM_WR_ADDR, 0x8001);
523 		while (READ_DEMUX_REG(FM_WR_ADDR) & 0x8000)
524 			;
525 
526 		WRITE_DEMUX_REG(MAX_FM_COMP_ADDR, 1);
527 
528 		WRITE_DEMUX_REG(STB_INT_MASK, 0);
529 		WRITE_DEMUX_REG(STB_INT_STATUS, 0xffff);
530 
531 		/* TS data path */
532 		WRITE_DEMUX_REG(FEC_INPUT_CONTROL, 0x7000);
533 		WRITE_DEMUX_REG(DEMUX_MEM_REQ_EN,
534 				(1 << VIDEO_PACKET) |
535 				(1 << AUDIO_PACKET) | (1 << SUB_PACKET));
536 		WRITE_DEMUX_REG(DEMUX_ENDIAN,
537 				(7 << OTHER_ENDIAN) |
538 				(7 << BYPASS_ENDIAN) | (0 << SECTION_ENDIAN));
539 		WRITE_DEMUX_REG(TS_HIU_CTL, 1 << USE_HI_BSF_INTERFACE);
540 		WRITE_DEMUX_REG(TS_FILE_CONFIG,
541 				(demux_skipbyte << 16) |
542 				(6 << DES_OUT_DLY) |
543 				(3 << TRANSPORT_SCRAMBLING_CONTROL_ODD) |
544 				(1 << TS_HIU_ENABLE) | (4 << FEC_FILE_CLK_DIV));
545 
546 		/* enable TS demux */
547 		WRITE_DEMUX_REG(DEMUX_CONTROL,
548 				(1 << STB_DEMUX_ENABLE) |
549 				(1 << KEEP_DUPLICATE_PACKAGE));
550 	}
551 
552 	if (fetchbuf == 0) {
553 		pr_info("%s: no fetchbuf\n", __func__);
554 		return -ENOMEM;
555 	}
556 
557 	/* hook stream buffer with PARSER */
558 	if (has_hevc_vdec() && is_hevc) {
559 		WRITE_PARSER_REG(PARSER_VIDEO_START_PTR, vdec->input.start);
560 		WRITE_PARSER_REG(PARSER_VIDEO_END_PTR, vdec->input.start +
561 			vdec->input.size - 8);
562 
563 		if (vdec_single(vdec)) {
564 			CLEAR_PARSER_REG_MASK(PARSER_ES_CONTROL,
565 					ES_VID_MAN_RD_PTR);
566 			/* set vififo_vbuf_rp_sel=>hevc */
567 			WRITE_VREG(DOS_GEN_CTRL0, 3 << 1);
568 			/* set use_parser_vbuf_wp */
569 			SET_VREG_MASK(HEVC_STREAM_CONTROL,
570 					  (1 << 3) | (0 << 4));
571 			/* set stream_fetch_enable */
572 			SET_VREG_MASK(HEVC_STREAM_CONTROL, 1);
573 			/* set stream_buffer_hole with 256 bytes */
574 			SET_VREG_MASK(HEVC_STREAM_FIFO_CTL,
575 					  (1 << 29));
576 		} else {
577 			SET_PARSER_REG_MASK(PARSER_ES_CONTROL,
578 					ES_VID_MAN_RD_PTR);
579 			WRITE_PARSER_REG(PARSER_VIDEO_WP, vdec->input.start);
580 			WRITE_PARSER_REG(PARSER_VIDEO_RP, vdec->input.start);
581 		}
582 	} else {
583 		WRITE_PARSER_REG(PARSER_VIDEO_START_PTR, vdec->input.start);
584 		WRITE_PARSER_REG(PARSER_VIDEO_END_PTR, vdec->input.start +
585 			vdec->input.size - 8);
586 
587 		if (vdec_single(vdec)) {
588 			CLEAR_PARSER_REG_MASK(PARSER_ES_CONTROL,
589 					ES_VID_MAN_RD_PTR);
590 
591 			WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
592 			CLEAR_VREG_MASK(VLD_MEM_VIFIFO_BUF_CNTL,
593 					MEM_BUFCTRL_INIT);
594 			/* set vififo_vbuf_rp_sel=>vdec */
595 			if (has_hevc_vdec())
596 				WRITE_VREG(DOS_GEN_CTRL0, 0);
597 		} else {
598 			SET_PARSER_REG_MASK(PARSER_ES_CONTROL,
599 					ES_VID_MAN_RD_PTR);
600 			WRITE_PARSER_REG(PARSER_VIDEO_WP, vdec->input.start);
601 			WRITE_PARSER_REG(PARSER_VIDEO_RP, vdec->input.start);
602 		}
603 	}
604 
605 	WRITE_PARSER_REG(PARSER_AUDIO_START_PTR,
606 				   READ_AIU_REG(AIU_MEM_AIFIFO_START_PTR));
607 	WRITE_PARSER_REG(PARSER_AUDIO_END_PTR,
608 				   READ_AIU_REG(AIU_MEM_AIFIFO_END_PTR));
609 	CLEAR_PARSER_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR);
610 
611 	WRITE_PARSER_REG(PARSER_CONFIG,
612 				   (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) |
613 				   (1 << PS_CFG_MAX_ES_WR_CYCLE_BIT) |
614 				   (16 << PS_CFG_MAX_FETCH_CYCLE_BIT));
615 
616 	WRITE_AIU_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
617 	CLEAR_AIU_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
618 
619 	if (!enable_demux_driver() || ((sid > 0) && (sid < 0x1fff))) {
620 		WRITE_PARSER_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr);
621 		WRITE_PARSER_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr);
622 		WRITE_PARSER_REG(PARSER_SUB_RP, parser_sub_rp);
623 	}
624 	SET_PARSER_REG_MASK(PARSER_ES_CONTROL,
625 			(7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR);
626 
627 	/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
628 	if (vid != 0xffff) {
629 		if (has_hevc_vdec())
630 			r = pts_start((is_hevc) ? PTS_TYPE_HEVC : PTS_TYPE_VIDEO);
631 		else
632 			/* #endif */
633 			r = pts_start(PTS_TYPE_VIDEO);
634 		if ((r < 0) && (r != -EBUSY)) {
635 			pr_info("Video pts start failed.(%d)\n", r);
636 			goto err1;
637 		}
638 	}
639 
640 	if (aid != 0xffff) {
641 		r = pts_start(PTS_TYPE_AUDIO);
642 		if ((r < 0) && (r != -EBUSY)) {
643 			pr_info("Audio pts start failed.(%d)\n", r);
644 			goto err2;
645 		}
646 	}
647 	/*TODO irq */
648 
649 	r = vdec_request_irq(PARSER_IRQ, parser_isr,
650 			"tsdemux-fetch", (void *)tsdemux_fetch_id);
651 
652 	if (r)
653 		goto err3;
654 
655 	WRITE_PARSER_REG(PARSER_INT_STATUS, 0xffff);
656 	WRITE_PARSER_REG(PARSER_INT_ENABLE,
657 			PARSER_INTSTAT_FETCH_CMD << PARSER_INT_HOST_EN_BIT);
658 
659 	WRITE_PARSER_REG(PARSER_VIDEO_HOLE, 0x400);
660 	WRITE_PARSER_REG(PARSER_AUDIO_HOLE, 0x400);
661 
662 	discontinued_counter = 0;
663 
664 	if (!enable_demux_driver()) {
665 		/*TODO irq */
666 
667 		r = vdec_request_irq(DEMUX_IRQ, tsdemux_isr,
668 				"tsdemux-irq", (void *)tsdemux_irq_id);
669 
670 		WRITE_DEMUX_REG(STB_INT_MASK, (1 << SUB_PES_READY)
671 					   | (1 << NEW_PDTS_READY)
672 					   | (1 << DIS_CONTINUITY_PACKET));
673 		if (r)
674 			goto err4;
675 	} else {
676 		tsdemux_config();
677 		tsdemux_request_irq(tsdemux_isr, (void *)tsdemux_irq_id);
678 		if (vid < 0x1FFF) {
679 			curr_vid_id = vid;
680 			tsdemux_set_vid(vid);
681 			pcrvideo_valid = 1;
682 		}
683 		if (aid < 0x1FFF) {
684 			curr_aud_id = aid;
685 			tsdemux_set_aid(aid);
686 			pcraudio_valid = 1;
687 		}
688 		if (sid < 0x1FFF) {
689 			curr_sub_id = sid;
690 			tsdemux_set_sid(sid);
691 		}
692 
693 		curr_pcr_id = pcrid;
694 		pcrscr_valid = reset_pcr_regs();
695 
696 		if ((pcrid < 0x1FFF) && (pcrid != vid) && (pcrid != aid)
697 			&& (pcrid != sid))
698 			tsdemux_set_pcrid(pcrid);
699 	}
700 
701 	first_pcr = 0;
702 
703 	return 0;
704 
705 err4:
706 	/*TODO irq */
707 
708 	if (!enable_demux_driver())
709 		vdec_free_irq(PARSER_IRQ, (void *)tsdemux_fetch_id);
710 
711 err3:
712 	pts_stop(PTS_TYPE_AUDIO);
713 err2:
714 	/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8 */
715 	if (has_hevc_vdec())
716 		pts_stop((is_hevc) ? PTS_TYPE_HEVC : PTS_TYPE_VIDEO);
717 	else
718 		/* #endif */
719 		pts_stop(PTS_TYPE_VIDEO);
720 err1:
721 	pr_info("TS Demux init failed.\n");
722 	return -ENOENT;
723 }
724 
tsdemux_release(void)725 void tsdemux_release(void)
726 {
727 	pcrscr_valid = 0;
728 	first_pcr = 0;
729 	pcr_init_flag = 0;
730 
731 	WRITE_PARSER_REG(PARSER_INT_ENABLE, 0);
732 	WRITE_PARSER_REG(PARSER_VIDEO_HOLE, 0);
733 	WRITE_PARSER_REG(PARSER_AUDIO_HOLE, 0);
734 
735 	/*TODO irq */
736 
737 	vdec_free_irq(PARSER_IRQ, (void *)tsdemux_fetch_id);
738 
739 	if (!enable_demux_driver()) {
740 		WRITE_DEMUX_REG(STB_INT_MASK, 0);
741 		/*TODO irq */
742 
743 		vdec_free_irq(DEMUX_IRQ, (void *)tsdemux_irq_id);
744 	} else {
745 
746 		tsdemux_set_aid(0xffff);
747 		tsdemux_set_vid(0xffff);
748 		tsdemux_set_sid(0xffff);
749 		tsdemux_set_pcrid(0xffff);
750 		tsdemux_free_irq();
751 
752 		curr_vid_id = 0xffff;
753 		curr_aud_id = 0xffff;
754 		curr_sub_id = 0xffff;
755 		curr_pcr_id = 0xffff;
756 		curr_pcr_num = 0xffff;
757 	}
758 
759 	pts_stop(PTS_TYPE_VIDEO);
760 	pts_stop(PTS_TYPE_AUDIO);
761 
762 	WRITE_RESET_REG(RESET1_REGISTER, RESET_PARSER);
763 #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC
764 	SET_PARSER_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR);
765 	WRITE_PARSER_REG(PARSER_VIDEO_WP, 0);
766 	WRITE_PARSER_REG(PARSER_VIDEO_RP, 0);
767 #endif
768 
769 	/* #if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6 */
770 	/*TODO clk */
771 	/*
772 	 *switch_mod_gate_by_type(MOD_DEMUX, 0);
773 	 */
774 	/* #endif */
775 	amports_switch_gate("demux", 0);
776 
777 }
778 EXPORT_SYMBOL(tsdemux_release);
779 
limited_delay_check(struct file * file,struct stream_buf_s * vbuf,struct stream_buf_s * abuf,const char __user * buf,size_t count)780 static int limited_delay_check(struct file *file,
781 		struct stream_buf_s *vbuf,
782 		struct stream_buf_s *abuf,
783 		const char __user *buf, size_t count)
784 {
785 	struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
786 	struct stream_port_s *port = priv->port;
787 	int write_size;
788 
789 	if (!((port->flag & PORT_FLAG_VID) &&
790 		(port->flag & PORT_FLAG_AID))) {
791 		struct stream_buf_s *buf =
792 			(port->flag & PORT_FLAG_VID) ? vbuf : abuf;
793 
794 		return min_t(int, count, stbuf_space(buf));
795 	}
796 
797 	if (vbuf->max_buffer_delay_ms > 0 && abuf->max_buffer_delay_ms > 0 &&
798 		stbuf_level(vbuf) > 1024 && stbuf_level(abuf) > 256) {
799 		int vdelay =
800 			calculation_stream_delayed_ms(PTS_TYPE_VIDEO,
801 					NULL, NULL);
802 		int adelay =
803 			calculation_stream_delayed_ms(PTS_TYPE_AUDIO,
804 					NULL, NULL);
805 		/*max wait 100ms,if timeout,try again top level. */
806 		int maxretry = 10;
807 		/*too big  delay,do wait now. */
808 		/*if noblock mode,don't do wait. */
809 		if (!(file->f_flags & O_NONBLOCK)) {
810 			while (vdelay > vbuf->max_buffer_delay_ms
811 				   && adelay > abuf->max_buffer_delay_ms
812 				   && maxretry-- > 0) {
813 				msleep(20);
814 				vdelay =
815 					calculation_stream_delayed_ms
816 					(PTS_TYPE_VIDEO, NULL, NULL);
817 				adelay =
818 					calculation_stream_delayed_ms
819 					(PTS_TYPE_AUDIO, NULL, NULL);
820 			}
821 		}
822 		if (vdelay > vbuf->max_buffer_delay_ms
823 			&& adelay > abuf->max_buffer_delay_ms)
824 			return 0;
825 	}
826 	write_size = min(stbuf_space(vbuf), stbuf_space(abuf));
827 	write_size = min_t(int, count, write_size);
828 	return write_size;
829 }
830 
drm_tswrite(struct file * file,struct stream_buf_s * vbuf,struct stream_buf_s * abuf,const char __user * buf,size_t count)831 ssize_t drm_tswrite(struct file *file,
832 					struct stream_buf_s *vbuf,
833 					struct stream_buf_s *abuf,
834 					const char __user *buf, size_t count)
835 {
836 	s32 r;
837 	u32 realcount = count;
838 	u32 re_count = count;
839 	u32 havewritebytes = 0;
840 
841 	struct drm_info tmpmm;
842 	struct drm_info *drm = &tmpmm;
843 	u32 res = 0;
844 	int isphybuf = 0;
845 	unsigned long realbuf;
846 
847 	struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
848 	struct stream_port_s *port = priv->port;
849 	size_t wait_size, write_size;
850 
851 	if (buf == NULL || count == 0)
852 		return -EINVAL;
853 
854 	res = copy_from_user(drm, buf, sizeof(struct drm_info));
855 	if (res) {
856 		pr_info("drm kmalloc failed res[%d]\n", res);
857 		return -EFAULT;
858 	}
859 
860 	if (drm->drm_flag == TYPE_DRMINFO && drm->drm_level == DRM_LEVEL1) {
861 		/* buf only has drminfo not have esdata; */
862 		if (drm->drm_pktsize <= MAX_DRM_PACKAGE_SIZE)
863 			realcount = drm->drm_pktsize;
864 		else {
865 			pr_err("drm package size is error, size is %u\n", drm->drm_pktsize);
866 			return -EINVAL;
867 		}
868 		realbuf = drm->drm_phy;
869 		isphybuf = 1;
870 	} else
871 	    realbuf = (unsigned long)buf;
872 	/* pr_info("drm->drm_flag = 0x%x,realcount = %d , buf = 0x%x ",*/
873 	   /*drm->drm_flag,realcount, buf); */
874 
875 	count = realcount;
876 
877 	while (count > 0) {
878 		if ((stbuf_space(vbuf) < count) ||
879 				(stbuf_space(abuf) < count)) {
880 			if (file->f_flags & O_NONBLOCK) {
881 				int v_stbuf_space = stbuf_space(vbuf);
882 				int a_stbuf_space = stbuf_space(abuf);
883 
884 				write_size = min(v_stbuf_space, a_stbuf_space);
885 				/*have 188 bytes,write now., */
886 				if (write_size <= 188)
887 					return -EAGAIN;
888 			} else {
889 				wait_size =
890 					min(stbuf_canusesize(vbuf) / 8,
891 						stbuf_canusesize(abuf) / 4);
892 				if ((port->flag & PORT_FLAG_VID)
893 					&& (stbuf_space(vbuf) < wait_size)) {
894 					r = stbuf_wait_space(vbuf, wait_size);
895 
896 					if (r < 0) {
897 						pr_info
898 						("write no space--- ");
899 						pr_info
900 						("no space,%d--%d,r-%d\n",
901 						 stbuf_space(vbuf),
902 						 stbuf_space(abuf), r);
903 						return r;
904 					}
905 				}
906 
907 				if ((port->flag & PORT_FLAG_AID)
908 					&& (stbuf_space(abuf) < wait_size)) {
909 					r = stbuf_wait_space(abuf, wait_size);
910 
911 					if (r < 0) {
912 						pr_info
913 						("write no stbuf_wait_space--");
914 						pr_info
915 						("no space,%d--%d,r-%d\n",
916 						 stbuf_space(vbuf),
917 						 stbuf_space(abuf), r);
918 						return r;
919 					}
920 				}
921 			}
922 		}
923 
924 		if ((port->flag & PORT_FLAG_VID) &&
925 			(port->flag & PORT_FLAG_AID)) {
926 			write_size = min(stbuf_space(vbuf), stbuf_space(abuf));
927 			write_size = min(count, write_size);
928 		} else {
929 			struct stream_buf_s *buf =
930 				(port->flag & PORT_FLAG_VID) ? vbuf : abuf;
931 
932 			write_size = min_t(int, count, stbuf_space(buf));
933 		}
934 		/* pr_info("write_size = %d,count = %d,\n",*/
935 		   /*write_size, count); */
936 		if (write_size > 0)
937 			r = _tsdemux_write((const char __user *)realbuf,
938 					 write_size, isphybuf);
939 		else
940 			return -EAGAIN;
941 
942 		havewritebytes += r;
943 
944 		/* pr_info("havewritebytes = %d, r = %d,\n",*/
945 		   /*havewritebytes,  r); */
946 		if (havewritebytes == realcount)
947 			break;	/* write ok; */
948 		else if (havewritebytes > realcount)
949 			pr_info(" error ! write too much\n");
950 
951 		count -= r;
952 	}
953 	return re_count;
954 }
955 
tsdemux_write(struct file * file,struct stream_buf_s * vbuf,struct stream_buf_s * abuf,const char __user * buf,size_t count)956 ssize_t tsdemux_write(struct file *file,
957 					  struct stream_buf_s *vbuf,
958 					  struct stream_buf_s *abuf,
959 					  const char __user *buf, size_t count)
960 {
961 	s32 r;
962 	struct port_priv_s *priv = (struct port_priv_s *)file->private_data;
963 	struct stream_port_s *port = priv->port;
964 	size_t wait_size, write_size;
965 
966 	if ((stbuf_space(vbuf) < count) || (stbuf_space(abuf) < count)) {
967 		if (file->f_flags & O_NONBLOCK) {
968 			write_size = min(stbuf_space(vbuf), stbuf_space(abuf));
969 			if (write_size <= 188)	/*have 188 bytes,write now., */
970 				return -EAGAIN;
971 		} else {
972 			wait_size =
973 				min(stbuf_canusesize(vbuf) / 8,
974 					stbuf_canusesize(abuf) / 4);
975 			if ((port->flag & PORT_FLAG_VID)
976 				&& (stbuf_space(vbuf) < wait_size)) {
977 				r = stbuf_wait_space(vbuf, wait_size);
978 
979 				if (r < 0) {
980 					/* pr_info("write no space--- ");
981 					 *   pr_info("no space,%d--%d,r-%d\n",
982 					 *   stbuf_space(vbuf),
983 					 *   stbuf_space(abuf),r);
984 					 */
985 					return r;
986 				}
987 			}
988 
989 			if ((port->flag & PORT_FLAG_AID)
990 				&& (stbuf_space(abuf) < wait_size)) {
991 				r = stbuf_wait_space(abuf, wait_size);
992 
993 				if (r < 0) {
994 					/* pr_info("write no stbuf_wait_space")'
995 					 * pr_info{"---no space,%d--%d,r-%d\n",
996 					 * stbuf_space(vbuf),
997 					 * stbuf_space(abuf),r);
998 					 */
999 					return r;
1000 				}
1001 			}
1002 		}
1003 	}
1004 	vbuf->last_write_jiffies64 = jiffies_64;
1005 	abuf->last_write_jiffies64 = jiffies_64;
1006 	write_size = limited_delay_check(file, vbuf, abuf, buf, count);
1007 	if (write_size > 0)
1008 		return _tsdemux_write(buf, write_size, 0);
1009 	else
1010 		return -EAGAIN;
1011 }
1012 
get_discontinue_counter(void)1013 int get_discontinue_counter(void)
1014 {
1015 	return discontinued_counter;
1016 }
1017 EXPORT_SYMBOL(get_discontinue_counter);
1018 
show_discontinue_counter(struct class * class,struct class_attribute * attr,char * buf)1019 static ssize_t show_discontinue_counter(struct class *class,
1020 		struct class_attribute *attr, char *buf)
1021 {
1022 	return sprintf(buf, "%d\n", discontinued_counter);
1023 }
1024 
1025 static struct class_attribute tsdemux_class_attrs[] = {
1026 	__ATTR(discontinue_counter, S_IRUGO, show_discontinue_counter, NULL),
1027 	__ATTR_NULL
1028 };
1029 
1030 static struct class tsdemux_class = {
1031 		.name = "tsdemux",
1032 		.class_attrs = tsdemux_class_attrs,
1033 	};
1034 
tsdemux_class_register(void)1035 int tsdemux_class_register(void)
1036 {
1037 	int r = class_register(&tsdemux_class);
1038 
1039 	if (r < 0)
1040 		pr_info("register tsdemux class error!\n");
1041 	discontinued_counter = 0;
1042 	return r;
1043 }
1044 
tsdemux_class_unregister(void)1045 void tsdemux_class_unregister(void)
1046 {
1047 	class_unregister(&tsdemux_class);
1048 }
1049 
tsdemux_change_avid(unsigned int vid,unsigned int aid)1050 void tsdemux_change_avid(unsigned int vid, unsigned int aid)
1051 {
1052 	if (!enable_demux_driver()) {
1053 		WRITE_DEMUX_REG(FM_WR_DATA,
1054 				(((vid & 0x1fff) | (VIDEO_PACKET << 13)) << 16)
1055 				| ((aid & 0x1fff) | (AUDIO_PACKET << 13)));
1056 		WRITE_DEMUX_REG(FM_WR_ADDR, 0x8000);
1057 		while (READ_DEMUX_REG(FM_WR_ADDR) & 0x8000)
1058 			;
1059 	} else {
1060 		curr_vid_id = vid;
1061 		curr_aud_id = aid;
1062 
1063 		tsdemux_set_vid(vid);
1064 		tsdemux_set_aid(aid);
1065 
1066 		reset_pcr_regs();
1067 	}
1068 
1069 }
1070 
tsdemux_change_sid(unsigned int sid)1071 void tsdemux_change_sid(unsigned int sid)
1072 {
1073 	if (!enable_demux_driver()) {
1074 		WRITE_DEMUX_REG(FM_WR_DATA,
1075 				(((sid & 0x1fff) | (SUB_PACKET << 13)) << 16)
1076 				| 0xffff);
1077 		WRITE_DEMUX_REG(FM_WR_ADDR, 0x8001);
1078 		while (READ_DEMUX_REG(FM_WR_ADDR) & 0x8000)
1079 			;
1080 	} else {
1081 		curr_sub_id = sid;
1082 
1083 		tsdemux_set_sid(sid);
1084 
1085 		reset_pcr_regs();
1086 	}
1087 
1088 }
1089 
tsdemux_audio_reset(void)1090 void tsdemux_audio_reset(void)
1091 {
1092 	ulong flags;
1093 
1094 	DEFINE_SPINLOCK(lock);
1095 
1096 	spin_lock_irqsave(&lock, flags);
1097 
1098 	WRITE_PARSER_REG(PARSER_AUDIO_WP,
1099 				   READ_AIU_REG(AIU_MEM_AIFIFO_START_PTR));
1100 	WRITE_PARSER_REG(PARSER_AUDIO_RP,
1101 				   READ_AIU_REG(AIU_MEM_AIFIFO_START_PTR));
1102 
1103 	WRITE_PARSER_REG(PARSER_AUDIO_START_PTR,
1104 				   READ_AIU_REG(AIU_MEM_AIFIFO_START_PTR));
1105 	WRITE_PARSER_REG(PARSER_AUDIO_END_PTR,
1106 				   READ_AIU_REG(AIU_MEM_AIFIFO_END_PTR));
1107 	CLEAR_PARSER_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR);
1108 
1109 	WRITE_AIU_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
1110 	CLEAR_AIU_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
1111 
1112 	spin_unlock_irqrestore(&lock, flags);
1113 
1114 }
1115 
tsdemux_sub_reset(void)1116 void tsdemux_sub_reset(void)
1117 {
1118 	ulong flags;
1119 	DEFINE_SPINLOCK(lock);
1120 	u32 parser_sub_start_ptr;
1121 	u32 parser_sub_end_ptr;
1122 
1123 	spin_lock_irqsave(&lock, flags);
1124 
1125 	parser_sub_start_ptr = READ_PARSER_REG(PARSER_SUB_START_PTR);
1126 	parser_sub_end_ptr = READ_PARSER_REG(PARSER_SUB_END_PTR);
1127 
1128 	WRITE_PARSER_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr);
1129 	WRITE_PARSER_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr);
1130 	WRITE_PARSER_REG(PARSER_SUB_RP, parser_sub_start_ptr);
1131 	WRITE_PARSER_REG(PARSER_SUB_WP, parser_sub_start_ptr);
1132 	SET_PARSER_REG_MASK(PARSER_ES_CONTROL,
1133 			(7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR);
1134 
1135 	spin_unlock_irqrestore(&lock, flags);
1136 
1137 }
1138 
tsdemux_set_skipbyte(int skipbyte)1139 void tsdemux_set_skipbyte(int skipbyte)
1140 {
1141 	if (!enable_demux_driver())
1142 		demux_skipbyte = skipbyte;
1143 	else
1144 		tsdemux_set_skip_byte(skipbyte);
1145 
1146 }
1147 
tsdemux_set_demux(int dev)1148 void tsdemux_set_demux(int dev)
1149 {
1150 	if (enable_demux_driver()) {
1151 		unsigned long flags;
1152 		int r = 0;
1153 
1154 		spin_lock_irqsave(&demux_ops_lock, flags);
1155 		if (demux_ops && demux_ops->set_demux)
1156 			r = demux_ops->set_demux(dev);
1157 		spin_unlock_irqrestore(&demux_ops_lock, flags);
1158 	}
1159 }
1160 
tsdemux_pcrscr_get(void)1161 u32 tsdemux_pcrscr_get(void)
1162 {
1163 	u32 pcr = 0;
1164 
1165 	if (pcrscr_valid == 0)
1166 		return 0;
1167 
1168 	if (READ_DEMUX_REG(TS_HIU_CTL_2) & 0x80)
1169 		pcr = READ_DEMUX_REG(PCR_DEMUX_2);
1170 	else if (READ_DEMUX_REG(TS_HIU_CTL_3) & 0x80)
1171 		pcr = READ_DEMUX_REG(PCR_DEMUX_3);
1172 	else
1173 		pcr = READ_DEMUX_REG(PCR_DEMUX);
1174 	if (first_pcr == 0)
1175 		first_pcr = pcr;
1176 	return pcr;
1177 }
1178 
tsdemux_first_pcrscr_get(void)1179 u32 tsdemux_first_pcrscr_get(void)
1180 {
1181 	if (pcrscr_valid == 0)
1182 		return 0;
1183 
1184 	if (first_pcr == 0) {
1185 		u32 pcr;
1186 		if (READ_DEMUX_REG(TS_HIU_CTL_2) & 0x80)
1187 			pcr = READ_DEMUX_REG(PCR_DEMUX_2);
1188 		else if (READ_DEMUX_REG(TS_HIU_CTL_3) & 0x80)
1189 			pcr = READ_DEMUX_REG(PCR_DEMUX_3);
1190 		else
1191 			pcr = READ_DEMUX_REG(PCR_DEMUX);
1192 		first_pcr = pcr;
1193 		/* pr_info("set first_pcr = 0x%x\n", pcr); */
1194 	}
1195 
1196 	return first_pcr;
1197 }
1198 
tsdemux_pcrscr_valid(void)1199 u8 tsdemux_pcrscr_valid(void)
1200 {
1201 	return pcrscr_valid;
1202 }
1203 
tsdemux_pcraudio_valid(void)1204 u8 tsdemux_pcraudio_valid(void)
1205 {
1206 	return pcraudio_valid;
1207 }
1208 
tsdemux_pcrvideo_valid(void)1209 u8 tsdemux_pcrvideo_valid(void)
1210 {
1211 	return pcrvideo_valid;
1212 }
1213 
tsdemux_pcr_set(unsigned int pcr)1214 void tsdemux_pcr_set(unsigned int pcr)
1215 {
1216 	if (pcr_init_flag == 0) {
1217 		/*timestamp_pcrscr_set(pcr);
1218 		timestamp_pcrscr_enable(1);*/
1219 		pcr_init_flag = 1;
1220 	}
1221 }
1222 
tsdemux_tsync_func_init(void)1223 void tsdemux_tsync_func_init(void)
1224 {
1225 	register_tsync_callbackfunc(
1226 		TSYNC_PCRSCR_VALID, (void *)(tsdemux_pcrscr_valid));
1227 	register_tsync_callbackfunc(
1228 		TSYNC_PCRSCR_GET, (void *)(tsdemux_pcrscr_get));
1229 	register_tsync_callbackfunc(
1230 		TSYNC_FIRST_PCRSCR_GET, (void *)(tsdemux_first_pcrscr_get));
1231 	register_tsync_callbackfunc(
1232 		TSYNC_PCRAUDIO_VALID, (void *)(tsdemux_pcraudio_valid));
1233 	register_tsync_callbackfunc(
1234 		TSYNC_PCRVIDEO_VALID, (void *)(tsdemux_pcrvideo_valid));
1235 	register_tsync_callbackfunc(
1236 		TSYNC_BUF_BY_BYTE, (void *)(get_buf_by_type));
1237 	register_tsync_callbackfunc(
1238 		TSYNC_STBUF_LEVEL, (void *)(stbuf_level));
1239 	register_tsync_callbackfunc(
1240 		TSYNC_STBUF_SPACE, (void *)(stbuf_space));
1241 	register_tsync_callbackfunc(
1242 		TSYNC_STBUF_SIZE, (void *)(stbuf_size));
1243 }
1244 
tsparser_stbuf_init(struct stream_buf_s * stbuf,struct vdec_s * vdec)1245 static int tsparser_stbuf_init(struct stream_buf_s *stbuf,
1246 			       struct vdec_s *vdec)
1247 {
1248 	int ret = -1;
1249 
1250 	ret = stbuf_init(stbuf, vdec);
1251 	if (ret)
1252 		goto out;
1253 
1254 	ret = tsdemux_init(stbuf->pars.vid,
1255 			   stbuf->pars.aid,
1256 			   stbuf->pars.sid,
1257 			   stbuf->pars.pcrid,
1258 			   stbuf->is_hevc,
1259 			   vdec);
1260 	if (ret)
1261 		goto out;
1262 
1263 	tsync_pcr_start();
1264 
1265 	stbuf->flag |= BUF_FLAG_IN_USE;
1266 out:
1267 	return ret;
1268 }
1269 
tsparser_stbuf_release(struct stream_buf_s * stbuf)1270 static void tsparser_stbuf_release(struct stream_buf_s *stbuf)
1271 {
1272 	tsync_pcr_stop();
1273 
1274 	tsdemux_release();
1275 
1276 	stbuf_release(stbuf);
1277 }
1278 
1279 static struct stream_buf_ops tsparser_stbuf_ops = {
1280 	.init	= tsparser_stbuf_init,
1281 	.release = tsparser_stbuf_release,
1282 	.get_wp	= parser_get_wp,
1283 	.set_wp	= parser_set_wp,
1284 	.get_rp	= parser_get_rp,
1285 	.set_rp	= parser_set_rp,
1286 };
1287 
get_tsparser_stbuf_ops(void)1288 struct stream_buf_ops *get_tsparser_stbuf_ops(void)
1289 {
1290 	return &tsparser_stbuf_ops;
1291 }
1292 EXPORT_SYMBOL(get_tsparser_stbuf_ops);
1293 
1294 
1295