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