Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] dib8000: be sure that stats are available before reading them

On dib8000, the BER statistics are updated on every 1.25e6 bits.
Adjust the code to only update the statistics after having it
done.

Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Acked-by: Patrick Boettcher <pboettcher@kernellabs.com>

+179 -55
+179 -55
drivers/media/dvb-frontends/dib8000.c
··· 119 119 u8 longest_intlv_layer; 120 120 u16 output_mode; 121 121 122 + /* for DVBv5 stats */ 122 123 s64 init_ucb; 124 + unsigned long jiffies_stats; 125 + unsigned long jiffies_stats_layer[3]; 126 + 123 127 #ifdef DIB8000_AGC_FREEZE 124 128 u16 agc1_max; 125 129 u16 agc1_min; 126 130 u16 agc2_max; 127 131 u16 agc2_min; 128 132 #endif 129 - 130 - unsigned long get_stats_time; 131 133 }; 132 134 133 135 enum dib8000_power_mode { ··· 1018 1016 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 1019 1017 1020 1018 dib8000_read_unc_blocks(fe, &ucb); 1019 + 1021 1020 state->init_ucb = -ucb; 1021 + state->jiffies_stats = 0; 1022 + memset(&state->jiffies_stats_layer, 0, 1023 + sizeof(state->jiffies_stats_layer)); 1022 1024 } 1023 1025 1024 1026 static int dib8000_reset(struct dvb_frontend *fe) ··· 3942 3936 return ret; 3943 3937 } 3944 3938 3939 + static u32 dib8000_get_time_us(struct dvb_frontend *fe, int layer) 3940 + { 3941 + struct dib8000_state *state = fe->demodulator_priv; 3942 + struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache; 3943 + int ini_layer, end_layer, i; 3944 + u64 time_us; 3945 + u32 tmp, denom; 3946 + int guard, rate_num, rate_denum, bits_per_symbol, nsegs; 3947 + int interleaving, fft_div; 3948 + 3949 + if (layer >= 0) { 3950 + ini_layer = layer; 3951 + end_layer = layer + 1; 3952 + } else { 3953 + ini_layer = 0; 3954 + end_layer = 3; 3955 + } 3956 + 3957 + switch (c->guard_interval) { 3958 + case GUARD_INTERVAL_1_4: 3959 + guard = 4; 3960 + break; 3961 + case GUARD_INTERVAL_1_8: 3962 + guard = 8; 3963 + break; 3964 + case GUARD_INTERVAL_1_16: 3965 + guard = 16; 3966 + break; 3967 + default: 3968 + case GUARD_INTERVAL_1_32: 3969 + guard = 32; 3970 + break; 3971 + } 3972 + 3973 + switch (c->transmission_mode) { 3974 + case TRANSMISSION_MODE_2K: 3975 + fft_div = 4; 3976 + break; 3977 + case TRANSMISSION_MODE_4K: 3978 + fft_div = 2; 3979 + break; 3980 + default: 3981 + case TRANSMISSION_MODE_8K: 3982 + fft_div = 1; 3983 + break; 3984 + } 3985 + 3986 + denom = 0; 3987 + for (i = ini_layer; i < end_layer; i++) { 3988 + nsegs = c->layer[i].segment_count; 3989 + if (nsegs == 0 || nsegs > 13) 3990 + continue; 3991 + 3992 + switch (c->layer[i].modulation) { 3993 + case DQPSK: 3994 + case QPSK: 3995 + bits_per_symbol = 2; 3996 + break; 3997 + case QAM_16: 3998 + bits_per_symbol = 4; 3999 + break; 4000 + default: 4001 + case QAM_64: 4002 + bits_per_symbol = 6; 4003 + break; 4004 + } 4005 + 4006 + switch (c->layer[i].fec) { 4007 + case FEC_1_2: 4008 + rate_num = 1; 4009 + rate_denum = 2; 4010 + break; 4011 + case FEC_2_3: 4012 + rate_num = 2; 4013 + rate_denum = 3; 4014 + break; 4015 + case FEC_3_4: 4016 + rate_num = 3; 4017 + rate_denum = 4; 4018 + break; 4019 + case FEC_5_6: 4020 + rate_num = 5; 4021 + rate_denum = 6; 4022 + break; 4023 + default: 4024 + case FEC_7_8: 4025 + rate_num = 7; 4026 + rate_denum = 8; 4027 + break; 4028 + } 4029 + 4030 + interleaving = c->layer[i].interleaving; 4031 + 4032 + denom += bits_per_symbol * rate_num * fft_div * nsegs * 384; 4033 + } 4034 + 4035 + /* If all goes wrong, wait for 1s for the next stats */ 4036 + if (!denom) 4037 + return 0; 4038 + 4039 + /* Estimate the period for the total bit rate */ 4040 + time_us = rate_denum * (1008 * 1562500L); 4041 + time_us = time_us + time_us / guard; 4042 + time_us += denom / 2; 4043 + do_div(time_us, denom); 4044 + 4045 + tmp = 1008 * 96 * interleaving; 4046 + time_us += tmp + tmp / guard; 4047 + 4048 + return time_us; 4049 + } 4050 + 3945 4051 static int dib8000_get_stats(struct dvb_frontend *fe, fe_status_t stat) 3946 4052 { 3947 4053 struct dib8000_state *state = fe->demodulator_priv; 3948 4054 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache; 3949 - int i, lock; 3950 - u32 snr, val; 4055 + int i; 4056 + u32 time_us, snr, val; 3951 4057 s32 db; 3952 4058 u16 strength; 3953 4059 ··· 4071 3953 ARRAY_SIZE(strength_to_db_table)) - 131000; 4072 3954 c->strength.stat[0].svalue = db; 4073 3955 4074 - /* Check if 1 second was elapsed */ 4075 - if (!time_after(jiffies, state->get_stats_time)) 4076 - return 0; 4077 - state->get_stats_time = jiffies + msecs_to_jiffies(1000); 4078 - 4079 - /* Get SNR */ 4080 - snr = dib8000_get_snr(fe); 4081 - for (i = 1; i < MAX_NUMBER_OF_FRONTENDS; i++) { 4082 - if (state->fe[i]) 4083 - snr += dib8000_get_snr(state->fe[i]); 4084 - } 4085 - snr = snr >> 16; 4086 - 4087 - if (snr) { 4088 - snr = 10 * intlog10(snr); 4089 - snr = (1000L * snr) >> 24; 4090 - } else { 4091 - snr = 0; 4092 - } 4093 - c->cnr.stat[0].svalue = snr; 4094 - c->cnr.stat[0].scale = FE_SCALE_DECIBEL; 4095 - 4096 - /* UCB/BER measures require lock */ 3956 + /* UCB/BER/CNR measures require lock */ 4097 3957 if (!(stat & FE_HAS_LOCK)) { 3958 + c->cnr.len = 1; 4098 3959 c->block_error.len = 1; 4099 3960 c->post_bit_error.len = 1; 4100 3961 c->post_bit_count.len = 1; 3962 + c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 4101 3963 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 4102 3964 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 4103 3965 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE; 4104 3966 return 0; 4105 3967 } 4106 3968 4107 - /* Get UCB and post-BER measures */ 3969 + /* Check if time for stats was elapsed */ 3970 + if (time_after(jiffies, state->jiffies_stats)) { 3971 + time_us = dib8000_get_time_us(fe, -1); 3972 + state->jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000); 4108 3973 4109 - /* FIXME: need to check if 1.25e6 bits already passed */ 4110 - dib8000_read_ber(fe, &val); 4111 - c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 4112 - c->post_bit_error.stat[0].uvalue += val; 3974 + dprintk("Next all layers stats available in %u us.\n", time_us); 4113 3975 4114 - c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 4115 - c->post_bit_count.stat[0].uvalue += 100000000; 3976 + /* Get SNR */ 3977 + snr = dib8000_get_snr(fe); 3978 + for (i = 1; i < MAX_NUMBER_OF_FRONTENDS; i++) { 3979 + if (state->fe[i]) 3980 + snr += dib8000_get_snr(state->fe[i]); 3981 + } 3982 + snr = snr >> 16; 4116 3983 4117 - dib8000_read_unc_blocks(fe, &val); 4118 - if (val < state->init_ucb) 4119 - state->init_ucb += 1L << 32; 3984 + if (snr) { 3985 + snr = 10 * intlog10(snr); 3986 + snr = (1000L * snr) >> 24; 3987 + } else { 3988 + snr = 0; 3989 + } 3990 + c->cnr.stat[0].svalue = snr; 3991 + c->cnr.stat[0].scale = FE_SCALE_DECIBEL; 4120 3992 4121 - c->block_error.stat[0].scale = FE_SCALE_COUNTER; 4122 - c->block_error.stat[0].uvalue = val + state->init_ucb; 3993 + /* Get UCB and post-BER measures */ 3994 + 3995 + dib8000_read_ber(fe, &val); 3996 + c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER; 3997 + c->post_bit_error.stat[0].uvalue += val; 3998 + 3999 + c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER; 4000 + c->post_bit_count.stat[0].uvalue += 100000000; 4001 + 4002 + dib8000_read_unc_blocks(fe, &val); 4003 + if (val < state->init_ucb) 4004 + state->init_ucb += 1L << 32; 4005 + 4006 + c->block_error.stat[0].scale = FE_SCALE_COUNTER; 4007 + c->block_error.stat[0].uvalue = val + state->init_ucb; 4008 + } 4123 4009 4124 4010 if (state->revision < 0x8002) 4125 4011 return 0; ··· 4133 4011 c->post_bit_count.len = 4; 4134 4012 4135 4013 for (i = 0; i < 3; i++) { 4136 - lock = dib8000_read_word(state, per_layer_regs[i].lock); 4137 - if (lock & 0x01) { 4138 - /* FIXME: need to check if 1.25e6 bits already passed */ 4139 - val = dib8000_read_word(state, per_layer_regs[i].ber); 4140 - c->post_bit_error.stat[1 + i].scale = FE_SCALE_COUNTER; 4141 - c->post_bit_error.stat[1 + i].uvalue += val; 4014 + if (!time_after(jiffies, state->jiffies_stats_layer[i])) 4015 + continue; 4016 + time_us = dib8000_get_time_us(fe, i); 4017 + if (!time_us) 4018 + continue; 4142 4019 4143 - c->post_bit_count.stat[1 + i].scale = FE_SCALE_COUNTER; 4144 - c->post_bit_count.stat[1 + i].uvalue += 100000000; 4020 + state->jiffies_stats_layer[i] = jiffies + msecs_to_jiffies((time_us + 500) / 1000); 4021 + dprintk("Next layer %c stats will be available in %u us\n", 4022 + 'A' + i, time_us); 4145 4023 4146 - /* 4147 - * FIXME: this is refreshed on every second, but a time 4148 - * drift between dib8000 and PC clock may cause troubles 4149 - */ 4150 - val = dib8000_read_word(state, per_layer_regs[i].per); 4024 + val = dib8000_read_word(state, per_layer_regs[i].ber); 4025 + c->post_bit_error.stat[1 + i].scale = FE_SCALE_COUNTER; 4026 + c->post_bit_error.stat[1 + i].uvalue += val; 4151 4027 4152 - c->block_error.stat[1 + i].scale = FE_SCALE_COUNTER; 4153 - c->block_error.stat[1 + i].uvalue += val; 4154 - } 4028 + c->post_bit_count.stat[1 + i].scale = FE_SCALE_COUNTER; 4029 + c->post_bit_count.stat[1 + i].uvalue += 100000000; 4030 + 4031 + val = dib8000_read_word(state, per_layer_regs[i].per); 4032 + 4033 + c->block_error.stat[1 + i].scale = FE_SCALE_COUNTER; 4034 + c->block_error.stat[1 + i].uvalue += val; 4155 4035 } 4156 4036 return 0; 4157 4037 }