diff options
author | Johannes Stezenbach <js@linuxtv.org> | 2005-05-17 00:54:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-17 10:59:25 -0400 |
commit | c4ee3fd469302884dda95e1f310d5ffcd9f5acf9 (patch) | |
tree | 00671eb14e2d6fd77f7f3b521105214845f212e5 /drivers/media | |
parent | 4853f16ad881194ec4c49f73287ef1999b2585ea (diff) |
[PATCH] dvb: flexcop: use hw pid filter
- enabled the HW PID by default for the PCI cards
- correct the TS demux parsing when PID filter is enabled (and thus the
timer IRQ)
- rewrote the PID-filter and FULLTS control part in flexcop-hw-filter
(thanks to Krzysztof Matula for pointing that out)
Signed-off-by: Patrick Boettcher <pb@linuxtv.org>
Signed-off-by: Johannes Stezenbach <js@linuxtv.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/b2c2/flexcop-common.h | 2 | ||||
-rw-r--r-- | drivers/media/dvb/b2c2/flexcop-hw-filter.c | 73 | ||||
-rw-r--r-- | drivers/media/dvb/b2c2/flexcop-pci.c | 28 |
3 files changed, 56 insertions, 47 deletions
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h index 534876d616b8..79e8581b4fb7 100644 --- a/drivers/media/dvb/b2c2/flexcop-common.h +++ b/drivers/media/dvb/b2c2/flexcop-common.h | |||
@@ -76,8 +76,10 @@ struct flexcop_device { | |||
76 | struct semaphore i2c_sem; | 76 | struct semaphore i2c_sem; |
77 | 77 | ||
78 | /* options and status */ | 78 | /* options and status */ |
79 | int extra_feedcount; | ||
79 | int feedcount; | 80 | int feedcount; |
80 | int pid_filtering; | 81 | int pid_filtering; |
82 | int fullts_streaming_state; | ||
81 | 83 | ||
82 | /* bus specific callbacks */ | 84 | /* bus specific callbacks */ |
83 | flexcop_ibi_value (*read_ibi_reg) (struct flexcop_device *, flexcop_ibi_register); | 85 | flexcop_ibi_value (*read_ibi_reg) (struct flexcop_device *, flexcop_ibi_register); |
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c index 7a5399b569c7..2baf43d3ce8f 100644 --- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c +++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c | |||
@@ -104,6 +104,9 @@ static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc, u16 pid, int ono | |||
104 | 104 | ||
105 | static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,int onoff) | 105 | static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,int onoff) |
106 | { | 106 | { |
107 | if (pid == 0x2000) | ||
108 | return; | ||
109 | |||
107 | deb_ts("setting pid: %5d %04x at index %d '%s'\n",pid,pid,index,onoff ? "on" : "off"); | 110 | deb_ts("setting pid: %5d %04x at index %d '%s'\n",pid,pid,index,onoff ? "on" : "off"); |
108 | 111 | ||
109 | /* We could use bit magic here to reduce source code size. | 112 | /* We could use bit magic here to reduce source code size. |
@@ -133,50 +136,50 @@ static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,in | |||
133 | } | 136 | } |
134 | } | 137 | } |
135 | 138 | ||
139 | static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc,int onoff) | ||
140 | { | ||
141 | if (fc->fullts_streaming_state != onoff) { | ||
142 | deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling"); | ||
143 | flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff)); | ||
144 | flexcop_pid_group_filter_ctrl(fc,onoff); | ||
145 | fc->fullts_streaming_state = onoff; | ||
146 | } | ||
147 | return 0; | ||
148 | } | ||
149 | |||
136 | int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff) | 150 | int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff) |
137 | { | 151 | { |
138 | int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32; | 152 | int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32; |
139 | 153 | ||
140 | fc->feedcount += (onoff ? 1 : -1); | 154 | fc->feedcount += onoff ? 1 : -1; |
155 | if (dvbdmxfeed->index >= max_pid_filter) | ||
156 | fc->extra_feedcount += onoff ? 1 : -1; | ||
141 | 157 | ||
142 | /* when doing hw pid filtering, set the pid */ | 158 | /* toggle complete-TS-streaming when: |
143 | if (fc->pid_filtering) | 159 | * - pid_filtering is not enabled and it is the first or last feed requested |
144 | flexcop_pid_control(fc,dvbdmxfeed->index,dvbdmxfeed->pid,onoff); | 160 | * - pid_filtering is enabled, |
161 | * - but the number of requested feeds is exceeded | ||
162 | * - or the requested pid is 0x2000 */ | ||
145 | 163 | ||
146 | /* if it was the first feed request */ | 164 | if (!fc->pid_filtering && fc->feedcount == onoff) |
147 | if (fc->feedcount == onoff && onoff) { | 165 | flexcop_toggle_fullts_streaming(fc,onoff); |
148 | if (!fc->pid_filtering) { | ||
149 | deb_ts("enabling full TS transfer\n"); | ||
150 | flexcop_pid_group_filter(fc, 0,0); | ||
151 | flexcop_pid_group_filter_ctrl(fc,1); | ||
152 | } | ||
153 | 166 | ||
154 | if (fc->stream_control) | 167 | if (fc->pid_filtering) { |
155 | fc->stream_control(fc,1); | 168 | flexcop_pid_control(fc,dvbdmxfeed->index,dvbdmxfeed->pid,onoff); |
156 | flexcop_rcv_data_ctrl(fc,1); | 169 | |
157 | 170 | if (fc->extra_feedcount > 0) | |
158 | /* if there is no more feed left to feed */ | 171 | flexcop_toggle_fullts_streaming(fc,1); |
159 | } else if (fc->feedcount == onoff && !onoff) { | 172 | else if (dvbdmxfeed->pid == 0x2000) |
160 | if (!fc->pid_filtering) { | 173 | flexcop_toggle_fullts_streaming(fc,onoff); |
161 | deb_ts("disabling full TS transfer\n"); | 174 | else |
162 | flexcop_pid_group_filter(fc, 0, 0x1fe0); | 175 | flexcop_toggle_fullts_streaming(fc,0); |
163 | flexcop_pid_group_filter_ctrl(fc,0); | ||
164 | } | ||
165 | |||
166 | flexcop_rcv_data_ctrl(fc,0); | ||
167 | if (fc->stream_control) | ||
168 | fc->stream_control(fc,0); | ||
169 | } | 176 | } |
170 | 177 | ||
171 | /* if pid_filtering is on and more pids than the hw-filter can provide are | 178 | /* if it was the first or last feed request change the stream-status */ |
172 | * requested enable the whole bandwidth. | 179 | if (fc->feedcount == onoff) { |
173 | */ | 180 | flexcop_rcv_data_ctrl(fc,onoff); |
174 | if (fc->pid_filtering && fc->feedcount > max_pid_filter) { | 181 | if (fc->stream_control) |
175 | flexcop_pid_group_filter(fc, 0,0); | 182 | fc->stream_control(fc,onoff); |
176 | flexcop_pid_group_filter_ctrl(fc,1); | ||
177 | } else if (fc->pid_filtering && fc->feedcount <= max_pid_filter) { | ||
178 | flexcop_pid_group_filter(fc, 0,0x1fe0); | ||
179 | flexcop_pid_group_filter_ctrl(fc,0); | ||
180 | } | 183 | } |
181 | 184 | ||
182 | return 0; | 185 | return 0; |
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c index c52286ea669f..78952096fb74 100644 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/drivers/media/dvb/b2c2/flexcop-pci.c | |||
@@ -9,7 +9,7 @@ | |||
9 | #define FC_LOG_PREFIX "flexcop-pci" | 9 | #define FC_LOG_PREFIX "flexcop-pci" |
10 | #include "flexcop-common.h" | 10 | #include "flexcop-common.h" |
11 | 11 | ||
12 | static int enable_pid_filtering = 0; | 12 | static int enable_pid_filtering = 1; |
13 | module_param(enable_pid_filtering, int, 0444); | 13 | module_param(enable_pid_filtering, int, 0444); |
14 | MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); | 14 | MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); |
15 | 15 | ||
@@ -45,13 +45,14 @@ struct flexcop_pci { | |||
45 | void __iomem *io_mem; | 45 | void __iomem *io_mem; |
46 | u32 irq; | 46 | u32 irq; |
47 | /* buffersize (at least for DMA1, need to be % 188 == 0, | 47 | /* buffersize (at least for DMA1, need to be % 188 == 0, |
48 | * this is logic is required */ | 48 | * this logic is required */ |
49 | #define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188) | 49 | #define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188) |
50 | #define FC_DEFAULT_DMA2_BUFSIZE (10 * 188) | 50 | #define FC_DEFAULT_DMA2_BUFSIZE (10 * 188) |
51 | struct flexcop_dma dma[2]; | 51 | struct flexcop_dma dma[2]; |
52 | 52 | ||
53 | int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ | 53 | int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ |
54 | u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */ | 54 | u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */ |
55 | int count; | ||
55 | 56 | ||
56 | spinlock_t irq_lock; | 57 | spinlock_t irq_lock; |
57 | 58 | ||
@@ -99,15 +100,6 @@ static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
99 | 100 | ||
100 | spin_lock_irq(&fc_pci->irq_lock); | 101 | spin_lock_irq(&fc_pci->irq_lock); |
101 | 102 | ||
102 | deb_irq("irq: %08x cur_addr: %08x (%d), our addrs. 1: %08x 2: %08x; 0x000: " | ||
103 | "%08x, 0x00c: %08x\n",v.raw, | ||
104 | fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2, | ||
105 | fc_pci->active_dma1_addr, | ||
106 | fc_pci->dma[0].dma_addr0,fc_pci->dma[0].dma_addr1, | ||
107 | fc->read_ibi_reg(fc,dma1_000).raw, | ||
108 | fc->read_ibi_reg(fc,dma1_00c).raw); | ||
109 | |||
110 | |||
111 | if (v.irq_20c.DMA1_IRQ_Status == 1) { | 103 | if (v.irq_20c.DMA1_IRQ_Status == 1) { |
112 | if (fc_pci->active_dma1_addr == 0) | 104 | if (fc_pci->active_dma1_addr == 0) |
113 | flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188); | 105 | flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188); |
@@ -123,21 +115,28 @@ static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
123 | fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; | 115 | fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; |
124 | u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; | 116 | u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; |
125 | 117 | ||
118 | deb_irq("irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ", | ||
119 | v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos); | ||
120 | |||
126 | /* buffer end was reached, restarted from the beginning | 121 | /* buffer end was reached, restarted from the beginning |
127 | * pass the data from last_cur_pos to the buffer end to the demux | 122 | * pass the data from last_cur_pos to the buffer end to the demux |
128 | */ | 123 | */ |
129 | if (cur_pos < fc_pci->last_dma1_cur_pos) { | 124 | if (cur_pos < fc_pci->last_dma1_cur_pos) { |
125 | deb_irq(" end was reached: passing %d bytes ",(fc_pci->dma[0].size*2 - 1) - fc_pci->last_dma1_cur_pos); | ||
130 | flexcop_pass_dmx_data(fc_pci->fc_dev, | 126 | flexcop_pass_dmx_data(fc_pci->fc_dev, |
131 | fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos, | 127 | fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos, |
132 | (fc_pci->dma[0].size*2 - 1) - fc_pci->last_dma1_cur_pos); | 128 | (fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos); |
133 | fc_pci->last_dma1_cur_pos = 0; | 129 | fc_pci->last_dma1_cur_pos = 0; |
130 | fc_pci->count = 0; | ||
134 | } | 131 | } |
135 | 132 | ||
136 | if (cur_pos > fc_pci->last_dma1_cur_pos) { | 133 | if (cur_pos > fc_pci->last_dma1_cur_pos) { |
134 | deb_irq(" passing %d bytes ",cur_pos - fc_pci->last_dma1_cur_pos); | ||
137 | flexcop_pass_dmx_data(fc_pci->fc_dev, | 135 | flexcop_pass_dmx_data(fc_pci->fc_dev, |
138 | fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos, | 136 | fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos, |
139 | cur_pos - fc_pci->last_dma1_cur_pos); | 137 | cur_pos - fc_pci->last_dma1_cur_pos); |
140 | } | 138 | } |
139 | deb_irq("\n"); | ||
141 | 140 | ||
142 | fc_pci->last_dma1_cur_pos = cur_pos; | 141 | fc_pci->last_dma1_cur_pos = cur_pos; |
143 | } else | 142 | } else |
@@ -301,6 +300,11 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e | |||
301 | 300 | ||
302 | fc->stream_control = flexcop_pci_stream_control; | 301 | fc->stream_control = flexcop_pci_stream_control; |
303 | 302 | ||
303 | if (enable_pid_filtering) | ||
304 | info("will use the HW PID filter."); | ||
305 | else | ||
306 | info("will pass the complete TS to the demuxer."); | ||
307 | |||
304 | fc->pid_filtering = enable_pid_filtering; | 308 | fc->pid_filtering = enable_pid_filtering; |
305 | fc->bus_type = FC_PCI; | 309 | fc->bus_type = FC_PCI; |
306 | 310 | ||