aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJohannes Stezenbach <js@linuxtv.org>2005-05-17 00:54:15 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-17 10:59:25 -0400
commitc4ee3fd469302884dda95e1f310d5ffcd9f5acf9 (patch)
tree00671eb14e2d6fd77f7f3b521105214845f212e5 /drivers/media
parent4853f16ad881194ec4c49f73287ef1999b2585ea (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.h2
-rw-r--r--drivers/media/dvb/b2c2/flexcop-hw-filter.c73
-rw-r--r--drivers/media/dvb/b2c2/flexcop-pci.c28
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
105static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,int onoff) 105static 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
139static 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
136int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff) 150int 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
12static int enable_pid_filtering = 0; 12static int enable_pid_filtering = 1;
13module_param(enable_pid_filtering, int, 0444); 13module_param(enable_pid_filtering, int, 0444);
14MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); 14MODULE_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