diff options
author | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2013-12-17 09:34:22 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2013-12-19 05:17:47 -0500 |
commit | 0400c5354ad09bf4c754132992bdde9ef3dbefcd (patch) | |
tree | 5f84117c9f3ec989e83a1cb14487a689e76a5627 /drivers/media/dvb-frontends/dib8000.c | |
parent | 704f01bbc7e41f4210fe9fa58da511ad3369b70b (diff) |
[media] dib8000: improve block statistics
PER/UCB statistics are collected once on each 1 second.
However, it doesn't provide the total number of packets
needed to calculate PER.
Yet, as we know the bit rate, it is possible to estimate
such number. So, do it.
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Acked-by: Patrick Boettcher <pboettcher@kernellabs.com>
Diffstat (limited to 'drivers/media/dvb-frontends/dib8000.c')
-rw-r--r-- | drivers/media/dvb-frontends/dib8000.c | 109 |
1 files changed, 75 insertions, 34 deletions
diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c index c67a3dba116c..7539d7af2cf7 100644 --- a/drivers/media/dvb-frontends/dib8000.c +++ b/drivers/media/dvb-frontends/dib8000.c | |||
@@ -121,8 +121,9 @@ struct dib8000_state { | |||
121 | 121 | ||
122 | /* for DVBv5 stats */ | 122 | /* for DVBv5 stats */ |
123 | s64 init_ucb; | 123 | s64 init_ucb; |
124 | unsigned long jiffies_stats; | 124 | unsigned long per_jiffies_stats; |
125 | unsigned long jiffies_stats_layer[3]; | 125 | unsigned long ber_jiffies_stats; |
126 | unsigned long ber_jiffies_stats_layer[3]; | ||
126 | 127 | ||
127 | #ifdef DIB8000_AGC_FREEZE | 128 | #ifdef DIB8000_AGC_FREEZE |
128 | u16 agc1_max; | 129 | u16 agc1_max; |
@@ -1006,6 +1007,7 @@ static void dib8000_reset_stats(struct dvb_frontend *fe) | |||
1006 | c->strength.len = 1; | 1007 | c->strength.len = 1; |
1007 | c->cnr.len = 1; | 1008 | c->cnr.len = 1; |
1008 | c->block_error.len = 1; | 1009 | c->block_error.len = 1; |
1010 | c->block_count.len = 1; | ||
1009 | c->post_bit_error.len = 1; | 1011 | c->post_bit_error.len = 1; |
1010 | c->post_bit_count.len = 1; | 1012 | c->post_bit_count.len = 1; |
1011 | 1013 | ||
@@ -1014,15 +1016,17 @@ static void dib8000_reset_stats(struct dvb_frontend *fe) | |||
1014 | 1016 | ||
1015 | c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | 1017 | c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
1016 | c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | 1018 | c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
1019 | c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
1017 | c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | 1020 | c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
1018 | c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | 1021 | c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
1019 | 1022 | ||
1020 | dib8000_read_unc_blocks(fe, &ucb); | 1023 | dib8000_read_unc_blocks(fe, &ucb); |
1021 | 1024 | ||
1022 | state->init_ucb = -ucb; | 1025 | state->init_ucb = -ucb; |
1023 | state->jiffies_stats = 0; | 1026 | state->ber_jiffies_stats = 0; |
1024 | memset(&state->jiffies_stats_layer, 0, | 1027 | state->per_jiffies_stats = 0; |
1025 | sizeof(state->jiffies_stats_layer)); | 1028 | memset(&state->ber_jiffies_stats_layer, 0, |
1029 | sizeof(state->ber_jiffies_stats_layer)); | ||
1026 | } | 1030 | } |
1027 | 1031 | ||
1028 | static int dib8000_reset(struct dvb_frontend *fe) | 1032 | static int dib8000_reset(struct dvb_frontend *fe) |
@@ -4059,7 +4063,9 @@ static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat) | |||
4059 | struct dib8000_state *state = fe->demodulator_priv; | 4063 | struct dib8000_state *state = fe->demodulator_priv; |
4060 | struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache; | 4064 | struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache; |
4061 | int i; | 4065 | int i; |
4062 | u32 time_us, snr, val; | 4066 | int show_per_stats = 0; |
4067 | u32 time_us = 0, snr, val; | ||
4068 | u64 blocks; | ||
4063 | s32 db; | 4069 | s32 db; |
4064 | u16 strength; | 4070 | u16 strength; |
4065 | 4071 | ||
@@ -4074,6 +4080,7 @@ static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat) | |||
4074 | /* UCB/BER/CNR measures require lock */ | 4080 | /* UCB/BER/CNR measures require lock */ |
4075 | if (!(stat & FE_HAS_LOCK)) { | 4081 | if (!(stat & FE_HAS_LOCK)) { |
4076 | c->cnr.len = 1; | 4082 | c->cnr.len = 1; |
4083 | c->block_count.len = 1; | ||
4077 | c->block_error.len = 1; | 4084 | c->block_error.len = 1; |
4078 | c->post_bit_error.len = 1; | 4085 | c->post_bit_error.len = 1; |
4079 | c->post_bit_count.len = 1; | 4086 | c->post_bit_count.len = 1; |
@@ -4081,15 +4088,13 @@ static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat) | |||
4081 | c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | 4088 | c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
4082 | c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | 4089 | c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
4083 | c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | 4090 | c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; |
4091 | c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; | ||
4084 | return 0; | 4092 | return 0; |
4085 | } | 4093 | } |
4086 | 4094 | ||
4087 | /* Check if time for stats was elapsed */ | 4095 | /* Check if time for stats was elapsed */ |
4088 | if (time_after(jiffies, state->jiffies_stats)) { | 4096 | if (time_after(jiffies, state->per_jiffies_stats)) { |
4089 | time_us = dib8000_get_time_us(fe, -1); | 4097 | state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000); |
4090 | state->jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000); | ||
4091 | |||
4092 | dprintk("Next all layers stats available in %u us.\n", time_us); | ||
4093 | 4098 | ||
4094 | /* Get SNR */ | 4099 | /* Get SNR */ |
4095 | snr = dib8000_get_snr(fe); | 4100 | snr = dib8000_get_snr(fe); |
@@ -4108,7 +4113,34 @@ static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat) | |||
4108 | c->cnr.stat[0].svalue = snr; | 4113 | c->cnr.stat[0].svalue = snr; |
4109 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; | 4114 | c->cnr.stat[0].scale = FE_SCALE_DECIBEL; |
4110 | 4115 | ||
4111 | /* Get UCB and post-BER measures */ | 4116 | /* Get UCB measures */ |
4117 | dib8000_read_unc_blocks(fe, &val); | ||
4118 | if (val < state->init_ucb) | ||
4119 | state->init_ucb += 0x100000000L; | ||
4120 | |||
4121 | c->block_error.stat[0].scale = FE_SCALE_COUNTER; | ||
4122 | c->block_error.stat[0].uvalue = val + state->init_ucb; | ||
4123 | |||
4124 | /* Estimate the number of packets based on bitrate */ | ||
4125 | if (!time_us) | ||
4126 | time_us = dib8000_get_time_us(fe, -1); | ||
4127 | |||
4128 | if (time_us) { | ||
4129 | blocks = 1250000UL * 1000000UL; | ||
4130 | do_div(blocks, time_us * 8 * 204); | ||
4131 | c->block_count.stat[0].scale = FE_SCALE_COUNTER; | ||
4132 | c->block_count.stat[0].uvalue += blocks; | ||
4133 | } | ||
4134 | |||
4135 | show_per_stats = 1; | ||
4136 | } | ||
4137 | |||
4138 | /* Get post-BER measures */ | ||
4139 | if (time_after(jiffies, state->ber_jiffies_stats)) { | ||
4140 | time_us = dib8000_get_time_us(fe, -1); | ||
4141 | state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000); | ||
4142 | |||
4143 | dprintk("Next all layers stats available in %u us.", time_us); | ||
4112 | 4144 | ||
4113 | dib8000_read_ber(fe, &val); | 4145 | dib8000_read_ber(fe, &val); |
4114 | c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; | 4146 | c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; |
@@ -4116,13 +4148,6 @@ static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat) | |||
4116 | 4148 | ||
4117 | c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; | 4149 | c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; |
4118 | c->post_bit_count.stat[0].uvalue += 100000000; | 4150 | c->post_bit_count.stat[0].uvalue += 100000000; |
4119 | |||
4120 | dib8000_read_unc_blocks(fe, &val); | ||
4121 | if (val < state->init_ucb) | ||
4122 | state->init_ucb += 1L << 32; | ||
4123 | |||
4124 | c->block_error.stat[0].scale = FE_SCALE_COUNTER; | ||
4125 | c->block_error.stat[0].uvalue = val + state->init_ucb; | ||
4126 | } | 4151 | } |
4127 | 4152 | ||
4128 | if (state->revision < 0x8002) | 4153 | if (state->revision < 0x8002) |
@@ -4133,27 +4158,43 @@ static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat) | |||
4133 | c->post_bit_count.len = 4; | 4158 | c->post_bit_count.len = 4; |
4134 | 4159 | ||
4135 | for (i = 0; i < 3; i++) { | 4160 | for (i = 0; i < 3; i++) { |
4136 | if (!time_after(jiffies, state->jiffies_stats_layer[i])) | 4161 | unsigned nsegs = c->layer[i].segment_count; |
4137 | continue; | 4162 | |
4138 | time_us = dib8000_get_time_us(fe, i); | 4163 | if (nsegs == 0 || nsegs > 13) |
4139 | if (!time_us) | ||
4140 | continue; | 4164 | continue; |
4141 | 4165 | ||
4142 | state->jiffies_stats_layer[i] = jiffies + msecs_to_jiffies((time_us + 500) / 1000); | 4166 | time_us = 0; |
4143 | dprintk("Next layer %c stats will be available in %u us\n", | 4167 | |
4144 | 'A' + i, time_us); | 4168 | if (time_after(jiffies, state->ber_jiffies_stats_layer[i])) { |
4169 | time_us = dib8000_get_time_us(fe, i); | ||
4170 | |||
4171 | state->ber_jiffies_stats_layer[i] = jiffies + msecs_to_jiffies((time_us + 500) / 1000); | ||
4172 | dprintk("Next layer %c stats will be available in %u us\n", | ||
4173 | 'A' + i, time_us); | ||
4145 | 4174 | ||
4146 | val = dib8000_read_word(state, per_layer_regs[i].ber); | 4175 | val = dib8000_read_word(state, per_layer_regs[i].ber); |
4147 | c->post_bit_error.stat[1 + i].scale = FE_SCALE_COUNTER; | 4176 | c->post_bit_error.stat[1 + i].scale = FE_SCALE_COUNTER; |
4148 | c->post_bit_error.stat[1 + i].uvalue += val; | 4177 | c->post_bit_error.stat[1 + i].uvalue += val; |
4149 | 4178 | ||
4150 | c->post_bit_count.stat[1 + i].scale = FE_SCALE_COUNTER; | 4179 | c->post_bit_count.stat[1 + i].scale = FE_SCALE_COUNTER; |
4151 | c->post_bit_count.stat[1 + i].uvalue += 100000000; | 4180 | c->post_bit_count.stat[1 + i].uvalue += 100000000; |
4181 | } | ||
4182 | |||
4183 | if (show_per_stats) { | ||
4184 | val = dib8000_read_word(state, per_layer_regs[i].per); | ||
4152 | 4185 | ||
4153 | val = dib8000_read_word(state, per_layer_regs[i].per); | 4186 | c->block_error.stat[1 + i].scale = FE_SCALE_COUNTER; |
4187 | c->block_error.stat[1 + i].uvalue += val; | ||
4154 | 4188 | ||
4155 | c->block_error.stat[1 + i].scale = FE_SCALE_COUNTER; | 4189 | if (!time_us) |
4156 | c->block_error.stat[1 + i].uvalue += val; | 4190 | time_us = dib8000_get_time_us(fe, i); |
4191 | if (time_us) { | ||
4192 | blocks = 1250000UL * 1000000UL; | ||
4193 | do_div(blocks, time_us * 8 * 204); | ||
4194 | c->block_count.stat[0].scale = FE_SCALE_COUNTER; | ||
4195 | c->block_count.stat[0].uvalue += blocks; | ||
4196 | } | ||
4197 | } | ||
4157 | } | 4198 | } |
4158 | return 0; | 4199 | return 0; |
4159 | } | 4200 | } |