summaryrefslogtreecommitdiff
path: root/drivers/stream_input/parser/hw_demux/aml_dmx.c (plain)
blob: 1e0c1caf66b60f2958e2d10e9afdfc155ad647e5
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 case DMX_PES_AUDIO3:
3277 type = OTHER_PES_PACKET;
3278 break;
3279 default:
3280 type = BYPASS_PACKET;
3281 break;
3282 }
3283 }
3284
3285 pr_dbg("chan target: %x %x\n", type, dmx->channel[cid].pid);
3286 return (type << PID_TYPE) | dmx->channel[cid].pid;
3287}
3288
3289/*Get the advance value of the channel*/
3290static inline u32 dmx_get_chan_advance(struct aml_dmx *dmx, int cid)
3291{
3292 return 0;
3293}
3294
3295/*Set the channel registers*/
3296static int dmx_set_chan_regs(struct aml_dmx *dmx, int cid)
3297{
3298 u32 data, addr, advance, max;
3299
3300 pr_dbg("set channel (id:%d PID:0x%x) registers\n", cid,
3301 dmx->channel[cid].pid);
3302
3303 while (DMX_READ_REG(dmx->id, FM_WR_ADDR) & 0x8000)
3304 udelay(1);
3305
3306 if (cid & 1) {
3307 data =
3308 (dmx_get_chan_target(dmx, cid - 1) << 16) |
3309 dmx_get_chan_target(dmx, cid);
3310 advance =
3311 (dmx_get_chan_advance(dmx, cid) << 8) |
3312 dmx_get_chan_advance(dmx, cid - 1);
3313 } else {
3314 data =
3315 (dmx_get_chan_target(dmx, cid) << 16) |
3316 dmx_get_chan_target(dmx, cid + 1);
3317 advance =
3318 (dmx_get_chan_advance(dmx, cid + 1) << 8) |
3319 dmx_get_chan_advance(dmx, cid);
3320 }
3321 addr = cid >> 1;
3322 DMX_WRITE_REG(dmx->id, FM_WR_DATA, data);
3323 DMX_WRITE_REG(dmx->id, FM_WR_ADDR, (advance << 16) | 0x8000 | addr);
3324
3325 pr_dbg("write fm %x:%x\n", (advance << 16) | 0x8000 | addr, data);
3326
3327 for (max = CHANNEL_COUNT - 1; max > 0; max--) {
3328 if (dmx->channel[max].used)
3329 break;
3330 }
3331
3332 data = DMX_READ_REG(dmx->id, MAX_FM_COMP_ADDR) & 0xF0;
3333 DMX_WRITE_REG(dmx->id, MAX_FM_COMP_ADDR, data | (max >> 1));
3334
3335 pr_dbg("write fm comp %x\n", data | (max >> 1));
3336
3337 if (DMX_READ_REG(dmx->id, OM_CMD_STATUS) & 0x8e00) {
3338 pr_error("error send cmd %x\n",
3339 DMX_READ_REG(dmx->id, OM_CMD_STATUS));
3340 }
3341
3342 if (cid == 0)
3343 first_video_pts = 0;
3344 else if (cid == 1)
3345 first_audio_pts = 0;
3346
3347 return 0;
3348}
3349
3350/*Get the filter target*/
3351static int dmx_get_filter_target(struct aml_dmx *dmx, int fid, u32 *target,
3352 u8 *advance)
3353{
3354 struct dmx_section_filter *filter;
3355 struct aml_filter *f;
3356 int i, cid, neq_bytes;
3357
3358 fid = fid & 0xFFFF;
3359 f = &dmx->filter[fid];
3360
3361 if (!f->used) {
3362 target[0] = 0x1fff;
3363 advance[0] = 0;
3364 for (i = 1; i < FILTER_LEN; i++) {
3365 target[i] = 0x9fff;
3366 advance[i] = 0;
3367 }
3368 return 0;
3369 }
3370
3371 cid = f->chan_id;
3372 filter = f->filter;
3373
3374 neq_bytes = 0;
3375 if (filter->filter_mode[0] != 0xFF) {
3376 neq_bytes = 2;
3377 } else {
3378 for (i = 3; i < FILTER_LEN; i++) {
3379 if (filter->filter_mode[i] != 0xFF)
3380 neq_bytes++;
3381 }
3382 }
3383
3384 f->neq = 0;
3385
3386 for (i = 0; i < FILTER_LEN; i++) {
3387 u8 value = filter->filter_value[i];
3388 u8 mask = filter->filter_mask[i];
3389 u8 mode = filter->filter_mode[i];
3390 u8 mb, mb1, nb, v, t, adv = 0;
3391
3392 if (!i) {
3393 mb = 1;
3394 mb1 = 1;
3395 v = 0;
3396 if ((mode == 0xFF) && mask) {
3397 t = mask & 0xF0;
3398 if (t) {
3399 mb1 = 0;
3400 adv |= t^0xF0;
3401 }
3402 v |= (value & 0xF0) | adv;
3403
3404 t = mask & 0x0F;
3405 if (t) {
3406 mb = 0;
3407 adv |= t^0x0F;
3408 }
3409 v |= (value & 0x0F) | adv;
3410 }
3411
3412 target[i] = (mb << SECTION_FIRSTBYTE_MASKLOW) |
3413 (mb1 << SECTION_FIRSTBYTE_MASKHIGH) |
3414 (0 << SECTION_FIRSTBYTE_DISABLE_PID_CHECK) |
3415 (cid << SECTION_FIRSTBYTE_PID_INDEX) | v;
3416 advance[i] = adv;
3417 } else {
3418 if (i < 3) {
3419 value = 0;
3420 mask = 0;
3421 mode = 0xff;
3422 }
3423 mb = 1;
3424 nb = 0;
3425 v = 0;
3426
3427 if ((i >= 3) && mask) {
3428 if (mode == 0xFF) {
3429 mb = 0;
3430 nb = 0;
3431 adv = mask ^ 0xFF;
3432 v = value | adv;
3433 } else {
3434 if (neq_bytes == 1) {
3435 mb = 0;
3436 nb = 1;
3437 adv = mask ^ 0xFF;
3438 v = value & ~adv;
3439 }
3440 }
3441 }
3442 target[i] = (mb << SECTION_RESTBYTE_MASK) |
3443 (nb << SECTION_RESTBYTE_MASK_EQ) |
3444 (0 << SECTION_RESTBYTE_DISABLE_PID_CHECK) |
3445 (cid << SECTION_RESTBYTE_PID_INDEX) | v;
3446 advance[i] = adv;
3447 }
3448
3449 f->value[i] = value;
3450 f->maskandmode[i] = mask & mode;
3451 f->maskandnotmode[i] = mask & ~mode;
3452
3453 if (f->maskandnotmode[i])
3454 f->neq = 1;
3455 }
3456
3457 return 0;
3458}
3459
3460/*Set the filter registers*/
3461static int dmx_set_filter_regs(struct aml_dmx *dmx, int fid)
3462{
3463 u32 t1[FILTER_LEN], t2[FILTER_LEN];
3464 u8 advance1[FILTER_LEN], advance2[FILTER_LEN];
3465 u32 addr, data, max, adv;
3466 int i;
3467
3468 pr_dbg("set filter (id:%d) registers\n", fid);
3469
3470 if (fid & 1) {
3471 dmx_get_filter_target(dmx, fid - 1, t1, advance1);
3472 dmx_get_filter_target(dmx, fid, t2, advance2);
3473 } else {
3474 dmx_get_filter_target(dmx, fid, t1, advance1);
3475 dmx_get_filter_target(dmx, fid + 1, t2, advance2);
3476 }
3477
3478 for (i = 0; i < FILTER_LEN; i++) {
3479 while (DMX_READ_REG(dmx->id, FM_WR_ADDR) & 0x8000)
3480 udelay(1);
3481
3482 data = (t1[i] << 16) | t2[i];
3483 addr = (fid >> 1) | ((i + 1) << 4);
3484 adv = (advance1[i] << 8) | advance2[i];
3485
3486 DMX_WRITE_REG(dmx->id, FM_WR_DATA, data);
3487 DMX_WRITE_REG(dmx->id, FM_WR_ADDR, (adv << 16) | 0x8000 | addr);
3488
3489 pr_dbg("write fm %x:%x\n", (adv << 16) | 0x8000 | addr, data);
3490 }
3491
3492 for (max = FILTER_COUNT - 1; max > 0; max--) {
3493 if (dmx->filter[max].used)
3494 break;
3495 }
3496
3497 data = DMX_READ_REG(dmx->id, MAX_FM_COMP_ADDR) & 0xF;
3498 DMX_WRITE_REG(dmx->id, MAX_FM_COMP_ADDR, data | ((max >> 1) << 4));
3499
3500 pr_dbg("write fm comp %x\n", data | ((max >> 1) << 4));
3501
3502 if (DMX_READ_REG(dmx->id, OM_CMD_STATUS) & 0x8e00) {
3503 pr_error("error send cmd %x\n",
3504 DMX_READ_REG(dmx->id, OM_CMD_STATUS));
3505 }
3506
3507 return 0;
3508}
3509
3510/*Clear the filter's buffer*/
3511static void dmx_clear_filter_buffer(struct aml_dmx *dmx, int fid)
3512{
3513 u32 section_busy32 = DMX_READ_REG(dmx->id, SEC_BUFF_READY);
3514 u32 filter_number;
3515 int i;
3516
3517 if (!section_busy32)
3518 return;
3519
3520 for (i = 0; i < SEC_BUF_COUNT; i++) {
3521 if (section_busy32 & (1 << i)) {
3522 DMX_WRITE_REG(dmx->id, SEC_BUFF_NUMBER, i);
3523 filter_number =
3524 (DMX_READ_REG(dmx->id, SEC_BUFF_NUMBER) >> 8);
3525 if (filter_number != fid)
3526 section_busy32 &= ~(1 << i);
3527 }
3528 }
3529
3530 if (section_busy32)
3531 DMX_WRITE_REG(dmx->id, SEC_BUFF_READY, section_busy32);
3532}
3533
3534static void async_fifo_set_regs(struct aml_asyncfifo *afifo, int source_val)
3535{
3536 u32 start_addr = afifo->secure_enable ? afifo->blk.addr :
3537 virt_to_phys((void *)afifo->pages);
3538 u32 size = afifo->buf_len;
3539 u32 flush_size = afifo->flush_size;
3540 int factor = dmx_get_order(size / flush_size);
3541 pr_error("ASYNC FIFO id=%d, link to DMX%d, start_addr %x, buf_size %d,"
3542 "source value 0x%x, factor %d\n",
3543 afifo->id, afifo->source, start_addr, size, source_val, factor);
3544 /* Destination address */
3545 WRITE_ASYNC_FIFO_REG(afifo->id, REG0, start_addr);
3546
3547 /* Setup flush parameters */
3548 WRITE_ASYNC_FIFO_REG(afifo->id, REG1,
3549 (0 << ASYNC_FIFO_TO_HIU) |
3550 (0 << ASYNC_FIFO_FLUSH) |
3551 /* don't flush the path */
3552 (1 << ASYNC_FIFO_RESET) |
3553 /* reset the path */
3554 (1 << ASYNC_FIFO_WRAP_EN) |
3555 /* wrap enable */
3556 (0 << ASYNC_FIFO_FLUSH_EN) |
3557 /* disable the flush path */
3558 /*(0x3 << ASYNC_FIFO_FLUSH_CNT_LSB);
3559 * flush 3 x 32 32-bit words
3560 */
3561 /*(0x7fff << ASYNC_FIFO_FLUSH_CNT_LSB);
3562 * flush 4MBytes of data
3563 */
3564 (((size >> 7) & 0x7fff) << ASYNC_FIFO_FLUSH_CNT_LSB));
3565 /* number of 128-byte blocks to flush */
3566
3567 /* clear the reset signal */
3568 WRITE_ASYNC_FIFO_REG(afifo->id, REG1,
3569 READ_ASYNC_FIFO_REG(afifo->id,
3570 REG1) & ~(1 << ASYNC_FIFO_RESET));
3571 /* Enable flush */
3572 WRITE_ASYNC_FIFO_REG(afifo->id, REG1,
3573 READ_ASYNC_FIFO_REG(afifo->id,
3574 REG1) | (1 << ASYNC_FIFO_FLUSH_EN));
3575
3576 /*Setup Fill parameters */
3577 WRITE_ASYNC_FIFO_REG(afifo->id, REG2,
3578 (1 << ASYNC_FIFO_ENDIAN_LSB) |
3579 (0 << ASYNC_FIFO_FILL_EN) |
3580 /* disable fill path to reset fill path */
3581 /*(96 << ASYNC_FIFO_FILL_CNT_LSB);
3582 *3 x 32 32-bit words
3583 */
3584 (0 << ASYNC_FIFO_FILL_CNT_LSB));
3585 /* forever FILL; */
3586 WRITE_ASYNC_FIFO_REG(afifo->id, REG2,
3587 READ_ASYNC_FIFO_REG(afifo->id, REG2) |
3588 (1 << ASYNC_FIFO_FILL_EN));/*Enable fill path*/
3589
3590 /* generate flush interrupt */
3591 WRITE_ASYNC_FIFO_REG(afifo->id, REG3,
3592 (READ_ASYNC_FIFO_REG(afifo->id, REG3) & 0xffff0000) |
3593 ((((size >> (factor + 7)) - 1) & 0x7fff) <<
3594 ASYNC_FLUSH_SIZE_IRQ_LSB));
3595
3596 /* Connect the STB DEMUX to ASYNC_FIFO */
3597 WRITE_ASYNC_FIFO_REG(afifo->id, REG2,
3598 READ_ASYNC_FIFO_REG(afifo->id, REG2) |
3599 (source_val << ASYNC_FIFO_SOURCE_LSB));
3600}
3601
3602/*Reset the ASYNC FIFOS when a ASYNC FIFO connect to a different DMX*/
3603static void reset_async_fifos(struct aml_dvb *dvb)
3604{
3605 struct aml_asyncfifo *low_dmx_fifo = NULL;
3606 struct aml_asyncfifo *high_dmx_fifo = NULL;
3607 struct aml_asyncfifo *highest_dmx_fifo = NULL;
3608 int i, j;
3609 int record_enable;
3610
3611 pr_dbg("reset ASYNC FIFOs\n");
3612 for (i = 0; i < dvb->async_fifo_total_count; i++) {
3613 if (!dvb->asyncfifo[i].init)
3614 continue;
3615 pr_dbg("Disable ASYNC FIFO id=%d\n", dvb->asyncfifo[i].id);
3616 CLEAR_ASYNC_FIFO_REG_MASK(dvb->asyncfifo[i].id, REG1,
3617 1 << ASYNC_FIFO_FLUSH_EN);
3618 CLEAR_ASYNC_FIFO_REG_MASK(dvb->asyncfifo[i].id, REG2,
3619 1 << ASYNC_FIFO_FILL_EN);
3620 if (READ_ASYNC_FIFO_REG(dvb->asyncfifo[i].id, REG2) &
3621 (1 << ASYNC_FIFO_FILL_EN) ||
3622 READ_ASYNC_FIFO_REG(dvb->asyncfifo[i].id, REG1) &
3623 (1 << ASYNC_FIFO_FLUSH_EN)) {
3624 pr_dbg("Set reg failed\n");
3625 } else
3626 pr_dbg("Set reg ok\n");
3627 dvb->asyncfifo[i].buf_toggle = 0;
3628 dvb->asyncfifo[i].buf_read = 0;
3629 }
3630
3631 for (j = 0; j < DMX_DEV_COUNT; j++) {
3632 if (!dvb->dmx[j].init)
3633 continue;
3634 record_enable = 0;
3635 for (i = 0; i < dvb->async_fifo_total_count; i++) {
3636 if (!dvb->asyncfifo[i].init)
3637 continue;
3638
3639 if (dvb->dmx[j].record
3640 && dvb->dmx[j].id == dvb->asyncfifo[i].source) {
3641 /*This dmx is linked to the async fifo,
3642 *Enable the TS_RECORDER_ENABLE
3643 */
3644 record_enable = 1;
3645 if (!low_dmx_fifo) {
3646 low_dmx_fifo = &dvb->asyncfifo[i];
3647 } else if (low_dmx_fifo->source >
3648 dvb->asyncfifo[i].source) {
3649 if (!high_dmx_fifo)
3650 high_dmx_fifo = low_dmx_fifo;
3651 else {
3652 highest_dmx_fifo = high_dmx_fifo;
3653 high_dmx_fifo = low_dmx_fifo;
3654 }
3655 low_dmx_fifo = &dvb->asyncfifo[i];
3656 } else if (low_dmx_fifo->source <
3657 dvb->asyncfifo[i].source) {
3658 if (!high_dmx_fifo)
3659 high_dmx_fifo = &dvb->asyncfifo[i];
3660 else {
3661 if (high_dmx_fifo->source > dvb->asyncfifo[i].source) {
3662 highest_dmx_fifo = high_dmx_fifo;
3663 high_dmx_fifo = &dvb->asyncfifo[i];
3664 } else {
3665 highest_dmx_fifo = &dvb->asyncfifo[i];
3666 }
3667 }
3668 }
3669
3670 break;
3671 }
3672 }
3673 pr_dbg("Set DMX%d TS_RECORDER_ENABLE to %d\n", dvb->dmx[j].id,
3674 record_enable ? 1 : 0);
3675 if (record_enable) {
3676 /*DMX_SET_REG_MASK(dvb->dmx[j].id,
3677 *DEMUX_CONTROL, 1<<TS_RECORDER_ENABLE);
3678 */
3679 DMX_WRITE_REG(dvb->dmx[j].id, DEMUX_CONTROL,
3680 DMX_READ_REG(dvb->dmx[j].id, DEMUX_CONTROL) |
3681 (1 << TS_RECORDER_ENABLE));
3682 } else {
3683 /*DMX_CLEAR_REG_MASK(dvb->dmx[j].id,
3684 *DEMUX_CONTROL, 1<<TS_ECORDER_ENABLE);
3685 */
3686 DMX_WRITE_REG(dvb->dmx[j].id, DEMUX_CONTROL,
3687 DMX_READ_REG(dvb->dmx[j].id, DEMUX_CONTROL) &
3688 (~(1 << TS_RECORDER_ENABLE)));
3689 }
3690 }
3691
3692 /*Set the async fifo regs */
3693 if (low_dmx_fifo) {
3694 async_fifo_set_regs(low_dmx_fifo, 0x3);
3695
3696 if (high_dmx_fifo) {
3697 async_fifo_set_regs(high_dmx_fifo, 0x2);
3698
3699 if (highest_dmx_fifo)
3700 async_fifo_set_regs(highest_dmx_fifo, 0x0);
3701 }
3702 }
3703}
3704
3705/*Reset the demux device*/
3706void dmx_reset_hw(struct aml_dvb *dvb)
3707{
3708 dmx_reset_hw_ex(dvb, 1);
3709}
3710
3711/*Reset the demux device*/
3712void dmx_reset_hw_ex(struct aml_dvb *dvb, int reset_irq)
3713{
3714 int id, times;
3715
3716 pr_dbg("demux reset begin\n");
3717
3718 for (id = 0; id < DMX_DEV_COUNT; id++) {
3719 if (!dvb->dmx[id].init)
3720 continue;
3721 if (reset_irq) {
3722 if (dvb->dmx[id].dmx_irq != -1)
3723 disable_irq(dvb->dmx[id].dmx_irq);
3724 if (dvb->dmx[id].dvr_irq != -1)
3725 disable_irq(dvb->dmx[id].dvr_irq);
3726 }
3727 }
3728#ifdef ENABLE_SEC_BUFF_WATCHDOG
3729 if (reset_irq)
3730 del_timer_sync(&dvb->watchdog_timer);
3731#endif
3732
3733 WRITE_MPEG_REG(RESET1_REGISTER, RESET_DEMUXSTB);
3734
3735 for (id = 0; id < DMX_DEV_COUNT; id++) {
3736 times = 0;
3737 while (times++ < 1000000) {
3738 if (!(DMX_READ_REG(id, OM_CMD_STATUS) & 0x01))
3739 break;
3740 }
3741 }
3742
3743 WRITE_MPEG_REG(STB_TOP_CONFIG, 0);
3744 WRITE_MPEG_REG(STB_S2P2_CONFIG, 0);
3745
3746 for (id = 0; id < DMX_DEV_COUNT; id++) {
3747 u32 version, data;
3748
3749 if (!dvb->dmx[id].init)
3750 continue;
3751
3752 if (reset_irq) {
3753 if (dvb->dmx[id].dmx_irq != -1)
3754 enable_irq(dvb->dmx[id].dmx_irq);
3755 if (dvb->dmx[id].dvr_irq != -1)
3756 enable_irq(dvb->dmx[id].dvr_irq);
3757 }
3758 DMX_WRITE_REG(id, DEMUX_CONTROL, 0x0000);
3759 version = DMX_READ_REG(id, STB_VERSION);
3760 DMX_WRITE_REG(id, STB_TEST_REG, version);
3761 pr_dbg("STB %d hardware version : %d\n", id, version);
3762 DMX_WRITE_REG(id, STB_TEST_REG, 0x5550);
3763 data = DMX_READ_REG(id, STB_TEST_REG);
3764 if (data != 0x5550)
3765 pr_error("STB %d register access failed\n", id);
3766 DMX_WRITE_REG(id, STB_TEST_REG, 0xaaa0);
3767 data = DMX_READ_REG(id, STB_TEST_REG);
3768 if (data != 0xaaa0)
3769 pr_error("STB %d register access failed\n", id);
3770 DMX_WRITE_REG(id, MAX_FM_COMP_ADDR, 0x0000);
3771 DMX_WRITE_REG(id, STB_INT_MASK, 0);
3772 DMX_WRITE_REG(id, STB_INT_STATUS, 0xffff);
3773 DMX_WRITE_REG(id, FEC_INPUT_CONTROL, 0);
3774 }
3775
3776 stb_enable(dvb);
3777
3778 for (id = 0; id < DMX_DEV_COUNT; id++) {
3779 struct aml_dmx *dmx = &dvb->dmx[id];
3780 int n;
3781 unsigned long addr;
3782 unsigned long base;
3783 unsigned long grp_addr[SEC_BUF_GRP_COUNT];
3784 int grp_len[SEC_BUF_GRP_COUNT];
3785
3786 if (!dvb->dmx[id].init)
3787 continue;
3788
3789 if (dmx->sec_pages) {
3790 grp_len[0] = (1 << SEC_GRP_LEN_0) * 8;
3791 grp_len[1] = (1 << SEC_GRP_LEN_1) * 8;
3792 grp_len[2] = (1 << SEC_GRP_LEN_2) * 8;
3793 grp_len[3] = (1 << SEC_GRP_LEN_3) * 8;
3794
3795 grp_addr[0] = virt_to_phys((void *)dmx->sec_pages);
3796 grp_addr[1] = grp_addr[0] + grp_len[0];
3797 grp_addr[2] = grp_addr[1] + grp_len[1];
3798 grp_addr[3] = grp_addr[2] + grp_len[2];
3799
3800 base = grp_addr[0] & 0xFFFF0000;
3801 DMX_WRITE_REG(dmx->id, SEC_BUFF_BASE, base >> 16);
3802 DMX_WRITE_REG(dmx->id, SEC_BUFF_01_START,
3803 (((grp_addr[0] - base) >> 8) << 16) |
3804 ((grp_addr[1] - base) >> 8));
3805 DMX_WRITE_REG(dmx->id, SEC_BUFF_23_START,
3806 (((grp_addr[2] - base) >> 8) << 16) |
3807 ((grp_addr[3] - base) >> 8));
3808 DMX_WRITE_REG(dmx->id, SEC_BUFF_SIZE,
3809 SEC_GRP_LEN_0 |
3810 (SEC_GRP_LEN_1 << 4) |
3811 (SEC_GRP_LEN_2 << 8) |
3812 (SEC_GRP_LEN_3 << 12));
3813 }
3814
3815 if (dmx->sub_pages) {
3816 addr = virt_to_phys((void *)dmx->sub_pages);
3817 DMX_WRITE_REG(dmx->id, SB_START, addr >> 12);
3818 DMX_WRITE_REG(dmx->id, SB_LAST_ADDR,
3819 (dmx->sub_buf_len >> 3) - 1);
3820 }
3821
3822 if (dmx->pes_pages) {
3823 addr = virt_to_phys((void *)dmx->pes_pages);
3824 DMX_WRITE_REG(dmx->id, OB_START, addr >> 12);
3825 DMX_WRITE_REG(dmx->id, OB_LAST_ADDR,
3826 (dmx->pes_buf_len >> 3) - 1);
3827 }
3828
3829 for (n = 0; n < CHANNEL_COUNT; n++) {
3830 /*struct aml_channel *chan = &dmx->channel[n];*/
3831
3832 /*if (chan->used)*/
3833 {
3834 dmx_set_chan_regs(dmx, n);
3835 }
3836 }
3837
3838 for (n = 0; n < FILTER_COUNT; n++) {
3839 struct aml_filter *filter = &dmx->filter[n];
3840
3841 if (filter->used)
3842 dmx_set_filter_regs(dmx, n);
3843 }
3844
3845 dmx_enable(&dvb->dmx[id]);
3846
3847 dmx_smallsec_set(&dmx->smallsec,
3848 dmx->smallsec.enable,
3849 dmx->smallsec.bufsize,
3850 1);
3851
3852 dmx_timeout_set(&dmx->timeout,
3853 dmx->timeout.enable,
3854 dmx->timeout.timeout,
3855 dmx->timeout.ch_disable,
3856 dmx->timeout.match,
3857 1);
3858 }
3859
3860 for (id = 0; id < DSC_DEV_COUNT; id++) {
3861 struct aml_dsc *dsc = &dvb->dsc[id];
3862 int n;
3863
3864 for (n = 0; n < DSC_COUNT; n++) {
3865 struct aml_dsc_channel *ch = &dsc->channel[n];
3866 /*if(ch->used) */
3867 {
3868 ch->id = n;
3869 ch->work_mode = -1;
3870 dsc_set_pid(ch, ch->pid);
3871 dsc_set_keys(ch);
3872 }
3873 }
3874 }
3875#ifdef ENABLE_SEC_BUFF_WATCHDOG
3876 if (reset_irq) {
3877 mod_timer(&dvb->watchdog_timer,
3878 jiffies + msecs_to_jiffies(WATCHDOG_TIMER));
3879 }
3880#endif
3881
3882 pr_dbg("demux reset end\n");
3883}
3884
3885/*Reset the individual demux*/
3886void dmx_reset_dmx_hw_ex_unlock(struct aml_dvb *dvb, struct aml_dmx *dmx,
3887 int reset_irq)
3888{
3889 {
3890 if (!dmx->init)
3891 return;
3892 if (reset_irq) {
3893 if (dmx->dmx_irq != -1)
3894 disable_irq(dmx->dmx_irq);
3895 if (dmx->dvr_irq != -1)
3896 disable_irq(dmx->dvr_irq);
3897 }
3898 }
3899#ifdef ENABLE_SEC_BUFF_WATCHDOG
3900 if (reset_irq) {
3901 /*del_timer_sync(&dvb->watchdog_timer); */
3902 dvb->dmx_watchdog_disable[dmx->id] = 1;
3903 }
3904#endif
3905
3906 WRITE_MPEG_REG(RESET3_REGISTER,
3907 (dmx->id) ? ((dmx->id ==
3908 1) ? RESET_DEMUX1 : RESET_DEMUX2) :
3909 RESET_DEMUX0);
3910 WRITE_MPEG_REG(RESET3_REGISTER, RESET_DES);
3911
3912 {
3913 int times;
3914
3915 times = 0;
3916 while (times++ < 1000000) {
3917 if (!(DMX_READ_REG(dmx->id, OM_CMD_STATUS) & 0x01))
3918 break;
3919 }
3920 }
3921
3922 /*WRITE_MPEG_REG(STB_TOP_CONFIG, 0); */
3923
3924 {
3925 u32 version, data;
3926
3927 if (!dmx->init)
3928 return;
3929
3930 if (reset_irq) {
3931 if (dmx->dmx_irq != -1)
3932 enable_irq(dmx->dmx_irq);
3933 if (dmx->dvr_irq != -1)
3934 enable_irq(dmx->dvr_irq);
3935 }
3936 DMX_WRITE_REG(dmx->id, DEMUX_CONTROL, 0x0000);
3937 version = DMX_READ_REG(dmx->id, STB_VERSION);
3938 DMX_WRITE_REG(dmx->id, STB_TEST_REG, version);
3939 pr_dbg("STB %d hardware version : %d\n", dmx->id, version);
3940 DMX_WRITE_REG(dmx->id, STB_TEST_REG, 0x5550);
3941 data = DMX_READ_REG(dmx->id, STB_TEST_REG);
3942 if (data != 0x5550)
3943 pr_error("STB %d register access failed\n", dmx->id);
3944 DMX_WRITE_REG(dmx->id, STB_TEST_REG, 0xaaa0);
3945 data = DMX_READ_REG(dmx->id, STB_TEST_REG);
3946 if (data != 0xaaa0)
3947 pr_error("STB %d register access failed\n", dmx->id);
3948 DMX_WRITE_REG(dmx->id, MAX_FM_COMP_ADDR, 0x0000);
3949 DMX_WRITE_REG(dmx->id, STB_INT_MASK, 0);
3950 DMX_WRITE_REG(dmx->id, STB_INT_STATUS, 0xffff);
3951 DMX_WRITE_REG(dmx->id, FEC_INPUT_CONTROL, 0);
3952 }
3953
3954 stb_enable(dvb);
3955
3956 {
3957 int n;
3958 unsigned long addr;
3959 unsigned long base;
3960 unsigned long grp_addr[SEC_BUF_GRP_COUNT];
3961 int grp_len[SEC_BUF_GRP_COUNT];
3962
3963 if (!dmx->init)
3964 return;
3965
3966 if (dmx->sec_pages) {
3967 grp_len[0] = (1 << SEC_GRP_LEN_0) * 8;
3968 grp_len[1] = (1 << SEC_GRP_LEN_1) * 8;
3969 grp_len[2] = (1 << SEC_GRP_LEN_2) * 8;
3970 grp_len[3] = (1 << SEC_GRP_LEN_3) * 8;
3971
3972 grp_addr[0] = virt_to_phys((void *)dmx->sec_pages);
3973 grp_addr[1] = grp_addr[0] + grp_len[0];
3974 grp_addr[2] = grp_addr[1] + grp_len[1];
3975 grp_addr[3] = grp_addr[2] + grp_len[2];
3976
3977 base = grp_addr[0] & 0xFFFF0000;
3978 DMX_WRITE_REG(dmx->id, SEC_BUFF_BASE, base >> 16);
3979 DMX_WRITE_REG(dmx->id, SEC_BUFF_01_START,
3980 (((grp_addr[0] - base) >> 8) << 16) |
3981 ((grp_addr[1] - base) >> 8));
3982 DMX_WRITE_REG(dmx->id, SEC_BUFF_23_START,
3983 (((grp_addr[2] - base) >> 8) << 16) |
3984 ((grp_addr[3] - base) >> 8));
3985 DMX_WRITE_REG(dmx->id, SEC_BUFF_SIZE,
3986 SEC_GRP_LEN_0 |
3987 (SEC_GRP_LEN_1 << 4) |
3988 (SEC_GRP_LEN_2 << 8) |
3989 (SEC_GRP_LEN_3 << 12));
3990 }
3991
3992 if (dmx->sub_pages) {
3993 addr = virt_to_phys((void *)dmx->sub_pages);
3994 DMX_WRITE_REG(dmx->id, SB_START, addr >> 12);
3995 DMX_WRITE_REG(dmx->id, SB_LAST_ADDR,
3996 (dmx->sub_buf_len >> 3) - 1);
3997 }
3998
3999 if (dmx->pes_pages) {
4000 addr = virt_to_phys((void *)dmx->pes_pages);
4001 DMX_WRITE_REG(dmx->id, OB_START, addr >> 12);
4002 DMX_WRITE_REG(dmx->id, OB_LAST_ADDR,
4003 (dmx->pes_buf_len >> 3) - 1);
4004 }
4005
4006 for (n = 0; n < CHANNEL_COUNT; n++) {
4007 /*struct aml_channel *chan = &dmx->channel[n];*/
4008
4009 /*if (chan->used)*/
4010 {
4011 dmx_set_chan_regs(dmx, n);
4012 }
4013 }
4014
4015 for (n = 0; n < FILTER_COUNT; n++) {
4016 struct aml_filter *filter = &dmx->filter[n];
4017
4018 if (filter->used)
4019 dmx_set_filter_regs(dmx, n);
4020 }
4021
4022 for (n = 0; n < SEC_CNT_MAX; n++) {
4023 dmx->sec_cnt[n] = 0;
4024 dmx->sec_cnt_match[n] = 0;
4025 dmx->sec_cnt_crc_fail[n] = 0;
4026 }
4027
4028 dmx_enable(dmx);
4029
4030 dmx_smallsec_set(&dmx->smallsec,
4031 dmx->smallsec.enable,
4032 dmx->smallsec.bufsize,
4033 1);
4034
4035 dmx_timeout_set(&dmx->timeout,
4036 dmx->timeout.enable,
4037 dmx->timeout.timeout,
4038 dmx->timeout.ch_disable,
4039 dmx->timeout.match,
4040 1);
4041 }
4042
4043 {
4044 int id;
4045
4046 for (id = 0; id < DSC_DEV_COUNT; id++) {
4047 struct aml_dsc *dsc = &dvb->dsc[id];
4048 int n;
4049
4050 for (n = 0; n < DSC_COUNT; n++) {
4051 struct aml_dsc_channel *ch = &dsc->channel[n];
4052 /*if(ch->used) */
4053 ch->work_mode = -1;
4054 dsc_set_pid(ch, ch->pid);
4055 dsc_set_keys(ch);
4056 }
4057 }
4058 }
4059#ifdef ENABLE_SEC_BUFF_WATCHDOG
4060 if (reset_irq) {
4061 /*mod_timer(&dvb->watchdog_timer,
4062 *jiffies+msecs_to_jiffies(WATCHDOG_TIMER));
4063 */
4064 dvb->dmx_watchdog_disable[dmx->id] = 0;
4065 }
4066#endif
4067}
4068
4069void dmx_reset_dmx_id_hw_ex_unlock(struct aml_dvb *dvb, int id, int reset_irq)
4070{
4071 dmx_reset_dmx_hw_ex_unlock(dvb, &dvb->dmx[id], reset_irq);
4072}
4073
4074void dmx_reset_dmx_hw_ex(struct aml_dvb *dvb, struct aml_dmx *dmx,
4075 int reset_irq)
4076{
4077 unsigned long flags;
4078
4079 spin_lock_irqsave(&dvb->slock, flags);
4080 dmx_reset_dmx_hw_ex_unlock(dvb, dmx, reset_irq);
4081 spin_unlock_irqrestore(&dvb->slock, flags);
4082}
4083
4084void dmx_reset_dmx_id_hw_ex(struct aml_dvb *dvb, int id, int reset_irq)
4085{
4086 unsigned long flags;
4087
4088 spin_lock_irqsave(&dvb->slock, flags);
4089 dmx_reset_dmx_id_hw_ex_unlock(dvb, id, reset_irq);
4090 spin_unlock_irqrestore(&dvb->slock, flags);
4091}
4092
4093void dmx_reset_dmx_hw(struct aml_dvb *dvb, int id)
4094{
4095 dmx_reset_dmx_id_hw_ex(dvb, id, 1);
4096}
4097
4098/*Allocate subtitle pes buffer*/
4099#if 0
4100static int alloc_subtitle_pes_buffer(struct aml_dmx *dmx)
4101{
4102 int start_ptr = 0;
4103 struct stream_buf_s *sbuff = 0;
4104 u32 phy_addr;
4105
4106 start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR);
4107 if (start_ptr) {
4108 WRITE_MPEG_REG(PARSER_SUB_RP, start_ptr);
4109 goto exit;
4110 }
4111 sbuff = get_stream_buffer(BUF_TYPE_SUBTITLE);
4112 if (sbuff) {
4113 if (sbuff->flag & BUF_FLAG_IOMEM)
4114 phy_addr = sbuff->buf_start;
4115 else
4116 phy_addr = virt_to_phys((void *)sbuff->buf_start);
4117
4118 WRITE_MPEG_REG(PARSER_SUB_RP, phy_addr);
4119 WRITE_MPEG_REG(PARSER_SUB_START_PTR, phy_addr);
4120 WRITE_MPEG_REG(PARSER_SUB_END_PTR,
4121 phy_addr + sbuff->buf_size - 8);
4122
4123 pr_dbg("pes buff=:%x %x\n", phy_addr, sbuff->buf_size);
4124 } else
4125 pr_dbg("Error stream buffer\n");
4126exit:
4127 return 0;
4128}
4129#endif
4130
4131/*Allocate a new channel*/
4132int dmx_alloc_chan(struct aml_dmx *dmx, int type, int pes_type, int pid)
4133{
4134 int id = -1;
4135 int ret;
4136
4137 if (type == DMX_TYPE_TS) {
4138 switch (pes_type) {
4139 case DMX_PES_VIDEO:
4140 if (!dmx->channel[0].used)
4141 id = 0;
4142 break;
4143 case DMX_PES_AUDIO:
4144 if (!dmx->channel[1].used)
4145 id = 1;
4146 break;
4147 case DMX_PES_SUBTITLE:
4148 case DMX_PES_TELETEXT:
4149 if (!dmx->channel[2].used)
4150 id = 2;
4151 //alloc_subtitle_pes_buffer(dmx);
4152 break;
4153 case DMX_PES_PCR:
4154 if (!dmx->channel[3].used)
4155 id = 3;
4156 break;
4157 case DMX_PES_OTHER:
4158 case DMX_PES_AUDIO3:
4159 {
4160 int i;
4161
4162 for (i = SYS_CHAN_COUNT;
4163 i < CHANNEL_COUNT; i++) {
4164 if (!dmx->channel[i].used) {
4165 id = i;
4166 break;
4167 }
4168 }
4169 }
4170 break;
4171 default:
4172 break;
4173 }
4174 } else {
4175 int i;
4176
4177 for (i = SYS_CHAN_COUNT; i < CHANNEL_COUNT; i++) {
4178 if (!dmx->channel[i].used) {
4179 id = i;
4180 break;
4181 }
4182 }
4183 }
4184
4185 if (id == -1) {
4186 pr_error("too many channels\n");
4187 return -1;
4188 }
4189
4190 pr_dbg("allocate channel(id:%d PID:0x%x)\n", id, pid);
4191
4192 if (id <= 3) {
4193 ret = dmx_get_chan(dmx, pid);
4194 if (ret >= 0 && DVR_FEED(dmx->channel[ret].feed)) {
4195 dmx_remove_feed(dmx, dmx->channel[ret].feed);
4196 dmx->channel[id].dvr_feed = dmx->channel[ret].feed;
4197 dmx->channel[id].dvr_feed->priv = (void *)(long)id;
4198 } else {
4199 dmx->channel[id].dvr_feed = NULL;
4200 }
4201 }
4202
4203 dmx->channel[id].type = type;
4204 dmx->channel[id].pes_type = pes_type;
4205 dmx->channel[id].pid = pid;
4206 dmx->channel[id].used = 1;
4207 dmx->channel[id].filter_count = 0;
4208
4209 dmx_set_chan_regs(dmx, id);
4210
4211 set_debug_dmx_chanpids(dmx->id, id, pid);
4212
4213 dmx->chan_count++;
4214
4215 dmx_enable(dmx);
4216
4217 return id;
4218}
4219
4220/*Free a channel*/
4221void dmx_free_chan(struct aml_dmx *dmx, int cid)
4222{
4223 pr_dbg("free channel(id:%d PID:0x%x)\n", cid, dmx->channel[cid].pid);
4224
4225 dmx->channel[cid].used = 0;
4226 dmx->channel[cid].pid = 0x1fff;
4227 dmx_set_chan_regs(dmx, cid);
4228
4229 if (cid == 2) {
4230 u32 parser_sub_start_ptr;
4231
4232 parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR);
4233 WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_start_ptr);
4234 WRITE_MPEG_REG(PARSER_SUB_WP, parser_sub_start_ptr);
4235 }
4236
4237 set_debug_dmx_chanpids(dmx->id, cid, -1);
4238 dmx->chan_count--;
4239
4240 dmx_enable(dmx);
4241
4242 /*Special pes type channel, check its dvr feed */
4243 if (cid <= 3 && dmx->channel[cid].dvr_feed) {
4244 /*start the dvr feed */
4245 dmx_add_feed(dmx, dmx->channel[cid].dvr_feed);
4246 }
4247}
4248
4249/*Add a section*/
4250static int dmx_chan_add_filter(struct aml_dmx *dmx, int cid,
4251 struct dvb_demux_filter *filter)
4252{
4253 int id = -1;
4254 int i;
4255
4256 for (i = 0; i < FILTER_COUNT; i++) {
4257 if (!dmx->filter[i].used) {
4258 id = i;
4259 break;
4260 }
4261 }
4262
4263 if (id == -1) {
4264 pr_error("too many filters\n");
4265 return -1;
4266 }
4267
4268 pr_dbg("channel(id:%d PID:0x%x) add filter(id:%d)\n", cid,
4269 filter->feed->pid, id);
4270
4271 dmx->filter[id].chan_id = cid;
4272 dmx->filter[id].used = 1;
4273 dmx->filter[id].filter = (struct dmx_section_filter *)filter;
4274 dmx->channel[cid].filter_count++;
4275
4276 dmx_set_filter_regs(dmx, id);
4277
4278 return id;
4279}
4280
4281static void dmx_remove_filter(struct aml_dmx *dmx, int cid, int fid)
4282{
4283 pr_dbg("channel(id:%d PID:0x%x) remove filter(id:%d)\n", cid,
4284 dmx->channel[cid].pid, fid);
4285
4286 dmx->filter[fid].used = 0;
4287 dmx->channel[cid].filter_count--;
4288
4289 dmx_set_filter_regs(dmx, fid);
4290 dmx_clear_filter_buffer(dmx, fid);
4291}
4292
4293static int sf_add_feed(struct aml_dmx *src_dmx, struct dvb_demux_feed *feed)
4294{
4295 int ret = 0;
4296
4297 struct aml_dvb *dvb = (struct aml_dvb *)src_dmx->demux.priv;
4298 struct aml_swfilter *sf = &dvb->swfilter;
4299
4300 pr_dbg_sf("sf add pid[%d]\n", feed->pid);
4301
4302 /*init sf */
4303 if (!sf->user) {
4304 void *mem;
4305
4306 mem = vmalloc(SF_BUFFER_SIZE);
4307 if (!mem) {
4308 ret = -ENOMEM;
4309 goto fail;
4310 }
4311 dvb_ringbuffer_init(&sf->rbuf, mem, SF_BUFFER_SIZE);
4312
4313 sf->dmx = &dvb->dmx[SF_DMX_ID];
4314 sf->afifo = &dvb->asyncfifo[SF_AFIFO_ID];
4315
4316 sf->dmx->source = src_dmx->source;
4317 sf->afifo->source = sf->dmx->id;
4318 sf->track_dmx = src_dmx->id;
4319 /*sf->afifo->flush_size = 188*10; */
4320
4321 pr_dbg_sf("init sf mode.\n");
4322
4323 } else if (sf->dmx->source != src_dmx->source) {
4324 pr_error(" pid=%d[src:%d] already used with sfdmx%d[src:%d]\n",
4325 feed->pid, src_dmx->source, sf->dmx->id,
4326 sf->dmx->source);
4327 ret = -EBUSY;
4328 goto fail;
4329 }
4330
4331 /*setup feed */
4332 ret = dmx_get_chan(sf->dmx, feed->pid);
4333 if (ret >= 0) {
4334 pr_error(" pid=%d[dmx:%d] already used [dmx:%d].\n",
4335 feed->pid, src_dmx->id,
4336 ((struct aml_dmx *)sf->dmx->channel[ret].feed->
4337 demux)->id);
4338 ret = -EBUSY;
4339 goto fail;
4340 }
4341 ret =
4342 dmx_alloc_chan(sf->dmx, DMX_TYPE_TS, DMX_PES_OTHER,
4343 feed->pid);
4344 if (ret < 0) {
4345 pr_error(" %s: alloc chan error, ret=%d\n", __func__, ret);
4346 ret = -EBUSY;
4347 goto fail;
4348 }
4349 sf->dmx->channel[ret].feed = feed;
4350 feed->priv = (void *)(long)ret;
4351
4352 sf->dmx->channel[ret].dvr_feed = feed;
4353
4354 sf->user++;
4355 debug_sf_user = sf->user;
4356
4357 dmx_enable(sf->dmx);
4358
4359 return 0;
4360
4361fail:
4362 feed->priv = (void *)-1;
4363 return ret;
4364}
4365
4366static int sf_remove_feed(struct aml_dmx *src_dmx, struct dvb_demux_feed *feed)
4367{
4368 int ret;
4369
4370 struct aml_dvb *dvb = (struct aml_dvb *)src_dmx->demux.priv;
4371 struct aml_swfilter *sf = &dvb->swfilter;
4372
4373 if (!sf->user || (sf->dmx->source != src_dmx->source))
4374 return 0;
4375
4376 /*add fail, no need to remove*/
4377 if (((long)feed->priv) < 0)
4378 return 0;
4379
4380 ret = dmx_get_chan(sf->dmx, feed->pid);
4381 if (ret < 0)
4382 return 0;
4383
4384 pr_dbg_sf("sf remove pid[%d]\n", feed->pid);
4385
4386 dmx_free_chan(sf->dmx, (long)feed->priv);
4387
4388 sf->dmx->channel[ret].feed = NULL;
4389 sf->dmx->channel[ret].dvr_feed = NULL;
4390
4391 sf->user--;
4392 debug_sf_user = sf->user;
4393
4394 if (!sf->user) {
4395 sf->dmx->source = -1;
4396 sf->afifo->source = AM_DMX_MAX;
4397 sf->track_dmx = -1;
4398 /*sf->afifo->flush_size = sf->afifo->buf_len>>1; */
4399
4400 if (sf->rbuf.data) {
4401 void *mem = sf->rbuf.data;
4402
4403 sf->rbuf.data = NULL;
4404 vfree(mem);
4405 }
4406 pr_dbg_sf("exit sf mode.\n");
4407 }
4408
4409 return 0;
4410}
4411
4412static int sf_feed_sf(struct aml_dmx *dmx, struct dvb_demux_feed *feed,
4413 int add_not_remove)
4414{
4415 int sf = 0;
4416
4417 if (sf_dmx_sf(dmx)) {
4418 pr_error("%s: demux %d is in sf mode\n", __func__, dmx->id);
4419 return -EINVAL;
4420 }
4421
4422 switch (feed->type) {
4423 case DMX_TYPE_TS:{
4424 struct dmxdev_filter *dmxdevfilter =
4425 feed->feed.ts.priv;
4426 if (!DVR_FEED(feed)) {
4427 if (dmxdevfilter->params.pes.
4428 flags & DMX_USE_SWFILTER)
4429 sf = 1;
4430 if (force_pes_sf)
4431 sf = 1;
4432 }
4433 }
4434 break;
4435
4436 case DMX_TYPE_SEC:{
4437 struct dvb_demux_filter *filter;
4438
4439 for (filter = feed->filter; filter;
4440 filter = filter->next) {
4441 struct dmxdev_filter *dmxdevfilter =
4442 filter->filter.priv;
4443 if (dmxdevfilter->params.sec.
4444 flags & DMX_USE_SWFILTER)
4445 sf = 1;
4446 if (add_not_remove)
4447 filter->hw_handle = (u16)-1;
4448 }
4449 if (force_sec_sf)
4450 sf = 1;
4451 }
4452 break;
4453 }
4454
4455 return sf ? 0 : 1;
4456}
4457
4458static int sf_check_feed(struct aml_dmx *dmx, struct dvb_demux_feed *feed,
4459 int add_not_remove)
4460{
4461 int ret = 0;
4462
4463 ret = sf_feed_sf(dmx, feed, add_not_remove);
4464 if (ret)
4465 return ret;
4466
4467 pr_dbg_sf("%s [pid:%d] %s\n",
4468 (feed->type == DMX_TYPE_TS) ? "DMX_TYPE_TS" : "DMX_TYPE_SEC",
4469 feed->pid, add_not_remove ? "-> sf mode" : "sf mode ->");
4470
4471 if (add_not_remove)
4472 ret = sf_add_feed(dmx, feed);
4473 else
4474 ret = sf_remove_feed(dmx, feed);
4475
4476 if (ret < 0) {
4477 pr_error("sf %s feed fail[%d]\n",
4478 add_not_remove ? "add" : "remove", ret);
4479 }
4480 return ret;
4481}
4482
4483static int dmx_add_feed(struct aml_dmx *dmx, struct dvb_demux_feed *feed)
4484{
4485 int id, ret = 0;
4486 struct dvb_demux_filter *filter;
4487 struct dvb_demux_feed *dfeed = NULL;
4488 int sf_ret = 0; /*<0:error, =0:sf_on, >0:sf_off */
4489
4490 sf_ret = sf_check_feed(dmx, feed, 1/*SF_FEED_OP_ADD */);
4491 if (sf_ret < 0)
4492 return sf_ret;
4493
4494 switch (feed->type) {
4495 case DMX_TYPE_TS:
4496 pr_dbg("%s: DMX_TYPE_TS\n", __func__);
4497 ret = dmx_get_chan(dmx, feed->pid);
4498 if (ret >= 0) {
4499 if (DVR_FEED(dmx->channel[ret].feed)) {
4500 if (DVR_FEED(feed)) {
4501 /*dvr feed already work */
4502 pr_error("PID %d already used(DVR)\n",
4503 feed->pid);
4504 ret = -EBUSY;
4505 goto fail;
4506 }
4507 if (sf_ret) {
4508 /*if sf_on, we do not reset the
4509 *previous dvr feed, just load the pes
4510 *feed on the sf, a diffrent data path.
4511 */
4512 dfeed = dmx->channel[ret].feed;
4513 dmx_remove_feed(dmx, dfeed);
4514 }
4515 } else {
4516 if (DVR_FEED(feed)
4517 && (!dmx->channel[ret].dvr_feed)) {
4518 /*just store the dvr_feed */
4519 dmx->channel[ret].dvr_feed = feed;
4520 feed->priv = (void *)(long)ret;
4521 if (!dmx->record)
4522 dmx_enable(dmx);
4523 dmx_add_recchan(dmx->id, ret);
4524 return 0;
4525 }
4526 {
4527 pr_error("PID %d already used\n",
4528 feed->pid);
4529 ret = -EBUSY;
4530 goto fail;
4531 }
4532 }
4533 }
4534
4535 if (sf_ret) { /*not sf feed. */
4536 ret =
4537 dmx_alloc_chan(dmx, feed->type,
4538 feed->pes_type, feed->pid);
4539 if (ret < 0) {
4540 pr_dbg("%s: alloc chan error, ret=%d\n",
4541 __func__, ret);
4542 ret = -EBUSY;
4543 goto fail;
4544 }
4545 dmx->channel[ret].feed = feed;
4546 feed->priv = (void *)(long)ret;
4547 dmx->channel[ret].dvr_feed = NULL;
4548 }
4549 /*dvr */
4550 if (DVR_FEED(feed)) {
4551 dmx->channel[ret].dvr_feed = feed;
4552 feed->priv = (void *)(long)ret;
4553 if (!dmx->record)
4554 dmx_enable(dmx);
4555 dmx_add_recchan(dmx->id, ret);
4556 } else if (dfeed && sf_ret) {
4557 dmx->channel[ret].dvr_feed = dfeed;
4558 dfeed->priv = (void *)(long)ret;
4559 if (!dmx->record)
4560 dmx_enable(dmx);
4561 dmx_add_recchan(dmx->id, ret);
4562 }
4563
4564 break;
4565 case DMX_TYPE_SEC:
4566 pr_dbg("%s: DMX_TYPE_SEC\n", __func__);
4567 ret = dmx_get_chan(dmx, feed->pid);
4568 if (ret >= 0) {
4569 if (DVR_FEED(dmx->channel[ret].feed)) {
4570 if (sf_ret) {
4571 /*if sf_on, we do not reset the
4572 *previous dvr feed, just load the pes
4573 *feed on the sf,a diffrent data path.
4574 */
4575 dfeed = dmx->channel[ret].feed;
4576 dmx_remove_feed(dmx, dfeed);
4577 }
4578 } else {
4579 pr_error("PID %d already used\n", feed->pid);
4580 ret = -EBUSY;
4581 goto fail;
4582 }
4583 }
4584 if (sf_ret) { /*not sf feed. */
4585 id = dmx_alloc_chan(dmx, feed->type,
4586 feed->pes_type, feed->pid);
4587 if (id < 0) {
4588 pr_dbg("%s: alloc chan error, ret=%d\n",
4589 __func__, id);
4590 ret = -EBUSY;
4591 goto fail;
4592 }
4593 for (filter = feed->filter; filter;
4594 filter = filter->next) {
4595 ret = dmx_chan_add_filter(dmx, id, filter);
4596 if (ret >= 0)
4597 filter->hw_handle = ret;
4598 else
4599 filter->hw_handle = (u16)-1;
4600 }
4601 dmx->channel[id].feed = feed;
4602 feed->priv = (void *)(long)id;
4603 dmx->channel[id].dvr_feed = NULL;
4604
4605 if (dfeed) {
4606 dmx->channel[id].dvr_feed = dfeed;
4607 dfeed->priv = (void *)(long)id;
4608 if (!dmx->record)
4609 dmx_enable(dmx);
4610 dmx_add_recchan(dmx->id, id);
4611 }
4612 }
4613 break;
4614 default:
4615 return -EINVAL;
4616 }
4617
4618 dmx->feed_count++;
4619
4620 return 0;
4621
4622fail:
4623 feed->priv = (void *)-1;
4624 return ret;
4625}
4626
4627static int dmx_remove_feed(struct aml_dmx *dmx, struct dvb_demux_feed *feed)
4628{
4629 struct dvb_demux_filter *filter;
4630 struct dvb_demux_feed *dfeed = NULL;
4631
4632 int sf_ret = 0; /*<0:error, =0:sf_on, >0:sf_off */
4633
4634 /*add fail, no need to remove*/
4635 if (((long)feed->priv) < 0)
4636 return 0;
4637
4638 sf_ret = sf_check_feed(dmx, feed, 0/*SF_FEED_OP_RM */);
4639 if (sf_ret <= 0)
4640 return sf_ret;
4641
4642 switch (feed->type) {
4643 case DMX_TYPE_TS:
4644 if (dmx->channel[(long)feed->priv].feed ==
4645 dmx->channel[(long)feed->priv].dvr_feed) {
4646 dmx_rm_recchan(dmx->id, (long)feed->priv);
4647 dmx_free_chan(dmx, (long)feed->priv);
4648 } else {
4649 if (feed == dmx->channel[(long)feed->priv].feed) {
4650 dfeed = dmx->channel[(long)feed->priv].dvr_feed;
4651 dmx_rm_recchan(dmx->id, (long)feed->priv);
4652 dmx_free_chan(dmx, (long)feed->priv);
4653 if (dfeed) {
4654 /*start the dvr feed */
4655 dmx_add_feed(dmx, dfeed);
4656 }
4657 } else if (feed ==
4658 dmx->channel[(long)feed->priv].dvr_feed) {
4659 /*just remove the dvr_feed */
4660 dmx->channel[(long)feed->priv].dvr_feed = NULL;
4661 dmx_rm_recchan(dmx->id, (long)feed->priv);
4662 if (dmx->record)
4663 dmx_enable(dmx);
4664 } else {
4665 /*This must never happen */
4666 pr_error("%s: unknown feed\n", __func__);
4667 return -EINVAL;
4668 }
4669 }
4670
4671 break;
4672 case DMX_TYPE_SEC:
4673 for (filter = feed->filter; filter; filter = filter->next) {
4674 if (filter->hw_handle != (u16)-1)
4675 dmx_remove_filter(dmx, (long)feed->priv,
4676 (int)filter->hw_handle);
4677 }
4678
4679 dfeed = dmx->channel[(long)feed->priv].dvr_feed;
4680 dmx_rm_recchan(dmx->id, (long)feed->priv);
4681 dmx_free_chan(dmx, (long)feed->priv);
4682 if (dfeed) {
4683 /*start the dvr feed */
4684 dmx_add_feed(dmx, dfeed);
4685 }
4686 break;
4687 default:
4688 return -EINVAL;
4689 }
4690
4691 dmx->feed_count--;
4692 return 0;
4693}
4694
4695int aml_dmx_hw_init(struct aml_dmx *dmx)
4696{
4697 /*
4698 *struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
4699 *unsigned long flags;
4700 */
4701 int ret;
4702
4703 /*Demux initialize */
4704 /*spin_lock_irqsave(&dvb->slock, flags);*/
4705 ret = dmx_init(dmx);
4706 /*spin_unlock_irqrestore(&dvb->slock, flags);*/
4707
4708 return ret;
4709}
4710
4711int aml_dmx_hw_deinit(struct aml_dmx *dmx)
4712{
4713 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
4714 unsigned long flags;
4715 int ret;
4716
4717 spin_lock_irqsave(&dvb->slock, flags);
4718 ret = dmx_deinit(dmx);
4719 spin_unlock_irqrestore(&dvb->slock, flags);
4720
4721 return ret;
4722}
4723
4724/*extern void afifo_reset(int v);*/
4725
4726int aml_asyncfifo_hw_init(struct aml_asyncfifo *afifo)
4727{
4728
4729/*
4730 * struct aml_dvb *dvb = afifo->dvb;
4731 * unsigned long flags;
4732 */
4733 int ret;
4734
4735 int len = asyncfifo_buf_len;
4736 unsigned long buf = asyncfifo_alloc_buffer(len);
4737
4738 if (!buf)
4739 return -1;
4740
4741 /*Async FIFO initialize*/
4742/*
4743 * spin_lock_irqsave(&dvb->slock, flags);
4744 */
4745/*
4746 *#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
4747 * CLK_GATE_ON(ASYNC_FIFO);
4748 *#endif
4749 */
4750 /*afifo_reset(0);*/
4751
4752 WRITE_MPEG_REG(RESET6_REGISTER, (1<<11)|(1<<12));
4753
4754 ret = async_fifo_init(afifo, 1, len, buf);
4755/*
4756 * spin_unlock_irqrestore(&dvb->slock, flags);
4757 */
4758 if (ret < 0)
4759 asyncfifo_free_buffer(buf, len);
4760
4761 return ret;
4762}
4763
4764int aml_asyncfifo_hw_deinit(struct aml_asyncfifo *afifo)
4765{
4766 int ret;
4767
4768 ret = async_fifo_deinit(afifo, 1);
4769/*
4770 *#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON8
4771 * CLK_GATE_OFF(ASYNC_FIFO);
4772 *#endif
4773 */
4774 /*afifo_reset(1);*/
4775
4776 return ret;
4777}
4778
4779int aml_asyncfifo_hw_reset(struct aml_asyncfifo *afifo)
4780{
4781 struct aml_dvb *dvb = afifo->dvb;
4782 unsigned long flags;
4783 int ret, src = -1;
4784
4785 unsigned long buf = 0;
4786 int len = asyncfifo_buf_len;
4787 buf = asyncfifo_alloc_buffer(len);
4788 if (!buf)
4789 return -1;
4790
4791 if (afifo->init) {
4792 src = afifo->source;
4793 async_fifo_deinit(afifo, 0);
4794 }
4795
4796 spin_lock_irqsave(&dvb->slock, flags);
4797 ret = async_fifo_init(afifo, 0, len, buf);
4798 /* restore the source */
4799 if (src != -1)
4800 afifo->source = src;
4801
4802 if ((ret == 0) && afifo->dvb)
4803 reset_async_fifos(afifo->dvb);
4804
4805 spin_unlock_irqrestore(&dvb->slock, flags);
4806
4807 if (ret < 0)
4808 asyncfifo_free_buffer(buf, len);
4809
4810 return ret;
4811}
4812
4813int aml_dmx_hw_start_feed(struct dvb_demux_feed *dvbdmxfeed)
4814{
4815 struct aml_dmx *dmx = (struct aml_dmx *)dvbdmxfeed->demux;
4816 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
4817 unsigned long flags;
4818 int ret = 0;
4819
4820 spin_lock_irqsave(&dvb->slock, flags);
4821 ret = dmx_add_feed(dmx, dvbdmxfeed);
4822 spin_unlock_irqrestore(&dvb->slock, flags);
4823
4824 /*handle errors silently*/
4825 if (ret != 0)
4826 ret = 0;
4827
4828 return ret;
4829}
4830
4831int aml_dmx_hw_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
4832{
4833 struct aml_dmx *dmx = (struct aml_dmx *)dvbdmxfeed->demux;
4834 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
4835 unsigned long flags;
4836
4837 spin_lock_irqsave(&dvb->slock, flags);
4838 dmx_remove_feed(dmx, dvbdmxfeed);
4839 spin_unlock_irqrestore(&dvb->slock, flags);
4840
4841 return 0;
4842}
4843
4844int sf_dmx_track_source(struct aml_dmx *dmx)
4845{
4846 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
4847 struct aml_swfilter *sf = &dvb->swfilter;
4848
4849 if (sf->user && (dmx->id == sf->track_dmx)) {
4850 pr_dbg_sf("tracking dmx src [%d -> %d]\n",
4851 sf->dmx->source, dmx->source);
4852 sf->dmx->source = dmx->source;
4853 dmx_reset_dmx_hw_ex_unlock(dvb, sf->dmx, 0);
4854 }
4855 return 0;
4856}
4857
4858int aml_dmx_hw_set_source(struct dmx_demux *demux, dmx_source_t src)
4859{
4860 struct aml_dmx *dmx = (struct aml_dmx *)demux;
4861 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
4862 int ret = 0;
4863 int hw_src;
4864 unsigned long flags;
4865
4866 if (sf_dmx_sf(dmx)) {
4867 pr_error("%s: demux %d is in sf mode\n", __func__, dmx->id);
4868 return -EINVAL;
4869 }
4870
4871 spin_lock_irqsave(&dvb->slock, flags);
4872
4873 hw_src = dmx->source;
4874
4875 switch (src) {
4876 case DMX_SOURCE_FRONT0:
4877 hw_src =
4878 (dvb->ts[0].mode ==
4879 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS0) : AM_TS_SRC_TS0;
4880 break;
4881 case DMX_SOURCE_FRONT1:
4882 hw_src =
4883 (dvb->ts[1].mode ==
4884 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS1) : AM_TS_SRC_TS1;
4885 break;
4886 case DMX_SOURCE_FRONT2:
4887 hw_src =
4888 (dvb->ts[2].mode ==
4889 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS2) : AM_TS_SRC_TS2;
4890 break;
4891 case DMX_SOURCE_FRONT3:
4892 hw_src =
4893 (dvb->ts[3].mode ==
4894 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS3) : AM_TS_SRC_TS3;
4895 break;
4896 case DMX_SOURCE_DVR0:
4897 hw_src = AM_TS_SRC_HIU;
4898 break;
4899 case DMX_SOURCE_DVR1:
4900 hw_src = AM_TS_SRC_HIU1;
4901 break;
4902 case DMX_SOURCE_FRONT0_OFFSET:
4903 hw_src = AM_TS_SRC_DMX0;
4904 break;
4905 case DMX_SOURCE_FRONT1_OFFSET:
4906 hw_src = AM_TS_SRC_DMX1;
4907 break;
4908 case DMX_SOURCE_FRONT2_OFFSET:
4909 hw_src = AM_TS_SRC_DMX2;
4910 break;
4911 default:
4912 pr_error("illegal demux source %d\n", src);
4913 ret = -EINVAL;
4914 break;
4915 }
4916
4917 if (hw_src != dmx->source) {
4918 dmx->source = hw_src;
4919 dmx_reset_dmx_hw_ex_unlock(dvb, dmx, 0);
4920 sf_dmx_track_source(dmx);
4921 }
4922
4923 spin_unlock_irqrestore(&dvb->slock, flags);
4924
4925 return ret;
4926}
4927
4928#define IS_SRC_DMX(_src) ((_src) >= AM_TS_SRC_DMX0 && (_src) <= AM_TS_SRC_DMX2)
4929
4930int aml_stb_hw_set_source(struct aml_dvb *dvb, dmx_source_t src)
4931{
4932 unsigned long flags;
4933 int hw_src;
4934 int ret;
4935
4936 ret = 0;
4937 spin_lock_irqsave(&dvb->slock, flags);
4938
4939 hw_src = dvb->stb_source;
4940
4941 switch (src) {
4942 case DMX_SOURCE_FRONT0:
4943 hw_src =
4944 (dvb->ts[0].mode ==
4945 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS0) : AM_TS_SRC_TS0;
4946 break;
4947 case DMX_SOURCE_FRONT1:
4948 hw_src =
4949 (dvb->ts[1].mode ==
4950 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS1) : AM_TS_SRC_TS1;
4951 break;
4952 case DMX_SOURCE_FRONT2:
4953 hw_src =
4954 (dvb->ts[2].mode ==
4955 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS2) : AM_TS_SRC_TS2;
4956 break;
4957 case DMX_SOURCE_FRONT3:
4958 hw_src =
4959 (dvb->ts[3].mode ==
4960 AM_TS_SERIAL) ? (AM_TS_SRC_S_TS3) : AM_TS_SRC_TS3;
4961 break;
4962 case DMX_SOURCE_DVR0:
4963 hw_src = AM_TS_SRC_HIU;
4964 break;
4965 case DMX_SOURCE_DVR1:
4966 hw_src = AM_TS_SRC_HIU1;
4967 break;
4968 case DMX_SOURCE_FRONT0_OFFSET:
4969 hw_src = AM_TS_SRC_DMX0;
4970 break;
4971 case DMX_SOURCE_FRONT1_OFFSET:
4972 hw_src = AM_TS_SRC_DMX1;
4973 break;
4974 case DMX_SOURCE_FRONT2_OFFSET:
4975 hw_src = AM_TS_SRC_DMX2;
4976 break;
4977 default:
4978 pr_error("illegal demux source %d\n", src);
4979 ret = -EINVAL;
4980 break;
4981 }
4982
4983 if (dvb->stb_source != hw_src) {
4984 int old_source = dvb->stb_source;
4985
4986 dvb->stb_source = hw_src;
4987
4988 if (IS_SRC_DMX(old_source)) {
4989 dmx_set_misc_id(dvb,
4990 (old_source - AM_TS_SRC_DMX0), 0, -1);
4991 } else {
4992 /*which dmx for av-play is unknown,
4993 *can't avoid reset-all
4994 */
4995 dmx_reset_hw_ex(dvb, 0);
4996 }
4997
4998 if (IS_SRC_DMX(dvb->stb_source)) {
4999 dmx_set_misc_id(dvb,
5000 (dvb->stb_source - AM_TS_SRC_DMX0), 1, -1);
5001 /*dmx_reset_dmx_id_hw_ex_unlock
5002 * (dvb, (dvb->stb_source-AM_TS_SRC_DMX0), 0);
5003 */
5004 } else {
5005 /*which dmx for av-play is unknown,
5006 *can't avoid reset-all
5007 */
5008 dmx_reset_hw_ex(dvb, 0);
5009 }
5010 }
5011
5012 spin_unlock_irqrestore(&dvb->slock, flags);
5013
5014 return ret;
5015}
5016
5017
5018
5019int aml_dsc_hw_set_source(struct aml_dsc *dsc,
5020 dmx_source_t src, dmx_source_t dst)
5021{
5022 struct aml_dvb *dvb = dsc->dvb;
5023 int ret = 0;
5024 unsigned long flags;
5025 int hw_src = -1, hw_dst = -1, org_src = -1, org_dst = -1;
5026 int src_reset = 0, dst_reset = 0;
5027
5028 spin_lock_irqsave(&dvb->slock, flags);
5029
5030 hw_src = dsc->source;
5031 hw_dst = dsc->dst;
5032
5033 switch (src) {
5034 case DMX_SOURCE_FRONT0_OFFSET:
5035 hw_src = AM_TS_SRC_DMX0;
5036 break;
5037 case DMX_SOURCE_FRONT1_OFFSET:
5038 hw_src = AM_TS_SRC_DMX1;
5039 break;
5040 case DMX_SOURCE_FRONT2_OFFSET:
5041 hw_src = AM_TS_SRC_DMX2;
5042 break;
5043 default:
5044 hw_src = -1;
5045 break;
5046 }
5047 switch (dst) {
5048 case DMX_SOURCE_FRONT0_OFFSET:
5049 hw_dst = AM_TS_SRC_DMX0;
5050 break;
5051 case DMX_SOURCE_FRONT1_OFFSET:
5052 hw_dst = AM_TS_SRC_DMX1;
5053 break;
5054 case DMX_SOURCE_FRONT2_OFFSET:
5055 hw_dst = AM_TS_SRC_DMX2;
5056 break;
5057 default:
5058 hw_dst = -1;
5059 break;
5060 }
5061
5062 if (hw_src != dsc->source) {
5063 org_src = dsc->source;
5064 dsc->source = hw_src;
5065 src_reset = 1;
5066 }
5067 if (hw_dst != dsc->dst) {
5068 org_dst = dsc->dst;
5069 dsc->dst = hw_dst;
5070 dst_reset = 1;
5071 }
5072
5073 if (src_reset) {
5074 pr_inf("dsc%d source changed: %d -> %d\n",
5075 dsc->id, org_src, hw_src);
5076 if (org_src != -1) {
5077 pr_inf("reset dmx%d\n", (org_src - AM_TS_SRC_DMX0));
5078 dmx_reset_dmx_id_hw_ex_unlock(dvb,
5079 (org_src - AM_TS_SRC_DMX0), 0);
5080 }
5081 if (hw_src != -1) {
5082 pr_inf("reset dmx%d\n", (hw_src - AM_TS_SRC_DMX0));
5083 dmx_reset_dmx_id_hw_ex_unlock(dvb,
5084 (hw_src - AM_TS_SRC_DMX0), 0);
5085 } else
5086 dsc_enable(dsc, 0);
5087 }
5088 if (dst_reset) {
5089 pr_inf("dsc%d dest changed: %d -> %d\n",
5090 dsc->id, org_dst, hw_dst);
5091 if (((!src_reset) && (org_dst != -1)) ||
5092 (src_reset && (org_dst != -1) &&
5093 (org_dst != org_src) && (org_dst != hw_src))) {
5094 pr_inf("reset dmx%d\n", (org_dst - AM_TS_SRC_DMX0));
5095 dmx_reset_dmx_id_hw_ex_unlock(dvb,
5096 (org_dst - AM_TS_SRC_DMX0), 0);
5097 }
5098 if (((!src_reset) && (hw_dst != -1)) ||
5099 (src_reset && (hw_dst != -1)
5100 && (hw_dst != org_src) && (hw_dst != hw_src))) {
5101 pr_inf("reset dmx%d\n", (hw_dst - AM_TS_SRC_DMX0));
5102 dmx_reset_dmx_id_hw_ex_unlock(dvb,
5103 (hw_dst - AM_TS_SRC_DMX0), 0);
5104 }
5105 if (hw_dst == -1)
5106 dsc_enable(dsc, 0);
5107 }
5108
5109 spin_unlock_irqrestore(&dvb->slock, flags);
5110
5111 return ret;
5112}
5113
5114int aml_tso_hw_set_source(struct aml_dvb *dvb, dmx_source_t src)
5115{
5116 int ret = 0;
5117 unsigned long flags;
5118 int hw_src;
5119
5120 spin_lock_irqsave(&dvb->slock, flags);
5121
5122 hw_src = dvb->tso_source;
5123
5124 switch (src) {
5125 case DMX_SOURCE_FRONT0:
5126 hw_src = (dvb->ts[0].mode == AM_TS_SERIAL)
5127 ? (AM_TS_SRC_S_TS0) : AM_TS_SRC_TS0;
5128 break;
5129 case DMX_SOURCE_FRONT1:
5130 hw_src = (dvb->ts[1].mode == AM_TS_SERIAL)
5131 ? (AM_TS_SRC_S_TS1) : AM_TS_SRC_TS1;
5132 break;
5133 case DMX_SOURCE_FRONT2:
5134 hw_src = (dvb->ts[2].mode == AM_TS_SERIAL)
5135 ? (AM_TS_SRC_S_TS2) : AM_TS_SRC_TS2;
5136 break;
5137 case DMX_SOURCE_FRONT3:
5138 hw_src = (dvb->ts[3].mode == AM_TS_SERIAL)
5139 ? (AM_TS_SRC_S_TS3) : AM_TS_SRC_TS3;
5140 break;
5141 case DMX_SOURCE_DVR0:
5142 hw_src = AM_TS_SRC_HIU;
5143 break;
5144 case DMX_SOURCE_FRONT0 + 100:
5145 hw_src = AM_TS_SRC_DMX0;
5146 break;
5147 case DMX_SOURCE_FRONT1 + 100:
5148 hw_src = AM_TS_SRC_DMX1;
5149 break;
5150 case DMX_SOURCE_FRONT2 + 100:
5151 hw_src = AM_TS_SRC_DMX2;
5152 break;
5153 default:
5154 hw_src = -1;
5155 ret = -EINVAL;
5156 break;
5157 }
5158
5159 if (hw_src != dvb->tso_source) {
5160 dvb->tso_source = hw_src;
5161 stb_enable(dvb);
5162 }
5163
5164 spin_unlock_irqrestore(&dvb->slock, flags);
5165
5166 return ret;
5167}
5168
5169int aml_asyncfifo_hw_set_source(struct aml_asyncfifo *afifo,
5170 enum aml_dmx_id_t src)
5171{
5172 struct aml_dvb *dvb = afifo->dvb;
5173 int ret = -1;
5174 unsigned long flags;
5175
5176 if (sf_afifo_sf(afifo)) {
5177 pr_error("%s: afifo %d is in sf mode\n", __func__, afifo->id);
5178 return -EINVAL;
5179 }
5180
5181 spin_lock_irqsave(&dvb->slock, flags);
5182
5183 pr_dbg("asyncfifo %d set source %d->%d",
5184 afifo->id, afifo->source, src);
5185 switch (src) {
5186 case AM_DMX_0:
5187 case AM_DMX_1:
5188 case AM_DMX_2:
5189 if (afifo->source != src) {
5190 afifo->source = src;
5191 ret = 0;
5192 }
5193 break;
5194 default:
5195 pr_error("illegal async fifo source %d\n", src);
5196 ret = -EINVAL;
5197 break;
5198 }
5199
5200 if (ret == 0 && afifo->dvb)
5201 reset_async_fifos(afifo->dvb);
5202
5203 spin_unlock_irqrestore(&dvb->slock, flags);
5204
5205 return ret;
5206}
5207
5208int aml_dmx_hw_set_dump_ts_select(struct dmx_demux *demux, int dump_ts_select)
5209{
5210 struct aml_dmx *dmx = (struct aml_dmx *)demux;
5211 struct aml_dvb *dvb = (struct aml_dvb *)dmx->demux.priv;
5212 int ret = 0;
5213 unsigned long flags;
5214
5215 spin_lock_irqsave(&dvb->slock, flags);
5216 dump_ts_select = !!dump_ts_select;
5217 if (dmx->dump_ts_select != dump_ts_select) {
5218 dmx->dump_ts_select = dump_ts_select;
5219 dmx_reset_dmx_hw_ex_unlock(dvb, dmx, 0);
5220 }
5221 spin_unlock_irqrestore(&dvb->slock, flags);
5222
5223 return ret;
5224}
5225
5226u32 aml_dmx_get_video_pts(struct aml_dvb *dvb)
5227{
5228 unsigned long flags;
5229 u32 pts;
5230
5231 spin_lock_irqsave(&dvb->slock, flags);
5232 pts = video_pts;
5233 spin_unlock_irqrestore(&dvb->slock, flags);
5234
5235 return pts;
5236}
5237
5238u32 aml_dmx_get_audio_pts(struct aml_dvb *dvb)
5239{
5240 unsigned long flags;
5241 u32 pts;
5242
5243 spin_lock_irqsave(&dvb->slock, flags);
5244 pts = audio_pts;
5245 spin_unlock_irqrestore(&dvb->slock, flags);
5246
5247 return pts;
5248}
5249
5250u32 aml_dmx_get_video_pts_bit32(struct aml_dvb *dvb)
5251{
5252 unsigned long flags;
5253 u32 bit32;
5254
5255 spin_lock_irqsave(&dvb->slock, flags);
5256 bit32 = video_pts_bit32;
5257 spin_unlock_irqrestore(&dvb->slock, flags);
5258
5259 return bit32;
5260}
5261
5262u32 aml_dmx_get_audio_pts_bit32(struct aml_dvb *dvb)
5263{
5264 unsigned long flags;
5265 u32 bit32;
5266
5267 spin_lock_irqsave(&dvb->slock, flags);
5268 bit32 = audio_pts_bit32;
5269 spin_unlock_irqrestore(&dvb->slock, flags);
5270
5271 return bit32;
5272}
5273u32 aml_dmx_get_first_video_pts(struct aml_dvb *dvb)
5274{
5275 unsigned long flags;
5276 u32 pts;
5277
5278 spin_lock_irqsave(&dvb->slock, flags);
5279 pts = first_video_pts;
5280 spin_unlock_irqrestore(&dvb->slock, flags);
5281
5282 return pts;
5283}
5284
5285u32 aml_dmx_get_first_audio_pts(struct aml_dvb *dvb)
5286{
5287 unsigned long flags;
5288 u32 pts;
5289
5290 spin_lock_irqsave(&dvb->slock, flags);
5291 pts = first_audio_pts;
5292 spin_unlock_irqrestore(&dvb->slock, flags);
5293
5294 return pts;
5295}
5296
5297int aml_dmx_set_skipbyte(struct aml_dvb *dvb, int skipbyte)
5298{
5299 if (demux_skipbyte != skipbyte) {
5300 pr_dbg("set skip byte %d\n", skipbyte);
5301 demux_skipbyte = skipbyte;
5302 dmx_reset_hw_ex(dvb, 0);
5303 }
5304
5305 return 0;
5306}
5307
5308int aml_dmx_set_demux(struct aml_dvb *dvb, int id)
5309{
5310 aml_stb_hw_set_source(dvb, DMX_SOURCE_DVR0);
5311 if (id < DMX_DEV_COUNT) {
5312 struct aml_dmx *dmx = &dvb->dmx[id];
5313
5314 aml_dmx_hw_set_source((struct dmx_demux *)dmx,
5315 DMX_SOURCE_DVR0);
5316 }
5317
5318 return 0;
5319}
5320
5321int _set_tsfile_clkdiv(struct aml_dvb *dvb, int clkdiv)
5322{
5323 if (tsfile_clkdiv != clkdiv) {
5324 pr_dbg("set ts file clock div %d\n", clkdiv);
5325 tsfile_clkdiv = clkdiv;
5326 dmx_reset_hw(dvb);
5327 }
5328
5329 return 0;
5330}
5331
5332static ssize_t stb_set_tsfile_clkdiv(struct class *class,
5333 struct class_attribute *attr,
5334 const char *buf, size_t size)
5335{
5336 /*int div = (int)simple_strtol(buf, NULL, 10);*/
5337 long div;
5338
5339 if (kstrtol(buf, 0, &div) == 0)
5340 _set_tsfile_clkdiv(aml_get_dvb_device(), (int)div);
5341 return size;
5342}
5343
5344static ssize_t stb_get_tsfile_clkdiv(struct class *class,
5345 struct class_attribute *attr, char *buf)
5346{
5347 ssize_t ret;
5348
5349 ret = sprintf(buf, "%d\n", tsfile_clkdiv);
5350 return ret;
5351}
5352
5353
5354static int dmx_id;
5355
5356static ssize_t dmx_smallsec_show(struct class *class,
5357 struct class_attribute *attr, char *buf)
5358{
5359 ssize_t ret;
5360 struct aml_dvb *dvb = aml_get_dvb_device();
5361
5362 ret = sprintf(buf, "%d:%d\n", dvb->dmx[dmx_id].smallsec.enable,
5363 dvb->dmx[dmx_id].smallsec.bufsize);
5364 return ret;
5365}
5366static ssize_t dmx_smallsec_store(struct class *class,
5367 struct class_attribute *attr,
5368 const char *buf, size_t size)
5369{
5370 int i, e, s = 0, f = 0;
5371 struct aml_dvb *dvb = aml_get_dvb_device();
5372
5373 i = sscanf(buf, "%d:%i:%d", &e, &s, &f);
5374 if (i <= 0)
5375 return size;
5376
5377 dmx_smallsec_set(&dvb->dmx[dmx_id].smallsec, e, s, f);
5378 return size;
5379}
5380
5381static ssize_t dmx_timeout_show(struct class *class,
5382 struct class_attribute *attr, char *buf)
5383{
5384 ssize_t ret;
5385 struct aml_dvb *dvb = aml_get_dvb_device();
5386
5387 ret = sprintf(buf, "%d:%d:0x%x:%d:%d\n",
5388 dvb->dmx[dmx_id].timeout.enable,
5389 dvb->dmx[dmx_id].timeout.timeout,
5390 dvb->dmx[dmx_id].timeout.ch_disable,
5391 dvb->dmx[dmx_id].timeout.match,
5392 (DMX_READ_REG(dmx_id, STB_INT_STATUS)&(1<<INPUT_TIME_OUT)) ?
5393 1 : 0);
5394 DMX_WRITE_REG(dmx_id, STB_INT_STATUS, (1<<INPUT_TIME_OUT));
5395 return ret;
5396}
5397static ssize_t dmx_timeout_store(struct class *class,
5398 struct class_attribute *attr,
5399 const char *buf, size_t size)
5400{
5401 int i, e, t = 0, c = 0, m = 0, f = 0;
5402 struct aml_dvb *dvb = aml_get_dvb_device();
5403
5404 i = sscanf(buf, "%d:%i:%i:%d:%d", &e, &t, &c, &m, &f);
5405 if (i <= 0)
5406 return size;
5407
5408 dmx_timeout_set(&dvb->dmx[dmx_id].timeout, e, t, c, m, f);
5409 return size;
5410}
5411
5412
5413#define DEMUX_SCAMBLE_FUNC_DECL(i) \
5414static ssize_t dmx_reg_value_show_demux##i##_scramble(struct class *class, \
5415struct class_attribute *attr, char *buf)\
5416{\
5417 int data = 0;\
5418 int aflag = 0;\
5419 int vflag = 0;\
5420 ssize_t ret = 0;\
5421 data = DMX_READ_REG(i, DEMUX_SCRAMBLING_STATE);\
5422 if ((data & 0x01) == 0x01) \
5423 vflag = 1;\
5424 if ((data & 0x02) == 0x02) \
5425 aflag = 1;\
5426 ret = sprintf(buf, "%d %d\n", vflag, aflag);\
5427 return ret;\
5428}
5429
5430#if DMX_DEV_COUNT > 0
5431DEMUX_SCAMBLE_FUNC_DECL(0)
5432#endif
5433#if DMX_DEV_COUNT > 1
5434DEMUX_SCAMBLE_FUNC_DECL(1)
5435#endif
5436#if DMX_DEV_COUNT > 2
5437DEMUX_SCAMBLE_FUNC_DECL(2)
5438#endif
5439static ssize_t ciplus_output_ctrl_show(struct class *class,
5440 struct class_attribute *attr,
5441 char *buf)
5442{
5443 int ret;
5444 char *out = "none";
5445
5446 pr_inf("output demux use 3 bit to indicate.\n");
5447 pr_inf("1bit:demux0 2bit:demux1 3bit:demux2\n");
5448
5449 switch (ciplus_out_sel) {
5450 case 1:
5451 out = "dmx0";
5452 break;
5453 case 2:
5454 out = "dmx1";
5455 break;
5456 case 4:
5457 out = "dmx2";
5458 break;
5459 default:
5460 break;
5461 }
5462
5463 ret = sprintf(buf, "%s 0x%x %s\n",
5464 out,
5465 ciplus_out_sel,
5466 (ciplus_out_auto_mode) ? "" : "(force)");
5467 return ret;
5468}
5469
5470static ssize_t ciplus_output_ctrl_store(struct class *class,
5471 struct class_attribute *attr,
5472 const char *buf, size_t size)
5473{
5474 int i, tmp;
5475
5476 i = kstrtoint(buf, -1, &tmp);
5477 if (tmp > 8 || tmp < 0)
5478 pr_error("Invalid output set\n");
5479 else if (tmp == 8) {
5480 ciplus_out_auto_mode = 1;
5481 ciplus_out_sel = -1;
5482 pr_error("Auto set output mode enable\n");
5483 } else {
5484 ciplus_out_auto_mode = 0;
5485 ciplus_out_sel = tmp;
5486 pr_error("Auto set output mode disable\n");
5487 }
5488 return size;
5489}
5490static ssize_t reset_fec_input_ctrl_show(struct class *class,
5491 struct class_attribute *attr,
5492 char *buf)
5493{
5494 return 0;
5495}
5496
5497static ssize_t reset_fec_input_ctrl_store(struct class *class,
5498 struct class_attribute *attr,
5499 const char *buf, size_t size)
5500{
5501 u32 v;
5502
5503 v = READ_MPEG_REG(FEC_INPUT_CONTROL);
5504 v &= ~(1<<11);
5505 WRITE_MPEG_REG(FEC_INPUT_CONTROL, v);
5506
5507 pr_dbg("reset FEC_INPUT_CONTROL to %x\n", v);
5508
5509 return size;
5510}
5511static ssize_t dmx_reg_addr_show_source(struct class *class,
5512 struct class_attribute *attr,
5513 char *buf);
5514static ssize_t dmx_reg_addr_store_source(struct class *class,
5515 struct class_attribute *attr,
5516 const char *buf, size_t size);
5517static ssize_t dmx_id_show_source(struct class *class,
5518 struct class_attribute *attr, char *buf);
5519static ssize_t dmx_id_store_source(struct class *class,
5520 struct class_attribute *attr,
5521 const char *buf, size_t size);
5522static ssize_t dmx_reg_value_show_source(struct class *class,
5523 struct class_attribute *attr,
5524 char *buf);
5525static ssize_t dmx_reg_value_store_source(struct class *class,
5526 struct class_attribute *attr,
5527 const char *buf, size_t size);
5528static ssize_t dmx_sec_statistics_show(struct class *class,
5529 struct class_attribute *attr,
5530 char *buf);
5531static int reg_addr;
5532
5533static struct class_attribute aml_dmx_class_attrs[] = {
5534 __ATTR(dmx_id, 0644, dmx_id_show_source,
5535 dmx_id_store_source),
5536 __ATTR(register_addr, 0644, dmx_reg_addr_show_source,
5537 dmx_reg_addr_store_source),
5538 __ATTR(register_value, 0644, dmx_reg_value_show_source,
5539 dmx_reg_value_store_source),
5540 __ATTR(tsfile_clkdiv, 0644, stb_get_tsfile_clkdiv,
5541 stb_set_tsfile_clkdiv),
5542
5543#define DEMUX_SCAMBLE_ATTR_DECL(i)\
5544 __ATTR(demux##i##_scramble, 0644, \
5545 dmx_reg_value_show_demux##i##_scramble, NULL)
5546#if DMX_DEV_COUNT > 0
5547 DEMUX_SCAMBLE_ATTR_DECL(0),
5548#endif
5549#if DMX_DEV_COUNT > 1
5550 DEMUX_SCAMBLE_ATTR_DECL(1),
5551#endif
5552#if DMX_DEV_COUNT > 2
5553 DEMUX_SCAMBLE_ATTR_DECL(2),
5554#endif
5555
5556 __ATTR(dmx_smallsec, 0644,
5557 dmx_smallsec_show,
5558 dmx_smallsec_store),
5559 __ATTR(dmx_timeout, 0644,
5560 dmx_timeout_show,
5561 dmx_timeout_store),
5562 __ATTR(reset_fec_input_ctrl, 0644,
5563 reset_fec_input_ctrl_show,
5564 reset_fec_input_ctrl_store),
5565 __ATTR(ciplus_output_ctrl, 0644,
5566 ciplus_output_ctrl_show,
5567 ciplus_output_ctrl_store),
5568 __ATTR_RO(dmx_sec_statistics),
5569 __ATTR_NULL
5570};
5571
5572static struct class aml_dmx_class = {
5573 .name = "dmx",
5574 .class_attrs = aml_dmx_class_attrs,
5575};
5576
5577static ssize_t dmx_id_show_source(struct class *class,
5578 struct class_attribute *attr, char *buf)
5579{
5580 int ret;
5581
5582 ret = sprintf(buf, "%d\n", dmx_id);
5583 return ret;
5584}
5585
5586static ssize_t dmx_id_store_source(struct class *class,
5587 struct class_attribute *attr,
5588 const char *buf, size_t size)
5589{
5590 int id = 0;
5591 long value = 0;
5592
5593 if (kstrtol(buf, 0, &value) == 0)
5594 id = (int)value;
5595 /*id = simple_strtol(buf, 0, 16);*/
5596
5597 if (id < 0 || id > 2)
5598 pr_dbg("dmx id must 0 ~2\n");
5599 else
5600 dmx_id = id;
5601
5602 return size;
5603}
5604
5605static ssize_t dmx_reg_addr_show_source(struct class *class,
5606 struct class_attribute *attr,
5607 char *buf)
5608{
5609 int ret;
5610
5611 ret = sprintf(buf, "%x\n", reg_addr);
5612 return ret;
5613}
5614
5615static ssize_t dmx_reg_addr_store_source(struct class *class,
5616 struct class_attribute *attr,
5617 const char *buf, size_t size)
5618{
5619 int addr = 0;
5620 /*addr = simple_strtol(buf, 0, 16);*/
5621 long value = 0;
5622
5623 if (kstrtol(buf, 0, &value) == 0)
5624 addr = (int)value;
5625 reg_addr = addr;
5626 return size;
5627}
5628
5629static ssize_t dmx_reg_value_show_source(struct class *class,
5630 struct class_attribute *attr,
5631 char *buf)
5632{
5633 int ret, value;
5634
5635 value = READ_MPEG_REG(reg_addr);
5636 ret = sprintf(buf, "%x\n", value);
5637 return ret;
5638}
5639
5640static ssize_t dmx_reg_value_store_source(struct class *class,
5641 struct class_attribute *attr,
5642 const char *buf, size_t size)
5643{
5644 int value = 0;
5645 /*value = simple_strtol(buf, 0, 16);*/
5646 long val = 0;
5647
5648 if (kstrtol(buf, 0, &val) == 0)
5649 value = (int)val;
5650 WRITE_MPEG_REG(reg_addr, value);
5651 return size;
5652}
5653
5654static ssize_t dmx_sec_statistics_show(struct class *class,
5655 struct class_attribute *attr,
5656 char *buf)
5657{
5658 ssize_t ret;
5659 char tmp[128];
5660 struct aml_dvb *dvb = aml_get_dvb_device();
5661
5662 ret = sprintf(tmp, "[hw]%#lx:%#lx:%#lx\n[sw]%#lx:%#lx:%#lx\n",
5663 dvb->dmx[dmx_id].sec_cnt[SEC_CNT_HW],
5664 dvb->dmx[dmx_id].sec_cnt_match[SEC_CNT_HW],
5665 dvb->dmx[dmx_id].sec_cnt_crc_fail[SEC_CNT_HW],
5666 dvb->dmx[dmx_id].sec_cnt[SEC_CNT_SW],
5667 dvb->dmx[dmx_id].sec_cnt_match[SEC_CNT_SW],
5668 dvb->dmx[dmx_id].sec_cnt_crc_fail[SEC_CNT_SW]);
5669 ret = sprintf(buf, "%s[ss]%#lx:%#lx:%#lx\n",
5670 tmp,
5671 dvb->dmx[dmx_id].sec_cnt[SEC_CNT_SS],
5672 dvb->dmx[dmx_id].sec_cnt_match[SEC_CNT_SS],
5673 dvb->dmx[dmx_id].sec_cnt_crc_fail[SEC_CNT_SS]);
5674 return ret;
5675}
5676
5677int aml_regist_dmx_class(void)
5678{
5679
5680 if (class_register(&aml_dmx_class) < 0)
5681 pr_error("register class error\n");
5682
5683 return 0;
5684}
5685
5686int aml_unregist_dmx_class(void)
5687{
5688
5689 class_unregister(&aml_dmx_class);
5690 return 0;
5691}
5692
5693