SkystarS2 pid filtering fix and stream control
Subsystems (2)
Jemma Denson
maintainerv2 cover SkystarS2 pid filtering fix and stream control
This patch series finishes off the addition of the SkyStarS2 card - the patches here aren't strictly required for running the card so haven't previously been included.
The first patch fixes a bug present in the current flexcop driver - I've seen it with this card, and it has also been noticed in some other cards. Those cards will need identifying and patches created to use this fix as it is not enabled by default.
The other three patches add in a feature that was half complete in the original binary blob for this card, and allows the demod chip to control the streams on the b2c2 when it turns off it's output during tuning. This helps to avoid a situation where the hardware filter is constantly reset by a software watchdog in flexcop-pci because it can't see any data coming in.
Changes since v1:
* Move the stream reset code from flexcop_pci to flexcop_hw_filter so the fact it might interfere with hw_filter code isn't missed.
* Control both streams - so output stream aswell as receive.
* Track the external stream state so we don't leave the stream turned off in a reset.
* Don't let the external control start the stream until a feed is actually requested.
Jemma Denson (4):
b2c2: Add option to skip the first 6 pid filters
b2c2: Move stream reset code from flexcop-pci to flexcop
b2c2: Add external stream control
cx24120: Take control of b2c2 streams
drivers/media/common/b2c2/flexcop-common.h | 5 ++ drivers/media/common/b2c2/flexcop-fe-tuner.c | 13 +++++ drivers/media/common/b2c2/flexcop-hw-filter.c | 71 ++++++++++++++++++++++----- drivers/media/dvb-frontends/cx24120.c | 29 +++++++---- drivers/media/dvb-frontends/cx24120.h | 1 + drivers/media/pci/b2c2/flexcop-pci.c | 19 ++----- 6 files changed, 103 insertions(+), 35 deletions(-)
Signature · 1 line
2.1.0
Jemma Denson
maintainerPATCH v2 1/4 b2c2: Add option to skip the first 6 pid filters
The flexcop bridge chip has two banks of hardware pid filters - an initial 6, and on some chip revisions an additional bank of 32.
A bug is present on the initial 6 - when changing transponders one of two PAT packets from the old transponder would be included in the initial packets from the new transponder. This usually transpired with userspace programs complaining about services missing, because they are seeing a PAT that they would not be expecting. Running in full TS mode does not exhibit this problem, neither does using just the additional 32.
This patch adds in an option to not use the inital 6 and solely use just the additional 32, and enables this option for the SkystarS2 card. Other cards can be added as required if they also have this bug.
--- drivers/media/common/b2c2/flexcop-common.h | 1 + drivers/media/common/b2c2/flexcop-fe-tuner.c | 3 +++ drivers/media/common/b2c2/flexcop-hw-filter.c | 16 ++++++++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-)
drivers/media/common/b2c2/flexcop-common.h +1 -0
@@ -91,6 +91,7 @@ struct flexcop_device {int feedcount;int pid_filtering;int fullts_streaming_state; +int skip_6_hw_pid_filter;/* bus specific callbacks */ flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *,
drivers/media/common/b2c2/flexcop-fe-tuner.c +3 -0
@@ -651,6 +651,9 @@ static int skystarS2_rev33_attach(struct flexcop_device *fc, }info ("ISL6421 successfully attached." ); +if (fc->has_32_hw_pid_filter) + fc->skip_6_hw_pid_filter =1 ; +return 1 ; }#else
drivers/media/common/b2c2/flexcop-hw-filter.c +14 -2
@@ -117,6 +117,10 @@ static void flexcop_pid_control(struct flexcop_device *fc,deb_ts ("setting pid: %5d %04x at index %d '%s'\n" , pid, pid, index, onoff ?"on" :"off" ); +/* First 6 can be buggy - skip over them if option set */ +if (fc->skip_6_hw_pid_filter) + index +=6 ; +/* We could use bit magic here to reduce source code size. * I decided against it, but to use the real register names */ switch (index) {
@@ -170,7 +174,10 @@ static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff)int flexcop_pid_feed_control (struct flexcop_device *fc,struct dvb_demux_feed *dvbdmxfeed,int onoff) { -int max_pid_filter =6 + fc->has_32_hw_pid_filter*32 ; +int max_pid_filter =6 ; + + max_pid_filter -=6 * fc->skip_6_hw_pid_filter; + max_pid_filter +=32 * fc->has_32_hw_pid_filter; fc->feedcount += onoff ?1 :-1 ;/* the number of PIDs/Feed currently requested */ if (dvbdmxfeed->index >= max_pid_filter)
@@ -217,7 +224,12 @@ void flexcop_hw_filter_init(struct flexcop_device *fc) {int i;flexcop_ibi_value v; -for (i =0 ; i <6 +32 *fc->has_32_hw_pid_filter; i++) +int max_pid_filter =6 ; + + max_pid_filter -=6 * fc->skip_6_hw_pid_filter; + max_pid_filter +=32 * fc->has_32_hw_pid_filter; + +for (i =0 ; i < max_pid_filter; i++)flexcop_pid_control (fc, i,0x1fff ,0 );flexcop_pid_group_filter (fc,0 ,0x1fe0 );
Signature · 1 line
2.1.0
Re: [PATCH v2 1/4] b2c2: Add option to skip the first 6 pid filters
Quoted 11 lines · Jemma Denson
The flexcop bridge chip has two banks of hardware pid filters - an initial 6, and on some chip revisions an additional bank of 32.
A bug is present on the initial 6 - when changing transponders one of two PAT packets from the old transponder would be included in the initial packets from the new transponder. This usually transpired with userspace programs complaining about services missing, because they are seeing a PAT that they would not be expecting. Running in full TS mode does not exhibit this problem, neither does using just the additional 32.
Quoted 4 lines
This patch adds in an option to not use the inital 6 and solely use just the additional 32, and enables this option for the SkystarS2 card. Other cards can be added as required if they also have this bug.
Why not to use strategy where 32 pid filter is used as a priority and that buggy 6 pid filter is used only when 32 pid filter is not available (or it is already 100% in use)?
regards
Antti
Signature · 1 line
http://palosaari.fi/
Jemma Denson
maintainerRe: [PATCH v2 1/4] b2c2: Add option to skip the first 6 pid filters
Hi Antti,
Quoted 12 lines · Antti Palosaari
Quoted 11 lines · Jemma Denson
The flexcop bridge chip has two banks of hardware pid filters - an initial 6, and on some chip revisions an additional bank of 32.
A bug is present on the initial 6 - when changing transponders one of two PAT packets from the old transponder would be included in the initial packets from the new transponder. This usually transpired with userspace programs complaining about services missing, because they are seeing a PAT that they would not be expecting. Running in full TS mode does not exhibit this problem, neither does using just the additional 32.
Quoted 7 lines
Quoted 4 lines
This patch adds in an option to not use the inital 6 and solely use just the additional 32, and enables this option for the SkystarS2 card. Other cards can be added as required if they also have this bug.
Why not to use strategy where 32 pid filter is used as a priority and that buggy 6 pid filter is used only when 32 pid filter is not available (or it is already 100% in use)?
Yes, that might work, I hadn't though of just swapping them around - thanks. It would however assume that the 0x0000 PAT feed is requested early on enough that it always sits within the bank of 32 and nothing else is too bothered by the odd out of order packet.
The only concern I have got is if there is any other oddness in the first 6 - this card is the only flexcop based card with dvb-s2 and there is a lack of stream with high bitrate transponders (>approx. 45Mbps), which we think might due to the hardware pid filter. The card apparently works fine under the windows driver so it's a case of trying to work out what that might be doing differently. It's quite speculative at the moment but I'm hoping this patch might help with that and I'm waiting for some feedback on that - I'm stuck with 28.2E which doesn't hold anything interesting.
At the moment it doesn't really matter too much having only 32 filters rather than the full 38 - it does switch to full-TS once it runs out of hardware filters, and the only issue with full-TS is that the flexcop can't pass a TS with more than 45Mbps (but they aren't working at the moment anyway)
Jemma.
Patrick Boettcher
maintainerRe: [PATCH v2 1/4] b2c2: Add option to skip the first 6 pid filters
Hi all,
Quoted 15 lines · On Mon, 01 Jun 2015 09:08:03 +0100 Jemma Denson <[email protected]> wrote:
Yes, that might work, I hadn't though of just swapping them around - thanks. It would however assume that the
0x0000PAT feed is requested early on enough that it always sits within the bank of 32 and nothing else is too bothered by the odd out of order packet.The only concern I have got is if there is any other oddness in the first 6 - this card is the only flexcop based card with dvb-s2 and there is a lack of stream with high bitrate transponders (>approx. 45Mbps), which we think might due to the hardware pid filter. The card apparently works fine under the windows driver so it's a case of trying to work out what that might be doing differently. It's quite speculative at the moment but I'm hoping this patch might help with that and I'm waiting for some feedback on that - I'm stuck with 28.2E which doesn't hold anything interesting.
Quoted 5 lines
At the moment it doesn't really matter too much having only 32 filters rather than the full 38 - it does switch to full-TS once it runs out of hardware filters, and the only issue with full-TS is that the flexcop can't pass a TS with more than 45Mbps (but they aren't working at the moment anyway)
I agree, if the 6 PID-filters are not working they should be used. The worth is receiving PSI of a transponder/channel which is in fact from the one previously tuned.
I think it is better to leave it as you suggested.
--
Patrick.
Jemma Denson
maintainerPATCH v2 2/4 b2c2: Move stream reset code from flexcop-pci to flexcop
In reply to Jemma DensonAs this bit of code is resetting the flexcop stream and the hardware filter a better place for it is in flexcop-hw-filter.c
--- drivers/media/common/b2c2/flexcop-common.h | 1 + drivers/media/common/b2c2/flexcop-hw-filter.c | 17 ++++++++++++++++- drivers/media/pci/b2c2/flexcop-pci.c | 14 +------------- 3 files changed, 18 insertions(+), 14 deletions(-)
drivers/media/common/b2c2/flexcop-common.h +1 -0
@@ -177,6 +177,7 @@ void flexcop_dump_reg(struct flexcop_device *fc,int flexcop_pid_feed_control (struct flexcop_device *fc,struct dvb_demux_feed *dvbdmxfeed,int onoff);void flexcop_hw_filter_init (struct flexcop_device *fc); +void flexcop_stream_reset (struct flexcop_device *fc);void flexcop_smc_ctrl (struct flexcop_device *fc,int onoff);
drivers/media/common/b2c2/flexcop-hw-filter.c +16 -1
@@ -218,7 +218,6 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, }return 0 ; } -EXPORT_SYMBOL (flexcop_pid_feed_control);void flexcop_hw_filter_init (struct flexcop_device *fc) {
@@ -242,3 +241,19 @@ void flexcop_hw_filter_init(struct flexcop_device *fc)flexcop_null_filter_ctrl (fc,1 ); } + +void flexcop_stream_reset (struct flexcop_device *fc) +{ +struct dvb_demux_feed *feed; + +spin_lock_irq (&fc->demux.lock); +list_for_each_entry (feed, &fc->demux.feed_list, list_head) { +flexcop_pid_feed_control (fc, feed,0 ); + } + +list_for_each_entry (feed, &fc->demux.feed_list, list_head) { +flexcop_pid_feed_control (fc, feed,1 ); + } +spin_unlock_irq (&fc->demux.lock); +} +EXPORT_SYMBOL (flexcop_stream_reset);
drivers/media/pci/b2c2/flexcop-pci.c +1 -13
@@ -112,21 +112,9 @@ static void flexcop_pci_irq_check_work(struct work_struct *work)if (fc_pci->count == fc_pci->count_prev) {deb_chk ("no IRQ since the last check\n" );if (fc_pci->stream_problem++ ==3 ) { -struct dvb_demux_feed *feed;deb_info ("flexcop-pci: stream problem, resetting pid filter\n" ); -spin_lock_irq (&fc->demux.lock); -list_for_each_entry (feed, &fc->demux.feed_list, - list_head) { -flexcop_pid_feed_control (fc, feed,0 ); - } - -list_for_each_entry (feed, &fc->demux.feed_list, - list_head) { -flexcop_pid_feed_control (fc, feed,1 ); - } -spin_unlock_irq (&fc->demux.lock); - +flexcop_stream_reset (fc); fc_pci->stream_problem =0 ; } }else {
Signature · 1 line
2.1.0
Jemma Denson
maintainerPATCH v2 3/4 b2c2: Add external stream control
In reply to Jemma DensonSome demods are aware that their stream has stopped, such as whilst tuning. Allow them to control the flexcop receive and output streams.
This avoids flexcop_pci_irq_check_work from triggering and resetting the stream unneccesarily due to a lack of data.
--- drivers/media/common/b2c2/flexcop-common.h | 3 +++ drivers/media/common/b2c2/flexcop-hw-filter.c | 38 ++++++++++++++++++++------- drivers/media/pci/b2c2/flexcop-pci.c | 5 +++- 3 files changed, 36 insertions(+), 10 deletions(-)
drivers/media/common/b2c2/flexcop-common.h +3 -0
@@ -91,6 +91,8 @@ struct flexcop_device {int feedcount;int pid_filtering;int fullts_streaming_state; +int use_external_stream_control; +int external_stream_started;int skip_6_hw_pid_filter;/* bus specific callbacks */
@@ -178,6 +180,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff);void flexcop_hw_filter_init (struct flexcop_device *fc);void flexcop_stream_reset (struct flexcop_device *fc); +void flexcop_external_stream_control (struct flexcop_device *fc,int onoff);void flexcop_smc_ctrl (struct flexcop_device *fc,int onoff);
drivers/media/common/b2c2/flexcop-hw-filter.c +29 -9
@@ -171,6 +171,8 @@ static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff)return 0 ; } +static void flexcop_stream_control (struct flexcop_device *fc,int onoff); +int flexcop_pid_feed_control (struct flexcop_device *fc,struct dvb_demux_feed *dvbdmxfeed,int onoff) {
@@ -206,15 +208,9 @@ int flexcop_pid_feed_control(struct flexcop_device *fc,/* if it was the first or last feed request change the stream-status */ if (fc->feedcount == onoff) { -flexcop_rcv_data_ctrl (fc, onoff); -if (fc->stream_control)/* device specific stream control */ - fc->stream_control (fc, onoff); - -/* feeding stopped -> reset the flexcop filter*/ -if (onoff ==0 ) { -flexcop_reset_block_300 (fc); -flexcop_hw_filter_init (fc); - } +if (!fc->use_external_stream_control || + fc->external_stream_started) +flexcop_stream_control (fc, onoff); }return 0 ; }
@@ -257,3 +253,27 @@ void flexcop_stream_reset(struct flexcop_device *fc)spin_unlock_irq (&fc->demux.lock); }EXPORT_SYMBOL (flexcop_stream_reset); + +void flexcop_stream_control (struct flexcop_device *fc,int onoff) +{ +flexcop_rcv_data_ctrl (fc, onoff); + +/* device specific stream control */ +if (fc->stream_control) + fc->stream_control (fc, onoff); + +/* feeding stopped -> reset the flexcop filter*/ +if (onoff ==0 ) { +flexcop_reset_block_300 (fc); +flexcop_hw_filter_init (fc); + } +} + +void flexcop_external_stream_control (struct flexcop_device *fc,int onoff) +{ + fc->external_stream_started = onoff; + +/* only change stream if feed already requested */ +if (fc->feedcount) +flexcop_stream_control (fc, onoff); +}
drivers/media/pci/b2c2/flexcop-pci.c +4 -1
@@ -62,6 +62,7 @@ struct flexcop_pci {int count;int count_prev;int stream_problem; +int stream_started;spinlock_t irq_lock;unsigned long last_irq;
@@ -107,7 +108,7 @@ static void flexcop_pci_irq_check_work(struct work_struct *work) container_of(work, struct flexcop_pci, irq_check_work.work);struct flexcop_device *fc = fc_pci->fc_dev; -if (fc->feedcount) { +if (fc_pci->stream_started) {if (fc_pci->count == fc_pci->count_prev) {deb_chk ("no IRQ since the last check\n" );
@@ -232,6 +233,7 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)flexcop_dma_control_timer_irq (fc,FC_DMA_1 ,1 );deb_irq ("IRQ enabled\n" ); fc_pci->count_prev = fc_pci->count; + fc_pci->stream_started =1 ; }else {flexcop_dma_control_timer_irq (fc,FC_DMA_1 ,0 );deb_irq ("IRQ disabled\n" );
@@ -239,6 +241,7 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)flexcop_dma_xfer_control (fc,FC_DMA_1 ,FC_DMA_SUBADDR_0 |FC_DMA_SUBADDR_1 ,0 );deb_irq ("DMA xfer disabled\n" ); + fc_pci->stream_started =0 ; }return 0 ; }
Signature · 1 line
2.1.0
Jemma Denson
maintainerPATCH v2 4/4 cx24120: Take control of b2c2 streams
In reply to Jemma DensonNow that b2c2 has an option to allow us to do so, turn off the flexcop streams when we turn off mpeg output whilst tuning.
--- drivers/media/common/b2c2/flexcop-fe-tuner.c | 10 ++++++++++ drivers/media/dvb-frontends/cx24120.c | 29 +++++++++++++++++++--------- drivers/media/dvb-frontends/cx24120.h | 1 + 3 files changed, 31 insertions(+), 9 deletions(-)
drivers/media/common/b2c2/flexcop-fe-tuner.c +10 -0
@@ -625,11 +625,20 @@ fail:/* SkyStar S2 PCI DVB-S/S2 card based on Conexant cx24120/cx24118 */ #if FE_SUPPORTED (CX24120 ) &&FE_SUPPORTED (ISL6421 ) +static int skystarS2_rev33_stream_control (struct dvb_frontend *fe,int onoff) +{ +struct flexcop_device *fc = fe->dvb->priv; + +flexcop_external_stream_control (fc, onoff); +return 0 ; +} +static const struct cx24120_config skystar2_rev3_3_cx24120_config = { .i2c_addr =0x55 , .xtal_khz =10111 , .initial_mpeg_config = {0xa1 ,0x76 ,0x07 }, .request_firmware = flexcop_fe_request_firmware, + .stream_control = skystarS2_rev33_stream_control, .i2c_wr_max =4 , };
@@ -651,6 +660,7 @@ static int skystarS2_rev33_attach(struct flexcop_device *fc, }info ("ISL6421 successfully attached." ); + fc->use_external_stream_control =1 ;if (fc->has_32_hw_pid_filter) fc->skip_6_hw_pid_filter =1 ;
drivers/media/dvb-frontends/cx24120.c +20 -9
@@ -371,6 +371,8 @@ static void cx24120_check_cmd(struct cx24120_state *state, u8 id)case CMD_DISEQC_BURST :cx24120_msg_mpeg_output_global_config (state,0 );/* Old driver would do a msleep(100) here */ + state->config->stream_control (&state->frontend,0 ); + state->mpeg_enabled =0 ;default :return ; }
@@ -382,10 +384,9 @@ static int cx24120_message_send(struct cx24120_state *state, {int ficus; -if (state->mpeg_enabled) { -/* Disable mpeg out on certain commands */ +/* If controlling stream, turn if off whilst tuning */ +if (state->config->stream_control && state->mpeg_enabled)cx24120_check_cmd (state, cmd->id); - }cx24120_writereg (state,CX24120_REG_CMD_START , cmd->id); cx24120_writeregs(state, CX24120_REG_CMD_ARGS, &cmd->arg[0],
@@ -464,7 +465,6 @@ static int cx24120_msg_mpeg_output_global_config(struct cx24120_state *state,return ret; } - state->mpeg_enabled = enable;dev_dbg (&state->i2c->dev,"MPEG output %s\n" , enable ?"enabled" :"disabled" );
@@ -743,11 +743,13 @@ static int cx24120_read_status(struct dvb_frontend *fe, fe_status_t *status)/* Set clock ratios */ cx24120_set_clock_ratios (fe); -/* Old driver would do a msleep(200) here */ -/* Renable mpeg output */ -if (!state->mpeg_enabled) +if (state->config->stream_control && !state->mpeg_enabled) { +/* Old driver would do a msleep(200) here */ cx24120_msg_mpeg_output_global_config (state,1 ); + state->config->stream_control (fe,1 ); + state->mpeg_enabled =1 ; + } state->need_clock_set =0 ; }
@@ -1418,8 +1420,17 @@ static int cx24120_init(struct dvb_frontend *fe)/* Initialise mpeg outputs */ cx24120_writereg (state,0xeb ,0x0a ); -if (cx24120_msg_mpeg_output_global_config (state,0 ) || -cx24120_msg_mpeg_output_config (state,0 ) || + +/* Enable global output now if we're not doing stream control */ +if (!state->config->stream_control) + ret =cx24120_msg_mpeg_output_global_config (state,1 ); +else + ret =cx24120_msg_mpeg_output_global_config (state,0 ); + +if (ret !=0 ) +return ret; + +if (cx24120_msg_mpeg_output_config (state,0 ) ||cx24120_msg_mpeg_output_config (state,1 ) ||cx24120_msg_mpeg_output_config (state,2 )) {err ("Error initialising mpeg output. :(\n" );
drivers/media/dvb-frontends/cx24120.h +1 -0
@@ -37,6 +37,7 @@ struct cx24120_config {int (*request_firmware)(struct dvb_frontend *fe,const struct firmware **fw,char *name); +int (*stream_control)(struct dvb_frontend *fe,int onoff);/* max bytes I2C provider can write at once */ u16 i2c_wr_max;
Signature · 1 line
2.1.0