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