summaryrefslogtreecommitdiff
path: root/drivers/stream_input/parser/hw_demux/aml_dmx.c (plain)
blob: 974fcc68dba06656eca54cb26fc16c5dafb0dc24
1/*
2* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
3*
4* This program is free software; you can redistribute it and/or modify
5* it under the terms of the GNU General Public License as published by
6* the Free Software Foundation; either version 2 of the License, or
7* (at your option) any later version.
8*
9* This program is distributed in the hope that it will be useful, but WITHOUT
10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12* more details.
13*
14* You should have received a copy of the GNU General Public License along
15* with this program; if not, write to the Free Software Foundation, Inc.,
16* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17*
18* Description:
19*/
20/*
21 * AMLOGIC demux driver.
22 */
23
24#include <linux/version.h>
25#include <linux/kernel.h>
26#include <linux/module.h>
27#include <linux/mutex.h>
28#include <linux/wait.h>
29#include <linux/string.h>
30#include <linux/interrupt.h>
31#include <linux/fs.h>
32#include <linux/cdev.h>
33#include <linux/device.h>
34#include <linux/spinlock.h>
35#include <linux/fcntl.h>
36#include <asm/irq.h>
37#include <linux/uaccess.h>
38#include <linux/poll.h>
39#include <linux/delay.h>
40#include <linux/platform_device.h>
41#include <linux/delay.h>
42#include <asm/cacheflush.h>
43#include <linux/dma-mapping.h>
44#include <linux/pinctrl/pinmux.h>
45#include <linux/vmalloc.h>
46#include <linux/amlogic/media/codec_mm/codec_mm.h>
47#include <linux/amlogic/media/codec_mm/configs.h>
48#include "../streambuf.h"
49#include "c_stb_define.h"
50#include "c_stb_regs_define.h"
51#include "aml_dvb.h"
52#include "aml_dvb_reg.h"
53
54
55#define ENABLE_SEC_BUFF_WATCHDOG
56#define USE_AHB_MODE
57#define PR_ERROR_SPEED_LIMIT
58
59#define pr_dbg_flag(_f, _args...)\
60 do {\
61 if (debug_dmx&(_f))\
62 printk(_args);\
63 } while (0)
64#define pr_dbg_irq_flag(_f, _args...)\
65 do {\
66 if (debug_irq&(_f))\
67 printk(_args);\
68 } while (0)
69#define pr_dbg(args...) pr_dbg_flag(0x1, args)
70#define pr_dbg_irq(args...)pr_dbg_irq_flag(0x1, args)
71#define pr_dbg_irq_dvr(args...)pr_dbg_irq_flag(0x2, args)
72#define pr_dbg_sf(args...) pr_dbg_flag(0x4, args)
73#define pr_dbg_irq_sf(args...) pr_dbg_irq_flag(0x4, args)
74#define pr_dbg_ss(args...) pr_dbg_flag(0x8, args)
75#define pr_dbg_irq_ss(args...) pr_dbg_irq_flag(0x8, args)
76#define pr_dbg_irq_pes(args...) pr_dbg_irq_flag(0x10, args)
77#define pr_dbg_irq_sub(args...) pr_dbg_irq_flag(0x20, args)
78
79#ifdef PR_ERROR_SPEED_LIMIT
80static u32 last_pr_error_time;
81#define pr_error(fmt, _args...)\
82 do {\
83 u32 diff = jiffies_to_msecs(jiffies - last_pr_error_time);\
84 if (!last_pr_error_time || diff > 50) {\
85 pr_err("DVB:" fmt, ## _args);\
86 last_pr_error_time = jiffies;\
87 } \
88 } while (0)
89#else
90#define pr_error(fmt, args...) pr_err("DVB: " fmt, ## args)
91#endif
92
93#define pr_inf(fmt, args...) printk("DVB: " fmt, ## args)
94
95#define dump(b, l) \
96 do { \
97 int i; \
98 printk("dump: "); \
99 for (i = 0; i < (l); i++) {\
100 if (!(i&0xf)) \
101 printk("\n\t"); \
102 printk("%02x ", *(((unsigned char *)(b))+i)); \
103 } \
104 printk("\n"); \
105 } while (0)
106
107MODULE_PARM_DESC(debug_dmx, "\n\t\t Enable demux debug information");
108static int debug_dmx;
109module_param(debug_dmx, int, 0644);
110
111MODULE_PARM_DESC(debug_irq, "\n\t\t Enable demux IRQ debug information");
112static int debug_irq;
113module_param(debug_irq, int, 0644);
114
115MODULE_PARM_DESC(disable_dsc, "\n\t\t Disable discrambler");
116static int disable_dsc;
117module_param(disable_dsc, int, 0644);
118
119/*For old version kernel */
120#ifndef MESON_CPU_MAJOR_ID_GXL
121#define MESON_CPU_MAJOR_ID_GXL 0x21
122#endif
123
124static int npids = CHANNEL_COUNT;
125#define MOD_PARAM_DECLARE_CHANPIDS(_dmx) \
126MODULE_PARM_DESC(debug_dmx##_dmx##_chanpids, "\n\t\t pids of dmx channels"); \
127static short debug_dmx##_dmx##_chanpids[CHANNEL_COUNT] = \
128 {[0 ... (CHANNEL_COUNT - 1)] = -1}; \
129module_param_array(debug_dmx##_dmx##_chanpids, short, &npids, 0444)
130
131#define CIPLUS_OUTPUT_AUTO 8
132static int ciplus_out_sel = CIPLUS_OUTPUT_AUTO;
133static int ciplus_out_auto_mode = 1;
134static u32 ciplus = 0;
135#define CIPLUS_OUT_SEL 28
136#define CIPLUS_IN_SEL 26
137
138MOD_PARAM_DECLARE_CHANPIDS(0);
139MOD_PARAM_DECLARE_CHANPIDS(1);
140MOD_PARAM_DECLARE_CHANPIDS(2);
141
142#define set_debug_dmx_chanpids(_dmx, _idx, _pid)\
143 do { \
144 if ((_dmx) == 0) \
145 debug_dmx0_chanpids[(_idx)] = (_pid); \
146 else if ((_dmx) == 1) \
147 debug_dmx1_chanpids[(_idx)] = (_pid); \
148 else if ((_dmx) == 2) \
149 debug_dmx2_chanpids[(_idx)] = (_pid); \
150 } while (0)
151
152MODULE_PARM_DESC(debug_sf_user, "\n\t\t only for sf mode check");
153static int debug_sf_user;
154module_param(debug_sf_user, int, 0444);
155
156MODULE_PARM_DESC(force_sec_sf, "\n\t\t force sf mode for sec filter");
157static int force_sec_sf;
158module_param(force_sec_sf, int, 0644);
159
160MODULE_PARM_DESC(force_pes_sf, "\n\t\t force sf mode for pes filter");
161static int force_pes_sf;
162module_param(force_pes_sf, int, 0644);
163
164MODULE_PARM_DESC(use_of_sop, "\n\t\t Enable use of sop input");
165static int use_of_sop;
166module_param(use_of_sop, int, 0644);
167
168/*#define CIPLUS_KEY0 0x16f8
169#define CIPLUS_KEY1 0x16f9
170#define CIPLUS_KEY2 0x16fa
171#define CIPLUS_KEY3 0x16fb
172#define CIPLUS_KEY_WR 0x16fc
173#define CIPLUS_CONFIG 0x16fd
174#define CIPLUS_ENDIAN 0x16fe*/
175
176static u32 old_stb_top_config;
177static u32 old_fec_input_control;
178static int have_old_stb_top_config = 1;
179static int have_old_fec_input_control = 1;
180
181static void
182dmx_write_reg(int r, u32 v)
183{
184 u32 oldv, mask;
185
186 if (disable_dsc) {
187 if (r == STB_TOP_CONFIG) {
188 if (have_old_stb_top_config) {
189 oldv = old_stb_top_config;
190 have_old_stb_top_config = 0;
191 } else {
192 oldv = READ_MPEG_REG(STB_TOP_CONFIG);
193 }
194
195 mask = (1<<7)|(1<<15)|(3<<26)|(7<<28);
196 v &= ~mask;
197 v |= (oldv & mask);
198 } else if (r == FEC_INPUT_CONTROL) {
199 if (have_old_fec_input_control) {
200 oldv = old_fec_input_control;
201 have_old_fec_input_control = 0;
202 } else {
203 oldv = READ_MPEG_REG(FEC_INPUT_CONTROL);
204 }
205
206 mask = (1<<15);
207 v &= ~mask;
208 v |= (oldv & mask);
209 } else if ((r == RESET1_REGISTER) || (r == RESET3_REGISTER)) {
210 if (!have_old_stb_top_config) {
211 have_old_stb_top_config = 1;
212 old_stb_top_config =
213 READ_MPEG_REG(STB_TOP_CONFIG);
214 }
215 if (!have_old_fec_input_control) {
216 have_old_fec_input_control = 1;
217 old_fec_input_control =
218 READ_MPEG_REG(FEC_INPUT_CONTROL);
219 }
220 } else if ((r == TS_PL_PID_INDEX) || (r == TS_PL_PID_DATA)
221 || (r == COMM_DESC_KEY0)
222 || (r == COMM_DESC_KEY1)
223 || (r == COMM_DESC_KEY_RW)
224 || (r == CIPLUS_KEY0)
225 || (r == CIPLUS_KEY1)
226 || (r == CIPLUS_KEY2)
227 || (r == CIPLUS_KEY3)
228 || (r == CIPLUS_KEY_WR)
229 || (r == CIPLUS_CONFIG)
230 || (r == CIPLUS_ENDIAN)) {
231 return;
232 }
233 }
234 WRITE_MPEG_REG(r, v);
235}
236
237#undef WRITE_MPEG_REG
238#define WRITE_MPEG_REG(r, v) dmx_write_reg(r, v)
239
240#define DMX_READ_REG(i, r)\
241 ((i)?((i == 1)?READ_MPEG_REG(r##_2) :\
242 READ_MPEG_REG(r##_3)) : READ_MPEG_REG(r))
243
244#define DMX_WRITE_REG(i, r, d)\
245 do {\
246 if (i == 1) {\
247 WRITE_MPEG_REG(r##_2, d);\
248 } else if (i == 2) {\
249 WRITE_MPEG_REG(r##_3, d);\
250 } \
251 else {\
252 WRITE_MPEG_REG(r, d);\
253 } \
254 } while (0)
255
256#define READ_PERI_REG READ_CBUS_REG
257#define WRITE_PERI_REG WRITE_CBUS_REG
258
259#define READ_ASYNC_FIFO_REG(i, r)\
260 ((i) ? ((i-1)?READ_PERI_REG(ASYNC_FIFO1_##r):\
261 READ_PERI_REG(ASYNC_FIFO2_##r)) : READ_PERI_REG(ASYNC_FIFO_##r))
262
263#define WRITE_ASYNC_FIFO_REG(i, r, d)\
264 do {\
265 if (i == 2) {\
266 WRITE_PERI_REG(ASYNC_FIFO1_##r, d);\
267 } else if (i == 0) {\
268 WRITE_PERI_REG(ASYNC_FIFO_##r, d);\
269 } else {\
270 WRITE_PERI_REG(ASYNC_FIFO2_##r, d);\
271 } \
272 } while (0)
273
274#define CLEAR_ASYNC_FIFO_REG_MASK(i, reg, mask) \
275 WRITE_ASYNC_FIFO_REG(i, reg, \
276 (READ_ASYNC_FIFO_REG(i, reg)&(~(mask))))
277
278#define DVR_FEED(f) \
279 ((f) && ((f)->type == DMX_TYPE_TS) && \
280 (((f)->ts_type & (TS_PACKET | TS_DEMUX)) == TS_PACKET))
281
282#define MOD_PARAM_DECLARE_CHANREC(_dmx) \
283MODULE_PARM_DESC(dmx##_dmx##_chanrec_enable, \
284 "\n\t\t record by channel, one time use in the beginning"); \
285static int dmx##_dmx##_chanrec_enable; \
286module_param(dmx##_dmx##_chanrec_enable, int, 0644); \
287MODULE_PARM_DESC(dmx##_dmx##_chanrec, "\n\t\t record channels bits"); \
288static int dmx##_dmx##_chanrec; \
289module_param(dmx##_dmx##_chanrec, int, 0644)
290
291MOD_PARAM_DECLARE_CHANREC(0);
292MOD_PARAM_DECLARE_CHANREC(1);
293MOD_PARAM_DECLARE_CHANREC(2);
294
295#define MOD_PARAM_DECLARE_CHANPROC(_dmx) \
296MODULE_PARM_DESC(dmx##_dmx##_chanproc_enable, "channel further processing"); \
297static int dmx##_dmx##_chanproc_enable; \
298module_param(dmx##_dmx##_chanproc_enable, int, 0644); \
299MODULE_PARM_DESC(dmx##_dmx##_chanproc, "further process channels bits"); \
300static int dmx##_dmx##_chanproc; \
301module_param(dmx##_dmx##_chanproc, int, 0644)
302
303MOD_PARAM_DECLARE_CHANPROC(0);
304MOD_PARAM_DECLARE_CHANPROC(1);
305MOD_PARAM_DECLARE_CHANPROC(2);
306
307#define DMX_CH_OP_CHANREC 0
308#define DMX_CH_OP_CHANPROC 1
309
310static inline int _setbit(int v, int b) { return v|(1<<b); }
311static inline int _clrbit(int v, int b) { return v&~(1<<b); }
312static inline int _set(int v, int b) { return b; }
313
314static int dsc_set_csa_key(struct aml_dsc_channel *ch, int flags,
315 enum ca_cw_type type, u8 *key);
316static int dsc_set_aes_des_sm4_key(struct aml_dsc_channel *ch, int flags,
317 enum ca_cw_type type, u8 *key);
318static void aml_ci_plus_disable(void);
319static void am_ci_plus_set_output(struct aml_dsc_channel *ch);
320static int set_subtitle_pes_buffer(struct aml_dmx *dmx);
321
322static void dmxn_op_chan(int dmx, int ch, int(*op)(int, int), int ch_op)
323{
324 int enable_0, enable_1, enable_2;
325 int *set_0, *set_1, *set_2;
326 int reg;
327
328 if (ch_op == DMX_CH_OP_CHANREC) {
329 enable_0 = dmx0_chanrec_enable;
330 enable_1 = dmx1_chanrec_enable;
331 enable_2 = dmx2_chanrec_enable;
332 set_0 = &dmx0_chanrec;
333 set_1 = &dmx1_chanrec;
334 set_2 = &dmx2_chanrec;
335 reg = DEMUX_CHAN_RECORD_EN;
336 } else if (ch_op == DMX_CH_OP_CHANPROC) {
337 enable_0 = dmx0_chanproc_enable;
338 enable_1 = dmx1_chanproc_enable;
339 enable_2 = dmx2_chanproc_enable;
340 set_0 = &dmx0_chanproc;
341 set_1 = &dmx1_chanproc;
342 set_2 = &dmx2_chanproc;
343 reg = DEMUX_CHAN_PROCESS_EN;
344 } else {
345 return;
346 }
347 if (dmx == 0) {
348 if (enable_0) {
349 *set_0 = op(*set_0, ch);
350 WRITE_MPEG_REG(reg+DEMUX_1_OFFSET, *set_0);
351 }
352 } else if (dmx == 1) {
353 if (enable_1) {
354 *set_1 = op(*set_1, ch);
355 WRITE_MPEG_REG(reg+DEMUX_2_OFFSET, *set_1);
356 }
357 } else if (dmx == 2) {
358 if (enable_2) {
359 *set_2 = op(*set_2, ch);
360 WRITE_MPEG_REG(reg+DEMUX_3_OFFSET, *set_2);
361 }
362 }
363}
364#define dmx_add_recchan(_dmx, _chid) \
365 do { \
366 pr_dbg("dmx[%d]_add_recchan[%d]\n", _dmx, _chid); \
367 dmxn_op_chan(_dmx, _chid, _setbit, DMX_CH_OP_CHANREC); \
368 } while (0)
369#define dmx_rm_recchan(_dmx, _chid) \
370 do { \
371 pr_dbg("dmx[%d]_rm_recchan[%ld]\n", _dmx, _chid); \
372 dmxn_op_chan(_dmx, _chid, _clrbit, DMX_CH_OP_CHANREC); \
373 } while (0)
374#define dmx_set_recchan(_dmx, _chs) \
375 do { \
376 pr_dbg("dmx[%d]_set_recchan[%d]\n", _dmx, _chs); \
377 dmxn_op_chan(_dmx, _chs, _set, DMX_CH_OP_CHANREC); \
378 } while (0)
379
380#define dmx_add_procchan(_dmx, _chid) \
381 do { \
382 pr_dbg("dmx[%d]_add_procchan[%d]\n", _dmx, _chid); \
383 dmxn_op_chan(_dmx, _chid, _setbit, DMX_CH_OP_CHANPROC); \
384 } while (0)
385#define dmx_rm_procchan(_dmx, _chid) \
386 do { \
387 pr_dbg("dmx[%d]_rm_procchan[%ld]\n", _dmx, _chid); \
388 dmxn_op_chan(_dmx, _chid, _clrbit, DMX_CH_OP_CHANPROC); \
389 } while (0)
390#define dmx_set_procchan(_dmx, _chs) \
391 do { \
392 pr_dbg("dmx[%d]_set_procchan[%d]\n", _dmx, _chs); \
393 dmxn_op_chan(_dmx, _chs, _set, DMX_CH_OP_CHANPROC); \
394 } while (0)
395
396#define NO_SUB
397#define SUB_BUF_DMX
398#define SUB_PARSER
399
400#ifndef SUB_BUF_DMX
401#undef SUB_PARSER
402#endif
403
404#define SUB_BUF_SHARED
405#define PES_BUF_SHARED
406
407#define SYS_CHAN_COUNT (4)
408#define SEC_GRP_LEN_0 (0xc)
409#define SEC_GRP_LEN_1 (0xc)
410#define SEC_GRP_LEN_2 (0xc)
411#define SEC_GRP_LEN_3 (0xc)
412#define LARGE_SEC_BUFF_MASK 0xFFFFFFFF
413#define LARGE_SEC_BUFF_COUNT 32
414#define WATCHDOG_TIMER 250
415#define ASYNCFIFO_BUFFER_SIZE_DEFAULT (512*1024)
416
417#define DEMUX_INT_MASK\
418 ((0<<(AUDIO_SPLICING_POINT)) |\
419 (0<<(VIDEO_SPLICING_POINT)) |\
420 (1<<(OTHER_PES_READY)) |\
421 (1<<(PCR_READY)) |\
422 (1<<(SUB_PES_READY)) |\
423 (1<<(SECTION_BUFFER_READY)) |\
424 (0<<(OM_CMD_READ_PENDING)) |\
425 (1<<(TS_ERROR_PIN)) |\
426 (1<<(NEW_PDTS_READY)) |\
427 (0<<(DUPLICATED_PACKET)) |\
428 (0<<(DIS_CONTINUITY_PACKET)))
429
430#define TS_SRC_MAX 3
431
432/*Reset the demux device*/
433#define RESET_DEMUX2 (1<<15)
434#define RESET_DEMUX1 (1<<14)
435#define RESET_DEMUX0 (1<<13)
436#define RESET_S2P1 (1<<12)
437#define RESET_S2P0 (1<<11)
438#define RESET_DES (1<<10)
439#define RESET_TOP (1<<9)
440
441static int dmx_remove_feed(struct aml_dmx *dmx, struct dvb_demux_feed *feed);
442static void reset_async_fifos(struct aml_dvb *dvb);
443static int dmx_add_feed(struct aml_dmx *dmx, struct dvb_demux_feed *feed);
444static int dmx_smallsec_set(struct aml_smallsec *ss, int enable, int bufsize,
445 int force);
446static int dmx_timeout_set(struct aml_dmxtimeout *dto, int enable,
447 int timeout, int ch_dis, int nomatch,
448 int force);
449
450/*Audio & Video PTS value*/
451static u32 video_pts = 0;
452static u32 audio_pts = 0;
453static u32 video_pts_bit32 = 0;
454static u32 audio_pts_bit32 = 0;
455static u32 first_video_pts = 0;
456static u32 first_audio_pts = 0;
457static int demux_skipbyte;
458static int tsfile_clkdiv = 5;
459static int asyncfifo_buf_len = ASYNCFIFO_BUFFER_SIZE_DEFAULT;
460
461#define SF_DMX_ID 2
462#define SF_AFIFO_ID 1
463
464#define sf_dmx_sf(_dmx) \
465 (((_dmx)->id == SF_DMX_ID) \
466 && ((struct aml_dvb *)(_dmx)->demux.priv)->swfilter.user)
467#define sf_afifo_sf(_afifo) \
468 (((_afifo)->id == SF_AFIFO_ID) && (_afifo)->dvb->swfilter.user)
469#define dmx_get_dev(dmx) (((struct aml_dvb *)((dmx)->demux.priv))->dev)
470#define asyncfifo_get_dev(afifo) ((afifo)->dvb->dev)
471
472
473/*Section buffer watchdog*/
474static void section_buffer_watchdog_func(unsigned long arg)
475{
476 struct aml_dvb *dvb = (struct aml_dvb *)arg;
477 struct aml_dmx *dmx;
478 u32 section_busy32 = 0, om_cmd_status32 = 0,
479 demux_channel_activity32 = 0;
480 u16 demux_int_status1 = 0;
481 u32 device_no = 0;
482 u32 filter_number = 0;
483 u32 i = 0;
484 unsigned long flags;
485
486 spin_lock_irqsave(&dvb->slock, flags);
487
488 for (device_no = 0; device_no < DMX_DEV_COUNT; device_no++) {
489
490 dmx = &dvb->dmx[device_no];
491
492 if (dvb->dmx_watchdog_disable[device_no])
493 continue;
494
495 if (!dmx->init)
496 continue;
497
498 om_cmd_status32 =
499 DMX_READ_REG(device_no, OM_CMD_STATUS);
500 demux_channel_activity32 =
501 DMX_READ_REG(device_no, DEMUX_CHANNEL_ACTIVITY);
502 section_busy32 =
503 DMX_READ_REG(device_no, SEC_BUFF_BUSY);
504#if 1
505 if (om_cmd_status32 & 0x8fc2) {
506 /* bit 15:12 -- om_cmd_count */
507 /* bit 11:9 -- overflow_count */
508 /* bit 8:6 -- om_overwrite_count */
509 /* bit 1 -- om_cmd_overflow */
510 /*BUG: If the recoder is running, return */
511 if (dmx->record)
512 goto end;
513 /*Reset the demux */
514 pr_dbg("reset the demux\n"
515 "%04x\t%03x\t%03x\t%03x\t%01x\t%01x\t"
516 "%x\t%x\tdmx%d:status:0x%x\n",
517 (om_cmd_status32 >> 12) & 0xf,
518 (om_cmd_status32 >> 9) & 0x7,
519 (om_cmd_status32 >> 6) & 0x7,
520 (om_cmd_status32 >> 3) & 0x7,
521 (om_cmd_status32 >> 2) & 0x1,
522 (om_cmd_status32 >> 1) & 0x1,
523 demux_channel_activity32, section_busy32,
524 dmx->id, om_cmd_status32);
525
526 dmx_reset_dmx_hw_ex_unlock(dvb, dmx, 0);
527 goto end;
528 }
529#else
530 /* bit 15:12 -- om_cmd_count (read only) */
531 /* bit 11:9 -- overflow_count */
532 /* bit 11:9 -- om_cmd_wr_ptr(read only) */
533 /* bit 8:6 -- om_overwrite_count */
534 /* bit 8:6 -- om_cmd_rd_ptr(read only) */
535 /* bit 5:3 -- type_stb_om_w_rd(read only) */
536 /* bit 2 -- unit_start_stb_om_w_rd(read only) */
537 /* bit 1 -- om_cmd_overflow(read only) */
538 /* bit 0 -- om_cmd_pending(read) */
539 /* bit 0 -- om_cmd_read_finished(write) */
540 if (om_cmd_status32 & 0x0002) {
541 pr_error("reset the demux\n");
542 dmx_reset_hw_ex(dvb, 0);
543 goto end;
544 }
545#endif
546 section_busy32 =
547 DMX_READ_REG(device_no, SEC_BUFF_BUSY);
548 if (LARGE_SEC_BUFF_MASK ==
549 (section_busy32 & LARGE_SEC_BUFF_MASK)) {
550 /*All the largest section buffers occupied,
551 * clear buffers
552 */
553 DMX_WRITE_REG(device_no,
554 SEC_BUFF_READY, section_busy32);
555 } else {
556 for (i = 0; i < SEC_BUF_COUNT; i++) {
557 if (!(section_busy32 & (1 << i)))
558 continue;
559 DMX_WRITE_REG(device_no, SEC_BUFF_NUMBER, i);
560 filter_number = DMX_READ_REG(device_no,
561 SEC_BUFF_NUMBER);
562 filter_number >>= 8;
563 if ((filter_number >= FILTER_COUNT)
564 /* >=31, do not handle this case */
565 || ((filter_number < FILTER_COUNT)
566 && dmx->filter[filter_number].used))
567 section_busy32 &= ~(1 << i);
568 }
569 if (section_busy32 & (dmx->smallsec.enable ?
570 0x7FFFFFFF :
571 LARGE_SEC_BUFF_MASK)) {
572 /*Clear invalid buffers */
573 DMX_WRITE_REG(device_no,
574 SEC_BUFF_READY,
575 section_busy32);
576 pr_error("clear invalid buffer 0x%x\n",
577 section_busy32);
578 }
579#if 0
580 section_busy32 = 0x7fffffff;
581 for (i = 0; i < SEC_BUF_BUSY_SIZE; i++) {
582 dmx->section_busy[i] = (
583 (i == SEC_BUF_BUSY_SIZE - 1) ?
584 DMX_READ_REG(device_no, SEC_BUFF_BUSY) :
585 dmx->section_busy[i + 1]);
586 section_busy32 &= dmx->section_busy[i];
587 }
588
589 /*count the number of '1' bits */
590 i = section_busy32;
591 i = (i & 0x55555555) + ((i & 0xaaaaaaaa) >> 1);
592 i = (i & 0x33333333) + ((i & 0xcccccccc) >> 2);
593 i = (i & 0x0f0f0f0f) + ((i & 0xf0f0f0f0) >> 4);
594 i = (i & 0x00ff00ff) + ((i & 0xff00ff00) >> 8);
595 i = (i & 0x0000ffff) + ((i & 0xffff0000) >> 16);
596 if (i > LARGE_SEC_BUFF_COUNT) {
597 /*too long some of the section
598 * buffers are being processed
599 */
600 DMX_WRITE_REG(device_no, SEC_BUFF_READY,
601 section_busy32);
602 }
603#endif
604 }
605 demux_int_status1 =
606 DMX_READ_REG(device_no, STB_INT_STATUS) & 0xfff7;
607 if (demux_int_status1 & (1 << TS_ERROR_PIN)) {
608 DMX_WRITE_REG(device_no,
609 STB_INT_STATUS,
610 (1 << TS_ERROR_PIN));
611 }
612 }
613
614end:
615 spin_unlock_irqrestore(&dvb->slock, flags);
616#ifdef ENABLE_SEC_BUFF_WATCHDOG
617 mod_timer(&dvb->watchdog_timer,
618 jiffies + msecs_to_jiffies(WATCHDOG_TIMER));
619#endif
620}
621
622static inline int sec_filter_match(struct aml_dmx *dmx, struct aml_filter *f,
623 u8 *p)
624{
625 int b;
626 u8 neq = 0;
627
628 if (!f->used || !dmx->channel[f->chan_id].used)
629 return 0;
630
631 for (b = 0; b < FILTER_LEN; b++) {
632 u8 xor = p[b] ^ f->value[b];
633
634 if (xor & f->maskandmode[b])
635 return 0;
636
637 if (xor & f->maskandnotmode[b])
638 neq = 1;
639 }
640
641 if (f->neq && !neq)
642 return 0;
643
644 return 1;
645}
646
647static void trigger_crc_monitor(struct aml_dmx *dmx)
648{
649 if (!dmx->crc_check_time) {
650 dmx->crc_check_time = jiffies;
651 dmx->crc_check_count = 0;
652 }
653
654 if (dmx->crc_check_count > 100) {
655 if (jiffies_to_msecs(jiffies - dmx->crc_check_time) <= 1000) {
656 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
657
658 pr_error("Too many crc fail (%d crc fail in %d ms)!\n",
659 dmx->crc_check_count,
660 jiffies_to_msecs(jiffies - dmx->crc_check_time)
661 );
662 dmx_reset_dmx_hw_ex_unlock(dvb, dmx, 0);
663 }
664 dmx->crc_check_time = 0;
665 }
666
667 dmx->crc_check_count++;
668}
669static int section_crc(struct aml_dmx *dmx, struct aml_filter *f, u8 *p)
670{
671 int sec_len = (((p[1] & 0xF) << 8) | p[2]) + 3;
672 struct dvb_demux_feed *feed = dmx->channel[f->chan_id].feed;
673
674 if (feed->feed.sec.check_crc) {
675 struct dvb_demux *demux = feed->demux;
676 struct dmx_section_feed *sec = &feed->feed.sec;
677 int section_syntax_indicator;
678
679 section_syntax_indicator = ((p[1] & 0x80) != 0);
680 sec->seclen = sec_len;
681 sec->crc_val = ~0;
682 if (demux->check_crc32(feed, p, sec_len)) {
683 pr_error("section CRC check failed! pid[%d]\n", feed->pid);
684
685#if 0
686{
687 int i;
688
689 pr_error("sec:[%#lx:%#lx:%#lx-%#lx:%#lx:%#lx-%#lx:%#lx:%#lx]\n",
690 dmx->sec_cnt[0], dmx->sec_cnt_match[0], dmx->sec_cnt_crc_fail[0],
691 dmx->sec_cnt[1], dmx->sec_cnt_match[1], dmx->sec_cnt_crc_fail[1],
692 dmx->sec_cnt[2], dmx->sec_cnt_match[2], dmx->sec_cnt_crc_fail[2]);
693 pr_error("bad sec[%d]:\n", sec_len);
694 /*
695 * if (sec_len > 256)
696 * sec_len = 256;
697 * for (i = 0; i < sec_len; i++) {
698 * pr_err("%02x ", p[i]);
699 * if (!((i + 1) % 16))
700 * pr_err("\n");
701 * }
702 */
703}
704#endif
705 trigger_crc_monitor(dmx);
706 return 0;
707 }
708#if 0
709 int i;
710
711 for (i = 0; i < sec_len; i++) {
712 pr_dbg("%02x ", p[i]);
713 if (!((i + 1) % 16))
714 pr_dbg("\n");
715 }
716 pr_dbg("\nsection data\n");
717#endif
718 }
719
720 return 1;
721}
722
723static void section_notify(struct aml_dmx *dmx, struct aml_filter *f, u8 *p)
724{
725 int sec_len = (((p[1] & 0xF) << 8) | p[2]) + 3;
726 struct dvb_demux_feed *feed = dmx->channel[f->chan_id].feed;
727
728 if (feed && feed->cb.sec)
729 feed->cb.sec(p, sec_len, NULL, 0, f->filter);
730}
731
732static void hardware_match_section(struct aml_dmx *dmx,
733 u16 sec_num, u16 buf_num)
734{
735 u8 *p = (u8 *) dmx->sec_buf[buf_num].addr;
736 struct aml_filter *f;
737 int chid, i;
738 int need_crc = 1;
739
740 if (sec_num >= FILTER_COUNT) {
741 pr_dbg("sec_num invalid: %d\n", sec_num);
742 return;
743 }
744
745 dma_sync_single_for_cpu(dmx_get_dev(dmx),
746 dmx->sec_pages_map + (buf_num << 0x0c),
747 (1 << 0x0c), DMA_FROM_DEVICE);
748
749 f = &dmx->filter[sec_num];
750 chid = f->chan_id;
751
752 dmx->sec_cnt[SEC_CNT_HW]++;
753
754 for (i = 0; i < FILTER_COUNT; i++) {
755 f = &dmx->filter[i];
756 if (f->chan_id != chid)
757 continue;
758 if (sec_filter_match(dmx, f, p)) {
759 if (need_crc) {
760 dmx->sec_cnt_match[SEC_CNT_HW]++;
761 if (!section_crc(dmx, f, p)) {
762 dmx->sec_cnt_crc_fail[SEC_CNT_HW]++;
763 return;
764 }
765 need_crc = 0;
766 }
767 section_notify(dmx, f, p);
768 }
769 }
770}
771
772static void software_match_section(struct aml_dmx *dmx, u16 buf_num)
773{
774 u8 *p = (u8 *) dmx->sec_buf[buf_num].addr;
775 struct aml_filter *f, *fmatch = NULL;
776 int i, fid = -1;
777
778 dma_sync_single_for_cpu(dmx_get_dev(dmx),
779 dmx->sec_pages_map + (buf_num << 0x0c),
780 (1 << 0x0c), DMA_FROM_DEVICE);
781
782 dmx->sec_cnt[SEC_CNT_SW]++;
783
784 for (i = 0; i < FILTER_COUNT; i++) {
785 f = &dmx->filter[i];
786
787 if (sec_filter_match(dmx, f, p)) {
788 pr_dbg("[software match]filter %d match, pid %d\n",
789 i, dmx->channel[f->chan_id].pid);
790 if (!fmatch) {
791 fmatch = f;
792 fid = i;
793 } else {
794 pr_error("[sw match]Muli-filter match this\n"
795 "section, will skip this section\n");
796 return;
797 }
798 }
799 }
800
801 if (fmatch) {
802 pr_dbg("[software match]dispatch\n"
803 "section to filter %d pid %d\n",
804 fid, dmx->channel[fmatch->chan_id].pid);
805 dmx->sec_cnt_match[SEC_CNT_SW]++;
806 if (section_crc(dmx, fmatch, p))
807 section_notify(dmx, fmatch, p);
808 else
809 dmx->sec_cnt_crc_fail[SEC_CNT_SW]++;
810 } else {
811 pr_dbg("[software match]this section do not\n"
812 "match any filter!!!\n");
813 }
814}
815
816
817static int _rbuf_write(struct dvb_ringbuffer *buf, const u8 *src, size_t len)
818{
819 ssize_t free;
820
821 if (!len)
822 return 0;
823 if (!buf->data)
824 return 0;
825
826 free = dvb_ringbuffer_free(buf);
827 if (len > free) {
828 pr_error("sf: buffer overflow\n");
829 return -EOVERFLOW;
830 }
831
832 return dvb_ringbuffer_write(buf, src, len);
833}
834
835static int _rbuf_filter_pkts(struct dvb_ringbuffer *rb,
836 u8 *wrapbuf,
837 void (*swfilter_packets)(struct dvb_demux *demux,
838 const u8 *buf,
839 size_t count),
840 struct dvb_demux *demux)
841{
842 ssize_t len1 = 0;
843 ssize_t len2 = 0;
844 size_t off;
845 size_t count;
846 size_t size;
847
848 if (debug_irq & 0x4)
849 dump(&rb->data[rb->pread], (debug_irq & 0xFFF00) >> 8);
850
851 /*
852 * rb|====--------===[0x47]====|
853 * ^ ^
854 * wr rd
855 */
856
857 len1 = rb->pwrite - rb->pread;
858 if (len1 < 0) {
859 len1 = rb->size - rb->pread;
860 len2 = rb->pwrite;
861 }
862
863 for (off = 0; off < len1; off++) {
864 if (rb->data[rb->pread + off] == 0x47)
865 break;
866 }
867
868 if (off)
869 pr_dbg_irq_sf("off ->|%zd\n", off);
870
871 len1 -= off;
872 rb->pread = (rb->pread + off) % rb->size;
873
874 count = len1 / 188;
875 if (count) {
876 pr_dbg_irq_sf("pkt >> 1[%zd<->%zd]\n", rb->pread, rb->pwrite);
877 swfilter_packets(demux, rb->data + rb->pread, count);
878
879 size = count * 188;
880 len1 -= size;
881 rb->pread += size;
882 }
883
884 if (len2 && len1 && ((len1 + len2) > 188)) {
885 pr_dbg_irq_sf("pkt >> 2[%zd<->%zd]\n", rb->pread, rb->pwrite);
886 size = 188 - len1;
887 memcpy(wrapbuf, rb->data + rb->pread, len1);
888 memcpy(wrapbuf + len1, rb->data, size);
889 swfilter_packets(demux, wrapbuf, 1);
890 rb->pread = size;
891 len2 -= size;
892 }
893
894 if (len2) {
895 pr_dbg_irq_sf("pkt >> 3[%zd<->%zd]\n", rb->pread, rb->pwrite);
896 count = len2 / 188;
897 if (count) {
898 swfilter_packets(demux, rb->data + rb->pread, count);
899 rb->pread += count * 188;
900 }
901 }
902 return 0;
903}
904
905static void smallsection_match_section(struct aml_dmx *dmx, u8 *p, u16 sec_num)
906{
907 struct aml_filter *f;
908 int chid, i;
909 int need_crc = 1;
910
911 if (sec_num >= FILTER_COUNT) {
912 pr_dbg("sec_num invalid: %d\n", sec_num);
913 return;
914 }
915
916 f = &dmx->filter[sec_num];
917 chid = f->chan_id;
918
919 dmx->sec_cnt[SEC_CNT_SS]++;
920
921 for (i = 0; i < FILTER_COUNT; i++) {
922 f = &dmx->filter[i];
923 if (f->chan_id != chid)
924 continue;
925 if (sec_filter_match(dmx, f, p)) {
926 if (need_crc) {
927 dmx->sec_cnt_match[SEC_CNT_SS]++;
928 if (!section_crc(dmx, f, p)) {
929 dmx->sec_cnt_crc_fail[SEC_CNT_SS]++;
930 return;
931 }
932 need_crc = 0;
933 }
934 section_notify(dmx, f, p);
935 }
936 }
937
938}
939static void process_smallsection(struct aml_dmx *dmx)
940{
941
942 u32 v, wr, rd;
943 u32 data32;
944 struct aml_smallsec *ss = &dmx->smallsec;
945
946 v = DMX_READ_REG(dmx->id, DEMUX_SMALL_SEC_CTL);
947 wr = (v >> 8) & 0xff;
948 rd = (v >> 16) & 0xff;
949
950 if (rd != wr) {
951 int n1 = wr - rd,
952 n2 = 0,
953 max = (ss->bufsize>>8);
954 int i;
955 u8 *p;
956 int sec_len;
957
958 pr_dbg_irq_ss("secbuf[31] ctrl:0x%x\n", v);
959
960 if (n1 < 0) {
961 n1 = max - rd;
962 n2 = wr;
963 }
964 if (n1) {
965 pr_dbg_irq_ss("n1:%d\n", n1);
966 dma_sync_single_for_cpu(dmx_get_dev(dmx),
967 ss->buf_map+(rd<<8),
968 n1<<8,
969 DMA_FROM_DEVICE);
970 for (i = 0; i < n1; i++) {
971 p = (u8 *)ss->buf+((rd+i)<<8);
972 sec_len = (((p[1] & 0xF) << 8) | p[2]) + 3;
973 smallsection_match_section(dmx, p,
974 *(p+sec_len+1));
975 }
976 }
977 if (n2) {
978 pr_dbg_irq_ss("n2:%d\n", n2);
979 dma_sync_single_for_cpu(dmx_get_dev(dmx),
980 ss->buf_map,
981 n2<<8,
982 DMA_FROM_DEVICE);
983 for (i = 0; i < n2; i++) {
984 p = (u8 *)ss->buf+(i<<8);
985 sec_len = (((p[1] & 0xF) << 8) | p[2]) + 3;
986 smallsection_match_section(dmx, p,
987 *(p+sec_len+1));
988 }
989 }
990
991 rd = wr;
992 data32 = (DMX_READ_REG(dmx->id, DEMUX_SMALL_SEC_CTL)
993 & 0xff00ffff)
994 | (rd << 16);
995 DMX_WRITE_REG(dmx->id, DEMUX_SMALL_SEC_CTL, data32);
996 }
997}
998
999
1000static void process_section(struct aml_dmx *dmx)
1001{
1002 u32 ready, i, sec_busy;
1003 u16 sec_num;
1004
1005 /*pr_dbg("section\n"); */
1006 ready = DMX_READ_REG(dmx->id, SEC_BUFF_READY);
1007 if (ready) {
1008#ifdef USE_AHB_MODE
1009 /* WRITE_ISA_REG(AHB_BRIDGE_CTRL1,
1010 * READ_ISA_REG (AHB_BRIDGE_CTRL1) | (1 << 31));
1011 */
1012 /* WRITE_ISA_REG(AHB_BRIDGE_CTRL1,
1013 * READ_ISA_REG (AHB_BRIDGE_CTRL1) & (~ (1 << 31)));
1014 */
1015#endif
1016
1017 if ((ready & (1<<31)) && dmx->smallsec.enable) {
1018 u32 v, wr, rd;
1019
1020 v = DMX_READ_REG(dmx->id, DEMUX_SMALL_SEC_CTL);
1021 wr = (v >> 8) & 0xff;
1022 rd = (v >> 16) & 0xff;
1023 if ((wr < rd) && (5 > (rd - wr)))
1024 pr_error("warning: small ss buf [w%dr%d]\n",
1025 wr, rd);
1026 pr_dbg_irq_ss("ss>%x\n",
1027 DMX_READ_REG(dmx->id, DEMUX_SMALL_SEC_CTL));
1028 process_smallsection(dmx);
1029 /*tasklet_hi_schedule(&dmx->dmx_tasklet);*/
1030 /*tasklet_schedule(&dmx->dmx_tasklet);*/
1031 DMX_WRITE_REG(dmx->id, SEC_BUFF_READY, (1<<31));
1032 return;
1033 }
1034
1035 for (i = 0; i < SEC_BUF_COUNT; i++) {
1036
1037 if (!(ready & (1 << i)))
1038 continue;
1039
1040 /* get section busy */
1041 sec_busy = DMX_READ_REG(dmx->id, SEC_BUFF_BUSY);
1042 /* get filter number */
1043 DMX_WRITE_REG(dmx->id, SEC_BUFF_NUMBER, i);
1044 sec_num = (DMX_READ_REG(dmx->id, SEC_BUFF_NUMBER) >> 8);
1045
1046 /*
1047 * sec_buf_watchdog_count dispatch:
1048 * byte0 -- always busy=0 's watchdog count
1049 * byte1 -- always busy=1 & filter_num=31 's
1050 * watchdog count
1051 */
1052
1053 /* sec_busy is not set, check busy=0 watchdog count */
1054 if (!(sec_busy & (1 << i))) {
1055 /* clear other wd count of this buffer */
1056 dmx->sec_buf_watchdog_count[i] &= 0x000000ff;
1057 dmx->sec_buf_watchdog_count[i] += 0x1;
1058 pr_dbg("bit%d ready=1, busy=0,\n"
1059 "sec_num=%d for %d times\n",
1060 i, sec_num,
1061 dmx->sec_buf_watchdog_count[i]);
1062 if (dmx->sec_buf_watchdog_count[i] >= 5) {
1063 pr_dbg("busy=0 reach the max count,\n"
1064 "try software match.\n");
1065 software_match_section(dmx, i);
1066 dmx->sec_buf_watchdog_count[i] = 0;
1067 DMX_WRITE_REG(dmx->id, SEC_BUFF_READY,
1068 (1 << i));
1069 }
1070 continue;
1071 }
1072
1073 /* filter_num == 31 && busy == 1,check watchdog count */
1074 if (sec_num >= FILTER_COUNT) {
1075 /* clear other wd count of this buffer */
1076 dmx->sec_buf_watchdog_count[i] &= 0x0000ff00;
1077 dmx->sec_buf_watchdog_count[i] += 0x100;
1078 pr_dbg("bit%d ready=1,busy=1,\n"
1079 "sec_num=%d for %d times\n",
1080 i, sec_num,
1081 dmx->sec_buf_watchdog_count[i] >> 8);
1082 if (dmx->sec_buf_watchdog_count[i] >= 0x500) {
1083 pr_dbg("busy=1&filter_num=31\n"
1084 " reach the max count, clear\n"
1085 " the buf ready & busy!\n");
1086 software_match_section(dmx, i);
1087 dmx->sec_buf_watchdog_count[i] = 0;
1088 DMX_WRITE_REG(dmx->id,
1089 SEC_BUFF_READY,
1090 (1 << i));
1091 DMX_WRITE_REG(dmx->id,
1092 SEC_BUFF_BUSY,
1093 (1 << i));
1094 }
1095 continue;
1096 }
1097
1098 /* now, ready & busy are both set and
1099 * filter number is valid
1100 */
1101 if (dmx->sec_buf_watchdog_count[i] != 0)
1102 dmx->sec_buf_watchdog_count[i] = 0;
1103
1104 /* process this section */
1105 hardware_match_section(dmx, sec_num, i);
1106
1107 /* clear the ready & busy bit */
1108 DMX_WRITE_REG(dmx->id, SEC_BUFF_READY, (1 << i));
1109 DMX_WRITE_REG(dmx->id, SEC_BUFF_BUSY, (1 << i));
1110 }
1111 }
1112}
1113
1114#ifdef NO_SUB
1115static void process_sub(struct aml_dmx *dmx)
1116{
1117
1118 u32 rd_ptr = 0;
1119
1120 u32 wr_ptr = READ_MPEG_REG(PARSER_SUB_WP);
1121 u32 start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR);
1122 u32 end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR);
1123
1124 u32 buffer1 = 0, buffer2 = 0;
1125 u8 *buffer1_virt = 0, *buffer2_virt = 0;
1126 u32 len1 = 0, len2 = 0;
1127
1128 if (!dmx->sub_buf_base_virt)
1129 return;
1130
1131 rd_ptr = READ_MPEG_REG(PARSER_SUB_RP);
1132 if (!rd_ptr)
1133 return;
1134 if (rd_ptr > wr_ptr) {
1135 len1 = end_ptr - rd_ptr + 8;
1136 buffer1 = rd_ptr;
1137
1138 len2 = wr_ptr - start_ptr;
1139 buffer2 = start_ptr;
1140
1141 rd_ptr = start_ptr + len2;
1142 } else if (rd_ptr < wr_ptr) {
1143 len1 = wr_ptr - rd_ptr;
1144 buffer1 = rd_ptr;
1145 rd_ptr += len1;
1146 len2 = 0;
1147 } else if (rd_ptr == wr_ptr) {
1148 pr_dbg("sub no data\n");
1149 }
1150
1151 if (buffer1 && len1)
1152#ifdef SUB_BUF_DMX
1153 buffer1_virt = (void *)dmx->sub_pages + (buffer1 - start_ptr);
1154#else
1155 buffer1_virt = (void *)dmx->sub_buf_base_virt + (buffer1 - start_ptr);
1156#endif
1157
1158 if (buffer2 && len2)
1159#ifdef SUB_BUF_DMX
1160 buffer2_virt = (void *)dmx->sub_pages + (buffer2 - start_ptr);
1161#else
1162 buffer2_virt = (void *)dmx->sub_buf_base_virt + (buffer2 - start_ptr);
1163#endif
1164
1165 pr_dbg_irq_sub("sub: rd_ptr:%x buf1:%x len1:%d buf2:%x len2:%d\n",
1166 rd_ptr, buffer1, len1, buffer2, len2);
1167 pr_dbg_irq_sub("sub: buf1_virt:%p buf2_virt:%p\n",
1168 buffer1_virt, buffer2_virt);
1169
1170 if (len1)
1171 dma_sync_single_for_cpu(dmx_get_dev(dmx),
1172 (dma_addr_t) buffer1, len1,
1173 DMA_FROM_DEVICE);
1174 if (len2)
1175 dma_sync_single_for_cpu(dmx_get_dev(dmx),
1176 (dma_addr_t) buffer2, len2,
1177 DMA_FROM_DEVICE);
1178
1179 if (dmx->channel[2].used) {
1180 if (dmx->channel[2].feed && dmx->channel[2].feed->cb.ts &&
1181 ((buffer1_virt != NULL && len1 !=0 ) || (buffer2_virt != NULL && len2 != 0)))
1182 {
1183 dmx->channel[2].feed->cb.ts(buffer1_virt, len1,
1184 buffer2_virt, len2,
1185 &dmx->channel[2].feed->feed.ts);
1186 }
1187 }
1188 WRITE_MPEG_REG(PARSER_SUB_RP, rd_ptr);
1189}
1190#endif
1191
1192static void process_pes(struct aml_dmx *dmx)
1193{
1194 static long off, off_pre;
1195 u8 *buffer1 = 0, *buffer2 = 0;
1196 u8 *buffer1_phys = 0, *buffer2_phys = 0;
1197 u32 len1 = 0, len2 = 0;
1198 int i = 1;
1199
1200 off = (DMX_READ_REG(dmx->id, OB_PES_WR_PTR) << 3);
1201
1202 pr_dbg_irq_pes("[%d]WR:0x%x PES WR:0x%x\n", dmx->id,
1203 DMX_READ_REG(dmx->id, OTHER_WR_PTR),
1204 DMX_READ_REG(dmx->id, OB_PES_WR_PTR));
1205 buffer1 = (u8 *)(dmx->pes_pages + off_pre);
1206 pr_dbg_irq_pes("[%d]PES WR[%02x %02x %02x %02x %02x %02x %02x %02x",
1207 dmx->id,
1208 buffer1[0], buffer1[1], buffer1[2], buffer1[3],
1209 buffer1[4], buffer1[5], buffer1[6], buffer1[7]);
1210 pr_dbg_irq_pes(" %02x %02x %02x %02x %02x %02x %02x %02x]\n",
1211 buffer1[8], buffer1[9], buffer1[10], buffer1[11],
1212 buffer1[12], buffer1[13], buffer1[14], buffer1[15]);
1213
1214 if (off > off_pre) {
1215 len1 = off-off_pre;
1216 buffer1 = (unsigned char *)(dmx->pes_pages + off_pre);
1217 } else if (off < off_pre) {
1218 len1 = dmx->pes_buf_len-off_pre;
1219 buffer1 = (unsigned char *)(dmx->pes_pages + off_pre);
1220 len2 = off;
1221 buffer2 = (unsigned char *)dmx->pes_pages;
1222 } else if (off == off_pre) {
1223 pr_dbg("pes no data\n");
1224 }
1225 off_pre = off;
1226 if (len1) {
1227 buffer1_phys = (unsigned char *)virt_to_phys(buffer1);
1228 dma_sync_single_for_cpu(dmx_get_dev(dmx),
1229 (dma_addr_t)buffer1_phys, len1, DMA_FROM_DEVICE);
1230 }
1231 if (len2) {
1232 buffer2_phys = (unsigned char *)virt_to_phys(buffer2);
1233 dma_sync_single_for_cpu(dmx_get_dev(dmx),
1234 (dma_addr_t)buffer2_phys, len2, DMA_FROM_DEVICE);
1235 }
1236 if (len1 || len2) {
1237 struct aml_channel *ch;
1238
1239 for (i = 0; i < CHANNEL_COUNT; i++) {
1240 ch = &dmx->channel[i];
1241 if (ch->used && ch->feed
1242 && (ch->feed->type == DMX_TYPE_TS)) {
1243 if (ch->feed->ts_type & TS_PAYLOAD_ONLY) {
1244 ch->feed->cb.ts(buffer1,
1245 len1, buffer2, len2,
1246 &ch->feed->feed.ts);
1247 }
1248 }
1249 }
1250 }
1251}
1252
1253static void process_om_read(struct aml_dmx *dmx)
1254{
1255 unsigned int i;
1256 unsigned short om_cmd_status_data_0 = 0;
1257 unsigned short om_cmd_status_data_1 = 0;
1258/* unsigned short om_cmd_status_data_2 = 0;*/
1259 unsigned short om_cmd_data_out = 0;
1260
1261 om_cmd_status_data_0 = DMX_READ_REG(dmx->id, OM_CMD_STATUS);
1262 om_cmd_status_data_1 = DMX_READ_REG(dmx->id, OM_CMD_DATA);
1263/* om_cmd_status_data_2 = DMX_READ_REG(dmx->id, OM_CMD_DATA2);*/
1264
1265 if (om_cmd_status_data_0 & 1) {
1266 DMX_WRITE_REG(dmx->id, OM_DATA_RD_ADDR,
1267 (1 << 15) | ((om_cmd_status_data_1 & 0xff) << 2));
1268 for (i = 0; i < (((om_cmd_status_data_1 >> 7) & 0x1fc) >> 1);
1269 i++) {
1270 om_cmd_data_out = DMX_READ_REG(dmx->id, OM_DATA_RD);
1271 }
1272
1273 om_cmd_data_out = DMX_READ_REG(dmx->id, OM_DATA_RD_ADDR);
1274 DMX_WRITE_REG(dmx->id, OM_DATA_RD_ADDR, 0);
1275 DMX_WRITE_REG(dmx->id, OM_CMD_STATUS, 1);
1276 }
1277}
1278
1279static void dmx_irq_bh_handler(unsigned long arg)
1280{
1281 struct aml_dmx *dmx = (struct aml_dmx *)arg;
1282#if 0
1283 u32 status;
1284
1285 status = DMX_READ_REG(dmx->id, STB_INT_STATUS);
1286
1287 if (status)
1288 DMX_WRITE_REG(dmx->id, STB_INT_STATUS, status);
1289#endif
1290 process_smallsection(dmx);
1291}
1292
1293static irqreturn_t dmx_irq_handler(int irq_number, void *para)
1294{
1295 struct aml_dmx *dmx = (struct aml_dmx *)para;
1296 struct aml_dvb *dvb = aml_get_dvb_device();
1297 u32 status;
1298 unsigned long flags;
1299
1300 spin_lock_irqsave(&dvb->slock, flags);
1301 status = DMX_READ_REG(dmx->id, STB_INT_STATUS);
1302 if (!status)
1303 goto irq_handled;
1304
1305 pr_dbg_irq("demux %d irq status: 0x%08x\n", dmx->id, status);
1306
1307 if (status & (1 << SECTION_BUFFER_READY))
1308 process_section(dmx);
1309#ifdef NO_SUB
1310 if (status & (1 << SUB_PES_READY)) {
1311 /*If the subtitle is set by tsdemux,
1312 *do not parser in demux driver.
1313 */
1314 if (dmx->sub_chan == -1)
1315 process_sub(dmx);
1316 }
1317#endif
1318 if (status & (1 << OTHER_PES_READY))
1319 process_pes(dmx);
1320 if (status & (1 << OM_CMD_READ_PENDING))
1321 process_om_read(dmx);
1322 /*
1323 *if (status & (1 << DUPLICATED_PACKET)) {
1324 *}
1325 *if (status & (1 << DIS_CONTINUITY_PACKET)) {
1326 *}
1327 *if (status & (1 << VIDEO_SPLICING_POINT)) {
1328 *}
1329 *if (status & (1 << AUDIO_SPLICING_POINT)) {
1330 *}
1331 */
1332 if (status & (1 << TS_ERROR_PIN))
1333 pr_error("TS_ERROR_PIN\n");
1334
1335 if (status & (1 << NEW_PDTS_READY)) {
1336 u32 pdts_status = DMX_READ_REG(dmx->id, STB_PTS_DTS_STATUS);
1337
1338 if (pdts_status & (1 << VIDEO_PTS_READY)) {
1339 video_pts = DMX_READ_REG(dmx->id, VIDEO_PTS_DEMUX);
1340 video_pts_bit32 =
1341 (pdts_status & (1 << VIDEO_PTS_BIT32)) ? 1 : 0;
1342 if (!first_video_pts
1343 || 0 > (int)(video_pts - first_video_pts))
1344 first_video_pts = video_pts;
1345 }
1346
1347 if (pdts_status & (1 << AUDIO_PTS_READY)) {
1348 audio_pts = DMX_READ_REG(dmx->id, AUDIO_PTS_DEMUX);
1349 audio_pts_bit32 =
1350 (pdts_status & (1 << AUDIO_PTS_BIT32)) ? 1 : 0;
1351 if (!first_audio_pts
1352 || 0 > (int)(audio_pts - first_audio_pts))
1353 first_audio_pts = audio_pts;
1354 }
1355 }
1356
1357 if (dmx->irq_handler)
1358 dmx->irq_handler(dmx->dmx_irq, (void *)(long)dmx->id);
1359
1360 DMX_WRITE_REG(dmx->id, STB_INT_STATUS, status);
1361
1362 /*tasklet_schedule(&dmx->dmx_tasklet);*/
1363
1364 {
1365 if (!dmx->int_check_time) {
1366 dmx->int_check_time = jiffies;
1367 dmx->int_check_count = 0;
1368 }
1369
1370 if (jiffies_to_msecs(jiffies - dmx->int_check_time) >= 100
1371 || dmx->int_check_count > 1000) {
1372 if (dmx->int_check_count > 1000) {
1373 struct aml_dvb *dvb =
1374 (struct aml_dvb *)dmx->demux.priv;
1375 pr_error("Too many irq (%d irq in %d ms)!\n",
1376 dmx->int_check_count,
1377 jiffies_to_msecs(jiffies -
1378 dmx->int_check_time));
1379 if (dmx->fe && !dmx->in_tune)
1380 DMX_WRITE_REG(dmx->id, STB_INT_MASK, 0);
1381 dmx_reset_hw_ex(dvb, 0);
1382 }
1383 dmx->int_check_time = 0;
1384 }
1385
1386 dmx->int_check_count++;
1387
1388 if (dmx->in_tune) {
1389 dmx->error_check++;
1390 if (dmx->error_check > 200)
1391 DMX_WRITE_REG(dmx->id, STB_INT_MASK, 0);
1392 }
1393 }
1394
1395irq_handled:
1396 spin_unlock_irqrestore(&dvb->slock, flags);
1397 return IRQ_HANDLED;
1398}
1399
1400static inline int dmx_get_order(unsigned long size)
1401{
1402 int order;
1403
1404 order = -1;
1405 do {
1406 size >>= 1;
1407 order++;
1408 } while (size);
1409
1410 return order;
1411}
1412
1413static void dvr_process_channel(struct aml_asyncfifo *afifo,
1414 struct aml_channel *channel,
1415 u32 total, u32 size,
1416 struct aml_swfilter *sf)
1417{
1418 int cnt;
1419 int ret = 0;
1420 struct aml_dvr_block blk;
1421
1422 if (afifo->buf_read > afifo->buf_toggle) {
1423 cnt = total - afifo->buf_read;
1424 if (!afifo->secure_enable) {
1425 dma_sync_single_for_cpu(asyncfifo_get_dev(afifo),
1426 afifo->pages_map+afifo->buf_read*size,
1427 cnt*size,
1428 DMA_FROM_DEVICE);
1429 if (sf)
1430 ret = _rbuf_write(&sf->rbuf,
1431 (u8 *)afifo->pages+afifo->buf_read*size,
1432 cnt*size);
1433 else
1434 channel->dvr_feed->cb.ts(
1435 (u8 *)afifo->pages+afifo->buf_read*size,
1436 cnt*size, NULL, 0,
1437 &channel->dvr_feed->feed.ts);
1438 } else {
1439 blk.addr = afifo->blk.addr+afifo->buf_read*size;
1440 blk.len = cnt*size;
1441 if (sf)
1442 ret = _rbuf_write(&sf->rbuf,
1443 (u8 *)afifo->pages+afifo->buf_read*size,
1444 cnt*size);
1445 else {
1446 channel->dvr_feed->cb.ts(
1447 (u8 *)&blk,
1448 sizeof(struct aml_dvr_block),
1449 NULL, 0,
1450 &channel->dvr_feed->feed.ts);
1451 }
1452 }
1453 afifo->buf_read = 0;
1454 }
1455
1456 if (afifo->buf_toggle > afifo->buf_read) {
1457 cnt = afifo->buf_toggle - afifo->buf_read;
1458 if (!afifo->secure_enable) {
1459 dma_sync_single_for_cpu(asyncfifo_get_dev(afifo),
1460 afifo->pages_map+afifo->buf_read*size,
1461 cnt*size,
1462 DMA_FROM_DEVICE);
1463 if (sf) {
1464 if (ret >= 0)
1465 ret = _rbuf_write(&sf->rbuf,
1466 (u8 *)afifo->pages+afifo->buf_read*size,
1467 cnt*size);
1468 } else {
1469 channel->dvr_feed->cb.ts(
1470 (u8 *)afifo->pages+afifo->buf_read*size,
1471 cnt*size, NULL, 0,
1472 &channel->dvr_feed->feed.ts);
1473 }
1474 } else {
1475 blk.addr = afifo->blk.addr+afifo->buf_read*size;
1476 blk.len = cnt*size;
1477 if (sf)
1478 ret = _rbuf_write(&sf->rbuf,
1479 (u8 *)afifo->pages+afifo->buf_read*size,
1480 cnt*size);
1481 else {
1482 channel->dvr_feed->cb.ts(
1483 (u8 *)&blk,
1484 sizeof(struct aml_dvr_block),
1485 NULL, 0,
1486 &channel->dvr_feed->feed.ts);
1487 }
1488 }
1489 afifo->buf_read = afifo->buf_toggle;
1490 }
1491
1492 if (sf && ret > 0) {
1493 _rbuf_filter_pkts(&sf->rbuf, sf->wrapbuf,
1494 dvb_dmx_swfilter_packets,
1495 channel->dvr_feed->demux);
1496 } else if (sf && ret <= 0)
1497 pr_error("sf rbuf write error[%d]\n", ret);
1498 else
1499 pr_dbg_irq_dvr("write data to dvr\n");
1500}
1501
1502static void dvr_irq_bh_handler(unsigned long arg)
1503{
1504 struct aml_asyncfifo *afifo = (struct aml_asyncfifo *)arg;
1505 struct aml_dvb *dvb = afifo->dvb;
1506 struct aml_dmx *dmx;
1507 u32 size, total;
1508 int i, factor;
1509 unsigned long flags;
1510
1511 pr_dbg_irq_dvr("async fifo %d irq\n", afifo->id);
1512
1513 spin_lock_irqsave(&dvb->slock, flags);
1514
1515 if (dvb && afifo->source >= AM_DMX_0 && afifo->source < AM_DMX_MAX) {
1516 dmx = &dvb->dmx[afifo->source];
1517 // pr_inf("async fifo %d irq, source:%d\n", afifo->id,afifo->source);
1518 if (dmx->init && dmx->record) {
1519 struct aml_swfilter *sf = &dvb->swfilter;
1520 int issf = 0;
1521
1522 total = afifo->buf_len / afifo->flush_size;
1523 factor = dmx_get_order(total);
1524 size = afifo->buf_len >> factor;
1525
1526 if (sf->user && (sf->afifo == afifo))
1527 issf = 1;
1528
1529 for (i = 0; i < CHANNEL_COUNT; i++) {
1530 if (dmx->channel[i].used
1531 && dmx->channel[i].dvr_feed) {
1532 dvr_process_channel(afifo,
1533 &dmx->channel[i],
1534 total,
1535 size,
1536 issf?sf:NULL);
1537 break;
1538 }
1539 }
1540
1541 }
1542 }
1543 spin_unlock_irqrestore(&dvb->slock, flags);
1544}
1545
1546static irqreturn_t dvr_irq_handler(int irq_number, void *para)
1547{
1548 struct aml_asyncfifo *afifo = (struct aml_asyncfifo *)para;
1549 int factor = dmx_get_order(afifo->buf_len / afifo->flush_size);
1550
1551 afifo->buf_toggle++;
1552 afifo->buf_toggle %= (1 << factor);
1553 tasklet_schedule(&afifo->asyncfifo_tasklet);
1554 return IRQ_HANDLED;
1555}
1556
1557/*Enable the STB*/
1558static void stb_enable(struct aml_dvb *dvb)
1559{
1560 int out_src, des_in, en_des, fec_clk, hiu, dec_clk_en;
1561 int src, tso_src, i;
1562 u32 fec_s0, fec_s1,fec_s2;
1563 u32 invert0, invert1, invert2;
1564 u32 data;
1565
1566 switch (dvb->stb_source) {
1567 case AM_TS_SRC_DMX0:
1568 src = dvb->dmx[0].source;
1569 break;
1570 case AM_TS_SRC_DMX1:
1571 src = dvb->dmx[1].source;
1572 break;
1573 case AM_TS_SRC_DMX2:
1574 src = dvb->dmx[2].source;
1575 break;
1576 default:
1577 src = dvb->stb_source;
1578 break;
1579 }
1580
1581 switch (src) {
1582 case AM_TS_SRC_TS0:
1583 fec_clk = tsfile_clkdiv;
1584 hiu = 0;
1585 break;
1586 case AM_TS_SRC_TS1:
1587 fec_clk = tsfile_clkdiv;
1588 hiu = 0;
1589 break;
1590 case AM_TS_SRC_TS2:
1591 fec_clk = tsfile_clkdiv;
1592 hiu = 0;
1593 break;
1594 case AM_TS_SRC_TS3:
1595 fec_clk = tsfile_clkdiv;
1596 hiu = 0;
1597 break;
1598 case AM_TS_SRC_S_TS0:
1599 fec_clk = tsfile_clkdiv;
1600 hiu = 0;
1601 break;
1602 case AM_TS_SRC_S_TS1:
1603 fec_clk = tsfile_clkdiv;
1604 hiu = 0;
1605 break;
1606 case AM_TS_SRC_S_TS2:
1607 fec_clk = tsfile_clkdiv;
1608 hiu = 0;
1609 break;
1610 case AM_TS_SRC_HIU:
1611 fec_clk = tsfile_clkdiv;
1612 hiu = 1;
1613 break;
1614 case AM_TS_SRC_HIU1:
1615 fec_clk = tsfile_clkdiv;
1616 hiu = 1;
1617 break;
1618 default:
1619 fec_clk = 0;
1620 hiu = 0;
1621 break;
1622 }
1623
1624 switch (dvb->dsc[0].source) {
1625 case AM_TS_SRC_DMX0:
1626 des_in = 0;
1627 en_des = 1;
1628 dec_clk_en = 1;
1629 break;
1630 case AM_TS_SRC_DMX1:
1631 des_in = 1;
1632 en_des = 1;
1633 dec_clk_en = 1;
1634 break;
1635 case AM_TS_SRC_DMX2:
1636 des_in = 2;
1637 en_des = 1;
1638 dec_clk_en = 1;
1639 break;
1640 default:
1641 des_in = 0;
1642 en_des = 0;
1643 dec_clk_en = 0;
1644 break;
1645 }
1646 switch (dvb->tso_source) {
1647 case AM_TS_SRC_DMX0:
1648 tso_src = dvb->dmx[0].source;
1649 break;
1650 case AM_TS_SRC_DMX1:
1651 tso_src = dvb->dmx[1].source;
1652 break;
1653 case AM_TS_SRC_DMX2:
1654 tso_src = dvb->dmx[2].source;
1655 break;
1656 default:
1657 tso_src = dvb->tso_source;
1658 break;
1659 }
1660
1661 switch (tso_src) {
1662 case AM_TS_SRC_TS0:
1663 out_src = 0;
1664 break;
1665 case AM_TS_SRC_TS1:
1666 out_src = 1;
1667 break;
1668 case AM_TS_SRC_TS2:
1669 out_src = 2;
1670 break;
1671 case AM_TS_SRC_TS3:
1672 out_src = 3;
1673 break;
1674 case AM_TS_SRC_S_TS0:
1675 out_src = 6;
1676 break;
1677 case AM_TS_SRC_S_TS1:
1678 out_src = 5;
1679 break;
1680 case AM_TS_SRC_S_TS2:
1681 out_src = 4;
1682 break;
1683 case AM_TS_SRC_HIU:
1684 out_src = 7;
1685 break;
1686 default:
1687 out_src = 0;
1688 break;
1689 }
1690
1691 pr_dbg("[stb]src: %d, dsc1in: %d, tso: %d\n", src, des_in, out_src);
1692
1693 fec_s0 = 0;
1694 fec_s1 = 0;
1695 fec_s2 = 0;
1696 invert0 = 0;
1697 invert1 = 0;
1698 invert2 = 0;
1699
1700 for (i = 0; i < dvb->ts_in_total_count; i++) {
1701 if (dvb->ts[i].s2p_id == 0)
1702 fec_s0 = i;
1703 else if (dvb->ts[i].s2p_id == 1)
1704 fec_s1 = i;
1705 else if (dvb->ts[i].s2p_id == 2)
1706 fec_s2 = i;
1707 }
1708
1709 invert0 = dvb->s2p[0].invert;
1710 invert1 = dvb->s2p[1].invert;
1711
1712 WRITE_MPEG_REG(STB_TOP_CONFIG,
1713 (invert1 << INVERT_S2P1_FEC_CLK) |
1714 (fec_s1 << S2P1_FEC_SERIAL_SEL) |
1715 (out_src << TS_OUTPUT_SOURCE) |
1716 (des_in << DES_INPUT_SEL) |
1717 (en_des << ENABLE_DES_PL) |
1718 (dec_clk_en << ENABLE_DES_PL_CLK) |
1719 (invert0 << INVERT_S2P0_FEC_CLK) |
1720 (fec_s0 << S2P0_FEC_SERIAL_SEL)|
1721 (ciplus));
1722 ciplus = 0;
1723
1724 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TL1) {
1725 invert2 = dvb->s2p[2].invert;
1726
1727 WRITE_MPEG_REG(STB_S2P2_CONFIG,
1728 (invert2 << INVERT_S2P2_FEC_CLK) |
1729 (fec_s2 << S2P2_FEC_SERIAL_SEL));
1730 }
1731
1732 if (dvb->reset_flag)
1733 hiu = 0;
1734 /* invert ts out clk,add ci model need add this*/
1735 if (dvb->ts_out_invert) {
1736 printk("ts out invert ---\r\n");
1737 data = READ_MPEG_REG(TS_TOP_CONFIG);
1738 data |= 1 << TS_OUT_CLK_INVERT;
1739 WRITE_MPEG_REG(TS_TOP_CONFIG, data);
1740 }
1741
1742 if (src == AM_TS_SRC_HIU1) {
1743 WRITE_MPEG_REG(TS_HIU1_CONFIG,
1744 (demux_skipbyte << FILE_M2TS_SKIP_BYTES_HIU1) |
1745 (hiu << TS_HIU_ENABLE_HIU1) |
1746 (fec_clk << FEC_CLK_DIV_HIU1) |
1747 (0xBB << TS_PACKAGE_LENGTH_SUB_1_HIU1) |
1748 (0x47 << FEC_SYNC_BYTE_HIU1));
1749 } else {
1750 /* invert ts out clk end */
1751 WRITE_MPEG_REG(TS_FILE_CONFIG,
1752 (demux_skipbyte << 16) |
1753 (6 << DES_OUT_DLY) |
1754 (3 << TRANSPORT_SCRAMBLING_CONTROL_ODD) |
1755 (3 << TRANSPORT_SCRAMBLING_CONTROL_ODD_2) |
1756 (hiu << TS_HIU_ENABLE) | (fec_clk << FEC_FILE_CLK_DIV));
1757 }
1758}
1759
1760int dsc_set_pid(struct aml_dsc_channel *ch, int pid)
1761{
1762 struct aml_dsc *dsc = ch->dsc;
1763 int is_dsc2 = (dsc->id == 1) ? 1 : 0;
1764 u32 data;
1765
1766 WRITE_MPEG_REG(TS_PL_PID_INDEX,
1767 ((ch->id & 0x0f) >> 1)+(is_dsc2 ? 4 : 0));
1768 data = READ_MPEG_REG(TS_PL_PID_DATA);
1769 if (ch->id & 1) {
1770 data &= 0xFFFF0000;
1771 data |= pid & 0x1fff;
1772 if (!ch->used)
1773 data |= 1 << PID_MATCH_DISABLE_LOW;
1774 } else {
1775 data &= 0xFFFF;
1776 data |= (pid & 0x1fff) << 16;
1777 if (!ch->used)
1778 data |= 1 << PID_MATCH_DISABLE_HIGH;
1779 }
1780 WRITE_MPEG_REG(TS_PL_PID_INDEX,
1781 ((ch->id & 0x0f) >> 1)+(is_dsc2 ? 4 : 0));
1782 WRITE_MPEG_REG(TS_PL_PID_DATA, data);
1783 WRITE_MPEG_REG(TS_PL_PID_INDEX, 0);
1784
1785 if (ch->used)
1786 pr_dbg("set DSC %d ch %d PID %d\n", dsc->id, ch->id, pid);
1787 else
1788 pr_dbg("disable DSC %d ch %d\n", dsc->id, ch->id);
1789 return 0;
1790}
1791
1792int dsc_get_pid(struct aml_dsc_channel *ch, int *pid)
1793{
1794 struct aml_dsc *dsc = ch->dsc;
1795 int is_dsc2 = (dsc->id == 1) ? 1 : 0;
1796 u32 data;
1797
1798 WRITE_MPEG_REG(TS_PL_PID_INDEX,
1799 ((ch->id & 0x0f) >> 1)+(is_dsc2 ? 4 : 0));
1800 data = READ_MPEG_REG(TS_PL_PID_DATA);
1801 if (ch->id & 1) {
1802 *pid = data & 0x1fff;
1803 } else {
1804 *pid = (data >> 16) & 0x1fff;
1805 }
1806
1807 /*pr_dbg("%s,get DSC %d ch %d PID %d\n", __FUNCTION__,dsc->id, ch->id, *pid);*/
1808 return 0;
1809}
1810
1811int dsc_set_key(struct aml_dsc_channel *ch, int flags, enum ca_cw_type type,
1812 u8 *key)
1813{
1814 /*struct aml_dsc *dsc = ch->dsc;*/
1815 int ret = -1;
1816
1817 switch (type) {
1818 case CA_CW_DVB_CSA_EVEN:
1819 case CA_CW_DVB_CSA_ODD:
1820 aml_ci_plus_disable();
1821 ret = dsc_set_csa_key(ch, flags, type, key);
1822 if (ret != 0)
1823 goto END;
1824 /* Different with old mode, do change */
1825 if (ch->work_mode == CIPLUS_MODE || ch->work_mode == -1) {
1826 if (ch->work_mode == -1)
1827 pr_inf("dsc[%d:%d] enable\n",
1828 ch->dsc->id, ch->id);
1829 else
1830 pr_inf("dsc[%d:%d] enable (from ciplus)\n",
1831 ch->dsc->id, ch->id);
1832 ch->mode = ECB_MODE;
1833 ch->work_mode = DVBCSA_MODE;
1834 }
1835 break;
1836 case CA_CW_AES_EVEN:
1837 case CA_CW_AES_ODD:
1838 case CA_CW_AES_EVEN_IV:
1839 case CA_CW_AES_ODD_IV:
1840 case CA_CW_DES_EVEN:
1841 case CA_CW_DES_ODD:
1842 case CA_CW_SM4_EVEN:
1843 case CA_CW_SM4_ODD:
1844 case CA_CW_SM4_EVEN_IV:
1845 case CA_CW_SM4_ODD_IV:
1846 am_ci_plus_set_output(ch);
1847 ret = dsc_set_aes_des_sm4_key(ch, flags, type, key);
1848 if (ret != 0)
1849 goto END;
1850 /* Different with old mode, do change */
1851 if (ch->work_mode == DVBCSA_MODE || ch->work_mode == -1) {
1852 if (ch->work_mode == -1)
1853 pr_inf("dsc[%d:%d] ciplus enable\n",
1854 ch->dsc->id, ch->id);
1855 else
1856 pr_inf("dsc[%d:%d] ciplus enable (from dsc)\n",
1857 ch->dsc->id, ch->id);
1858 ch->work_mode = CIPLUS_MODE;
1859 }
1860 break;
1861 default:
1862 break;
1863 }
1864END:
1865 return ret;
1866}
1867
1868int dsc_set_keys(struct aml_dsc_channel *ch)
1869{
1870 int types = ch->set & 0xFFFFFF;
1871 int flag = (ch->set >> 24) & 0xFF;
1872 int i;
1873 u8 *k;
1874 int ret = 0;
1875
1876 for (i = 0; i < CA_CW_TYPE_MAX; i++) {
1877 if (types & (1 << i)) {
1878 k = NULL;
1879 switch (i) {
1880 case CA_CW_DVB_CSA_EVEN:
1881 case CA_CW_AES_EVEN:
1882 case CA_CW_DES_EVEN:
1883 case CA_CW_SM4_EVEN:
1884 k = ch->even;
1885 break;
1886 case CA_CW_DVB_CSA_ODD:
1887 case CA_CW_AES_ODD:
1888 case CA_CW_DES_ODD:
1889 case CA_CW_SM4_ODD:
1890 k = ch->odd;
1891 break;
1892 case CA_CW_AES_EVEN_IV:
1893 case CA_CW_SM4_EVEN_IV:
1894 k = ch->even_iv;
1895 break;
1896 case CA_CW_AES_ODD_IV:
1897 case CA_CW_SM4_ODD_IV:
1898 k = ch->odd_iv;
1899 break;
1900 default:
1901 break;
1902 }
1903 /*
1904 if (k)
1905 pr_inf("dsc ch:%d flag:%d type:%d\n", ch->id, flag, i);
1906 */
1907 if (k)
1908 ret = dsc_set_key(ch, flag,
1909 i,
1910 k);
1911 }
1912 }
1913 return 0;
1914}
1915
1916static int dsc_set_csa_key(struct aml_dsc_channel *ch, int flags,
1917 enum ca_cw_type type, u8 *key)
1918{
1919 struct aml_dsc *dsc = ch->dsc;
1920 int is_dsc2 = (dsc->id == 1) ? 1 : 0;
1921 u16 k0, k1, k2, k3;
1922 u32 key0, key1;
1923 int reg;
1924
1925 if (flags & DSC_FROM_KL) {
1926 k0 = k1 = k2 = k3 = 0;
1927 /*dummy write to check if kl not working*/
1928 key0 = key1 = 0;
1929 WRITE_MPEG_REG(COMM_DESC_KEY0, key0);
1930 WRITE_MPEG_REG(COMM_DESC_KEY1, key1);
1931
1932 /*tdes? :*/
1933 if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB) {
1934 WRITE_MPEG_REG(COMM_DESC_KEY_RW,
1935/* (type ? (1 << 6) : (1 << 5)) | */
1936 ((1 << 5)) |
1937 ((ch->id + type * DSC_COUNT)+
1938 (is_dsc2 ? 16 : 0)));
1939 }
1940 if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXL ||
1941 get_cpu_type() == MESON_CPU_MAJOR_ID_GXM) {
1942 pr_info("do kl..\n");
1943 WRITE_MPEG_REG(COMM_DESC_KEY_RW,
1944 (type ? (1 << 6) : (1 << 5)) | (1<<7) |
1945 ((ch->id + type * DSC_COUNT)+
1946 (is_dsc2 ? 16 : 0)));
1947 }
1948 reg = (type ? (1 << 6) : (1 << 5)) |
1949 ((ch->id + type * DSC_COUNT)+
1950 (is_dsc2 ? 16 : 0));
1951 } else {
1952 k0 = (key[0] << 8) | key[1];
1953 k1 = (key[2] << 8) | key[3];
1954 k2 = (key[4] << 8) | key[5];
1955 k3 = (key[6] << 8) | key[7];
1956
1957 key0 = (k0 << 16) | k1;
1958 key1 = (k2 << 16) | k3;
1959 WRITE_MPEG_REG(COMM_DESC_KEY0, key0);
1960 WRITE_MPEG_REG(COMM_DESC_KEY1, key1);
1961
1962 reg = (ch->id + type * DSC_COUNT)+(is_dsc2 ? 16 : 0);
1963 WRITE_MPEG_REG(COMM_DESC_KEY_RW, reg);
1964 }
1965
1966 return 0;
1967}
1968
1969/************************* AES DESC************************************/
1970/*#define STB_TOP_CONFIG 0x16f0
1971#define CIPLUS_KEY0 0x16f8
1972#define CIPLUS_KEY1 0x16f9
1973#define CIPLUS_KEY2 0x16fa
1974#define CIPLUS_KEY3 0x16fb
1975#define CIPLUS_KEY_WR 0x16fc
1976#define CIPLUS_CONFIG 0x16fd
1977#define CIPLUS_ENDIAN 0x16fe*/
1978
1979#define ENABLE_DEC_PL 7
1980#define ENABLE_DES_PL_CLK 15
1981
1982#define KEY_WR_AES_IV_B 5
1983#define KEY_WR_AES_IV_A 4
1984#define KEY_WR_AES_B 3
1985#define KEY_WR_AES_A 2
1986#define KEY_WR_DES_B 1
1987#define KEY_WR_DES_A 0
1988
1989#define IDSA_MODE_BIT 31
1990#define SM4_MODE 30
1991#define CNTL_ENABLE 3
1992#define AES_CBC_DISABLE 2
1993#define AES_EN 1
1994#define DES_EN 0
1995
1996#define AES_MSG_OUT_ENDIAN 24
1997#define AES_MSG_IN_ENDIAN 20
1998#define AES_KEY_ENDIAN 16
1999#define DES_MSG_OUT_ENDIAN 8
2000#define DES_MSG_IN_ENDIAN 4
2001#define DES_KEY_ENDIAN 0
2002
2003#define ALGO_AES 0
2004#define ALGO_SM4 1
2005#define ALGO_DES 2
2006
2007#if 0
2008static void aml_ci_plus_set_stb(void)
2009{
2010 unsigned int data;
2011 /* data = READ_MPEG_REG(FEC_INPUT_CONTROL); */
2012 /* data |= (0<<FEC_SEL); */
2013 /* data |= (1<<FEC_CORE_SEL); */
2014 /* data |= (1<<FEC_INPUT_FEC_CLK);
2015 * local playback will not work if set this
2016 */
2017 /* WRITE_MPEG_REG(FEC_INPUT_CONTROL, data); */
2018
2019 data = READ_MPEG_REG(STB_TOP_CONFIG);
2020 WRITE_MPEG_REG(STB_TOP_CONFIG, data |
2021 (0 << CIPLUS_IN_SEL) | (0 << CIPLUS_OUT_SEL));
2022 data = READ_MPEG_REG(STB_TOP_CONFIG);
2023 /* data |= (1<<ENABLE_DEC_PL); bit 7 --
2024 * enable_des_pl, this step was set in dsc_enable
2025 */
2026 /*bit 15 -- enable_des_pl_clk*/
2027 /* data |= (1<<ENABLE_DES_PL_CLK); */
2028 data |= (1<<CIPLUS_OUT_SEL);/*bit 28 -- ciplus_out_sel from ciplus*/
2029 WRITE_MPEG_REG(STB_TOP_CONFIG, data);
2030 data = READ_MPEG_REG(STB_TOP_CONFIG);
2031}
2032#endif
2033
2034/*
2035 * param:
2036 * key:
2037 * 16bytes IV key
2038 * type:
2039 * AM_DSC_KEY_TYPE_AES_ODD IV odd key
2040 * AM_DSC_KEY_TYPE_AES_EVEN IV even key
2041 */
2042void aml_ci_plus_set_iv(struct aml_dsc_channel *ch, enum ca_cw_type type,
2043 u8 *key)
2044{
2045 unsigned int k0, k1, k2, k3;
2046
2047 k3 = (key[0] << 24) | (key[1] << 16) | (key[2] << 8) | key[3];
2048 k2 = (key[4] << 24) | (key[5] << 16) | (key[6] << 8) | key[7];
2049 k1 = (key[8] << 24) | (key[9] << 16) | (key[10] << 8) | key[11];
2050 k0 = (key[12] << 24) | (key[13] << 16) | (key[14] << 8) | key[15];
2051
2052 if (type == CA_CW_AES_EVEN_IV ||
2053 type == CA_CW_SM4_EVEN_IV) {
2054 WRITE_MPEG_REG(CIPLUS_KEY0, k0);
2055 WRITE_MPEG_REG(CIPLUS_KEY1, k1);
2056 WRITE_MPEG_REG(CIPLUS_KEY2, k2);
2057 WRITE_MPEG_REG(CIPLUS_KEY3, k3);
2058 WRITE_MPEG_REG(CIPLUS_KEY_WR,
2059 (ch->id << 9) | (1<<KEY_WR_AES_IV_A));
2060 } else if (type == CA_CW_AES_ODD_IV ||
2061 type == CA_CW_SM4_ODD_IV) {
2062 WRITE_MPEG_REG(CIPLUS_KEY0, k0);
2063 WRITE_MPEG_REG(CIPLUS_KEY1, k1);
2064 WRITE_MPEG_REG(CIPLUS_KEY2, k2);
2065 WRITE_MPEG_REG(CIPLUS_KEY3, k3);
2066 WRITE_MPEG_REG(CIPLUS_KEY_WR,
2067 (ch->id << 9) | (1<<KEY_WR_AES_IV_B));
2068 }
2069}
2070
2071/*
2072 * Param:
2073 * key_endian
2074 * S905D 7 for kl 0 for set key directly
2075 * mode
2076 * 0 for ebc
2077 * 1 for cbc
2078 */
2079static void aml_ci_plus_config(int key_endian, int mode, int algo)
2080{
2081 unsigned int data;
2082 unsigned int idsa_mode = 0;
2083 unsigned int sm4_mode = 0;
2084 unsigned int cbc_disable = 0;
2085 unsigned int des_enable = 0;
2086 unsigned int aes_enable = 1;
2087
2088 pr_dbg("%s mode:%d,alog:%d\n",__FUNCTION__,mode,algo);
2089
2090 if (get_cpu_type() < MESON_CPU_MAJOR_ID_SM1) {
2091 WRITE_MPEG_REG(CIPLUS_ENDIAN,
2092 (15 << AES_MSG_OUT_ENDIAN)
2093 | (15 << AES_MSG_IN_ENDIAN)
2094 | (key_endian << AES_KEY_ENDIAN)
2095 |
2096 (15 << DES_MSG_OUT_ENDIAN)
2097 | (15 << DES_MSG_IN_ENDIAN)
2098 | (key_endian << DES_KEY_ENDIAN)
2099 );
2100 } else {
2101 WRITE_MPEG_REG(CIPLUS_ENDIAN, 0);
2102 }
2103
2104 data = READ_MPEG_REG(CIPLUS_ENDIAN);
2105
2106 if (algo == ALGO_SM4) {
2107 sm4_mode = 1;
2108 } else if (algo == ALGO_AES){
2109 sm4_mode = 0;
2110 } else {
2111 sm4_mode = 0;
2112 des_enable = 1;
2113 }
2114
2115 if (mode == IDSA_MODE) {
2116 idsa_mode = 1;
2117 cbc_disable = 0;
2118 } else if (mode == CBC_MODE) {
2119 cbc_disable = 0;
2120 } else {
2121 cbc_disable = 1;
2122 }
2123 pr_dbg("idsa_mode:%d sm4_mode:%d cbc_disable:%d aes_enable:%d des_enable:%d\n", \
2124 idsa_mode,sm4_mode,cbc_disable,aes_enable,des_enable);
2125
2126 data = (idsa_mode << IDSA_MODE_BIT) |
2127 (sm4_mode << SM4_MODE ) |
2128 (cbc_disable << AES_CBC_DISABLE) |
2129 /*1 << AES_CBC_DISABLE : ECB
2130 *0 << AES_CBC_DISABLE : CBC
2131 */
2132 (1 << CNTL_ENABLE) |
2133 (aes_enable << AES_EN) |
2134 (des_enable << DES_EN);
2135
2136 WRITE_MPEG_REG(CIPLUS_CONFIG, data);
2137 data = READ_MPEG_REG(CIPLUS_CONFIG);
2138 pr_dbg("CIPLUS_CONFIG is 0x%x\n",data);
2139}
2140
2141/*
2142 * Set output to demux set.
2143 */
2144static void am_ci_plus_set_output(struct aml_dsc_channel *ch)
2145{
2146 struct aml_dsc *dsc = ch->dsc;
2147 u32 data;
2148 u32 in = 0, out = 0;
2149 int set = 0;
2150
2151 if (dsc->id != 0) {
2152 pr_error("Ciplus set output can only work at dsc0 device\n");
2153 return;
2154 }
2155
2156 switch (dsc->source) {
2157 case AM_TS_SRC_DMX0:
2158 in = 0;
2159 break;
2160 case AM_TS_SRC_DMX1:
2161 in = 1;
2162 break;
2163 case AM_TS_SRC_DMX2:
2164 in = 2;
2165 break;
2166 default:
2167 break;
2168 }
2169
2170 if (ciplus_out_auto_mode == 1) {
2171 switch (dsc->dst) {
2172 case AM_TS_SRC_DMX0:
2173 out = 1;
2174 break;
2175 case AM_TS_SRC_DMX1:
2176 out = 2;
2177 break;
2178 case AM_TS_SRC_DMX2:
2179 out = 4;
2180 break;
2181 default:
2182 break;
2183 }
2184 set = 1;
2185 ciplus_out_sel = out;
2186 } else if (ciplus_out_sel >= 0 && ciplus_out_sel <= 7) {
2187 set = 1;
2188 out = ciplus_out_sel;
2189 } else {
2190 pr_error("dsc ciplus out config is invalid\n");
2191 }
2192
2193 if (set) {
2194 /* Set ciplus input source ,
2195 * output set 0 means no output. ---> need confirm.
2196 * if output set 0 still affects dsc output, we need to disable
2197 * ciplus module.
2198 */
2199 data = READ_MPEG_REG(STB_TOP_CONFIG);
2200 data &= ~(3<<CIPLUS_IN_SEL);
2201 data |= in << CIPLUS_IN_SEL;
2202 data &= ~(7<<CIPLUS_OUT_SEL);
2203 data |= out << CIPLUS_OUT_SEL;
2204 WRITE_MPEG_REG(STB_TOP_CONFIG, data);
2205 pr_inf("dsc ciplus in[%x] out[%x] %s\n", in, out,
2206 (ciplus_out_auto_mode) ? "" : "force");
2207 }
2208}
2209
2210#if 0
2211/*
2212 * Ciplus output has high priority,
2213 * disable it's output will let dsc output go.
2214 */
2215static void aml_ci_plus_disable_output(void)
2216{
2217 u32 data = 0;
2218
2219 data = READ_MPEG_REG(STB_TOP_CONFIG);
2220 WRITE_MPEG_REG(STB_TOP_CONFIG, data &
2221 ~(7 << CIPLUS_OUT_SEL));
2222}
2223
2224static void aml_ci_plus_enable(void)
2225{
2226 u32 data = 0;
2227
2228 data = READ_MPEG_REG(STB_TOP_CONFIG);
2229 WRITE_MPEG_REG(CIPLUS_CONFIG,
2230 (1 << CNTL_ENABLE)
2231 | (1 << AES_EN)
2232 | (1 << DES_EN));
2233}
2234#endif
2235
2236static void aml_ci_plus_disable(void)
2237{
2238 u32 data = 0;
2239
2240 WRITE_MPEG_REG(CIPLUS_CONFIG, 0);
2241
2242 data = READ_MPEG_REG(STB_TOP_CONFIG);
2243 WRITE_MPEG_REG(STB_TOP_CONFIG, data &
2244 ~((1 << CIPLUS_IN_SEL) | (7 << CIPLUS_OUT_SEL)));
2245}
2246
2247static int dsc_set_aes_des_sm4_key(struct aml_dsc_channel *ch, int flags,
2248 enum ca_cw_type type, u8 *key)
2249{
2250 unsigned int k0, k1, k2, k3;
2251 int iv = 0, aes = 0, des = 0;
2252 int ab_iv = 0, ab_aes = 0, ab_des = 0;
2253 int from_kl = flags & CA_CW_FROM_KL;
2254 int algo = 0;
2255
2256 if (!from_kl) {
2257 if (get_cpu_type() < MESON_CPU_MAJOR_ID_SM1) {
2258 k3 = (key[0] << 24) | (key[1] << 16) | (key[2] << 8) | key[3];
2259 k2 = (key[4] << 24) | (key[5] << 16) | (key[6] << 8) | key[7];
2260 k1 = (key[8] << 24) | (key[9] << 16) | (key[10] << 8) | key[11];
2261 k0 = (key[12] << 24) | (key[13] << 16)
2262 | (key[14] << 8) | key[15];
2263 } else {
2264 k0 = (key[0]) | (key[1] << 8) | (key[2] << 16) | (key[3] << 24);
2265 k1 = (key[4]) | (key[5] << 8) | (key[6] << 16) | (key[7] << 24);
2266 k2 = (key[8]) | (key[9] << 8) | (key[10] << 16)| (key[11] << 24);
2267 k3 = (key[12])| (key[13] << 8)| (key[14] << 16)| (key[15] << 24);
2268 }
2269 } else
2270 k0 = k1 = k2 = k3 = 0;
2271
2272 switch (type) {
2273 case CA_CW_AES_EVEN:
2274 case CA_CW_SM4_EVEN:
2275 ab_aes = (from_kl) ? 0x2 : 0x1;
2276 if (ch->mode == -1)
2277 ch->mode = ECB_MODE;
2278 aes = 1;
2279 if (type == CA_CW_AES_EVEN)
2280 algo = ALGO_AES;
2281 else
2282 algo = ALGO_SM4;
2283 break;
2284 case CA_CW_AES_ODD:
2285 case CA_CW_SM4_ODD:
2286 ab_aes = (from_kl) ? 0x1 : 0x2;
2287 if (ch->mode == -1)
2288 ch->mode = ECB_MODE;
2289 aes = 1;
2290 if (type == CA_CW_AES_ODD)
2291 algo = ALGO_AES;
2292 else
2293 algo = ALGO_SM4;
2294 break;
2295 case CA_CW_AES_EVEN_IV:
2296 case CA_CW_SM4_EVEN_IV:
2297 ab_iv = 0x1;
2298 if (ch->mode == -1)
2299 ch->mode = CBC_MODE;
2300 iv = 1;
2301 if (type == CA_CW_AES_EVEN_IV)
2302 algo = ALGO_AES;
2303 else
2304 algo = ALGO_SM4;
2305 break;
2306 case CA_CW_AES_ODD_IV:
2307 case CA_CW_SM4_ODD_IV:
2308 ab_iv = 0x2;
2309 if (ch->mode == -1)
2310 ch->mode = CBC_MODE;
2311 iv = 1;
2312 if (type == CA_CW_AES_ODD_IV)
2313 algo = ALGO_AES;
2314 else
2315 algo = ALGO_SM4;
2316 break;
2317 case CA_CW_DES_EVEN:
2318 ab_des = 0x1;
2319 ch->mode = ECB_MODE;
2320 des = 1;
2321 algo = ALGO_DES;
2322 break;
2323 case CA_CW_DES_ODD:
2324 ab_des = 0x2;
2325 ch->mode = ECB_MODE;
2326 algo = ALGO_DES;
2327 des = 1;
2328 break;
2329 default:
2330 break;
2331 }
2332
2333 /* Set endian and cbc/ecb mode */
2334 if (from_kl)
2335 aml_ci_plus_config(7, ch->mode, algo);
2336 else
2337 aml_ci_plus_config(0, ch->mode, algo);
2338
2339 /* Write keys to work */
2340 if (iv || aes) {
2341 WRITE_MPEG_REG(CIPLUS_KEY0, k0);
2342 WRITE_MPEG_REG(CIPLUS_KEY1, k1);
2343 WRITE_MPEG_REG(CIPLUS_KEY2, k2);
2344 WRITE_MPEG_REG(CIPLUS_KEY3, k3);
2345 } else {/*des*/
2346 WRITE_MPEG_REG(CIPLUS_KEY0, k2);
2347 WRITE_MPEG_REG(CIPLUS_KEY1, k3);
2348 WRITE_MPEG_REG(CIPLUS_KEY2, 0);
2349 WRITE_MPEG_REG(CIPLUS_KEY3, 0);
2350 }
2351 WRITE_MPEG_REG(CIPLUS_KEY_WR,
2352 (ch->id << 9) |
2353 /* bit[11:9] the key of index,
2354 need match PID index*/
2355 ((from_kl && des) ? (1 << 8) : 0) |
2356 /* bit[8] des key use cw[127:64]*/
2357 (0 << 7) | /* bit[7] aes iv use cw*/
2358 ((from_kl && (aes || des)) ? (1 << 6) : 0) |
2359 /* bit[6] aes/des key use cw*/
2360 /* bit[5] write AES IV B value*/
2361 (ab_iv << 4) | /* bit[4] write AES IV A value*/
2362 /* bit[3] write AES B key*/
2363 (ab_aes << 2) | /* bit[2] write AES A key*/
2364 /* bit[1] write DES B key*/
2365 (ab_des)); /* bit[0] write DES A key*/
2366
2367 /*
2368 pr_inf("k:%08x:%08x:%08x:%08x kl:%d aes:%d des:%d ab_iv:%d ab_aes:%d ab_des:%d id:%d mod:%d\n",
2369 k0, k1, k2, k3,
2370 from_kl, aes, des, ab_iv, ab_aes, ab_des, ch->id, ch->aes_mode);
2371 */
2372 return 0;
2373}
2374
2375void dsc_release(void)
2376{
2377 aml_ci_plus_disable();
2378}
2379/************************* AES DESC************************************/
2380
2381int dsc_enable(struct aml_dsc *dsc, int enable)
2382{
2383 if (dsc->id == 0) {
2384 WRITE_MPEG_REG(STB_TOP_CONFIG,
2385 READ_MPEG_REG(STB_TOP_CONFIG) &
2386 ~((0x11 << DES_INPUT_SEL)|
2387 (1 << ENABLE_DES_PL)|
2388 (1 << ENABLE_DES_PL_CLK)));
2389 } else if (dsc->id == 1) {
2390 WRITE_MPEG_REG(COMM_DESC_2_CTL, 0);
2391 }
2392 return 0;
2393}
2394
2395/*Set section buffer*/
2396static int dmx_alloc_sec_buffer(struct aml_dmx *dmx)
2397{
2398 unsigned long base;
2399 unsigned long grp_addr[SEC_BUF_GRP_COUNT];
2400 int grp_len[SEC_BUF_GRP_COUNT];
2401 int i;
2402
2403 if (dmx->sec_pages)
2404 return 0;
2405
2406 grp_len[0] = (1 << SEC_GRP_LEN_0) * 8;
2407 grp_len[1] = (1 << SEC_GRP_LEN_1) * 8;
2408 grp_len[2] = (1 << SEC_GRP_LEN_2) * 8;
2409 grp_len[3] = (1 << SEC_GRP_LEN_3) * 8;
2410
2411 dmx->sec_total_len = grp_len[0] + grp_len[1] + grp_len[2] + grp_len[3];
2412 dmx->sec_pages =
2413 __get_free_pages(GFP_KERNEL, get_order(dmx->sec_total_len));
2414 if (!dmx->sec_pages) {
2415 pr_error("cannot allocate section buffer %d bytes %d order\n",
2416 dmx->sec_total_len, get_order(dmx->sec_total_len));
2417 return -1;
2418 }
2419 dmx->sec_pages_map =
2420 dma_map_single(dmx_get_dev(dmx), (void *)dmx->sec_pages,
2421 dmx->sec_total_len, DMA_FROM_DEVICE);
2422
2423 grp_addr[0] = dmx->sec_pages_map;
2424
2425 grp_addr[1] = grp_addr[0] + grp_len[0];
2426 grp_addr[2] = grp_addr[1] + grp_len[1];
2427 grp_addr[3] = grp_addr[2] + grp_len[2];
2428
2429 dmx->sec_buf[0].addr = dmx->sec_pages;
2430 dmx->sec_buf[0].len = grp_len[0] / 8;
2431
2432 for (i = 1; i < SEC_BUF_COUNT; i++) {
2433 dmx->sec_buf[i].addr =
2434 dmx->sec_buf[i - 1].addr + dmx->sec_buf[i - 1].len;
2435 dmx->sec_buf[i].len = grp_len[i / 8] / 8;
2436 }
2437
2438 base = grp_addr[0] & 0xFFFF0000;
2439 DMX_WRITE_REG(dmx->id, SEC_BUFF_BASE, base >> 16);
2440 DMX_WRITE_REG(dmx->id, SEC_BUFF_01_START,
2441 (((grp_addr[0] - base) >> 8) << 16) |
2442 ((grp_addr[1] - base) >> 8));
2443 DMX_WRITE_REG(dmx->id, SEC_BUFF_23_START,
2444 (((grp_addr[2] - base) >> 8) << 16) |
2445 ((grp_addr[3] - base) >> 8));
2446 DMX_WRITE_REG(dmx->id, SEC_BUFF_SIZE,
2447 SEC_GRP_LEN_0 |
2448 (SEC_GRP_LEN_1 << 4) |
2449 (SEC_GRP_LEN_2 << 8) |
2450 (SEC_GRP_LEN_3 << 12));
2451
2452 return 0;
2453}
2454
2455#ifdef NO_SUB
2456/*Set subtitle buffer*/
2457static int dmx_alloc_sub_buffer(struct aml_dvb *dvb, struct aml_dmx *dmx)
2458{
2459#ifdef SUB_BUF_DMX
2460 unsigned long addr;
2461
2462 if (dmx->sub_pages)
2463 return 0;
2464
2465 /*check if use shared buf*/
2466 if (dvb->sub_pages) {
2467 dmx->sub_pages = dvb->sub_pages;
2468 dmx->sub_buf_len = dvb->sub_buf_len;
2469 dmx->sub_pages_map = dvb->sub_pages_map;
2470 goto end_alloc;
2471 }
2472
2473 dmx->sub_buf_len = 64 * 1024;
2474 dmx->sub_pages =
2475 __get_free_pages(GFP_KERNEL, get_order(dmx->sub_buf_len));
2476 if (!dmx->sub_pages) {
2477 pr_error("cannot allocate subtitle buffer\n");
2478 return -1;
2479 }
2480 dmx->sub_pages_map =
2481 dma_map_single(dmx_get_dev(dmx), (void *)dmx->sub_pages,
2482 dmx->sub_buf_len, DMA_FROM_DEVICE);
2483
2484end_alloc:
2485 addr = virt_to_phys((void *)dmx->sub_pages);
2486#ifndef SUB_PARSER
2487 DMX_WRITE_REG(dmx->id, SB_START, addr >> 12);
2488 DMX_WRITE_REG(dmx->id, SB_LAST_ADDR, (dmx->sub_buf_len >> 3) - 1);
2489#endif
2490 pr_inf("sub buff: (%d) %lx %x\n", dmx->id, addr, dmx->sub_buf_len);
2491#endif
2492 return 0;
2493}
2494#ifdef SUB_BUF_SHARED
2495static int dmx_alloc_sub_buffer_shared(struct aml_dvb *dvb)
2496{
2497#ifdef SUB_BUF_DMX
2498 if (dvb->sub_pages)
2499 return 0;
2500
2501 dvb->sub_buf_len = 64 * 1024;
2502 dvb->sub_pages =
2503 __get_free_pages(GFP_KERNEL, get_order(dvb->sub_buf_len));
2504 if (!dvb->sub_pages) {
2505 pr_error("cannot allocate subtitle buffer\n");
2506 return -1;
2507 }
2508 dvb->sub_pages_map =
2509 dma_map_single(dvb->dev, (void *)dvb->sub_pages,
2510 dvb->sub_buf_len, DMA_FROM_DEVICE);
2511
2512 pr_inf("sub buff shared: %lx %x\n",
2513 (unsigned long)virt_to_phys((void *)dvb->sub_pages),
2514 dvb->sub_buf_len);
2515#endif
2516 return 0;
2517}
2518#endif
2519#endif /*NO_SUB */
2520
2521/*Set PES buffer*/
2522static int dmx_alloc_pes_buffer(struct aml_dvb *dvb, struct aml_dmx *dmx)
2523{
2524 unsigned long addr;
2525
2526 if (dmx->pes_pages)
2527 return 0;
2528
2529 /*check if use shared buf*/
2530 if (dvb->pes_pages) {
2531 dmx->pes_pages = dvb->pes_pages;
2532 dmx->pes_buf_len = dvb->pes_buf_len;
2533 dmx->pes_pages_map = dvb->pes_pages_map;
2534 goto end_alloc;
2535 }
2536
2537 dmx->pes_buf_len = 64 * 1024;
2538 dmx->pes_pages =
2539 __get_free_pages(GFP_KERNEL, get_order(dmx->pes_buf_len));
2540 if (!dmx->pes_pages) {
2541 pr_error("cannot allocate pes buffer\n");
2542 return -1;
2543 }
2544 dmx->pes_pages_map =
2545 dma_map_single(dmx_get_dev(dmx), (void *)dmx->pes_pages,
2546 dmx->pes_buf_len, DMA_FROM_DEVICE);
2547end_alloc:
2548 addr = virt_to_phys((void *)dmx->pes_pages);
2549 DMX_WRITE_REG(dmx->id, OB_START, addr >> 12);
2550 DMX_WRITE_REG(dmx->id, OB_LAST_ADDR, (dmx->pes_buf_len >> 3) - 1);
2551
2552 pr_inf("pes buff: (%d) %lx %x\n", dmx->id, addr, dmx->pes_buf_len);
2553 return 0;
2554}
2555#ifdef PES_BUF_SHARED
2556static int dmx_alloc_pes_buffer_shared(struct aml_dvb *dvb)
2557{
2558 if (dvb->pes_pages)
2559 return 0;
2560
2561 dvb->pes_buf_len = 64 * 1024;
2562 dvb->pes_pages =
2563 __get_free_pages(GFP_KERNEL, get_order(dvb->pes_buf_len));
2564 if (!dvb->pes_pages) {
2565 pr_error("cannot allocate pes buffer\n");
2566 return -1;
2567 }
2568 dvb->pes_pages_map =
2569 dma_map_single(dvb->dev, (void *)dvb->pes_pages,
2570 dvb->pes_buf_len, DMA_FROM_DEVICE);
2571
2572 pr_inf("pes buff shared: %lx %x\n",
2573 (unsigned long)virt_to_phys((void *)dvb->pes_pages),
2574 dvb->pes_buf_len);
2575 return 0;
2576}
2577#endif
2578
2579/*Allocate ASYNC FIFO Buffer*/
2580static unsigned long asyncfifo_alloc_buffer(int len)
2581{
2582 unsigned long pages = __get_free_pages(GFP_KERNEL, get_order(len));
2583
2584 if (!pages) {
2585 pr_error("cannot allocate async fifo buffer\n");
2586 return 0;
2587 }
2588 return pages;
2589}
2590static void asyncfifo_free_buffer(unsigned long buf, int len)
2591{
2592 free_pages(buf, get_order(len));
2593}
2594
2595static int asyncfifo_set_buffer(struct aml_asyncfifo *afifo,
2596 int len, unsigned long buf)
2597{
2598 if (afifo->pages)
2599 return -1;
2600
2601 afifo->buf_toggle = 0;
2602 afifo->buf_read = 0;
2603 afifo->buf_len = len;
2604 pr_error("++++async fifo %d buf size %d, flush size %d\n",
2605 afifo->id, afifo->buf_len, afifo->flush_size);
2606
2607 if ((afifo->flush_size <= 0)
2608 || (afifo->flush_size > (afifo->buf_len>>1))) {
2609 afifo->flush_size = afifo->buf_len>>1;
2610 } else if (afifo->flush_size < 128) {
2611 afifo->flush_size = 128;
2612 } else {
2613 int fsize;
2614
2615 for (fsize = 128; fsize < (afifo->buf_len>>1); fsize <<= 1) {
2616 if (fsize >= afifo->flush_size)
2617 break;
2618 }
2619
2620 afifo->flush_size = fsize;
2621 }
2622
2623 afifo->pages = buf;
2624 if (!afifo->pages)
2625 return -1;
2626
2627 afifo->pages_map = dma_map_single(asyncfifo_get_dev(afifo),
2628 (void *)afifo->pages, afifo->buf_len, DMA_FROM_DEVICE);
2629
2630 return 0;
2631}
2632static void asyncfifo_put_buffer(struct aml_asyncfifo *afifo)
2633{
2634 if (afifo->pages) {
2635 dma_unmap_single(asyncfifo_get_dev(afifo),
2636 afifo->pages_map, afifo->buf_len, DMA_FROM_DEVICE);
2637 asyncfifo_free_buffer(afifo->pages, afifo->buf_len);
2638 afifo->pages_map = 0;
2639 afifo->pages = 0;
2640 }
2641}
2642
2643int async_fifo_init(struct aml_asyncfifo *afifo, int initirq,
2644 int buf_len, unsigned long buf)
2645{
2646 int ret = 0;
2647 int irq;
2648
2649 if (afifo->init)
2650 return -1;
2651
2652 afifo->source = AM_DMX_MAX;
2653 afifo->pages = 0;
2654 afifo->buf_toggle = 0;
2655 afifo->buf_read = 0;
2656 afifo->buf_len = 0;
2657
2658 if (afifo->asyncfifo_irq == -1) {
2659 pr_error("no irq for ASYNC_FIFO%d\n", afifo->id);
2660 /*Do not return error*/
2661 return -1;
2662 }
2663
2664 tasklet_init(&afifo->asyncfifo_tasklet,
2665 dvr_irq_bh_handler, (unsigned long)afifo);
2666 if (initirq)
2667 irq = request_irq(afifo->asyncfifo_irq, dvr_irq_handler,
2668 IRQF_SHARED|IRQF_TRIGGER_RISING,
2669 "dvr irq", afifo);
2670 else
2671 enable_irq(afifo->asyncfifo_irq);
2672
2673 /*alloc buffer*/
2674 ret = asyncfifo_set_buffer(afifo, buf_len, buf);
2675
2676 afifo->init = 1;
2677
2678 return ret;
2679}
2680
2681int async_fifo_deinit(struct aml_asyncfifo *afifo, int freeirq)
2682{
2683 struct aml_dvb *dvb = afifo->dvb;
2684 unsigned long flags;
2685
2686 if (!afifo->init)
2687 return 0;
2688
2689 spin_lock_irqsave(&dvb->slock, flags);
2690 CLEAR_ASYNC_FIFO_REG_MASK(afifo->id, REG1, 1 << ASYNC_FIFO_FLUSH_EN);
2691 CLEAR_ASYNC_FIFO_REG_MASK(afifo->id, REG2, 1 << ASYNC_FIFO_FILL_EN);
2692 spin_unlock_irqrestore(&dvb->slock, flags);
2693
2694 asyncfifo_put_buffer(afifo);
2695
2696 afifo->source = AM_DMX_MAX;
2697 afifo->buf_toggle = 0;
2698 afifo->buf_read = 0;
2699 afifo->buf_len = 0;
2700
2701 if (afifo->asyncfifo_irq != -1) {
2702 if (freeirq)
2703 free_irq(afifo->asyncfifo_irq, afifo);
2704 else
2705 disable_irq(afifo->asyncfifo_irq);
2706 }
2707 tasklet_kill(&afifo->asyncfifo_tasklet);
2708
2709 afifo->init = 0;
2710
2711 return 0;
2712}
2713
2714static int _dmx_smallsec_enable(struct aml_smallsec *ss, int bufsize)
2715{
2716 if (!ss->buf) {
2717
2718 ss->buf = __get_free_pages(GFP_KERNEL,
2719 get_order(bufsize));
2720 if (!ss->buf) {
2721 pr_error("cannot allocate smallsec buffer\n"
2722 "%d bytes %d order\n",
2723 bufsize, get_order(bufsize));
2724 return -1;
2725 }
2726 ss->buf_map = dma_map_single(dmx_get_dev(ss->dmx),
2727 (void *)ss->buf,
2728 bufsize, DMA_FROM_DEVICE);
2729 }
2730
2731 DMX_WRITE_REG(ss->dmx->id, DEMUX_SMALL_SEC_ADDR,
2732 ss->buf_map);
2733 DMX_WRITE_REG(ss->dmx->id, DEMUX_SMALL_SEC_CTL,
2734 ((((bufsize>>8)-1)&0xff)<<24) |
2735 (1<<1) |/*enable reset the wr ptr*/
2736 (1<<0));
2737
2738 ss->bufsize = bufsize;
2739 ss->enable = 1;
2740
2741 pr_inf("demux%d smallsec buf start: %lx, size: %d\n",
2742 ss->dmx->id, ss->buf, ss->bufsize);
2743 return 0;
2744}
2745
2746static int _dmx_smallsec_disable(struct aml_smallsec *ss)
2747{
2748 DMX_WRITE_REG(ss->dmx->id, DEMUX_SMALL_SEC_CTL, 0);
2749 if (ss->buf) {
2750 dma_unmap_single(dmx_get_dev(ss->dmx), ss->buf_map,
2751 ss->bufsize, DMA_FROM_DEVICE);
2752 free_pages(ss->buf, get_order(ss->bufsize));
2753 ss->buf = 0;
2754 ss->buf_map = 0;
2755 }
2756 ss->enable = 0;
2757 pr_inf("demux%d smallsec buf disable\n", ss->dmx->id);
2758 return 0;
2759}
2760
2761static int dmx_smallsec_set(struct aml_smallsec *ss, int enable, int bufsize,
2762 int force)
2763{
2764 if (!enable) {/*disable*/
2765
2766 if (ss->enable || force)
2767 _dmx_smallsec_disable(ss);
2768
2769 } else {/*enable*/
2770
2771 if (bufsize < 0)
2772 bufsize = SS_BUFSIZE_DEF;
2773 else if (!bufsize)
2774 bufsize = ss->bufsize;
2775 else {
2776 /*unit:FF max:FF00*/
2777 bufsize &= ~0xFF;
2778 bufsize &= 0x1FF00;
2779 }
2780
2781 if ((ss->enable && (bufsize != ss->bufsize)) || force)
2782 _dmx_smallsec_disable(ss);
2783
2784 if (!ss->enable)
2785 _dmx_smallsec_enable(ss, bufsize);
2786 }
2787
2788 return 0;
2789}
2790
2791static int _dmx_timeout_enable(struct aml_dmxtimeout *dto, int timeout,
2792 int ch_dis, int match)
2793{
2794
2795 DMX_WRITE_REG(dto->dmx->id, DEMUX_INPUT_TIMEOUT_C, ch_dis);
2796 DMX_WRITE_REG(dto->dmx->id, DEMUX_INPUT_TIMEOUT,
2797 ((!!match)<<31) |
2798 (timeout&0x7fffffff));
2799
2800 dto->ch_disable = ch_dis;
2801 dto->match = match;
2802 dto->timeout = timeout;
2803 dto->trigger = 0;
2804 dto->enable = 1;
2805
2806 pr_inf("demux%d timeout enable:timeout(%d),ch(0x%x),match(%d)\n",
2807 dto->dmx->id, dto->timeout, dto->ch_disable, dto->match);
2808
2809 return 0;
2810}
2811static int _dmx_timeout_disable(struct aml_dmxtimeout *dto)
2812{
2813
2814 DMX_WRITE_REG(dto->dmx->id, DEMUX_INPUT_TIMEOUT, 0);
2815 dto->enable = 0;
2816 dto->trigger = 0;
2817 pr_inf("demux%d timeout disable\n", dto->dmx->id);
2818
2819 return 0;
2820}
2821
2822static int dmx_timeout_set(struct aml_dmxtimeout *dto, int enable,
2823 int timeout, int ch_dis, int match,
2824 int force)
2825{
2826
2827 if (!enable) {/*disable*/
2828
2829 if (dto->enable || force)
2830 _dmx_timeout_disable(dto);
2831
2832 } else {/*enable*/
2833
2834 if (timeout < 0) {
2835 timeout = DTO_TIMEOUT_DEF;
2836 ch_dis = DTO_CHDIS_VAS;
2837 match = dto->match;
2838 } else if (!timeout) {
2839 timeout = dto->timeout;
2840 ch_dis = dto->ch_disable;
2841 match = dto->match;
2842 }
2843
2844 if ((dto->enable && (timeout != dto->timeout))
2845 || force)
2846 _dmx_timeout_disable(dto);
2847
2848 if (!dto->enable)
2849 _dmx_timeout_enable(dto, timeout, ch_dis, match);
2850 }
2851
2852 return 0;
2853}
2854
2855/*Initialize the registers*/
2856static int dmx_init(struct aml_dmx *dmx)
2857{
2858 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
2859 int irq;
2860 int ret = 0;
2861 char buf[32];
2862 u32 value = 0;
2863
2864 if (dmx->init)
2865 return 0;
2866
2867 pr_inf("demux init\n");
2868
2869 memset(buf, 0, 32);
2870 snprintf(buf, sizeof(buf), "asyncfifo_buf_len");
2871 ret = of_property_read_u32(dvb->pdev->dev.of_node, buf, &value);
2872 if (!ret) {
2873 pr_inf("%s: 0x%x\n", buf, value);
2874 asyncfifo_buf_len = value;
2875 }
2876 /*Register irq handlers */
2877 if (dmx->dmx_irq != -1) {
2878 pr_dbg("request irq\n");
2879 tasklet_init(&dmx->dmx_tasklet,
2880 dmx_irq_bh_handler,
2881 (unsigned long)dmx);
2882 irq = request_irq(dmx->dmx_irq, dmx_irq_handler,
2883 IRQF_SHARED|IRQF_TRIGGER_RISING,
2884 "dmx irq", dmx);
2885 }
2886
2887 /*Allocate buffer */
2888 if (dmx_alloc_sec_buffer(dmx) < 0)
2889 return -1;
2890#ifdef NO_SUB
2891#ifdef SUB_BUF_SHARED
2892 if (dmx_alloc_sub_buffer_shared(dvb) < 0)
2893 return -1;
2894#endif
2895 if (dmx_alloc_sub_buffer(dvb, dmx) < 0)
2896 return -1;
2897#endif
2898#ifdef PES_BUF_SHARED
2899 if (dmx_alloc_pes_buffer_shared(dvb) < 0)
2900 return -1;
2901#endif
2902 if (dmx_alloc_pes_buffer(dvb, dmx) < 0)
2903 return -1;
2904 /*Reset the hardware */
2905 if (!dvb->dmx_init) {
2906 init_timer(&dvb->watchdog_timer);
2907 dvb->watchdog_timer.function = section_buffer_watchdog_func;
2908 dvb->watchdog_timer.expires =
2909 jiffies + msecs_to_jiffies(WATCHDOG_TIMER);
2910 dvb->watchdog_timer.data = (unsigned long)dvb;
2911#ifdef ENABLE_SEC_BUFF_WATCHDOG
2912 add_timer(&dvb->watchdog_timer);
2913#endif
2914 dmx_reset_hw(dvb);
2915 }
2916
2917 dvb->dmx_init++;
2918
2919 memset(dmx->sec_buf_watchdog_count, 0,
2920 sizeof(dmx->sec_buf_watchdog_count));
2921
2922 dmx->init = 1;
2923
2924 return 0;
2925}
2926
2927/*Release the resource*/
2928static int dmx_deinit(struct aml_dmx *dmx)
2929{
2930 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
2931
2932 if (!dmx->init)
2933 return 0;
2934
2935 DMX_WRITE_REG(dmx->id, DEMUX_CONTROL, 0);
2936
2937 dvb->dmx_init--;
2938
2939 /*Reset the hardware */
2940 if (!dvb->dmx_init) {
2941 dmx_reset_hw(dvb);
2942#ifdef ENABLE_SEC_BUFF_WATCHDOG
2943 del_timer_sync(&dvb->watchdog_timer);
2944#endif
2945 }
2946
2947 if (dmx->sec_pages) {
2948 dma_unmap_single(dmx_get_dev(dmx), dmx->sec_pages_map,
2949 dmx->sec_total_len, DMA_FROM_DEVICE);
2950 free_pages(dmx->sec_pages, get_order(dmx->sec_total_len));
2951 dmx->sec_pages = 0;
2952 dmx->sec_pages_map = 0;
2953 }
2954#ifdef NO_SUB
2955#ifdef SUB_BUF_DMX
2956#ifdef SUB_BUF_SHARED
2957 if (dvb->sub_pages) {
2958 dma_unmap_single(dvb->dev, dvb->sub_pages_map,
2959 dvb->sub_buf_len, DMA_FROM_DEVICE);
2960 free_pages(dvb->sub_pages, get_order(dvb->sub_buf_len));
2961 dvb->sub_pages = 0;
2962 }
2963 dmx->sub_pages = 0;
2964#else
2965 if (dmx->sub_pages) {
2966 dma_unmap_single(dmx_get_dev(dmx), dmx->sub_pages_map,
2967 dmx->sub_buf_len, DMA_FROM_DEVICE);
2968 free_pages(dmx->sub_pages, get_order(dmx->sub_buf_len));
2969 dmx->sub_pages = 0;
2970 }
2971#endif
2972#endif
2973#endif
2974#ifdef PES_BUF_SHARED
2975 if (dvb->pes_pages) {
2976 dma_unmap_single(dvb->dev, dvb->pes_pages_map,
2977 dvb->pes_buf_len, DMA_FROM_DEVICE);
2978 free_pages(dvb->pes_pages, get_order(dvb->pes_buf_len));
2979 dvb->pes_pages = 0;
2980 }
2981 dmx->pes_pages = 0;
2982#else
2983 if (dmx->pes_pages) {
2984 dma_unmap_single(dmx_get_dev(dmx), dmx->pes_pages_map,
2985 dmx->pes_buf_len, DMA_FROM_DEVICE);
2986 free_pages(dmx->pes_pages, get_order(dmx->pes_buf_len));
2987 dmx->pes_pages = 0;
2988 }
2989#endif
2990 if (dmx->dmx_irq != -1) {
2991 free_irq(dmx->dmx_irq, dmx);
2992 tasklet_kill(&dmx->dmx_tasklet);
2993 }
2994
2995 dmx->init = 0;
2996
2997 return 0;
2998}
2999
3000/*Check the record flag*/
3001static int dmx_get_record_flag(struct aml_dmx *dmx)
3002{
3003 int i, linked = 0, record_flag = 0;
3004 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
3005
3006 /*Check whether a async fifo connected to this dmx */
3007 for (i = 0; i < dvb->async_fifo_total_count; i++) {
3008 if (!dvb->asyncfifo[i].init)
3009 continue;
3010 if ((dvb->asyncfifo[i].source == dmx->id)
3011 /*&& !(dvb->swfilter.user && (i==SF_AFIFO_ID)) */
3012 /*sf mode reserved */
3013 ) {
3014 linked = 1;
3015 break;
3016 }
3017 }
3018
3019 for (i = 0; i < CHANNEL_COUNT; i++) {
3020 if (dmx->channel[i].used && dmx->channel[i].dvr_feed) {
3021 if (!dmx->record) {
3022 dmx->record = 1;
3023
3024 if (linked) {
3025 /*A new record will start,
3026 * must reset the async fifos for
3027 * linking the right demux
3028 */
3029 reset_async_fifos(dvb);
3030 }
3031 }
3032 if (linked)
3033 record_flag = 1;
3034 goto find_done;
3035 }
3036 }
3037
3038 if (dmx->record) {
3039 dmx->record = 0;
3040 if (linked) {
3041 /*A record will stop, reset the async fifos
3042 *for linking the right demux
3043 */
3044 reset_async_fifos(dvb);
3045 }
3046 }
3047
3048find_done:
3049 return record_flag;
3050}
3051
3052static void dmx_cascade_set(int cur_dmx, int source) {
3053 int fec_sel_demux = 0;
3054 int data;
3055
3056 switch (source) {
3057 case AM_TS_SRC_DMX0:
3058 case AM_TS_SRC_DMX1:
3059 case AM_TS_SRC_DMX2:
3060 fec_sel_demux = source -AM_TS_SRC_DMX0;
3061 break;
3062 default:
3063 fec_sel_demux = cur_dmx;
3064 break;
3065 }
3066
3067 data = READ_MPEG_REG(TS_TOP_CONFIG1);
3068 data &= ~(0x3 << (cur_dmx*2));
3069 data |= (fec_sel_demux << (cur_dmx*2));
3070 WRITE_MPEG_REG(TS_TOP_CONFIG1,data);
3071
3072 pr_dbg("%s id:%d, source:%d data:0x%0x\n",__FUNCTION__,cur_dmx,fec_sel_demux,data);
3073}
3074
3075/*Enable the demux device*/
3076static int dmx_enable(struct aml_dmx *dmx)
3077{
3078 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
3079 int fec_sel, hi_bsf, fec_ctrl, record;
3080 int fec_core_sel = 0;
3081 int set_stb = 0, fec_s = 0;
3082 int s2p_id;
3083 u32 invert0 = 0, invert1 = 0, invert2 = 0, fec_s0 = 0, fec_s1 = 0, fec_s2 = 0;
3084 u32 use_sop = 0;
3085
3086 record = dmx_get_record_flag(dmx);
3087 if (use_of_sop == 1) {
3088 use_sop = 1;
3089 pr_inf("dmx use of sop input\r\n");
3090 }
3091 switch (dmx->source) {
3092 case AM_TS_SRC_TS0:
3093 fec_sel = 0;
3094 fec_ctrl = dvb->ts[0].control;
3095 record = record ? 1 : 0;
3096 break;
3097 case AM_TS_SRC_TS1:
3098 fec_sel = 1;
3099 fec_ctrl = dvb->ts[1].control;
3100 record = record ? 1 : 0;
3101 break;
3102 case AM_TS_SRC_TS2:
3103 fec_sel = 2;
3104 fec_ctrl = dvb->ts[2].control;
3105 record = record ? 1 : 0;
3106 break;
3107 case AM_TS_SRC_TS3:
3108 fec_sel = 3;
3109 fec_ctrl = dvb->ts[3].control;
3110 record = record ? 1 : 0;
3111 break;
3112 case AM_TS_SRC_S_TS0:
3113 case AM_TS_SRC_S_TS1:
3114 case AM_TS_SRC_S_TS2:
3115 s2p_id = 0;
3116 fec_ctrl = 0;
3117 if (dmx->source == AM_TS_SRC_S_TS0) {
3118 s2p_id = dvb->ts[0].s2p_id;
3119 fec_ctrl = dvb->ts[0].control;
3120 } else if (dmx->source == AM_TS_SRC_S_TS1) {
3121 s2p_id = dvb->ts[1].s2p_id;
3122 fec_ctrl = dvb->ts[1].control;
3123 } else if (dmx->source == AM_TS_SRC_S_TS2) {
3124 s2p_id = dvb->ts[2].s2p_id;
3125 fec_ctrl = dvb->ts[2].control;
3126 }
3127 //fec_sel = (s2p_id == 1) ? 5 : 6;
3128 fec_sel = 6 - s2p_id;
3129 record = record ? 1 : 0;
3130 set_stb = 1;
3131 fec_s = dmx->source - AM_TS_SRC_S_TS0;
3132 break;
3133 case AM_TS_SRC_HIU:
3134 fec_sel = 7;
3135 fec_ctrl = 0;
3136 /*
3137 support record in HIU mode
3138 record = 0;
3139 */
3140 break;
3141 case AM_TS_SRC_HIU1:
3142 fec_sel = 8;
3143 fec_ctrl = 0;
3144 /*
3145 support record in HIU mode
3146 record = 0;
3147 */
3148 break;
3149 case AM_TS_SRC_DMX0:
3150 case AM_TS_SRC_DMX1:
3151 case AM_TS_SRC_DMX2:
3152 fec_sel = -1;
3153 fec_ctrl = 0;
3154 record = record ? 1 : 0;
3155 break;
3156 default:
3157 fec_sel = 0;
3158 fec_ctrl = 0;
3159 record = 0;
3160 break;
3161 }
3162
3163 if (dmx->channel[0].used || dmx->channel[1].used) {
3164 hi_bsf = 1;
3165 if (fec_sel == 8) {
3166 hi_bsf = 2; /*hi_bsf select hiu1*/
3167 }
3168 }else {
3169 hi_bsf = 0;
3170 }
3171 if ((dvb->dsc[0].dst != -1)
3172 && ((dvb->dsc[0].dst - AM_TS_SRC_DMX0) == dmx->id))
3173 fec_core_sel = 1;
3174
3175 if ((dvb->dsc[1].dst != -1)
3176 && ((dvb->dsc[1].dst - AM_TS_SRC_DMX0) == dmx->id)) {
3177 int des_in, des_out, en_des = 0;
3178
3179 switch (dvb->dsc[1].source) {
3180 case AM_TS_SRC_DMX0:
3181 des_in = 0;
3182 en_des = 1;
3183 break;
3184 case AM_TS_SRC_DMX1:
3185 des_in = 1;
3186 en_des = 1;
3187 break;
3188 case AM_TS_SRC_DMX2:
3189 des_in = 2;
3190 en_des = 1;
3191 break;
3192 default:
3193 des_in = 0;
3194 en_des = 0;
3195 break;
3196 }
3197
3198 switch (dvb->dsc[1].dst) {
3199 case AM_TS_SRC_DMX0:
3200 des_out = 1;
3201 break;
3202 case AM_TS_SRC_DMX1:
3203 des_out = 2;
3204 break;
3205 case AM_TS_SRC_DMX2:
3206 des_out = 4;
3207 break;
3208 default:
3209 des_out = 0;
3210 break;
3211 }
3212
3213 if (!des_out)
3214 en_des = 0;
3215
3216 WRITE_MPEG_REG(COMM_DESC_2_CTL,
3217 (6 << 8) |/*des_out_dly_2*/
3218 ((!!en_des) << 6) |/* des_pl_clk_2*/
3219 ((!!en_des) << 5) |/* des_pl_2*/
3220 (des_out << 2) |/*use_des_2*/
3221 (des_in)/*des_i_sel_2*/
3222 );
3223 fec_core_sel = 1;
3224 pr_dbg("dsc2 ctrl: 0x%x\n", READ_MPEG_REG(COMM_DESC_2_CTL));
3225 }
3226
3227 pr_dbg("[dmx-%d]src: %d, rec: %d, hi_bsf: %d, dsc: %d\n",
3228 dmx->id, dmx->source, record, hi_bsf, fec_core_sel);
3229
3230 if (dmx->chan_count) {
3231 if (set_stb) {
3232 u32 v = READ_MPEG_REG(STB_TOP_CONFIG);
3233 int i;
3234
3235 for (i = 0; i < dvb->ts_in_total_count; i++) {
3236 if (dvb->ts[i].s2p_id == 0)
3237 fec_s0 = i;
3238 else if (dvb->ts[i].s2p_id == 1)
3239 fec_s1 = i;
3240 else if (dvb->ts[i].s2p_id == 2)
3241 fec_s2 = i;
3242 }
3243
3244 invert0 = dvb->s2p[0].invert;
3245 invert1 = dvb->s2p[1].invert;
3246
3247 v &= ~((0x3 << S2P0_FEC_SERIAL_SEL) |
3248 (0x1f << INVERT_S2P0_FEC_CLK) |
3249 (0x3 << S2P1_FEC_SERIAL_SEL) |
3250 (0x1f << INVERT_S2P1_FEC_CLK));
3251
3252 v |= (fec_s0 << S2P0_FEC_SERIAL_SEL) |
3253 (invert0 << INVERT_S2P0_FEC_CLK) |
3254 (fec_s1 << S2P1_FEC_SERIAL_SEL) |
3255 (invert1 << INVERT_S2P1_FEC_CLK);
3256 WRITE_MPEG_REG(STB_TOP_CONFIG, v);
3257
3258 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TL1) {
3259 invert2 = dvb->s2p[2].invert;
3260
3261 //add s2p2 config
3262 v = READ_MPEG_REG(STB_S2P2_CONFIG);
3263 v &= ~((0x3 << S2P2_FEC_SERIAL_SEL) |
3264 (0x1f << INVERT_S2P2_FEC_CLK));
3265 v |= (fec_s2 << S2P2_FEC_SERIAL_SEL) |
3266 (invert2 << INVERT_S2P2_FEC_CLK);
3267 WRITE_MPEG_REG(STB_S2P2_CONFIG, v);
3268 }
3269 }
3270
3271 /*Initialize the registers */
3272 DMX_WRITE_REG(dmx->id, STB_INT_MASK, DEMUX_INT_MASK);
3273 DMX_WRITE_REG(dmx->id, DEMUX_MEM_REQ_EN,
3274#ifdef USE_AHB_MODE
3275 (1 << SECTION_AHB_DMA_EN) |
3276 (0 << SUB_AHB_DMA_EN) |
3277 (1 << OTHER_PES_AHB_DMA_EN) |
3278#endif
3279 (1 << SECTION_PACKET) |
3280 (1 << VIDEO_PACKET) |
3281 (1 << AUDIO_PACKET) |
3282 (1 << SUB_PACKET) |
3283 (1 << SCR_ONLY_PACKET) |
3284 (1 << OTHER_PES_PACKET));
3285 DMX_WRITE_REG(dmx->id, PES_STRONG_SYNC, 0x1234);
3286 DMX_WRITE_REG(dmx->id, DEMUX_ENDIAN,
3287 (1<<SEPERATE_ENDIAN) |
3288 (0<<OTHER_PES_ENDIAN) |
3289 (7<<SCR_ENDIAN) |
3290 (7<<SUB_ENDIAN) |
3291 (7<<AUDIO_ENDIAN) |
3292 (7<<VIDEO_ENDIAN) |
3293 (7 << OTHER_ENDIAN) |
3294 (7 << BYPASS_ENDIAN) | (0 << SECTION_ENDIAN));
3295 if (fec_sel != 8) {
3296 DMX_WRITE_REG(dmx->id, TS_HIU_CTL,
3297// (0 << LAST_BURST_THRESHOLD) |
3298 (hi_bsf << USE_HI_BSF_INTERFACE));
3299 } else {
3300 DMX_WRITE_REG(dmx->id, TS_HIU_CTL,
3301 (1 << PDTS_WR_SEL) |
3302 (hi_bsf << USE_HI_BSF_INTERFACE));
3303 }
3304
3305 if (fec_sel == -1) {
3306 dmx_cascade_set(dmx->id,dmx->source);
3307 DMX_WRITE_REG(dmx->id, FEC_INPUT_CONTROL,
3308 (fec_core_sel << FEC_CORE_SEL) |
3309 (0 << FEC_SEL) | (fec_ctrl << 0));
3310 } else {
3311 dmx_cascade_set(dmx->id,dmx->source);
3312 if (fec_sel != 8) {
3313 DMX_WRITE_REG(dmx->id, FEC_INPUT_CONTROL,
3314 (fec_core_sel << FEC_CORE_SEL) |
3315 (fec_sel << FEC_SEL) | (fec_ctrl << 0));
3316 } else {
3317 DMX_WRITE_REG(dmx->id, FEC_INPUT_CONTROL,
3318 (fec_core_sel << FEC_CORE_SEL) |
3319 (1 << FEC_SEL_3BIT) | (fec_ctrl << 0));
3320 }
3321 }
3322 DMX_WRITE_REG(dmx->id, STB_OM_CTL,
3323 (0x40 << MAX_OM_DMA_COUNT) |
3324 (0x7f << LAST_OM_ADDR));
3325 DMX_WRITE_REG(dmx->id, DEMUX_CONTROL,
3326 (0 << BYPASS_USE_RECODER_PATH) |
3327 (0 << INSERT_AUDIO_PES_STRONG_SYNC) |
3328 (0 << INSERT_VIDEO_PES_STRONG_SYNC) |
3329 (0 << OTHER_INT_AT_PES_BEGINING) |
3330 (0 << DISCARD_AV_PACKAGE) |
3331 ((!!dmx->dump_ts_select) << TS_RECORDER_SELECT) |
3332 (record << TS_RECORDER_ENABLE) |
3333 (1 << KEEP_DUPLICATE_PACKAGE) |
3334 (1 << SECTION_END_WITH_TABLE_ID) |
3335 (1 << ENABLE_FREE_CLK_FEC_DATA_VALID) |
3336 (1 << ENABLE_FREE_CLK_STB_REG) |
3337 (1 << STB_DEMUX_ENABLE) |
3338 (use_sop << NOT_USE_OF_SOP_INPUT));
3339 } else {
3340 DMX_WRITE_REG(dmx->id, STB_INT_MASK, 0);
3341 DMX_WRITE_REG(dmx->id, FEC_INPUT_CONTROL, 0);
3342 DMX_WRITE_REG(dmx->id, DEMUX_CONTROL, 0);
3343 //dmx not used, but it can cascade for other dmx
3344 if ((dmx->source == AM_TS_SRC_DMX0 ||
3345 dmx->source == AM_TS_SRC_DMX1 ||
3346 dmx->source == AM_TS_SRC_DMX2 ) &&
3347 (dmx->id != dmx->source-AM_TS_SRC_DMX0))
3348 dmx_cascade_set(dmx->id,dmx->source);
3349 }
3350 return 0;
3351}
3352
3353static int dmx_set_misc(struct aml_dmx *dmx, int hi_bsf, int en_dsc)
3354{
3355 if (hi_bsf >= 0) {
3356 DMX_WRITE_REG(dmx->id, TS_HIU_CTL,
3357 hi_bsf ?
3358 (DMX_READ_REG(dmx->id, TS_HIU_CTL) |
3359 (1 << USE_HI_BSF_INTERFACE))
3360 :
3361 (DMX_READ_REG(dmx->id, TS_HIU_CTL) &
3362 (~(1 << USE_HI_BSF_INTERFACE))));
3363 }
3364
3365 if (en_dsc >= 0) {
3366 DMX_WRITE_REG(dmx->id, FEC_INPUT_CONTROL,
3367 en_dsc ?
3368 (DMX_READ_REG(dmx->id, FEC_INPUT_CONTROL) |
3369 (1 << FEC_CORE_SEL))
3370 :
3371 (DMX_READ_REG(dmx->id, FEC_INPUT_CONTROL) &
3372 (~(1 << FEC_CORE_SEL))));
3373 }
3374
3375 return 0;
3376}
3377
3378static int dmx_set_misc_id(struct aml_dvb *dvb, int id, int hi_bsf, int en_dsc)
3379{
3380 return dmx_set_misc(&dvb->dmx[id], hi_bsf, en_dsc);
3381}
3382
3383/*Get the channel's ID by its PID*/
3384static int dmx_get_chan(struct aml_dmx *dmx, int pid)
3385{
3386 int id;
3387
3388 for (id = 0; id < CHANNEL_COUNT; id++) {
3389 if (dmx->channel[id].used && dmx->channel[id].pid == pid)
3390 return id;
3391 }
3392
3393 return -1;
3394}
3395
3396/*Get the channel's target*/
3397static u32 dmx_get_chan_target(struct aml_dmx *dmx, int cid)
3398{
3399 u32 type;
3400
3401 if (!dmx->channel[cid].used)
3402 return 0xFFFF;
3403
3404 if (dmx->channel[cid].type == DMX_TYPE_SEC) {
3405 type = SECTION_PACKET;
3406 } else {
3407 switch (dmx->channel[cid].pes_type) {
3408 case DMX_PES_AUDIO:
3409 type = AUDIO_PACKET;
3410 break;
3411 case DMX_PES_VIDEO:
3412 type = VIDEO_PACKET;
3413 break;
3414 case DMX_PES_SUBTITLE:
3415 case DMX_PES_TELETEXT:
3416 type = SUB_PACKET;
3417 break;
3418 case DMX_PES_PCR:
3419 type = SCR_ONLY_PACKET;
3420 break;
3421 case DMX_PES_AUDIO3:
3422 type = OTHER_PES_PACKET;
3423 break;
3424 default:
3425 type = BYPASS_PACKET;
3426 break;
3427 }
3428 }
3429
3430 pr_dbg("chan target: %x %x\n", type, dmx->channel[cid].pid);
3431 return (type << PID_TYPE) | dmx->channel[cid].pid;
3432}
3433
3434/*Get the advance value of the channel*/
3435static inline u32 dmx_get_chan_advance(struct aml_dmx *dmx, int cid)
3436{
3437 return 0;
3438}
3439
3440/*Set the channel registers*/
3441static int dmx_set_chan_regs(struct aml_dmx *dmx, int cid)
3442{
3443 u32 data, addr, advance, max;
3444
3445 pr_dbg("set channel (id:%d PID:0x%x) registers\n", cid,
3446 dmx->channel[cid].pid);
3447
3448 while (DMX_READ_REG(dmx->id, FM_WR_ADDR) & 0x8000)
3449 udelay(1);
3450
3451 if (cid & 1) {
3452 data =
3453 (dmx_get_chan_target(dmx, cid - 1) << 16) |
3454 dmx_get_chan_target(dmx, cid);
3455 advance =
3456 (dmx_get_chan_advance(dmx, cid) << 8) |
3457 dmx_get_chan_advance(dmx, cid - 1);
3458 } else {
3459 data =
3460 (dmx_get_chan_target(dmx, cid) << 16) |
3461 dmx_get_chan_target(dmx, cid + 1);
3462 advance =
3463 (dmx_get_chan_advance(dmx, cid + 1) << 8) |
3464 dmx_get_chan_advance(dmx, cid);
3465 }
3466 addr = cid >> 1;
3467 DMX_WRITE_REG(dmx->id, FM_WR_DATA, data);
3468 DMX_WRITE_REG(dmx->id, FM_WR_ADDR, (advance << 16) | 0x8000 | addr);
3469
3470 pr_dbg("write fm %x:%x\n", (advance << 16) | 0x8000 | addr, data);
3471
3472 for (max = CHANNEL_COUNT - 1; max > 0; max--) {
3473 if (dmx->channel[max].used)
3474 break;
3475 }
3476
3477 data = DMX_READ_REG(dmx->id, MAX_FM_COMP_ADDR) & 0xF0;
3478 DMX_WRITE_REG(dmx->id, MAX_FM_COMP_ADDR, data | (max >> 1));
3479
3480 pr_dbg("write fm comp %x\n", data | (max >> 1));
3481
3482 if (DMX_READ_REG(dmx->id, OM_CMD_STATUS) & 0x8e00) {
3483 pr_error("error send cmd %x\n",
3484 DMX_READ_REG(dmx->id, OM_CMD_STATUS));
3485 }
3486
3487 if (cid == 0) {
3488 video_pts = 0;
3489 first_video_pts = 0;
3490 }
3491 else if (cid == 1) {
3492 audio_pts = 0;
3493 first_audio_pts = 0;
3494 }
3495
3496 return 0;
3497}
3498
3499/*Get the filter target*/
3500static int dmx_get_filter_target(struct aml_dmx *dmx, int fid, u32 *target,
3501 u8 *advance)
3502{
3503 struct dmx_section_filter *filter;
3504 struct aml_filter *f;
3505 int i, cid, neq_bytes;
3506
3507 fid = fid & 0xFFFF;
3508 f = &dmx->filter[fid];
3509
3510 if (!f->used) {
3511 target[0] = 0x1fff;
3512 advance[0] = 0;
3513 for (i = 1; i < FILTER_LEN; i++) {
3514 target[i] = 0x9fff;
3515 advance[i] = 0;
3516 }
3517 return 0;
3518 }
3519
3520 cid = f->chan_id;
3521 filter = f->filter;
3522
3523 neq_bytes = 0;
3524 if (filter->filter_mode[0] != 0xFF) {
3525 neq_bytes = 2;
3526 } else {
3527 for (i = 3; i < FILTER_LEN; i++) {
3528 if (filter->filter_mode[i] != 0xFF)
3529 neq_bytes++;
3530 }
3531 }
3532
3533 f->neq = 0;
3534
3535 for (i = 0; i < FILTER_LEN; i++) {
3536 u8 value = filter->filter_value[i];
3537 u8 mask = filter->filter_mask[i];
3538 u8 mode = filter->filter_mode[i];
3539 u8 mb, mb1, nb, v, t, adv = 0;
3540
3541 if (!i) {
3542 mb = 1;
3543 mb1 = 1;
3544 v = 0;
3545 if ((mode == 0xFF) && mask) {
3546 t = mask & 0xF0;
3547 if (t) {
3548 mb1 = 0;
3549 adv |= t^0xF0;
3550 }
3551 v |= (value & 0xF0) | adv;
3552
3553 t = mask & 0x0F;
3554 if (t) {
3555 mb = 0;
3556 adv |= t^0x0F;
3557 }
3558 v |= (value & 0x0F) | adv;
3559 }
3560
3561 target[i] = (mb << SECTION_FIRSTBYTE_MASKLOW) |
3562 (mb1 << SECTION_FIRSTBYTE_MASKHIGH) |
3563 (0 << SECTION_FIRSTBYTE_DISABLE_PID_CHECK) |
3564 (cid << SECTION_FIRSTBYTE_PID_INDEX) | v;
3565 advance[i] = adv;
3566 } else {
3567 if (i < 3) {
3568 value = 0;
3569 mask = 0;
3570 mode = 0xff;
3571 }
3572 mb = 1;
3573 nb = 0;
3574 v = 0;
3575
3576 if ((i >= 3) && mask) {
3577 if (mode == 0xFF) {
3578 mb = 0;
3579 nb = 0;
3580 adv = mask ^ 0xFF;
3581 v = value | adv;
3582 } else {
3583 if (neq_bytes == 1) {
3584 mb = 0;
3585 nb = 1;
3586 adv = mask ^ 0xFF;
3587 v = value & ~adv;
3588 }
3589 }
3590 }
3591 target[i] = (mb << SECTION_RESTBYTE_MASK) |
3592 (nb << SECTION_RESTBYTE_MASK_EQ) |
3593 (0 << SECTION_RESTBYTE_DISABLE_PID_CHECK) |
3594 (cid << SECTION_RESTBYTE_PID_INDEX) | v;
3595 advance[i] = adv;
3596 }
3597
3598 f->value[i] = value;
3599 f->maskandmode[i] = mask & mode;
3600 f->maskandnotmode[i] = mask & ~mode;
3601
3602 if (f->maskandnotmode[i])
3603 f->neq = 1;
3604 }
3605
3606 return 0;
3607}
3608
3609/*Set the filter registers*/
3610static int dmx_set_filter_regs(struct aml_dmx *dmx, int fid)
3611{
3612 u32 t1[FILTER_LEN], t2[FILTER_LEN];
3613 u8 advance1[FILTER_LEN], advance2[FILTER_LEN];
3614 u32 addr, data, max, adv;
3615 int i;
3616
3617 pr_dbg("set filter (id:%d) registers\n", fid);
3618
3619 if (fid & 1) {
3620 dmx_get_filter_target(dmx, fid - 1, t1, advance1);
3621 dmx_get_filter_target(dmx, fid, t2, advance2);
3622 } else {
3623 dmx_get_filter_target(dmx, fid, t1, advance1);
3624 dmx_get_filter_target(dmx, fid + 1, t2, advance2);
3625 }
3626
3627 for (i = 0; i < FILTER_LEN; i++) {
3628 while (DMX_READ_REG(dmx->id, FM_WR_ADDR) & 0x8000)
3629 udelay(1);
3630
3631 data = (t1[i] << 16) | t2[i];
3632 addr = (fid >> 1) | ((i + 1) << 4);
3633 adv = (advance1[i] << 8) | advance2[i];
3634
3635 DMX_WRITE_REG(dmx->id, FM_WR_DATA, data);
3636 DMX_WRITE_REG(dmx->id, FM_WR_ADDR, (adv << 16) | 0x8000 | addr);
3637
3638 pr_dbg("write fm %x:%x\n", (adv << 16) | 0x8000 | addr, data);
3639 }
3640
3641 for (max = FILTER_COUNT - 1; max > 0; max--) {
3642 if (dmx->filter[max].used)
3643 break;
3644 }
3645
3646 data = DMX_READ_REG(dmx->id, MAX_FM_COMP_ADDR) & 0xF;
3647 DMX_WRITE_REG(dmx->id, MAX_FM_COMP_ADDR, data | ((max >> 1) << 4));
3648
3649 pr_dbg("write fm comp %x\n", data | ((max >> 1) << 4));
3650
3651 if (DMX_READ_REG(dmx->id, OM_CMD_STATUS) & 0x8e00) {
3652 pr_error("error send cmd %x\n",
3653 DMX_READ_REG(dmx->id, OM_CMD_STATUS));
3654 }
3655
3656 return 0;
3657}
3658
3659/*Clear the filter's buffer*/
3660static void dmx_clear_filter_buffer(struct aml_dmx *dmx, int fid)
3661{
3662 u32 section_busy32 = DMX_READ_REG(dmx->id, SEC_BUFF_READY);
3663 u32 filter_number;
3664 int i;
3665
3666 if (!section_busy32)
3667 return;
3668
3669 for (i = 0; i < SEC_BUF_COUNT; i++) {
3670 if (section_busy32 & (1 << i)) {
3671 DMX_WRITE_REG(dmx->id, SEC_BUFF_NUMBER, i);
3672 filter_number =
3673 (DMX_READ_REG(dmx->id, SEC_BUFF_NUMBER) >> 8);
3674 if (filter_number != fid)
3675 section_busy32 &= ~(1 << i);
3676 }
3677 }
3678
3679 if (section_busy32)
3680 DMX_WRITE_REG(dmx->id, SEC_BUFF_READY, section_busy32);
3681}
3682
3683static void async_fifo_set_regs(struct aml_asyncfifo *afifo, int source_val)
3684{
3685 u32 start_addr = afifo->secure_enable ? afifo->blk.addr :
3686 virt_to_phys((void *)afifo->pages);
3687 u32 size = afifo->buf_len;
3688 u32 flush_size = afifo->flush_size;
3689 int factor = dmx_get_order(size / flush_size);
3690 pr_error("ASYNC FIFO id=%d, link to DMX%d, start_addr %x, buf_size %d,"
3691 "source value 0x%x, factor %d\n",
3692 afifo->id, afifo->source, start_addr, size, source_val, factor);
3693 /* Destination address */
3694 WRITE_ASYNC_FIFO_REG(afifo->id, REG0, start_addr);
3695
3696 /* Setup flush parameters */
3697 WRITE_ASYNC_FIFO_REG(afifo->id, REG1,
3698 (0 << ASYNC_FIFO_TO_HIU) |
3699 (0 << ASYNC_FIFO_FLUSH) |
3700 /* don't flush the path */
3701 (1 << ASYNC_FIFO_RESET) |
3702 /* reset the path */
3703 (1 << ASYNC_FIFO_WRAP_EN) |
3704 /* wrap enable */
3705 (0 << ASYNC_FIFO_FLUSH_EN) |
3706 /* disable the flush path */
3707 /*(0x3 << ASYNC_FIFO_FLUSH_CNT_LSB);
3708 * flush 3 x 32 32-bit words
3709 */
3710 /*(0x7fff << ASYNC_FIFO_FLUSH_CNT_LSB);
3711 * flush 4MBytes of data
3712 */
3713 (((size >> 7) & 0x7fff) << ASYNC_FIFO_FLUSH_CNT_LSB));
3714 /* number of 128-byte blocks to flush */
3715
3716 /* clear the reset signal */
3717 WRITE_ASYNC_FIFO_REG(afifo->id, REG1,
3718 READ_ASYNC_FIFO_REG(afifo->id,
3719 REG1) & ~(1 << ASYNC_FIFO_RESET));
3720 /* Enable flush */
3721 WRITE_ASYNC_FIFO_REG(afifo->id, REG1,
3722 READ_ASYNC_FIFO_REG(afifo->id,
3723 REG1) | (1 << ASYNC_FIFO_FLUSH_EN));
3724
3725 /*Setup Fill parameters */
3726 WRITE_ASYNC_FIFO_REG(afifo->id, REG2,
3727 (1 << ASYNC_FIFO_ENDIAN_LSB) |
3728 (0 << ASYNC_FIFO_FILL_EN) |
3729 /* disable fill path to reset fill path */
3730 /*(96 << ASYNC_FIFO_FILL_CNT_LSB);
3731 *3 x 32 32-bit words
3732 */
3733 (0 << ASYNC_FIFO_FILL_CNT_LSB));
3734 /* forever FILL; */
3735 WRITE_ASYNC_FIFO_REG(afifo->id, REG2,
3736 READ_ASYNC_FIFO_REG(afifo->id, REG2) |
3737 (1 << ASYNC_FIFO_FILL_EN));/*Enable fill path*/
3738
3739 /* generate flush interrupt */
3740 WRITE_ASYNC_FIFO_REG(afifo->id, REG3,
3741 (READ_ASYNC_FIFO_REG(afifo->id, REG3) & 0xffff0000) |
3742 ((((size >> (factor + 7)) - 1) & 0x7fff) <<
3743 ASYNC_FLUSH_SIZE_IRQ_LSB));
3744
3745 /* Connect the STB DEMUX to ASYNC_FIFO */
3746 WRITE_ASYNC_FIFO_REG(afifo->id, REG2,
3747 READ_ASYNC_FIFO_REG(afifo->id, REG2) |
3748 (source_val << ASYNC_FIFO_SOURCE_LSB));
3749}
3750
3751/*Reset the ASYNC FIFOS when a ASYNC FIFO connect to a different DMX*/
3752static void reset_async_fifos(struct aml_dvb *dvb)
3753{
3754 struct aml_asyncfifo *low_dmx_fifo = NULL;
3755 struct aml_asyncfifo *high_dmx_fifo = NULL;
3756 struct aml_asyncfifo *highest_dmx_fifo = NULL;
3757 int i, j;
3758 int record_enable;
3759
3760 pr_dbg("reset ASYNC FIFOs\n");
3761 for (i = 0; i < dvb->async_fifo_total_count; i++) {
3762 if (!dvb->asyncfifo[i].init)
3763 continue;
3764 pr_dbg("Disable ASYNC FIFO id=%d\n", dvb->asyncfifo[i].id);
3765 CLEAR_ASYNC_FIFO_REG_MASK(dvb->asyncfifo[i].id, REG1,
3766 1 << ASYNC_FIFO_FLUSH_EN);
3767 CLEAR_ASYNC_FIFO_REG_MASK(dvb->asyncfifo[i].id, REG2,
3768 1 << ASYNC_FIFO_FILL_EN);
3769 if (READ_ASYNC_FIFO_REG(dvb->asyncfifo[i].id, REG2) &
3770 (1 << ASYNC_FIFO_FILL_EN) ||
3771 READ_ASYNC_FIFO_REG(dvb->asyncfifo[i].id, REG1) &
3772 (1 << ASYNC_FIFO_FLUSH_EN)) {
3773 pr_dbg("Set reg failed\n");
3774 } else
3775 pr_dbg("Set reg ok\n");
3776 dvb->asyncfifo[i].buf_toggle = 0;
3777 dvb->asyncfifo[i].buf_read = 0;
3778 }
3779
3780 for (j = 0; j < DMX_DEV_COUNT; j++) {
3781 if (!dvb->dmx[j].init)
3782 continue;
3783 record_enable = 0;
3784 for (i = 0; i < dvb->async_fifo_total_count; i++) {
3785 if (!dvb->asyncfifo[i].init)
3786 continue;
3787
3788 if (dvb->dmx[j].record
3789 && dvb->dmx[j].id == dvb->asyncfifo[i].source) {
3790 /*This dmx is linked to the async fifo,
3791 *Enable the TS_RECORDER_ENABLE
3792 */
3793 record_enable = 1;
3794 if (!low_dmx_fifo) {
3795 low_dmx_fifo = &dvb->asyncfifo[i];
3796 } else if (low_dmx_fifo->source >
3797 dvb->asyncfifo[i].source) {
3798 if (!high_dmx_fifo)
3799 high_dmx_fifo = low_dmx_fifo;
3800 else {
3801 highest_dmx_fifo = high_dmx_fifo;
3802 high_dmx_fifo = low_dmx_fifo;
3803 }
3804 low_dmx_fifo = &dvb->asyncfifo[i];
3805 } else if (low_dmx_fifo->source <
3806 dvb->asyncfifo[i].source) {
3807 if (!high_dmx_fifo)
3808 high_dmx_fifo = &dvb->asyncfifo[i];
3809 else {
3810 if (high_dmx_fifo->source > dvb->asyncfifo[i].source) {
3811 highest_dmx_fifo = high_dmx_fifo;
3812 high_dmx_fifo = &dvb->asyncfifo[i];
3813 } else {
3814 highest_dmx_fifo = &dvb->asyncfifo[i];
3815 }
3816 }
3817 }
3818
3819 break;
3820 }
3821 }
3822 pr_dbg("Set DMX%d TS_RECORDER_ENABLE to %d\n", dvb->dmx[j].id,
3823 record_enable ? 1 : 0);
3824 if (record_enable) {
3825 /*DMX_SET_REG_MASK(dvb->dmx[j].id,
3826 *DEMUX_CONTROL, 1<<TS_RECORDER_ENABLE);
3827 */
3828 DMX_WRITE_REG(dvb->dmx[j].id, DEMUX_CONTROL,
3829 DMX_READ_REG(dvb->dmx[j].id, DEMUX_CONTROL) |
3830 (1 << TS_RECORDER_ENABLE));
3831 } else {
3832 /*DMX_CLEAR_REG_MASK(dvb->dmx[j].id,
3833 *DEMUX_CONTROL, 1<<TS_ECORDER_ENABLE);
3834 */
3835 DMX_WRITE_REG(dvb->dmx[j].id, DEMUX_CONTROL,
3836 DMX_READ_REG(dvb->dmx[j].id, DEMUX_CONTROL) &
3837 (~(1 << TS_RECORDER_ENABLE)));
3838 }
3839 }
3840
3841 /*Set the async fifo regs */
3842 if (low_dmx_fifo) {
3843 async_fifo_set_regs(low_dmx_fifo, 0x3);
3844
3845 if (high_dmx_fifo) {
3846 async_fifo_set_regs(high_dmx_fifo, 0x2);
3847
3848 if (highest_dmx_fifo)
3849 async_fifo_set_regs(highest_dmx_fifo, 0x0);
3850 }
3851 }
3852}
3853
3854/*Reset the demux device*/
3855void dmx_reset_hw(struct aml_dvb *dvb)
3856{
3857 dmx_reset_hw_ex(dvb, 1);
3858}
3859
3860/*Reset the demux device*/
3861void dmx_reset_hw_ex(struct aml_dvb *dvb, int reset_irq)
3862{
3863 int id, times;
3864
3865 pr_dbg("demux reset begin\n");
3866
3867 for (id = 0; id < DMX_DEV_COUNT; id++) {
3868 if (!dvb->dmx[id].init)
3869 continue;
3870 if (reset_irq) {
3871 if (dvb->dmx[id].dmx_irq != -1)
3872 disable_irq(dvb->dmx[id].dmx_irq);
3873 if (dvb->dmx[id].dvr_irq != -1)
3874 disable_irq(dvb->dmx[id].dvr_irq);
3875 }
3876 }
3877#ifdef ENABLE_SEC_BUFF_WATCHDOG
3878 if (reset_irq)
3879 del_timer_sync(&dvb->watchdog_timer);
3880#endif
3881 /*RESET_TOP will clear the dsc pid , save all dsc pid that setting in TA*/
3882 for (id = 0; id < DSC_DEV_COUNT; id++) {
3883 struct aml_dsc *dsc = &dvb->dsc[id];
3884 int n;
3885
3886 for (n = 0; n < DSC_COUNT; n++) {
3887 struct aml_dsc_channel *ch = &dsc->channel[n];
3888 /*if(ch->used)*/
3889 {
3890 ch->id = n;
3891 dsc_get_pid(ch,&ch->pid);
3892 }
3893 }
3894 }
3895 /*WRITE_MPEG_REG(RESET1_REGISTER, RESET_DEMUXSTB);*/
3896 WRITE_MPEG_REG(RESET3_REGISTER, RESET_DEMUX2|RESET_DEMUX1|RESET_DEMUX0|RESET_S2P1|RESET_S2P0|RESET_TOP);
3897
3898 for (id = 0; id < DMX_DEV_COUNT; id++) {
3899 times = 0;
3900 while (times++ < 1000000) {
3901 if (!(DMX_READ_REG(id, OM_CMD_STATUS) & 0x01))
3902 break;
3903 }
3904 }
3905 {
3906 u32 data;
3907 data = READ_MPEG_REG(STB_TOP_CONFIG);
3908 ciplus = 0x7C000000 & data;
3909 }
3910
3911 WRITE_MPEG_REG(STB_TOP_CONFIG, 0);
3912 WRITE_MPEG_REG(STB_S2P2_CONFIG, 0);
3913
3914 for (id = 0; id < DMX_DEV_COUNT; id++) {
3915 u32 version, data;
3916
3917 if (!dvb->dmx[id].init)
3918 continue;
3919
3920 if (reset_irq) {
3921 if (dvb->dmx[id].dmx_irq != -1)
3922 enable_irq(dvb->dmx[id].dmx_irq);
3923 if (dvb->dmx[id].dvr_irq != -1)
3924 enable_irq(dvb->dmx[id].dvr_irq);
3925 }
3926 DMX_WRITE_REG(id, DEMUX_CONTROL, 0x0000);
3927 version = DMX_READ_REG(id, STB_VERSION);
3928 DMX_WRITE_REG(id, STB_TEST_REG, version);
3929 pr_dbg("STB %d hardware version : %d\n", id, version);
3930 DMX_WRITE_REG(id, STB_TEST_REG, 0x5550);
3931 data = DMX_READ_REG(id, STB_TEST_REG);
3932 if (data != 0x5550)
3933 pr_error("STB %d register access failed\n", id);
3934 DMX_WRITE_REG(id, STB_TEST_REG, 0xaaa0);
3935 data = DMX_READ_REG(id, STB_TEST_REG);
3936 if (data != 0xaaa0)
3937 pr_error("STB %d register access failed\n", id);
3938 DMX_WRITE_REG(id, MAX_FM_COMP_ADDR, 0x0000);
3939 DMX_WRITE_REG(id, STB_INT_MASK, 0);
3940 DMX_WRITE_REG(id, STB_INT_STATUS, 0xffff);
3941 DMX_WRITE_REG(id, FEC_INPUT_CONTROL, 0);
3942 }
3943
3944 stb_enable(dvb);
3945
3946 for (id = 0; id < DMX_DEV_COUNT; id++) {
3947 struct aml_dmx *dmx = &dvb->dmx[id];
3948 int n;
3949 unsigned long addr;
3950 unsigned long base;
3951 unsigned long grp_addr[SEC_BUF_GRP_COUNT];
3952 int grp_len[SEC_BUF_GRP_COUNT];
3953
3954 if (!dvb->dmx[id].init)
3955 continue;
3956
3957 if (dmx->sec_pages) {
3958 grp_len[0] = (1 << SEC_GRP_LEN_0) * 8;
3959 grp_len[1] = (1 << SEC_GRP_LEN_1) * 8;
3960 grp_len[2] = (1 << SEC_GRP_LEN_2) * 8;
3961 grp_len[3] = (1 << SEC_GRP_LEN_3) * 8;
3962
3963 grp_addr[0] = virt_to_phys((void *)dmx->sec_pages);
3964 grp_addr[1] = grp_addr[0] + grp_len[0];
3965 grp_addr[2] = grp_addr[1] + grp_len[1];
3966 grp_addr[3] = grp_addr[2] + grp_len[2];
3967
3968 base = grp_addr[0] & 0xFFFF0000;
3969 DMX_WRITE_REG(dmx->id, SEC_BUFF_BASE, base >> 16);
3970 DMX_WRITE_REG(dmx->id, SEC_BUFF_01_START,
3971 (((grp_addr[0] - base) >> 8) << 16) |
3972 ((grp_addr[1] - base) >> 8));
3973 DMX_WRITE_REG(dmx->id, SEC_BUFF_23_START,
3974 (((grp_addr[2] - base) >> 8) << 16) |
3975 ((grp_addr[3] - base) >> 8));
3976 DMX_WRITE_REG(dmx->id, SEC_BUFF_SIZE,
3977 SEC_GRP_LEN_0 |
3978 (SEC_GRP_LEN_1 << 4) |
3979 (SEC_GRP_LEN_2 << 8) |
3980 (SEC_GRP_LEN_3 << 12));
3981 }
3982#ifdef NO_SUB
3983#ifndef SUB_PARSER
3984 if (dmx->sub_pages) {
3985 addr = virt_to_phys((void *)dmx->sub_pages);
3986 DMX_WRITE_REG(dmx->id, SB_START, addr >> 12);
3987 DMX_WRITE_REG(dmx->id, SB_LAST_ADDR,
3988 (dmx->sub_buf_len >> 3) - 1);
3989 }
3990#endif
3991#endif
3992 if (dmx->pes_pages) {
3993 addr = virt_to_phys((void *)dmx->pes_pages);
3994 DMX_WRITE_REG(dmx->id, OB_START, addr >> 12);
3995 DMX_WRITE_REG(dmx->id, OB_LAST_ADDR,
3996 (dmx->pes_buf_len >> 3) - 1);
3997 }
3998
3999 for (n = 0; n < CHANNEL_COUNT; n++) {
4000 /*struct aml_channel *chan = &dmx->channel[n];*/
4001
4002 /*if (chan->used)*/
4003 {
4004#ifdef NO_SUB
4005#ifdef SUB_PARSER
4006 /*
4007 check if subtitle channel was running,
4008 the parser will be used in amstream also,
4009 take care of the buff ptr.
4010 */
4011 u32 v = dmx_get_chan_target(dmx, n);
4012 if (v != 0xFFFF &&
4013 (v & (0x7 << PID_TYPE))
4014 == (SUB_PACKET << PID_TYPE))
4015 set_subtitle_pes_buffer(dmx);
4016#endif
4017#endif
4018 dmx_set_chan_regs(dmx, n);
4019 }
4020 }
4021
4022 for (n = 0; n < FILTER_COUNT; n++) {
4023 struct aml_filter *filter = &dmx->filter[n];
4024
4025 if (filter->used)
4026 dmx_set_filter_regs(dmx, n);
4027 }
4028
4029 dmx_enable(&dvb->dmx[id]);
4030
4031 dmx_smallsec_set(&dmx->smallsec,
4032 dmx->smallsec.enable,
4033 dmx->smallsec.bufsize,
4034 1);
4035
4036 dmx_timeout_set(&dmx->timeout,
4037 dmx->timeout.enable,
4038 dmx->timeout.timeout,
4039 dmx->timeout.ch_disable,
4040 dmx->timeout.match,
4041 1);
4042 }
4043
4044 for (id = 0; id < DSC_DEV_COUNT; id++) {
4045 struct aml_dsc *dsc = &dvb->dsc[id];
4046 int n;
4047
4048 for (n = 0; n < DSC_COUNT; n++) {
4049 int flag = 0;
4050 struct aml_dsc_channel *ch = &dsc->channel[n];
4051 /*if(ch->used)*/
4052 {
4053 ch->work_mode = -1;
4054 //if ta setting pid, used will 0
4055 if (ch->pid != 0x1fff && !ch->used) {
4056 flag = 1;
4057 ch->used = 1;
4058 }
4059 dsc_set_pid(ch, ch->pid);
4060 if (flag)
4061 ch->used = 0;
4062 //dsc_set_keys(ch);
4063 }
4064 }
4065 }
4066#ifdef ENABLE_SEC_BUFF_WATCHDOG
4067 if (reset_irq) {
4068 mod_timer(&dvb->watchdog_timer,
4069 jiffies + msecs_to_jiffies(WATCHDOG_TIMER));
4070 }
4071#endif
4072
4073 pr_dbg("demux reset end\n");
4074}
4075
4076/*Reset the individual demux*/
4077void dmx_reset_dmx_hw_ex_unlock(struct aml_dvb *dvb, struct aml_dmx *dmx,
4078 int reset_irq)
4079{
4080 {
4081 if (!dmx->init)
4082 return;
4083 if (reset_irq) {
4084 if (dmx->dmx_irq != -1)
4085 disable_irq(dmx->dmx_irq);
4086 if (dmx->dvr_irq != -1)
4087 disable_irq(dmx->dvr_irq);
4088 }
4089 }
4090#ifdef ENABLE_SEC_BUFF_WATCHDOG
4091 if (reset_irq) {
4092 /*del_timer_sync(&dvb->watchdog_timer); */
4093 dvb->dmx_watchdog_disable[dmx->id] = 1;
4094 }
4095#endif
4096
4097 WRITE_MPEG_REG(RESET3_REGISTER,
4098 (dmx->id) ? ((dmx->id ==
4099 1) ? RESET_DEMUX1 : RESET_DEMUX2) :
4100 RESET_DEMUX0);
4101 WRITE_MPEG_REG(RESET3_REGISTER, RESET_DES);
4102
4103 {
4104 int times;
4105
4106 times = 0;
4107 while (times++ < 1000000) {
4108 if (!(DMX_READ_REG(dmx->id, OM_CMD_STATUS) & 0x01))
4109 break;
4110 }
4111 }
4112
4113 /*WRITE_MPEG_REG(STB_TOP_CONFIG, 0); */
4114 {
4115 u32 data;
4116 data = READ_MPEG_REG(STB_TOP_CONFIG);
4117 ciplus = 0x7C000000 & data;
4118 }
4119
4120 {
4121 u32 version, data;
4122
4123 if (!dmx->init)
4124 return;
4125
4126 if (reset_irq) {
4127 if (dmx->dmx_irq != -1)
4128 enable_irq(dmx->dmx_irq);
4129 if (dmx->dvr_irq != -1)
4130 enable_irq(dmx->dvr_irq);
4131 }
4132 DMX_WRITE_REG(dmx->id, DEMUX_CONTROL, 0x0000);
4133 version = DMX_READ_REG(dmx->id, STB_VERSION);
4134 DMX_WRITE_REG(dmx->id, STB_TEST_REG, version);
4135 pr_dbg("STB %d hardware version : %d\n", dmx->id, version);
4136 DMX_WRITE_REG(dmx->id, STB_TEST_REG, 0x5550);
4137 data = DMX_READ_REG(dmx->id, STB_TEST_REG);
4138 if (data != 0x5550)
4139 pr_error("STB %d register access failed\n", dmx->id);
4140 DMX_WRITE_REG(dmx->id, STB_TEST_REG, 0xaaa0);
4141 data = DMX_READ_REG(dmx->id, STB_TEST_REG);
4142 if (data != 0xaaa0)
4143 pr_error("STB %d register access failed\n", dmx->id);
4144 DMX_WRITE_REG(dmx->id, MAX_FM_COMP_ADDR, 0x0000);
4145 DMX_WRITE_REG(dmx->id, STB_INT_MASK, 0);
4146 DMX_WRITE_REG(dmx->id, STB_INT_STATUS, 0xffff);
4147 DMX_WRITE_REG(dmx->id, FEC_INPUT_CONTROL, 0);
4148 }
4149
4150 stb_enable(dvb);
4151
4152 {
4153 int n;
4154 unsigned long addr;
4155 unsigned long base;
4156 unsigned long grp_addr[SEC_BUF_GRP_COUNT];
4157 int grp_len[SEC_BUF_GRP_COUNT];
4158
4159 if (!dmx->init)
4160 return;
4161
4162 if (dmx->sec_pages) {
4163 grp_len[0] = (1 << SEC_GRP_LEN_0) * 8;
4164 grp_len[1] = (1 << SEC_GRP_LEN_1) * 8;
4165 grp_len[2] = (1 << SEC_GRP_LEN_2) * 8;
4166 grp_len[3] = (1 << SEC_GRP_LEN_3) * 8;
4167
4168 grp_addr[0] = virt_to_phys((void *)dmx->sec_pages);
4169 grp_addr[1] = grp_addr[0] + grp_len[0];
4170 grp_addr[2] = grp_addr[1] + grp_len[1];
4171 grp_addr[3] = grp_addr[2] + grp_len[2];
4172
4173 base = grp_addr[0] & 0xFFFF0000;
4174 DMX_WRITE_REG(dmx->id, SEC_BUFF_BASE, base >> 16);
4175 DMX_WRITE_REG(dmx->id, SEC_BUFF_01_START,
4176 (((grp_addr[0] - base) >> 8) << 16) |
4177 ((grp_addr[1] - base) >> 8));
4178 DMX_WRITE_REG(dmx->id, SEC_BUFF_23_START,
4179 (((grp_addr[2] - base) >> 8) << 16) |
4180 ((grp_addr[3] - base) >> 8));
4181 DMX_WRITE_REG(dmx->id, SEC_BUFF_SIZE,
4182 SEC_GRP_LEN_0 |
4183 (SEC_GRP_LEN_1 << 4) |
4184 (SEC_GRP_LEN_2 << 8) |
4185 (SEC_GRP_LEN_3 << 12));
4186 }
4187#ifdef NO_SUB
4188#ifndef SUB_PARSER
4189 if (dmx->sub_pages) {
4190 addr = virt_to_phys((void *)dmx->sub_pages);
4191 DMX_WRITE_REG(dmx->id, SB_START, addr >> 12);
4192 DMX_WRITE_REG(dmx->id, SB_LAST_ADDR,
4193 (dmx->sub_buf_len >> 3) - 1);
4194 }
4195#endif
4196#endif
4197 if (dmx->pes_pages) {
4198 addr = virt_to_phys((void *)dmx->pes_pages);
4199 DMX_WRITE_REG(dmx->id, OB_START, addr >> 12);
4200 DMX_WRITE_REG(dmx->id, OB_LAST_ADDR,
4201 (dmx->pes_buf_len >> 3) - 1);
4202 }
4203
4204 for (n = 0; n < CHANNEL_COUNT; n++) {
4205 /*struct aml_channel *chan = &dmx->channel[n];*/
4206
4207 /*if (chan->used)*/
4208 {
4209#ifdef NO_SUB
4210#ifdef SUB_PARSER
4211 /*
4212 check if subtitle channel was running,
4213 the parser will be used in amstream also,
4214 take care of the buff ptr.
4215 */
4216 u32 v = dmx_get_chan_target(dmx, n);
4217 if (v != 0xFFFF &&
4218 (v & (0x7 << PID_TYPE))
4219 == (SUB_PACKET << PID_TYPE))
4220 set_subtitle_pes_buffer(dmx);
4221#endif
4222#endif
4223 dmx_set_chan_regs(dmx, n);
4224 }
4225 }
4226
4227 for (n = 0; n < FILTER_COUNT; n++) {
4228 struct aml_filter *filter = &dmx->filter[n];
4229
4230 if (filter->used)
4231 dmx_set_filter_regs(dmx, n);
4232 }
4233
4234 for (n = 0; n < SEC_CNT_MAX; n++) {
4235 dmx->sec_cnt[n] = 0;
4236 dmx->sec_cnt_match[n] = 0;
4237 dmx->sec_cnt_crc_fail[n] = 0;
4238 }
4239
4240 dmx_enable(dmx);
4241
4242 dmx_smallsec_set(&dmx->smallsec,
4243 dmx->smallsec.enable,
4244 dmx->smallsec.bufsize,
4245 1);
4246
4247 dmx_timeout_set(&dmx->timeout,
4248 dmx->timeout.enable,
4249 dmx->timeout.timeout,
4250 dmx->timeout.ch_disable,
4251 dmx->timeout.match,
4252 1);
4253 }
4254
4255 {
4256 int id;
4257
4258 for (id = 0; id < DSC_DEV_COUNT; id++) {
4259 struct aml_dsc *dsc = &dvb->dsc[id];
4260 int n;
4261
4262 for (n = 0; n < DSC_COUNT; n++) {
4263 int flag = 0;
4264 struct aml_dsc_channel *ch = &dsc->channel[n];
4265 /*if(ch->used)*/ {
4266 ch->id = n;
4267 ch->work_mode = -1;
4268 dsc_get_pid(ch,&ch->pid);
4269 if (ch->pid != 0x1fff && !ch->used) {
4270 flag = 1;
4271 ch->used = 1;
4272 }
4273 dsc_set_pid(ch, ch->pid);
4274 if (flag)
4275 ch->used = 0;
4276 //dsc_set_keys(ch);
4277 }
4278 }
4279 }
4280 }
4281#ifdef ENABLE_SEC_BUFF_WATCHDOG
4282 if (reset_irq) {
4283 /*mod_timer(&dvb->watchdog_timer,
4284 *jiffies+msecs_to_jiffies(WATCHDOG_TIMER));
4285 */
4286 dvb->dmx_watchdog_disable[dmx->id] = 0;
4287 }
4288#endif
4289}
4290
4291void dmx_reset_dmx_id_hw_ex_unlock(struct aml_dvb *dvb, int id, int reset_irq)
4292{
4293 dmx_reset_dmx_hw_ex_unlock(dvb, &dvb->dmx[id], reset_irq);
4294}
4295
4296void dmx_reset_dmx_hw_ex(struct aml_dvb *dvb, struct aml_dmx *dmx,
4297 int reset_irq)
4298{
4299 unsigned long flags;
4300
4301 spin_lock_irqsave(&dvb->slock, flags);
4302 dmx_reset_dmx_hw_ex_unlock(dvb, dmx, reset_irq);
4303 spin_unlock_irqrestore(&dvb->slock, flags);
4304}
4305
4306void dmx_reset_dmx_id_hw_ex(struct aml_dvb *dvb, int id, int reset_irq)
4307{
4308 unsigned long flags;
4309
4310 spin_lock_irqsave(&dvb->slock, flags);
4311 dmx_reset_dmx_id_hw_ex_unlock(dvb, id, reset_irq);
4312 spin_unlock_irqrestore(&dvb->slock, flags);
4313}
4314
4315void dmx_reset_dmx_hw(struct aml_dvb *dvb, int id)
4316{
4317 dmx_reset_dmx_id_hw_ex(dvb, id, 1);
4318}
4319
4320/*Allocate subtitle pes buffer*/
4321#if 0
4322static int alloc_subtitle_pes_buffer(struct aml_dmx *dmx)
4323{
4324 int start_ptr = 0;
4325 struct stream_buf_s *sbuff = 0;
4326 u32 phy_addr;
4327
4328 start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR);
4329 if (start_ptr) {
4330 WRITE_MPEG_REG(PARSER_SUB_RP, start_ptr);
4331 goto exit;
4332 }
4333 sbuff = get_stream_buffer(BUF_TYPE_SUBTITLE);
4334 if (sbuff) {
4335 if (sbuff->flag & BUF_FLAG_IOMEM)
4336 phy_addr = sbuff->buf_start;
4337 else
4338 phy_addr = virt_to_phys((void *)sbuff->buf_start);
4339
4340 WRITE_MPEG_REG(PARSER_SUB_RP, phy_addr);
4341 WRITE_MPEG_REG(PARSER_SUB_START_PTR, phy_addr);
4342 WRITE_MPEG_REG(PARSER_SUB_END_PTR,
4343 phy_addr + sbuff->buf_size - 8);
4344
4345 pr_dbg("pes buff=:%x %x\n", phy_addr, sbuff->buf_size);
4346 } else
4347 pr_dbg("Error stream buffer\n");
4348exit:
4349 return 0;
4350}
4351#endif
4352
4353static int set_subtitle_pes_buffer(struct aml_dmx *dmx)
4354{
4355#ifdef SUB_PARSER
4356 unsigned long addr = virt_to_phys((void *)dmx->sub_pages);
4357 WRITE_MPEG_REG(PARSER_SUB_RP, addr);
4358 WRITE_MPEG_REG(PARSER_SUB_START_PTR, addr);
4359 WRITE_MPEG_REG(PARSER_SUB_END_PTR, addr + dmx->sub_buf_len - 8);
4360 pr_inf("set sub buff: (%d) %lx %x\n", dmx->id, addr, dmx->sub_buf_len);
4361#endif
4362 return 0;
4363}
4364
4365int dmx_get_sub_buffer(unsigned long *base, unsigned long *virt)
4366{
4367#ifndef SUB_BUF_DMX
4368 unsigned long s = READ_MPEG_REG(PARSER_SUB_START_PTR);
4369 if (base)
4370 *base = s;
4371 if (virt)
4372 *virt = (unsigned long)codec_mm_phys_to_virt(s);
4373#endif
4374 return 0;
4375}
4376
4377int dmx_init_sub_buffer(struct aml_dmx *dmx, unsigned long base, unsigned long virt)
4378{
4379#ifndef SUB_BUF_DMX
4380 dmx->sub_buf_base = base;
4381 pr_inf("sub buf base: 0x%lx\n", dmx->sub_buf_base);
4382
4383 dmx->sub_buf_base_virt = (u8 *)virt;
4384 pr_inf("sub buf base virt: 0x%p\n", dmx->sub_buf_base_virt);
4385#endif
4386 return 0;
4387}
4388
4389/*Allocate a new channel*/
4390int dmx_alloc_chan(struct aml_dmx *dmx, int type, int pes_type, int pid)
4391{
4392 int id = -1;
4393 int ret;
4394
4395 if (type == DMX_TYPE_TS) {
4396 switch (pes_type) {
4397 case DMX_PES_VIDEO:
4398 if (!dmx->channel[0].used)
4399 id = 0;
4400 break;
4401 case DMX_PES_AUDIO:
4402 if (!dmx->channel[1].used)
4403 id = 1;
4404 break;
4405 case DMX_PES_SUBTITLE:
4406 case DMX_PES_TELETEXT:
4407 if (!dmx->channel[2].used)
4408 id = 2;
4409 //alloc_subtitle_pes_buffer(dmx);
4410 set_subtitle_pes_buffer(dmx);
4411 break;
4412 case DMX_PES_PCR:
4413 if (!dmx->channel[3].used)
4414 id = 3;
4415 break;
4416 case DMX_PES_OTHER:
4417 case DMX_PES_AUDIO3:
4418 {
4419 int i;
4420
4421 for (i = SYS_CHAN_COUNT;
4422 i < CHANNEL_COUNT; i++) {
4423 if (!dmx->channel[i].used) {
4424 id = i;
4425 break;
4426 }
4427 }
4428 }
4429 break;
4430 default:
4431 break;
4432 }
4433 } else {
4434 int i;
4435
4436 for (i = SYS_CHAN_COUNT; i < CHANNEL_COUNT; i++) {
4437 if (!dmx->channel[i].used) {
4438 id = i;
4439 break;
4440 }
4441 }
4442 }
4443
4444 if (id == -1) {
4445 pr_error("too many channels\n");
4446 return -1;
4447 }
4448
4449 pr_dbg("allocate channel(id:%d PID:0x%x)\n", id, pid);
4450
4451 if (id <= 3) {
4452 ret = dmx_get_chan(dmx, pid);
4453 if (ret >= 0 && DVR_FEED(dmx->channel[ret].feed)) {
4454 dmx_remove_feed(dmx, dmx->channel[ret].feed);
4455 dmx->channel[id].dvr_feed = dmx->channel[ret].feed;
4456 dmx->channel[id].dvr_feed->priv = (void *)(long)id;
4457 } else {
4458 dmx->channel[id].dvr_feed = NULL;
4459 }
4460 }
4461
4462 dmx->channel[id].type = type;
4463 dmx->channel[id].pes_type = pes_type;
4464 dmx->channel[id].pid = pid;
4465 dmx->channel[id].used = 1;
4466 dmx->channel[id].filter_count = 0;
4467
4468 dmx_set_chan_regs(dmx, id);
4469
4470 set_debug_dmx_chanpids(dmx->id, id, pid);
4471
4472 dmx->chan_count++;
4473
4474 dmx_enable(dmx);
4475
4476 return id;
4477}
4478
4479/*Free a channel*/
4480void dmx_free_chan(struct aml_dmx *dmx, int cid)
4481{
4482 pr_dbg("free channel(id:%d PID:0x%x)\n", cid, dmx->channel[cid].pid);
4483
4484 dmx->channel[cid].used = 0;
4485 dmx->channel[cid].pid = 0x1fff;
4486 dmx_set_chan_regs(dmx, cid);
4487
4488 if (cid == 2) {
4489 u32 parser_sub_start_ptr;
4490
4491 parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR);
4492 WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_start_ptr);
4493 WRITE_MPEG_REG(PARSER_SUB_WP, parser_sub_start_ptr);
4494 }
4495
4496 set_debug_dmx_chanpids(dmx->id, cid, -1);
4497 dmx->chan_count--;
4498
4499 dmx_enable(dmx);
4500
4501 /*Special pes type channel, check its dvr feed */
4502 if (cid <= 3 && dmx->channel[cid].dvr_feed) {
4503 /*start the dvr feed */
4504 dmx_add_feed(dmx, dmx->channel[cid].dvr_feed);
4505 }
4506}
4507
4508/*Add a section*/
4509static int dmx_chan_add_filter(struct aml_dmx *dmx, int cid,
4510 struct dvb_demux_filter *filter)
4511{
4512 int id = -1;
4513 int i;
4514
4515 for (i = 0; i < FILTER_COUNT; i++) {
4516 if (!dmx->filter[i].used) {
4517 id = i;
4518 break;
4519 }
4520 }
4521
4522 if (id == -1) {
4523 pr_error("too many filters\n");
4524 return -1;
4525 }
4526
4527 pr_dbg("channel(id:%d PID:0x%x) add filter(id:%d)\n", cid,
4528 filter->feed->pid, id);
4529
4530 dmx->filter[id].chan_id = cid;
4531 dmx->filter[id].used = 1;
4532 dmx->filter[id].filter = (struct dmx_section_filter *)filter;
4533 dmx->channel[cid].filter_count++;
4534
4535 dmx_set_filter_regs(dmx, id);
4536
4537 return id;
4538}
4539
4540static void dmx_remove_filter(struct aml_dmx *dmx, int cid, int fid)
4541{
4542 pr_dbg("channel(id:%d PID:0x%x) remove filter(id:%d)\n", cid,
4543 dmx->channel[cid].pid, fid);
4544
4545 dmx->filter[fid].used = 0;
4546 dmx->channel[cid].filter_count--;
4547
4548 dmx_set_filter_regs(dmx, fid);
4549 dmx_clear_filter_buffer(dmx, fid);
4550}
4551
4552static int sf_add_feed(struct aml_dmx *src_dmx, struct dvb_demux_feed *feed)
4553{
4554 int ret = 0;
4555
4556 struct aml_dvb *dvb = (struct aml_dvb *)src_dmx->demux.priv;
4557 struct aml_swfilter *sf = &dvb->swfilter;
4558
4559 pr_dbg_sf("sf add pid[%d]\n", feed->pid);
4560
4561 /*init sf */
4562 if (!sf->user) {
4563 void *mem;
4564
4565 mem = vmalloc(SF_BUFFER_SIZE);
4566 if (!mem) {
4567 ret = -ENOMEM;
4568 goto fail;
4569 }
4570 dvb_ringbuffer_init(&sf->rbuf, mem, SF_BUFFER_SIZE);
4571
4572 sf->dmx = &dvb->dmx[SF_DMX_ID];
4573 sf->afifo = &dvb->asyncfifo[SF_AFIFO_ID];
4574
4575 sf->dmx->source = src_dmx->source;
4576 sf->afifo->source = sf->dmx->id;
4577 sf->track_dmx = src_dmx->id;
4578 /*sf->afifo->flush_size = 188*10; */
4579
4580 pr_dbg_sf("init sf mode.\n");
4581
4582 } else if (sf->dmx->source != src_dmx->source) {
4583 pr_error(" pid=%d[src:%d] already used with sfdmx%d[src:%d]\n",
4584 feed->pid, src_dmx->source, sf->dmx->id,
4585 sf->dmx->source);
4586 ret = -EBUSY;
4587 goto fail;
4588 }
4589
4590 /*setup feed */
4591 ret = dmx_get_chan(sf->dmx, feed->pid);
4592 if (ret >= 0) {
4593 pr_error(" pid=%d[dmx:%d] already used [dmx:%d].\n",
4594 feed->pid, src_dmx->id,
4595 ((struct aml_dmx *)sf->dmx->channel[ret].feed->
4596 demux)->id);
4597 ret = -EBUSY;
4598 goto fail;
4599 }
4600 ret =
4601 dmx_alloc_chan(sf->dmx, DMX_TYPE_TS, DMX_PES_OTHER,
4602 feed->pid);
4603 if (ret < 0) {
4604 pr_error(" %s: alloc chan error, ret=%d\n", __func__, ret);
4605 ret = -EBUSY;
4606 goto fail;
4607 }
4608 sf->dmx->channel[ret].feed = feed;
4609 feed->priv = (void *)(long)ret;
4610
4611 sf->dmx->channel[ret].dvr_feed = feed;
4612
4613 sf->user++;
4614 debug_sf_user = sf->user;
4615
4616 dmx_enable(sf->dmx);
4617
4618 return 0;
4619
4620fail:
4621 feed->priv = (void *)-1;
4622 return ret;
4623}
4624
4625static int sf_remove_feed(struct aml_dmx *src_dmx, struct dvb_demux_feed *feed)
4626{
4627 int ret;
4628
4629 struct aml_dvb *dvb = (struct aml_dvb *)src_dmx->demux.priv;
4630 struct aml_swfilter *sf = &dvb->swfilter;
4631
4632 if (!sf->user || (sf->dmx->source != src_dmx->source))
4633 return 0;
4634
4635 /*add fail, no need to remove*/
4636 if (((long)feed->priv) < 0)
4637 return 0;
4638
4639 ret = dmx_get_chan(sf->dmx, feed->pid);
4640 if (ret < 0)
4641 return 0;
4642
4643 pr_dbg_sf("sf remove pid[%d]\n", feed->pid);
4644
4645 dmx_free_chan(sf->dmx, (long)feed->priv);
4646
4647 sf->dmx->channel[ret].feed = NULL;
4648 sf->dmx->channel[ret].dvr_feed = NULL;
4649
4650 sf->user--;
4651 debug_sf_user = sf->user;
4652
4653 if (!sf->user) {
4654 sf->dmx->source = -1;
4655 sf->afifo->source = AM_DMX_MAX;
4656 sf->track_dmx = -1;
4657 /*sf->afifo->flush_size = sf->afifo->buf_len>>1; */
4658
4659 if (sf->rbuf.data) {
4660 void *mem = sf->rbuf.data;
4661
4662 sf->rbuf.data = NULL;
4663 vfree(mem);
4664 }
4665 pr_dbg_sf("exit sf mode.\n");
4666 }
4667
4668 return 0;
4669}
4670
4671static int sf_feed_sf(struct aml_dmx *dmx, struct dvb_demux_feed *feed,
4672 int add_not_remove)
4673{
4674 int sf = 0;
4675
4676 if (sf_dmx_sf(dmx)) {
4677 pr_error("%s: demux %d is in sf mode\n", __func__, dmx->id);
4678 return -EINVAL;
4679 }
4680
4681 switch (feed->type) {
4682 case DMX_TYPE_TS:{
4683 struct dmxdev_filter *dmxdevfilter =
4684 feed->feed.ts.priv;
4685 if (!DVR_FEED(feed)) {
4686 if (dmxdevfilter->params.pes.
4687 flags & DMX_USE_SWFILTER)
4688 sf = 1;
4689 if (force_pes_sf)
4690 sf = 1;
4691 }
4692 }
4693 break;
4694
4695 case DMX_TYPE_SEC:{
4696 struct dvb_demux_filter *filter;
4697
4698 for (filter = feed->filter; filter;
4699 filter = filter->next) {
4700 struct dmxdev_filter *dmxdevfilter =
4701 filter->filter.priv;
4702 if (dmxdevfilter->params.sec.
4703 flags & DMX_USE_SWFILTER)
4704 sf = 1;
4705 if (add_not_remove)
4706 filter->hw_handle = (u16)-1;
4707 }
4708 if (force_sec_sf)
4709 sf = 1;
4710 }
4711 break;
4712 }
4713
4714 return sf ? 0 : 1;
4715}
4716
4717static int sf_check_feed(struct aml_dmx *dmx, struct dvb_demux_feed *feed,
4718 int add_not_remove)
4719{
4720 int ret = 0;
4721
4722 ret = sf_feed_sf(dmx, feed, add_not_remove);
4723 if (ret)
4724 return ret;
4725
4726 pr_dbg_sf("%s [pid:%d] %s\n",
4727 (feed->type == DMX_TYPE_TS) ? "DMX_TYPE_TS" : "DMX_TYPE_SEC",
4728 feed->pid, add_not_remove ? "-> sf mode" : "sf mode ->");
4729
4730 if (add_not_remove)
4731 ret = sf_add_feed(dmx, feed);
4732 else
4733 ret = sf_remove_feed(dmx, feed);
4734
4735 if (ret < 0) {
4736 pr_error("sf %s feed fail[%d]\n",
4737 add_not_remove ? "add" : "remove", ret);
4738 }
4739 return ret;
4740}
4741
4742static int dmx_add_feed(struct aml_dmx *dmx, struct dvb_demux_feed *feed)
4743{
4744 int id, ret = 0;
4745 struct dvb_demux_filter *filter;
4746 struct dvb_demux_feed *dfeed = NULL;
4747 int sf_ret = 0; /*<0:error, =0:sf_on, >0:sf_off */
4748
4749 sf_ret = sf_check_feed(dmx, feed, 1/*SF_FEED_OP_ADD */);
4750 if (sf_ret < 0)
4751 return sf_ret;
4752
4753 switch (feed->type) {
4754 case DMX_TYPE_TS:
4755 pr_dbg("%s: DMX_TYPE_TS\n", __func__);
4756 ret = dmx_get_chan(dmx, feed->pid);
4757 if (ret >= 0) {
4758 if (DVR_FEED(dmx->channel[ret].feed)) {
4759 if (DVR_FEED(feed)) {
4760 /*dvr feed already work */
4761 pr_error("PID %d already used(DVR)\n",
4762 feed->pid);
4763 ret = -EBUSY;
4764 goto fail;
4765 }
4766 if (sf_ret) {
4767 /*if sf_on, we do not reset the
4768 *previous dvr feed, just load the pes
4769 *feed on the sf, a diffrent data path.
4770 */
4771 dfeed = dmx->channel[ret].feed;
4772 dmx_remove_feed(dmx, dfeed);
4773 }
4774 } else {
4775 if (DVR_FEED(feed)
4776 && (!dmx->channel[ret].dvr_feed)) {
4777 /*just store the dvr_feed */
4778 dmx->channel[ret].dvr_feed = feed;
4779 feed->priv = (void *)(long)ret;
4780 if (!dmx->record)
4781 dmx_enable(dmx);
4782 dmx_add_recchan(dmx->id, ret);
4783 return 0;
4784 }
4785 {
4786 pr_error("PID %d already used\n",
4787 feed->pid);
4788 ret = -EBUSY;
4789 goto fail;
4790 }
4791 }
4792 }
4793
4794 if (sf_ret) { /*not sf feed. */
4795 ret =
4796 dmx_alloc_chan(dmx, feed->type,
4797 feed->pes_type, feed->pid);
4798 if (ret < 0) {
4799 pr_dbg("%s: alloc chan error, ret=%d\n",
4800 __func__, ret);
4801 ret = -EBUSY;
4802 goto fail;
4803 }
4804 dmx->channel[ret].feed = feed;
4805 feed->priv = (void *)(long)ret;
4806 dmx->channel[ret].dvr_feed = NULL;
4807 }
4808 /*dvr */
4809 if (DVR_FEED(feed)) {
4810 dmx->channel[ret].dvr_feed = feed;
4811 feed->priv = (void *)(long)ret;
4812 if (!dmx->record)
4813 dmx_enable(dmx);
4814 dmx_add_recchan(dmx->id, ret);
4815 } else if (dfeed && sf_ret) {
4816 dmx->channel[ret].dvr_feed = dfeed;
4817 dfeed->priv = (void *)(long)ret;
4818 if (!dmx->record)
4819 dmx_enable(dmx);
4820 dmx_add_recchan(dmx->id, ret);
4821 }
4822
4823 break;
4824 case DMX_TYPE_SEC:
4825 pr_dbg("%s: DMX_TYPE_SEC\n", __func__);
4826 ret = dmx_get_chan(dmx, feed->pid);
4827 if (ret >= 0) {
4828 if (DVR_FEED(dmx->channel[ret].feed)) {
4829 if (sf_ret) {
4830 /*if sf_on, we do not reset the
4831 *previous dvr feed, just load the pes
4832 *feed on the sf,a diffrent data path.
4833 */
4834 dfeed = dmx->channel[ret].feed;
4835 dmx_remove_feed(dmx, dfeed);
4836 }
4837 } else {
4838 pr_error("PID %d already used\n", feed->pid);
4839 ret = -EBUSY;
4840 goto fail;
4841 }
4842 }
4843 if (sf_ret) { /*not sf feed. */
4844 id = dmx_alloc_chan(dmx, feed->type,
4845 feed->pes_type, feed->pid);
4846 if (id < 0) {
4847 pr_dbg("%s: alloc chan error, ret=%d\n",
4848 __func__, id);
4849 ret = -EBUSY;
4850 goto fail;
4851 }
4852 for (filter = feed->filter; filter;
4853 filter = filter->next) {
4854 ret = dmx_chan_add_filter(dmx, id, filter);
4855 if (ret >= 0)
4856 filter->hw_handle = ret;
4857 else
4858 filter->hw_handle = (u16)-1;
4859 }
4860 dmx->channel[id].feed = feed;
4861 feed->priv = (void *)(long)id;
4862 dmx->channel[id].dvr_feed = NULL;
4863
4864 if (dfeed) {
4865 dmx->channel[id].dvr_feed = dfeed;
4866 dfeed->priv = (void *)(long)id;
4867 if (!dmx->record)
4868 dmx_enable(dmx);
4869 dmx_add_recchan(dmx->id, id);
4870 }
4871 }
4872 break;
4873 default:
4874 return -EINVAL;
4875 }
4876
4877 dmx->feed_count++;
4878
4879 return 0;
4880
4881fail:
4882 feed->priv = (void *)-1;
4883 return ret;
4884}
4885
4886static int dmx_remove_feed(struct aml_dmx *dmx, struct dvb_demux_feed *feed)
4887{
4888 struct dvb_demux_filter *filter;
4889 struct dvb_demux_feed *dfeed = NULL;
4890
4891 int sf_ret = 0; /*<0:error, =0:sf_on, >0:sf_off */
4892
4893 /*add fail, no need to remove*/
4894 if (((long)feed->priv) < 0)
4895 return 0;
4896
4897 sf_ret = sf_check_feed(dmx, feed, 0/*SF_FEED_OP_RM */);
4898 if (sf_ret <= 0)
4899 return sf_ret;
4900
4901 switch (feed->type) {
4902 case DMX_TYPE_TS:
4903 if (dmx->channel[(long)feed->priv].feed ==
4904 dmx->channel[(long)feed->priv].dvr_feed) {
4905 dmx_rm_recchan(dmx->id, (long)feed->priv);
4906 dmx_free_chan(dmx, (long)feed->priv);
4907 } else {
4908 if (feed == dmx->channel[(long)feed->priv].feed) {
4909 dfeed = dmx->channel[(long)feed->priv].dvr_feed;
4910 dmx_rm_recchan(dmx->id, (long)feed->priv);
4911 dmx_free_chan(dmx, (long)feed->priv);
4912 if (dfeed) {
4913 /*start the dvr feed */
4914 dmx_add_feed(dmx, dfeed);
4915 }
4916 } else if (feed ==
4917 dmx->channel[(long)feed->priv].dvr_feed) {
4918 /*just remove the dvr_feed */
4919 dmx->channel[(long)feed->priv].dvr_feed = NULL;
4920 dmx_rm_recchan(dmx->id, (long)feed->priv);
4921 if (dmx->record)
4922 dmx_enable(dmx);
4923 } else {
4924 /*This must never happen */
4925 pr_error("%s: unknown feed\n", __func__);
4926 return -EINVAL;
4927 }
4928 }
4929
4930 break;
4931 case DMX_TYPE_SEC:
4932 for (filter = feed->filter; filter; filter = filter->next) {
4933 if (filter->hw_handle != (u16)-1)
4934 dmx_remove_filter(dmx, (long)feed->priv,
4935 (int)filter->hw_handle);
4936 }
4937
4938 dfeed = dmx->channel[(long)feed->priv].dvr_feed;
4939 dmx_rm_recchan(dmx->id, (long)feed->priv);
4940 dmx_free_chan(dmx, (long)feed->priv);
4941 if (dfeed) {
4942 /*start the dvr feed */
4943 dmx_add_feed(dmx, dfeed);
4944 }
4945 break;
4946 default:
4947 return -EINVAL;
4948 }
4949
4950 dmx->feed_count--;
4951 return 0;
4952}
4953
4954int aml_dmx_hw_init(struct aml_dmx *dmx)
4955{
4956 /*
4957 *struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
4958 *unsigned long flags;
4959 */
4960 int ret;
4961
4962 /*Demux initialize */
4963 /*spin_lock_irqsave(&dvb->slock, flags);*/
4964 ret = dmx_init(dmx);
4965 /*spin_unlock_irqrestore(&dvb->slock, flags);*/
4966
4967 return ret;
4968}
4969
4970int aml_dmx_hw_deinit(struct aml_dmx *dmx)
4971{
4972 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
4973 unsigned long flags;
4974 int ret;
4975
4976 spin_lock_irqsave(&dvb->slock, flags);
4977 ret = dmx_deinit(dmx);
4978 spin_unlock_irqrestore(&dvb->slock, flags);
4979
4980 return ret;
4981}
4982
4983/*extern void afifo_reset(int v);*/
4984
4985int aml_asyncfifo_hw_init(struct aml_asyncfifo *afifo)
4986{
4987
4988/*
4989 * struct aml_dvb *dvb = afifo->dvb;
4990 * unsigned long flags;
4991 */
4992 int ret;
4993
4994 int len = asyncfifo_buf_len;
4995 unsigned long buf = asyncfifo_alloc_buffer(len);
4996
4997 if (!buf)
4998 return -1;
4999
5000 /*Async FIFO initialize*/
5001/*
5002 * spin_lock_irqsave(&dvb->slock, flags);
5003 */
5004/*
5005 *#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
5006 * CLK_GATE_ON(ASYNC_FIFO);
5007 *#endif
5008 */
5009 /*afifo_reset(0);*/
5010
5011 WRITE_MPEG_REG(RESET6_REGISTER, (1<<11)|(1<<12));
5012
5013 ret = async_fifo_init(afifo, 1, len, buf);
5014/*
5015 * spin_unlock_irqrestore(&dvb->slock, flags);
5016 */
5017 if (ret < 0)
5018 asyncfifo_free_buffer(buf, len);
5019
5020 return ret;
5021}
5022
5023int aml_asyncfifo_hw_deinit(struct aml_asyncfifo *afifo)
5024{
5025 int ret;
5026
5027 ret = async_fifo_deinit(afifo, 1);
5028/*
5029 *#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
5030 * CLK_GATE_OFF(ASYNC_FIFO);
5031 *#endif
5032 */
5033 /*afifo_reset(1);*/
5034
5035 return ret;
5036}
5037
5038int aml_asyncfifo_hw_reset(struct aml_asyncfifo *afifo)
5039{
5040 struct aml_dvb *dvb = afifo->dvb;
5041 unsigned long flags;
5042 int ret, src = -1;
5043
5044 unsigned long buf = 0;
5045 int len = asyncfifo_buf_len;
5046 buf = asyncfifo_alloc_buffer(len);
5047 if (!buf)
5048 return -1;
5049
5050 if (afifo->init) {
5051 src = afifo->source;
5052 async_fifo_deinit(afifo, 0);
5053 }
5054
5055 spin_lock_irqsave(&dvb->slock, flags);
5056 ret = async_fifo_init(afifo, 0, len, buf);
5057 /* restore the source */
5058 if (src != -1)
5059 afifo->source = src;
5060
5061 if ((ret == 0) && afifo->dvb)
5062 reset_async_fifos(afifo->dvb);
5063
5064 spin_unlock_irqrestore(&dvb->slock, flags);
5065
5066 if (ret < 0)
5067 asyncfifo_free_buffer(buf, len);
5068
5069 return ret;
5070}
5071
5072int aml_dmx_hw_start_feed(struct dvb_demux_feed *dvbdmxfeed)
5073{
5074 struct aml_dmx *dmx = (struct aml_dmx *)dvbdmxfeed->demux;
5075 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
5076 unsigned long flags;
5077 int ret = 0;
5078
5079 spin_lock_irqsave(&dvb->slock, flags);
5080 ret = dmx_add_feed(dmx, dvbdmxfeed);
5081 spin_unlock_irqrestore(&dvb->slock, flags);
5082
5083 /*handle errors silently*/
5084 if (ret != 0)
5085 ret = 0;
5086
5087 return ret;
5088}
5089
5090int aml_dmx_hw_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
5091{
5092 struct aml_dmx *dmx = (struct aml_dmx *)dvbdmxfeed->demux;
5093 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
5094 unsigned long flags;
5095
5096 spin_lock_irqsave(&dvb->slock, flags);
5097 dmx_remove_feed(dmx, dvbdmxfeed);
5098 spin_unlock_irqrestore(&dvb->slock, flags);
5099
5100 return 0;
5101}
5102
5103int sf_dmx_track_source(struct aml_dmx *dmx)
5104{
5105 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
5106 struct aml_swfilter *sf = &dvb->swfilter;
5107
5108 if (sf->user && (dmx->id == sf->track_dmx)) {
5109 pr_dbg_sf("tracking dmx src [%d -> %d]\n",
5110 sf->dmx->source, dmx->source);
5111 sf->dmx->source = dmx->source;
5112 dmx_reset_dmx_hw_ex_unlock(dvb, sf->dmx, 0);
5113 }
5114 return 0;
5115}
5116
5117int aml_dmx_hw_set_source(struct dmx_demux *demux, dmx_source_t src)
5118{
5119 struct aml_dmx *dmx = (struct aml_dmx *)demux;
5120 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
5121 int ret = 0;
5122 int hw_src;
5123 unsigned long flags;
5124
5125 if (sf_dmx_sf(dmx)) {
5126 pr_error("%s: demux %d is in sf mode\n", __func__, dmx->id);
5127 return -EINVAL;
5128 }
5129
5130 spin_lock_irqsave(&dvb->slock, flags);
5131
5132 hw_src = dmx->source;
5133
5134 switch (src) {
5135 case DMX_SOURCE_FRONT0:
5136 hw_src =
5137 (dvb->ts[0].mode ==
5138 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS0) : AM_TS_SRC_TS0;
5139 break;
5140 case DMX_SOURCE_FRONT1:
5141 hw_src =
5142 (dvb->ts[1].mode ==
5143 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS1) : AM_TS_SRC_TS1;
5144 break;
5145 case DMX_SOURCE_FRONT2:
5146 hw_src =
5147 (dvb->ts[2].mode ==
5148 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS2) : AM_TS_SRC_TS2;
5149 break;
5150 case DMX_SOURCE_FRONT3:
5151 hw_src =
5152 (dvb->ts[3].mode ==
5153 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS3) : AM_TS_SRC_TS3;
5154 break;
5155 case DMX_SOURCE_DVR0:
5156 hw_src = AM_TS_SRC_HIU;
5157 break;
5158 case DMX_SOURCE_DVR1:
5159 hw_src = AM_TS_SRC_HIU1;
5160 break;
5161 case DMX_SOURCE_FRONT0_OFFSET:
5162 hw_src = AM_TS_SRC_DMX0;
5163 break;
5164 case DMX_SOURCE_FRONT1_OFFSET:
5165 hw_src = AM_TS_SRC_DMX1;
5166 break;
5167 case DMX_SOURCE_FRONT2_OFFSET:
5168 hw_src = AM_TS_SRC_DMX2;
5169 break;
5170 default:
5171 pr_error("illegal demux source %d\n", src);
5172 ret = -EINVAL;
5173 break;
5174 }
5175
5176 if (hw_src != dmx->source) {
5177 dmx->source = hw_src;
5178 dmx_reset_dmx_hw_ex_unlock(dvb, dmx, 0);
5179 sf_dmx_track_source(dmx);
5180 }
5181
5182 spin_unlock_irqrestore(&dvb->slock, flags);
5183
5184 return ret;
5185}
5186
5187#define IS_SRC_DMX(_src) ((_src) >= AM_TS_SRC_DMX0 && (_src) <= AM_TS_SRC_DMX2)
5188
5189int aml_stb_hw_set_source(struct aml_dvb *dvb, dmx_source_t src)
5190{
5191 unsigned long flags;
5192 int hw_src;
5193 int ret;
5194
5195 ret = 0;
5196 spin_lock_irqsave(&dvb->slock, flags);
5197
5198 hw_src = dvb->stb_source;
5199
5200 switch (src) {
5201 case DMX_SOURCE_FRONT0:
5202 hw_src =
5203 (dvb->ts[0].mode ==
5204 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS0) : AM_TS_SRC_TS0;
5205 break;
5206 case DMX_SOURCE_FRONT1:
5207 hw_src =
5208 (dvb->ts[1].mode ==
5209 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS1) : AM_TS_SRC_TS1;
5210 break;
5211 case DMX_SOURCE_FRONT2:
5212 hw_src =
5213 (dvb->ts[2].mode ==
5214 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS2) : AM_TS_SRC_TS2;
5215 break;
5216 case DMX_SOURCE_FRONT3:
5217 hw_src =
5218 (dvb->ts[3].mode ==
5219 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS3) : AM_TS_SRC_TS3;
5220 break;
5221 case DMX_SOURCE_DVR0:
5222 hw_src = AM_TS_SRC_HIU;
5223 break;
5224 case DMX_SOURCE_DVR1:
5225 hw_src = AM_TS_SRC_HIU1;
5226 break;
5227 case DMX_SOURCE_FRONT0_OFFSET:
5228 hw_src = AM_TS_SRC_DMX0;
5229 break;
5230 case DMX_SOURCE_FRONT1_OFFSET:
5231 hw_src = AM_TS_SRC_DMX1;
5232 break;
5233 case DMX_SOURCE_FRONT2_OFFSET:
5234 hw_src = AM_TS_SRC_DMX2;
5235 break;
5236 default:
5237 pr_error("illegal demux source %d\n", src);
5238 ret = -EINVAL;
5239 break;
5240 }
5241
5242 if (dvb->stb_source != hw_src) {
5243 int old_source = dvb->stb_source;
5244
5245 dvb->stb_source = hw_src;
5246
5247 if (IS_SRC_DMX(old_source)) {
5248 dmx_set_misc_id(dvb,
5249 (old_source - AM_TS_SRC_DMX0), 0, -1);
5250 } else {
5251 /*which dmx for av-play is unknown,
5252 *can't avoid reset-all
5253 */
5254 dmx_reset_hw_ex(dvb, 0);
5255 }
5256
5257 if (IS_SRC_DMX(dvb->stb_source)) {
5258 dmx_set_misc_id(dvb,
5259 (dvb->stb_source - AM_TS_SRC_DMX0), 1, -1);
5260 /*dmx_reset_dmx_id_hw_ex_unlock
5261 * (dvb, (dvb->stb_source-AM_TS_SRC_DMX0), 0);
5262 */
5263 } else {
5264 /*which dmx for av-play is unknown,
5265 *can't avoid reset-all
5266 */
5267 dmx_reset_hw_ex(dvb, 0);
5268 }
5269 }
5270
5271 spin_unlock_irqrestore(&dvb->slock, flags);
5272
5273 return ret;
5274}
5275
5276
5277
5278int aml_dsc_hw_set_source(struct aml_dsc *dsc,
5279 dmx_source_t src, dmx_source_t dst)
5280{
5281 struct aml_dvb *dvb = dsc->dvb;
5282 int ret = 0;
5283 unsigned long flags;
5284 int hw_src = -1, hw_dst = -1, org_src = -1, org_dst = -1;
5285 int src_reset = 0, dst_reset = 0;
5286
5287 spin_lock_irqsave(&dvb->slock, flags);
5288
5289 hw_src = dsc->source;
5290 hw_dst = dsc->dst;
5291
5292 switch (src) {
5293 case DMX_SOURCE_FRONT0_OFFSET:
5294 hw_src = AM_TS_SRC_DMX0;
5295 break;
5296 case DMX_SOURCE_FRONT1_OFFSET:
5297 hw_src = AM_TS_SRC_DMX1;
5298 break;
5299 case DMX_SOURCE_FRONT2_OFFSET:
5300 hw_src = AM_TS_SRC_DMX2;
5301 break;
5302 default:
5303 hw_src = -1;
5304 break;
5305 }
5306 switch (dst) {
5307 case DMX_SOURCE_FRONT0_OFFSET:
5308 hw_dst = AM_TS_SRC_DMX0;
5309 break;
5310 case DMX_SOURCE_FRONT1_OFFSET:
5311 hw_dst = AM_TS_SRC_DMX1;
5312 break;
5313 case DMX_SOURCE_FRONT2_OFFSET:
5314 hw_dst = AM_TS_SRC_DMX2;
5315 break;
5316 default:
5317 hw_dst = -1;
5318 break;
5319 }
5320
5321 if (hw_src != dsc->source) {
5322 org_src = dsc->source;
5323 dsc->source = hw_src;
5324 src_reset = 1;
5325 }
5326 if (hw_dst != dsc->dst) {
5327 org_dst = dsc->dst;
5328 dsc->dst = hw_dst;
5329 dst_reset = 1;
5330 }
5331
5332 if (src_reset) {
5333 pr_inf("dsc%d source changed: %d -> %d\n",
5334 dsc->id, org_src, hw_src);
5335 if (org_src != -1) {
5336 pr_inf("reset dmx%d\n", (org_src - AM_TS_SRC_DMX0));
5337 dmx_reset_dmx_id_hw_ex_unlock(dvb,
5338 (org_src - AM_TS_SRC_DMX0), 0);
5339 }
5340 if (hw_src != -1) {
5341 pr_inf("reset dmx%d\n", (hw_src - AM_TS_SRC_DMX0));
5342 dmx_reset_dmx_id_hw_ex_unlock(dvb,
5343 (hw_src - AM_TS_SRC_DMX0), 0);
5344 } else
5345 dsc_enable(dsc, 0);
5346 }
5347 if (dst_reset) {
5348 pr_inf("dsc%d dest changed: %d -> %d\n",
5349 dsc->id, org_dst, hw_dst);
5350 if (((!src_reset) && (org_dst != -1)) ||
5351 (src_reset && (org_dst != -1) &&
5352 (org_dst != org_src) && (org_dst != hw_src))) {
5353 pr_inf("reset dmx%d\n", (org_dst - AM_TS_SRC_DMX0));
5354 dmx_reset_dmx_id_hw_ex_unlock(dvb,
5355 (org_dst - AM_TS_SRC_DMX0), 0);
5356 }
5357 if (((!src_reset) && (hw_dst != -1)) ||
5358 (src_reset && (hw_dst != -1)
5359 && (hw_dst != org_src) && (hw_dst != hw_src))) {
5360 pr_inf("reset dmx%d\n", (hw_dst - AM_TS_SRC_DMX0));
5361 dmx_reset_dmx_id_hw_ex_unlock(dvb,
5362 (hw_dst - AM_TS_SRC_DMX0), 0);
5363 }
5364 if (hw_dst == -1)
5365 dsc_enable(dsc, 0);
5366 }
5367
5368 spin_unlock_irqrestore(&dvb->slock, flags);
5369
5370 return ret;
5371}
5372
5373int aml_tso_hw_set_source(struct aml_dvb *dvb, dmx_source_t src)
5374{
5375 int ret = 0;
5376 unsigned long flags;
5377 int hw_src;
5378
5379 spin_lock_irqsave(&dvb->slock, flags);
5380
5381 hw_src = dvb->tso_source;
5382
5383 switch (src) {
5384 case DMX_SOURCE_FRONT0:
5385 hw_src = (dvb->ts[0].mode == AM_TS_SERIAL)
5386 ? (AM_TS_SRC_S_TS0) : AM_TS_SRC_TS0;
5387 break;
5388 case DMX_SOURCE_FRONT1:
5389 hw_src = (dvb->ts[1].mode == AM_TS_SERIAL)
5390 ? (AM_TS_SRC_S_TS1) : AM_TS_SRC_TS1;
5391 break;
5392 case DMX_SOURCE_FRONT2:
5393 hw_src = (dvb->ts[2].mode == AM_TS_SERIAL)
5394 ? (AM_TS_SRC_S_TS2) : AM_TS_SRC_TS2;
5395 break;
5396 case DMX_SOURCE_FRONT3:
5397 hw_src = (dvb->ts[3].mode == AM_TS_SERIAL)
5398 ? (AM_TS_SRC_S_TS3) : AM_TS_SRC_TS3;
5399 break;
5400 case DMX_SOURCE_DVR0:
5401 hw_src = AM_TS_SRC_HIU;
5402 break;
5403 case DMX_SOURCE_FRONT0 + 100:
5404 hw_src = AM_TS_SRC_DMX0;
5405 break;
5406 case DMX_SOURCE_FRONT1 + 100:
5407 hw_src = AM_TS_SRC_DMX1;
5408 break;
5409 case DMX_SOURCE_FRONT2 + 100:
5410 hw_src = AM_TS_SRC_DMX2;
5411 break;
5412 default:
5413 hw_src = -1;
5414 ret = -EINVAL;
5415 break;
5416 }
5417
5418 if (hw_src != dvb->tso_source) {
5419 dvb->tso_source = hw_src;
5420 stb_enable(dvb);
5421 }
5422
5423 spin_unlock_irqrestore(&dvb->slock, flags);
5424
5425 return ret;
5426}
5427
5428int aml_asyncfifo_hw_set_source(struct aml_asyncfifo *afifo,
5429 enum aml_dmx_id_t src)
5430{
5431 struct aml_dvb *dvb = afifo->dvb;
5432 int ret = -1;
5433 unsigned long flags;
5434
5435 if (sf_afifo_sf(afifo)) {
5436 pr_error("%s: afifo %d is in sf mode\n", __func__, afifo->id);
5437 return -EINVAL;
5438 }
5439
5440 spin_lock_irqsave(&dvb->slock, flags);
5441
5442 pr_dbg("asyncfifo %d set source %d->%d",
5443 afifo->id, afifo->source, src);
5444 switch (src) {
5445 case AM_DMX_0:
5446 case AM_DMX_1:
5447 case AM_DMX_2:
5448 if (afifo->source != src) {
5449 afifo->source = src;
5450 ret = 0;
5451 }
5452 break;
5453 default:
5454 pr_error("illegal async fifo source %d\n", src);
5455 ret = -EINVAL;
5456 break;
5457 }
5458
5459 if (ret == 0 && afifo->dvb)
5460 reset_async_fifos(afifo->dvb);
5461
5462 spin_unlock_irqrestore(&dvb->slock, flags);
5463
5464 return ret;
5465}
5466
5467int aml_dmx_hw_set_dump_ts_select(struct dmx_demux *demux, int dump_ts_select)
5468{
5469 struct aml_dmx *dmx = (struct aml_dmx *)demux;
5470 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
5471 int ret = 0;
5472 unsigned long flags;
5473
5474 spin_lock_irqsave(&dvb->slock, flags);
5475 dump_ts_select = !!dump_ts_select;
5476 if (dmx->dump_ts_select != dump_ts_select) {
5477 dmx->dump_ts_select = dump_ts_select;
5478 dmx_reset_dmx_hw_ex_unlock(dvb, dmx, 0);
5479 }
5480 spin_unlock_irqrestore(&dvb->slock, flags);
5481
5482 return ret;
5483}
5484
5485u32 aml_dmx_get_video_pts(struct aml_dvb *dvb)
5486{
5487 unsigned long flags;
5488 u32 pts;
5489
5490 spin_lock_irqsave(&dvb->slock, flags);
5491 pts = video_pts;
5492 spin_unlock_irqrestore(&dvb->slock, flags);
5493
5494 return pts;
5495}
5496
5497u32 aml_dmx_get_audio_pts(struct aml_dvb *dvb)
5498{
5499 unsigned long flags;
5500 u32 pts;
5501
5502 spin_lock_irqsave(&dvb->slock, flags);
5503 pts = audio_pts;
5504 spin_unlock_irqrestore(&dvb->slock, flags);
5505
5506 return pts;
5507}
5508
5509u32 aml_dmx_get_video_pts_bit32(struct aml_dvb *dvb)
5510{
5511 unsigned long flags;
5512 u32 bit32;
5513
5514 spin_lock_irqsave(&dvb->slock, flags);
5515 bit32 = video_pts_bit32;
5516 spin_unlock_irqrestore(&dvb->slock, flags);
5517
5518 return bit32;
5519}
5520
5521u32 aml_dmx_get_audio_pts_bit32(struct aml_dvb *dvb)
5522{
5523 unsigned long flags;
5524 u32 bit32;
5525
5526 spin_lock_irqsave(&dvb->slock, flags);
5527 bit32 = audio_pts_bit32;
5528 spin_unlock_irqrestore(&dvb->slock, flags);
5529
5530 return bit32;
5531}
5532u32 aml_dmx_get_first_video_pts(struct aml_dvb *dvb)
5533{
5534 unsigned long flags;
5535 u32 pts;
5536
5537 spin_lock_irqsave(&dvb->slock, flags);
5538 pts = first_video_pts;
5539 spin_unlock_irqrestore(&dvb->slock, flags);
5540
5541 return pts;
5542}
5543
5544u32 aml_dmx_get_first_audio_pts(struct aml_dvb *dvb)
5545{
5546 unsigned long flags;
5547 u32 pts;
5548
5549 spin_lock_irqsave(&dvb->slock, flags);
5550 pts = first_audio_pts;
5551 spin_unlock_irqrestore(&dvb->slock, flags);
5552
5553 return pts;
5554}
5555
5556int aml_dmx_set_skipbyte(struct aml_dvb *dvb, int skipbyte)
5557{
5558 if (demux_skipbyte != skipbyte) {
5559 pr_dbg("set skip byte %d\n", skipbyte);
5560 demux_skipbyte = skipbyte;
5561 dmx_reset_hw_ex(dvb, 0);
5562 }
5563
5564 return 0;
5565}
5566
5567int aml_dmx_set_demux(struct aml_dvb *dvb, int id)
5568{
5569 aml_stb_hw_set_source(dvb, DMX_SOURCE_DVR0);
5570 if (id < DMX_DEV_COUNT) {
5571 struct aml_dmx *dmx = &dvb->dmx[id];
5572
5573 aml_dmx_hw_set_source((struct dmx_demux *)dmx,
5574 DMX_SOURCE_DVR0);
5575 }
5576
5577 return 0;
5578}
5579
5580int _set_tsfile_clkdiv(struct aml_dvb *dvb, int clkdiv)
5581{
5582 if (tsfile_clkdiv != clkdiv) {
5583 pr_dbg("set ts file clock div %d\n", clkdiv);
5584 tsfile_clkdiv = clkdiv;
5585 dmx_reset_hw(dvb);
5586 }
5587
5588 return 0;
5589}
5590
5591static ssize_t stb_set_tsfile_clkdiv(struct class *class,
5592 struct class_attribute *attr,
5593 const char *buf, size_t size)
5594{
5595 /*int div = (int)simple_strtol(buf, NULL, 10);*/
5596 long div;
5597
5598 if (kstrtol(buf, 0, &div) == 0)
5599 _set_tsfile_clkdiv(aml_get_dvb_device(), (int)div);
5600 return size;
5601}
5602
5603static ssize_t stb_get_tsfile_clkdiv(struct class *class,
5604 struct class_attribute *attr, char *buf)
5605{
5606 ssize_t ret;
5607
5608 ret = sprintf(buf, "%d\n", tsfile_clkdiv);
5609 return ret;
5610}
5611
5612
5613static int dmx_id;
5614
5615static ssize_t dmx_smallsec_show(struct class *class,
5616 struct class_attribute *attr, char *buf)
5617{
5618 ssize_t ret;
5619 struct aml_dvb *dvb = aml_get_dvb_device();
5620
5621 ret = sprintf(buf, "%d:%d\n", dvb->dmx[dmx_id].smallsec.enable,
5622 dvb->dmx[dmx_id].smallsec.bufsize);
5623 return ret;
5624}
5625static ssize_t dmx_smallsec_store(struct class *class,
5626 struct class_attribute *attr,
5627 const char *buf, size_t size)
5628{
5629 int i, e, s = 0, f = 0;
5630 struct aml_dvb *dvb = aml_get_dvb_device();
5631
5632 i = sscanf(buf, "%d:%i:%d", &e, &s, &f);
5633 if (i <= 0)
5634 return size;
5635
5636 dmx_smallsec_set(&dvb->dmx[dmx_id].smallsec, e, s, f);
5637 return size;
5638}
5639
5640static ssize_t dmx_timeout_show(struct class *class,
5641 struct class_attribute *attr, char *buf)
5642{
5643 ssize_t ret;
5644 struct aml_dvb *dvb = aml_get_dvb_device();
5645
5646 ret = sprintf(buf, "%d:%d:0x%x:%d:%d\n",
5647 dvb->dmx[dmx_id].timeout.enable,
5648 dvb->dmx[dmx_id].timeout.timeout,
5649 dvb->dmx[dmx_id].timeout.ch_disable,
5650 dvb->dmx[dmx_id].timeout.match,
5651 (DMX_READ_REG(dmx_id, STB_INT_STATUS)&(1<<INPUT_TIME_OUT)) ?
5652 1 : 0);
5653 DMX_WRITE_REG(dmx_id, STB_INT_STATUS, (1<<INPUT_TIME_OUT));
5654 return ret;
5655}
5656static ssize_t dmx_timeout_store(struct class *class,
5657 struct class_attribute *attr,
5658 const char *buf, size_t size)
5659{
5660 int i, e, t = 0, c = 0, m = 0, f = 0;
5661 struct aml_dvb *dvb = aml_get_dvb_device();
5662
5663 i = sscanf(buf, "%d:%i:%i:%d:%d", &e, &t, &c, &m, &f);
5664 if (i <= 0)
5665 return size;
5666
5667 dmx_timeout_set(&dvb->dmx[dmx_id].timeout, e, t, c, m, f);
5668 return size;
5669}
5670
5671
5672#define DEMUX_SCAMBLE_FUNC_DECL(i) \
5673static ssize_t dmx_reg_value_show_demux##i##_scramble(struct class *class, \
5674struct class_attribute *attr, char *buf)\
5675{\
5676 int data = 0;\
5677 int aflag = 0;\
5678 int vflag = 0;\
5679 ssize_t ret = 0;\
5680 data = DMX_READ_REG(i, DEMUX_SCRAMBLING_STATE);\
5681 if ((data & 0x01) == 0x01) \
5682 vflag = 1;\
5683 if ((data & 0x02) == 0x02) \
5684 aflag = 1;\
5685 ret = sprintf(buf, "%d %d\n", vflag, aflag);\
5686 return ret;\
5687}
5688
5689#if DMX_DEV_COUNT > 0
5690DEMUX_SCAMBLE_FUNC_DECL(0)
5691#endif
5692#if DMX_DEV_COUNT > 1
5693DEMUX_SCAMBLE_FUNC_DECL(1)
5694#endif
5695#if DMX_DEV_COUNT > 2
5696DEMUX_SCAMBLE_FUNC_DECL(2)
5697#endif
5698static ssize_t ciplus_output_ctrl_show(struct class *class,
5699 struct class_attribute *attr,
5700 char *buf)
5701{
5702 int ret;
5703 char *out = "none";
5704
5705 pr_inf("output demux use 3 bit to indicate.\n");
5706 pr_inf("1bit:demux0 2bit:demux1 3bit:demux2\n");
5707
5708 switch (ciplus_out_sel) {
5709 case 1:
5710 out = "dmx0";
5711 break;
5712 case 2:
5713 out = "dmx1";
5714 break;
5715 case 4:
5716 out = "dmx2";
5717 break;
5718 default:
5719 break;
5720 }
5721
5722 ret = sprintf(buf, "%s 0x%x %s\n",
5723 out,
5724 ciplus_out_sel,
5725 (ciplus_out_auto_mode) ? "" : "(force)");
5726 return ret;
5727}
5728
5729static ssize_t ciplus_output_ctrl_store(struct class *class,
5730 struct class_attribute *attr,
5731 const char *buf, size_t size)
5732{
5733 int i, tmp;
5734
5735 i = kstrtoint(buf, -1, &tmp);
5736 if (tmp > 8 || tmp < 0)
5737 pr_error("Invalid output set\n");
5738 else if (tmp == 8) {
5739 ciplus_out_auto_mode = 1;
5740 ciplus_out_sel = -1;
5741 pr_error("Auto set output mode enable\n");
5742 } else {
5743 ciplus_out_auto_mode = 0;
5744 ciplus_out_sel = tmp;
5745 pr_error("Auto set output mode disable\n");
5746 }
5747 return size;
5748}
5749static ssize_t reset_fec_input_ctrl_show(struct class *class,
5750 struct class_attribute *attr,
5751 char *buf)
5752{
5753 return 0;
5754}
5755
5756static ssize_t reset_fec_input_ctrl_store(struct class *class,
5757 struct class_attribute *attr,
5758 const char *buf, size_t size)
5759{
5760 u32 v;
5761
5762 v = READ_MPEG_REG(FEC_INPUT_CONTROL);
5763 v &= ~(1<<11);
5764 WRITE_MPEG_REG(FEC_INPUT_CONTROL, v);
5765
5766 pr_dbg("reset FEC_INPUT_CONTROL to %x\n", v);
5767
5768 return size;
5769}
5770static ssize_t dmx_reg_addr_show_source(struct class *class,
5771 struct class_attribute *attr,
5772 char *buf);
5773static ssize_t dmx_reg_addr_store_source(struct class *class,
5774 struct class_attribute *attr,
5775 const char *buf, size_t size);
5776static ssize_t dmx_id_show_source(struct class *class,
5777 struct class_attribute *attr, char *buf);
5778static ssize_t dmx_id_store_source(struct class *class,
5779 struct class_attribute *attr,
5780 const char *buf, size_t size);
5781static ssize_t dmx_reg_value_show_source(struct class *class,
5782 struct class_attribute *attr,
5783 char *buf);
5784static ssize_t dmx_reg_value_store_source(struct class *class,
5785 struct class_attribute *attr,
5786 const char *buf, size_t size);
5787static ssize_t dmx_sec_statistics_show(struct class *class,
5788 struct class_attribute *attr,
5789 char *buf);
5790static int reg_addr;
5791
5792static struct class_attribute aml_dmx_class_attrs[] = {
5793 __ATTR(dmx_id, 0644, dmx_id_show_source,
5794 dmx_id_store_source),
5795 __ATTR(register_addr, 0644, dmx_reg_addr_show_source,
5796 dmx_reg_addr_store_source),
5797 __ATTR(register_value, 0644, dmx_reg_value_show_source,
5798 dmx_reg_value_store_source),
5799 __ATTR(tsfile_clkdiv, 0644, stb_get_tsfile_clkdiv,
5800 stb_set_tsfile_clkdiv),
5801
5802#define DEMUX_SCAMBLE_ATTR_DECL(i)\
5803 __ATTR(demux##i##_scramble, 0644, \
5804 dmx_reg_value_show_demux##i##_scramble, NULL)
5805#if DMX_DEV_COUNT > 0
5806 DEMUX_SCAMBLE_ATTR_DECL(0),
5807#endif
5808#if DMX_DEV_COUNT > 1
5809 DEMUX_SCAMBLE_ATTR_DECL(1),
5810#endif
5811#if DMX_DEV_COUNT > 2
5812 DEMUX_SCAMBLE_ATTR_DECL(2),
5813#endif
5814
5815 __ATTR(dmx_smallsec, 0644,
5816 dmx_smallsec_show,
5817 dmx_smallsec_store),
5818 __ATTR(dmx_timeout, 0644,
5819 dmx_timeout_show,
5820 dmx_timeout_store),
5821 __ATTR(reset_fec_input_ctrl, 0644,
5822 reset_fec_input_ctrl_show,
5823 reset_fec_input_ctrl_store),
5824 __ATTR(ciplus_output_ctrl, 0644,
5825 ciplus_output_ctrl_show,
5826 ciplus_output_ctrl_store),
5827 __ATTR_RO(dmx_sec_statistics),
5828 __ATTR_NULL
5829};
5830
5831static struct class aml_dmx_class = {
5832 .name = "dmx",
5833 .class_attrs = aml_dmx_class_attrs,
5834};
5835
5836static ssize_t dmx_id_show_source(struct class *class,
5837 struct class_attribute *attr, char *buf)
5838{
5839 int ret;
5840
5841 ret = sprintf(buf, "%d\n", dmx_id);
5842 return ret;
5843}
5844
5845static ssize_t dmx_id_store_source(struct class *class,
5846 struct class_attribute *attr,
5847 const char *buf, size_t size)
5848{
5849 int id = 0;
5850 long value = 0;
5851
5852 if (kstrtol(buf, 0, &value) == 0)
5853 id = (int)value;
5854 /*id = simple_strtol(buf, 0, 16);*/
5855
5856 if (id < 0 || id > 2)
5857 pr_dbg("dmx id must 0 ~2\n");
5858 else
5859 dmx_id = id;
5860
5861 return size;
5862}
5863
5864static ssize_t dmx_reg_addr_show_source(struct class *class,
5865 struct class_attribute *attr,
5866 char *buf)
5867{
5868 int ret;
5869
5870 ret = sprintf(buf, "%x\n", reg_addr);
5871 return ret;
5872}
5873
5874static ssize_t dmx_reg_addr_store_source(struct class *class,
5875 struct class_attribute *attr,
5876 const char *buf, size_t size)
5877{
5878 int addr = 0;
5879 /*addr = simple_strtol(buf, 0, 16);*/
5880 long value = 0;
5881
5882 if (kstrtol(buf, 0, &value) == 0)
5883 addr = (int)value;
5884 reg_addr = addr;
5885 return size;
5886}
5887
5888static ssize_t dmx_reg_value_show_source(struct class *class,
5889 struct class_attribute *attr,
5890 char *buf)
5891{
5892 int ret, value;
5893
5894 value = READ_MPEG_REG(reg_addr);
5895 ret = sprintf(buf, "%x\n", value);
5896 return ret;
5897}
5898
5899static ssize_t dmx_reg_value_store_source(struct class *class,
5900 struct class_attribute *attr,
5901 const char *buf, size_t size)
5902{
5903 int value = 0;
5904 /*value = simple_strtol(buf, 0, 16);*/
5905 long val = 0;
5906
5907 if (kstrtol(buf, 0, &val) == 0)
5908 value = (int)val;
5909 WRITE_MPEG_REG(reg_addr, value);
5910 return size;
5911}
5912
5913static ssize_t dmx_sec_statistics_show(struct class *class,
5914 struct class_attribute *attr,
5915 char *buf)
5916{
5917 ssize_t ret;
5918 char tmp[128];
5919 struct aml_dvb *dvb = aml_get_dvb_device();
5920
5921 ret = sprintf(tmp, "[hw]%#lx:%#lx:%#lx\n[sw]%#lx:%#lx:%#lx\n",
5922 dvb->dmx[dmx_id].sec_cnt[SEC_CNT_HW],
5923 dvb->dmx[dmx_id].sec_cnt_match[SEC_CNT_HW],
5924 dvb->dmx[dmx_id].sec_cnt_crc_fail[SEC_CNT_HW],
5925 dvb->dmx[dmx_id].sec_cnt[SEC_CNT_SW],
5926 dvb->dmx[dmx_id].sec_cnt_match[SEC_CNT_SW],
5927 dvb->dmx[dmx_id].sec_cnt_crc_fail[SEC_CNT_SW]);
5928 ret = sprintf(buf, "%s[ss]%#lx:%#lx:%#lx\n",
5929 tmp,
5930 dvb->dmx[dmx_id].sec_cnt[SEC_CNT_SS],
5931 dvb->dmx[dmx_id].sec_cnt_match[SEC_CNT_SS],
5932 dvb->dmx[dmx_id].sec_cnt_crc_fail[SEC_CNT_SS]);
5933 return ret;
5934}
5935
5936int aml_regist_dmx_class(void)
5937{
5938
5939 if (class_register(&aml_dmx_class) < 0)
5940 pr_error("register class error\n");
5941
5942 return 0;
5943}
5944
5945int aml_unregist_dmx_class(void)
5946{
5947
5948 class_unregister(&aml_dmx_class);
5949 return 0;
5950}
5951
5952static struct mconfig parser_configs[] = {
5953 MC_PU32("video_pts", &video_pts),
5954 MC_PU32("audio_pts", &audio_pts),
5955 MC_PU32("video_pts_bit32", &video_pts_bit32),
5956 MC_PU32("audio_pts_bit32", &audio_pts_bit32),
5957 MC_PU32("first_video_pts", &first_video_pts),
5958 MC_PU32("first_audio_pts", &first_audio_pts),
5959};
5960
5961void aml_register_parser_mconfig(void)
5962{
5963 REG_PATH_CONFIGS("media.parser", parser_configs);
5964}
5965
5966