aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends/dib8000.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2013-12-17 09:34:22 -0500
committerMauro Carvalho Chehab <m.chehab@samsung.com>2013-12-19 05:17:47 -0500
commit0400c5354ad09bf4c754132992bdde9ef3dbefcd (patch)
tree5f84117c9f3ec989e83a1cb14487a689e76a5627 /drivers/media/dvb-frontends/dib8000.c
parent704f01bbc7e41f4210fe9fa58da511ad3369b70b (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.c109
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
1028static int dib8000_reset(struct dvb_frontend *fe) 1032static 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}