📄 skystar2.c
字号:
static int pid_get_group_pid(struct adapter *adapter){ return read_reg_dw(adapter, 0x30c) & 0x00001fff;}static int pid_get_group_mask(struct adapter *adapter){ return (read_reg_dw(adapter, 0x30c) >> 0x10)& 0x00001fff;}*//*static void reset_hardware_pid_filter(struct adapter *adapter){ pid_set_stream1_pid(adapter, 0x1fff); pid_set_stream2_pid(adapter, 0x1fff); filter_enable_stream2_filter(adapter, 0); pid_set_pcr_pid(adapter, 0x1fff); filter_enable_pcr_filter(adapter, 0); pid_set_pmt_pid(adapter, 0x1fff); filter_enable_pmt_filter(adapter, 0); pid_set_ecm_pid(adapter, 0x1fff); filter_enable_ecm_filter(adapter, 0); pid_set_emm_pid(adapter, 0x1fff); filter_enable_emm_filter(adapter, 0);}*/static void init_pids(struct adapter *adapter){ int i; adapter->pid_count = 0; adapter->whole_bandwidth_count = 0; for (i = 0; i < adapter->useable_hw_filters; i++) { dprintk("%s: setting filter %d to 0x1fff\n", __FUNCTION__, i); adapter->hw_pids[i] = 0x1fff; pid_set_hw_pid(adapter, i, 0x1fff);} pid_set_group_pid(adapter, 0); pid_set_group_mask(adapter, 0x1fe0);}static void open_whole_bandwidth(struct adapter *adapter){ dprintk("%s:\n", __FUNCTION__); pid_set_group_pid(adapter, 0); pid_set_group_mask(adapter, 0);/* filter_enable_mask_filter(adapter, 1);*/}static void close_whole_bandwidth(struct adapter *adapter){ dprintk("%s:\n", __FUNCTION__); pid_set_group_pid(adapter, 0); pid_set_group_mask(adapter, 0x1fe0);/* filter_enable_mask_filter(adapter, 1);*/}static void whole_bandwidth_inc(struct adapter *adapter){ if (adapter->whole_bandwidth_count++ == 0) open_whole_bandwidth(adapter);}static void whole_bandwidth_dec(struct adapter *adapter){ if (--adapter->whole_bandwidth_count <= 0) close_whole_bandwidth(adapter);}/* The specified PID has to be let through the hw filters. We try to allocate an hardware filter and open whole bandwidth when allocation is impossible. All pids<=0x1f pass through the group filter. Returns 1 on success, -1 on error */static int add_hw_pid(struct adapter *adapter, u16 pid){ int i; dprintk("%s: pid=%d\n", __FUNCTION__, pid); if (pid <= 0x1f) return 1; /* we can't use a filter for 0x2000, so no search */ if (pid != 0x2000) { /* find an unused hardware filter */ for (i = 0; i < adapter->useable_hw_filters; i++) { dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i); if (adapter->hw_pids[i] == 0x1fff) { dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i); adapter->hw_pids[i] = pid; pid_set_hw_pid(adapter, i, pid); filter_enable_hw_filter(adapter, i, 1); return 1; } } } /* if we have not used a filter, this pid depends on whole bandwidth */ dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid); whole_bandwidth_inc(adapter); return 1; }/* returns -1 if the pid was not present in the filters */static int remove_hw_pid(struct adapter *adapter, u16 pid){ int i; dprintk("%s: pid=%d\n", __FUNCTION__, pid); if (pid <= 0x1f) return 1; /* we can't use a filter for 0x2000, so no search */ if (pid != 0x2000) { for (i = 0; i < adapter->useable_hw_filters; i++) { dprintk("%s: pid=%d searching slot=%d\n", __FUNCTION__, pid, i); if (adapter->hw_pids[i] == pid) { // find the pid slot dprintk("%s: pid=%d slot=%d\n", __FUNCTION__, pid, i); adapter->hw_pids[i] = 0x1fff; pid_set_hw_pid(adapter, i, 0x1fff); filter_enable_hw_filter(adapter, i, 0); return 1; } } } /* if we have not used a filter, this pid depended on whole bandwith */ dprintk("%s: pid=%d whole_bandwidth\n", __FUNCTION__, pid); whole_bandwidth_dec(adapter); return 1; }/* Adds a PID to the filters. Adding a pid more than once is possible, we keep reference counts. Whole stream available through pid==0x2000. Returns 1 on success, -1 on error */static int add_pid(struct adapter *adapter, u16 pid){ int i; dprintk("%s: pid=%d\n", __FUNCTION__, pid); if (pid > 0x1ffe && pid != 0x2000) return -1; // check if the pid is already present for (i = 0; i < adapter->pid_count; i++) if (adapter->pid_list[i] == pid) { adapter->pid_rc[i]++; // increment ref counter return 1; } if (adapter->pid_count == N_PID_SLOTS) return -1; // no more pids can be added adapter->pid_list[adapter->pid_count] = pid; // register pid adapter->pid_rc[adapter->pid_count] = 1; adapter->pid_count++; // hardware setting add_hw_pid(adapter, pid); return 1; }/* Removes a PID from the filters. */static int remove_pid(struct adapter *adapter, u16 pid){ int i; dprintk("%s: pid=%d\n", __FUNCTION__, pid); if (pid > 0x1ffe && pid != 0x2000) return -1; // check if the pid is present (it must be!) for (i = 0; i < adapter->pid_count; i++) { if (adapter->pid_list[i] == pid) { adapter->pid_rc[i]--; if (adapter->pid_rc[i] <= 0) { // remove from the list adapter->pid_count--; adapter->pid_list[i]=adapter->pid_list[adapter->pid_count]; adapter->pid_rc[i] = adapter->pid_rc[adapter->pid_count]; // hardware setting remove_hw_pid(adapter, pid); } return 1; } } return -1;}/* dma & irq */static void ctrl_enable_smc(struct adapter *adapter, u32 op){ write_reg_bitfield(adapter, 0x208, 0x00000800, op ? 0x00000800 : 0);}static void dma_enable_disable_irq(struct adapter *adapter, u32 flag1, u32 flag2, u32 flag3){ adapter->dma_ctrl = adapter->dma_ctrl & 0x000f0000; if (flag1 == 0) { if (flag2 == 0) adapter->dma_ctrl = adapter->dma_ctrl & ~0x00010000; else adapter->dma_ctrl = adapter->dma_ctrl | 0x00010000; if (flag3 == 0) adapter->dma_ctrl = adapter->dma_ctrl & ~0x00020000; else adapter->dma_ctrl = adapter->dma_ctrl | 0x00020000; } else { if (flag2 == 0) adapter->dma_ctrl = adapter->dma_ctrl & ~0x00040000; else adapter->dma_ctrl = adapter->dma_ctrl | 0x00040000; if (flag3 == 0) adapter->dma_ctrl = adapter->dma_ctrl & ~0x00080000; else adapter->dma_ctrl = adapter->dma_ctrl | 0x00080000; }}static void irq_dma_enable_disable_irq(struct adapter *adapter, u32 op){ u32 value; value = read_reg_dw(adapter, 0x208) & 0xfff0ffff; if (op != 0) value = value | (adapter->dma_ctrl & 0x000f0000); write_reg_dw(adapter, 0x208, value);}/* FlexCopII has 2 dma channels. DMA1 is used to transfer TS data to system memory. The DMA1 buffer is divided in 2 subbuffers of equal size. FlexCopII will transfer TS data to one subbuffer, signal an interrupt when the subbuffer is full and continue fillig the second subbuffer. For DMA1: subbuffer size in 32-bit words is stored in the first 24 bits of register 0x004. The last 8 bits of register 0x004 contain the number of subbuffers. the first 30 bits of register 0x000 contain the address of the first subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1, when dma1 is enabled. the first 30 bits of register 0x00c contain the address of the second subbuffer. the last 2 bits contain 1. register 0x008 will contain the address of the subbuffer that was filled with TS data, when FlexCopII will generate an interrupt. For DMA2: subbuffer size in 32-bit words is stored in the first 24 bits of register 0x014. The last 8 bits of register 0x014 contain the number of subbuffers. the first 30 bits of register 0x010 contain the address of the first subbuffer. The last 2 bits contain 0, when dma1 is disabled and 1, when dma1 is enabled. the first 30 bits of register 0x01c contain the address of the second subbuffer. the last 2 bits contain 1. register 0x018 contains the address of the subbuffer that was filled with TS data, when FlexCopII generates an interrupt.*/static int dma_init_dma(struct adapter *adapter, u32 dma_channel){ u32 subbuffers, subbufsize, subbuf0, subbuf1; if (dma_channel == 0) { dprintk("%s: Initializing DMA1 channel\n", __FUNCTION__); subbuffers = 2; subbufsize = (((adapter->dmaq1.buffer_size / 2) / 4) << 8) | subbuffers; subbuf0 = adapter->dmaq1.bus_addr & 0xfffffffc; subbuf1 = ((adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) & 0xfffffffc) | 1; dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0); udelay(1000); write_reg_dw(adapter, 0x000, subbuf0); dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4); udelay(1000); write_reg_dw(adapter, 0x004, subbufsize); dprintk("%s: second subbuffer address = 0x%x\n", __FUNCTION__, subbuf1); udelay(1000); write_reg_dw(adapter, 0x00c, subbuf1); dprintk("%s: counter = 0x%x\n", __FUNCTION__, adapter->dmaq1.bus_addr & 0xfffffffc); write_reg_dw(adapter, 0x008, adapter->dmaq1.bus_addr & 0xfffffffc); udelay(1000); dma_enable_disable_irq(adapter, 0, 1, subbuffers ? 1 : 0); irq_dma_enable_disable_irq(adapter, 1); sram_set_media_dest(adapter, 1); sram_set_net_dest(adapter, 1); sram_set_cai_dest(adapter, 2); sram_set_cao_dest(adapter, 2); } if (dma_channel == 1) { dprintk("%s: Initializing DMA2 channel\n", __FUNCTION__); subbuffers = 2; subbufsize = (((adapter->dmaq2.buffer_size / 2) / 4) << 8) | subbuffers; subbuf0 = adapter->dmaq2.bus_addr & 0xfffffffc; subbuf1 = ((adapter->dmaq2.bus_addr + adapter->dmaq2.buffer_size / 2) & 0xfffffffc) | 1; dprintk("%s: first subbuffer address = 0x%x\n", __FUNCTION__, subbuf0); udelay(1000); write_reg_dw(adapter, 0x010, subbuf0); dprintk("%s: subbuffer size = 0x%x\n", __FUNCTION__, (subbufsize >> 8) * 4); udelay(1000); write_reg_dw(adapter, 0x014, subbufsize); dprintk("%s: second buffer address = 0x%x\n", __FUNCTION__, subbuf1); udelay(1000); write_reg_dw(adapter, 0x01c, subbuf1); sram_set_cai_dest(adapter, 2); } return 0;}static void ctrl_enable_receive_data(struct adapter *adapter, u32 op){ if (op == 0) { write_reg_bitfield(adapter, 0x208, 0x00008000, 0); adapter->dma_status = adapter->dma_status & ~0x00000004; } else { write_reg_bitfield(adapter, 0x208, 0x00008000, 0x00008000); adapter->dma_status = adapter->dma_status | 0x00000004; }}/* bit 0 of dma_mask is set to 1 if dma1 channel has to be enabled/disabled bit 1 of dma_mask is set to 1 if dma2 channel has to be enabled/disabled*/static void dma_start_stop(struct adapter *adapter, u32 dma_mask, int start_stop){ u32 dma_enable, dma1_enable, dma2_enable; dprintk("%s: dma_mask=%x\n", __FUNCTION__, dma_mask); if (start_stop == 1) { dprintk("%s: starting dma\n", __FUNCTION__); dma1_enable = 0; dma2_enable = 0; if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) == 0) && (adapter->dmaq1.bus_addr != 0)) { adapter->dma_status = adapter->dma_status | 1; dma1_enable = 1; } if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) == 0) && (adapter->dmaq2.bus_addr != 0)) { adapter->dma_status = adapter->dma_status | 2; dma2_enable = 1; } // enable dma1 and dma2 if ((dma1_enable == 1) && (dma2_enable == 1)) { write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1); write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1); write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1); ctrl_enable_receive_data(adapter, 1); return; } // enable dma1 if ((dma1_enable == 1) && (dma2_enable == 0)) { write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr | 1); write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1); ctrl_enable_receive_data(adapter, 1); return; } // enable dma2 if ((dma1_enable == 0) && (dma2_enable == 1)) { write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr | 1); ctrl_enable_receive_data(adapter, 1); return; } // start dma if ((dma1_enable == 0) && (dma2_enable == 0)) { ctrl_enable_receive_data(adapter, 1); return; } } else { dprintk("%s: stopping dma\n", __FUNCTION__); dma_enable = adapter->dma_status & 0x00000003; if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0)) { dma_enable = dma_enable & 0xfffffffe; } if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0)) { dma_enable = dma_enable & 0xfffffffd; } //stop dma if ((dma_enable == 0) && ((adapter->dma_status & 4) != 0)) { ctrl_enable_receive_data(adapter, 0); udelay(3000); } //disable dma1 if (((dma_mask & 1) != 0) && ((adapter->dma_status & 1) != 0) && (adapter->dmaq1.bus_addr != 0)) { write_reg_dw(adapter, 0x000, adapter->dmaq1.bus_addr); write_reg_dw(adapter, 0x00c, (adapter->dmaq1.bus_addr + adapter->dmaq1.buffer_size / 2) | 1); adapter->dma_status = adapter->dma_status & ~0x00000001; } //disable dma2 if (((dma_mask & 2) != 0) && ((adapter->dma_status & 2) != 0) && (adapter->dmaq2.bus_addr != 0)) { write_reg_dw(adapter, 0x010, adapter->dmaq2.bus_addr); adapter->dma_status = adapter->dma_status & ~0x00000002; } }}static void open_stream(struct adapter *adapter, u16 pid){ u32 dma_mask; ++adapter->capturing; filter_enable_mask_filter(adapter, 1); add_pid(adapter, pid); dprintk("%s: adapter->dma_status=%x\n", __FUNCTION__, adapter->dma_status); if ((adapter->dma_status & 7) != 7) { dma_mask = 0; if (((adapter->dma_status & 0x10000000) != 0) && ((adapter->dma_status & 1) == 0)) { dma_mask = dma_mask | 1; adapter->dmaq1.head = 0; adapter->dmaq1.tail = 0; memset(adapter->dmaq1.buffer, 0, adapter->dmaq1.buffer_size); } if (((adapter->dma_status & 0x20000000) != 0) && ((adapter->dma_status & 2) == 0)) { dma_mask = dma_mask | 2; adapter->dmaq2.head = 0; adapter->dmaq2.tail = 0; } if (dma_mask != 0) { irq_dma_enable_disable_irq(adapter, 1); dma_start_stop(adapter, dma_mask, 1); } }}static void close_stream(struct adapter *adapter, u16 pid){ if (adapter->capturing > 0) --adapter->capturing; dprintk("%s: dma_status=%x\n", __FUNCTION__, adapter->dma_status); if (adapter->capturing == 0) { u32 dma_mask = 0; if ((adapter->dma_status & 1) != 0) dma_mask = dma_mask | 0x00000001; if ((adapter->dma_status & 2) != 0) dma_mask = dma_mask | 0x00000002; if (dma_mask != 0) { dma_start_stop(adapter, dma_mask, 0); } } remove_pid(adapter, pid);}static void interrupt_service_dma1(struct adapter *adapter){ struct dvb_demux *dvbdmx = &adapter->demux; int n_cur_dma_counter;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -