| // SPDX-License-Identifier: (GPL-2.0+ OR MIT) |
| /* |
| * Copyright (c) 2019 Amlogic, Inc. All rights reserved. |
| */ |
| |
| #include "addr_dtmb_front_bit.h" |
| /*#include "reg_dtmb.h"*/ |
| |
| #include "demod_func.h" |
| #include "demod_dbg.h" |
| |
| MODULE_PARM_DESC(demod_enable_performance, "\n\t\t demod_enable_performance information"); |
| static int demod_enable_performance = 1; |
| module_param(demod_enable_performance, int, 0644); |
| |
| MODULE_PARM_DESC(demod_sync_count, "\n\t\t timeout debug information"); |
| static int demod_sync_count = 60; |
| module_param(demod_sync_count, int, 0644); |
| |
| MODULE_PARM_DESC(demod_sync_delay_time, "\n\t\t timeout debug information"); |
| static int demod_sync_delay_time = 8; |
| module_param(demod_sync_delay_time, int, 0644); |
| |
| |
| MODULE_PARM_DESC(demod_timeout, "\n\t\t timeout debug information"); |
| static int demod_timeout = 120; |
| module_param(demod_timeout, int, 0644); |
| |
| |
| void dtmb_set_fe_config_modify(unsigned int modify) |
| { |
| union DTMB_SYNC_FE_CONFIG_BITS fe_cofig; |
| |
| fe_cofig.d32 = dtmb_read_reg(DTMB_SYNC_FE_CONFIG); |
| fe_cofig.b.fe_modify = modify; |
| |
| dtmb_write_reg(DTMB_SYNC_FE_CONFIG, fe_cofig.d32); |
| PR_DTMB("set modiy=0x%x,0x%x\n", modify, fe_cofig.d32); |
| } |
| /* formula: fs(MHz) |
| * 2*7.56*2^23/fs/256 |
| * 24MHz: 0x50a3 |
| * 25MHz: 0x4d6a |
| */ |
| void dtmb_clk_set(unsigned int adc_clk) |
| { |
| unsigned int fe_modify = 0x4d6a; |
| |
| if (adc_clk) |
| fe_modify = 3963617280UL / (adc_clk << 3); |
| |
| dtmb_set_fe_config_modify(fe_modify); |
| |
| } |
| |
| static void dtmb_24m_coeff(void) |
| { |
| dtmb_write_reg(DTMB_FRONT_COEF_SET19, 0xebd2530d); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET18, 0x04dad364); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET17, 0x181e0508); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET16, 0x080a031a); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET15, 0x0217161f); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET14, 0x000c0c); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET13, 0x0e3f3334); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET12, 0x2e330310); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET11, 0x08160f3c); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET10, 0x352731); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET9, 0x70101f11); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET8, 0x2d126b5c); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET7, 0x1f); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET6, 0xd4c8ef); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET5, 0x04e013); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET4, 0x46); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET3, 0x3883ee); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET2, 0x37e); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET1, 0x123013); |
| dtmb_write_reg(DTMB_FRONT_ACF_BYPASS, |
| ((dtmb_read_reg(DTMB_FRONT_ACF_BYPASS) & ~0xffffff) |
| | 0x29922b)); |
| } |
| |
| static void dtmb_25m_coeff(void) |
| { |
| dtmb_write_reg(DTMB_FRONT_COEF_SET19, 0x242fde12); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET18, 0x451dce); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET17, 0x051f1a1b); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET16, 0x181c0307); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET15, 0x0809031b); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET14, 0x15161f); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET13, 0x060e0a3e); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET12, 0x06363038); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET11, 0x2d3e0f12); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET10, 0x133c2b); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET9, 0x5f700c1b); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET8, 0x23270b6a); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET7, 0x7e); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET6, 0xf3cbd4); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET5, 0x04f031); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET4, 0x29); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET3, 0x37f3cc); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET2, 0x396); |
| dtmb_write_reg(DTMB_FRONT_COEF_SET1, 0x131036); |
| dtmb_write_reg(DTMB_FRONT_ACF_BYPASS, |
| ((dtmb_read_reg(DTMB_FRONT_ACF_BYPASS) & ~0xffffff) |
| | 0x274217)); |
| } |
| |
| void dtmb_all_reset(struct aml_dtvdemod *demod) |
| { |
| int temp_data = 0; |
| unsigned int reg_val; |
| |
| if (is_meson_txl_cpu()) { |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| /*fix bug 139044: DTMB lost sync*/ |
| /*dtmb_write_reg(DTMB_FRONT_AFIFO_ADC, 0x1f);*/ |
| dtmb_write_reg(DTMB_FRONT_AFIFO_ADC, 0x22); |
| /*modified bu xiaotong*/ |
| dtmb_write_reg(DTMB_CHE_TPS_CONFIG, 0xc00000); |
| dtmb_write_reg(DTMB_CHE_EQ_CONFIG, 0x1a027719); |
| dtmb_write_reg(DTMB_FRONT_AGC_CONFIG1, 0x101a7); |
| /*21bit set ddr access urgent*/ |
| dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x331a31); |
| /*detect 64qam 420 595 problems*/ |
| dtmb_write_reg(DTMB_FRONT_19_CONFIG, 0x300); |
| dtmb_write_reg(DTMB_FRONT_4d_CONFIG, 0x12ffbe0); |
| /*fix fsm b bug*/ |
| dtmb_write_reg(DTMB_FRONT_DEBUG_CFG, 0x5680000); |
| /*fix agc problem,skip warm_up status*/ |
| dtmb_write_reg(DTMB_FRONT_46_CONFIG, 0x1a000f0f); |
| dtmb_write_reg(DTMB_FRONT_ST_FREQ, 0xf2400000); |
| dtmb_clk_set(ADC_CLK_25M); |
| #endif |
| } else if (is_meson_txhd_cpu()) { |
| #ifndef CONFIG_AMLOGIC_REMOVE_OLD |
| /* dtmb_write_reg(DTMB_FRONT_AFIFO_ADC, 0x1f); */ |
| dtmb_write_reg(DTMB_FRONT_AFIFO_ADC, 0x1e); |
| |
| /*demod can't sync when freq offset >1.5KHz for air signal*/ |
| dtmb_write_reg(DTMB_FRONT_DDC_BYPASS, 0x6aaaaa); |
| dtmb_write_reg(DTMB_FRONT_SRC_CONFIG1, 0x13196596); |
| |
| /*modified bu xiaotong*/ |
| dtmb_write_reg(DTMB_CHE_TPS_CONFIG, 0xc00000); |
| dtmb_write_reg(DTMB_CHE_EQ_CONFIG, 0x1a027719); |
| dtmb_write_reg(DTMB_FRONT_AGC_CONFIG1, 0x101a7); |
| /*21bit set ddr access urgent*/ |
| dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x331a31); |
| /*detect 64qam 420 595 problems*/ |
| dtmb_write_reg(DTMB_FRONT_19_CONFIG, 0x300); |
| dtmb_write_reg(DTMB_FRONT_4d_CONFIG, 0x12ffbe0); |
| /*fix fsm b bug*/ |
| dtmb_write_reg(DTMB_FRONT_DEBUG_CFG, 0x5680000); |
| /*fix agc problem,skip warm_up status*/ |
| dtmb_write_reg(DTMB_FRONT_46_CONFIG, 0x1a000f0f); |
| dtmb_write_reg(DTMB_FRONT_ST_FREQ, 0xf2400000); |
| dtmb_clk_set(ADC_CLK_24M); |
| dtmb_write_reg(DTMB_CHE_EQ_CONFIG, 0x1b027719); |
| #endif |
| } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) { |
| if (demod_get_adc_clk(demod) == ADC_CLK_24M) { |
| dtmb_write_reg(DTMB_FRONT_DDC_BYPASS, 0x6aaaaa); |
| dtmb_write_reg(DTMB_FRONT_SRC_CONFIG1, 0x13196596); |
| dtmb_write_reg(0x5b, 0x50a30a25); |
| dtmb_24m_coeff(); |
| } else if (demod_get_adc_clk(demod) == ADC_CLK_25M) { |
| dtmb_write_reg(DTMB_FRONT_DDC_BYPASS, 0x62c1a5); |
| dtmb_write_reg(DTMB_FRONT_SRC_CONFIG1, 0x131a747d); |
| dtmb_write_reg(0x5b, 0x4d6a0a25); |
| dtmb_25m_coeff(); |
| } |
| |
| /*for timeshift mosaic issue |
| *bit 30:ts_sync_sel,0=ts_sync,1=searched ts_sync |
| */ |
| dtmb_write_reg(DTMB_FRONT_4e_CONFIG, 0x656cf604); |
| |
| /*delay fec lock & make fec lost faster |
| *to prevent eq is confused by signal |
| */ |
| dtmb_write_reg(DTMB_FRONT_DEBUG_CFG, 0x5480000); |
| /*reduce fec lost timeout*/ |
| dtmb_write_reg(DTMB_FRONT_19_CONFIG, 0x30); |
| |
| reg_val = dtmb_read_reg(DTMB_TOP_CTRL_TPS); |
| /* for Task 19:Switch mode and modulation parameters test |
| * spectrum: 0=normal, 1=inverted |
| */ |
| if (demod->demod_status.spectrum == 0) |
| reg_val |= 0x4; |
| else if (demod->demod_status.spectrum == 1) |
| reg_val &= ~0x4; |
| dtmb_write_reg(DTMB_TOP_CTRL_TPS, reg_val); |
| } else { |
| dtmb_write_reg(DTMB_FRONT_AGC_CONFIG1, 0x10127); |
| dtmb_write_reg(DTMB_CHE_IBDFE_CONFIG6, 0x943228cc); |
| dtmb_write_reg(DTMB_CHE_IBDFE_CONFIG7, 0xc09aa8cd); |
| dtmb_write_reg(DTMB_CHE_FD_TD_COEFF, 0x0); |
| dtmb_write_reg(DTMB_CHE_EQ_CONFIG, 0x9dc59); |
| /*0x2 is auto,0x406 is invert spectrum*/ |
| if (demod->demod_status.spectrum == 0) |
| dtmb_write_reg(DTMB_TOP_CTRL_TPS, 0x406); |
| else if (demod->demod_status.spectrum == 1) |
| dtmb_write_reg(DTMB_TOP_CTRL_TPS, 0x402); |
| else |
| dtmb_write_reg(DTMB_TOP_CTRL_TPS, 0x2); |
| |
| PR_DTMB("spectrum is %d\n", demod->demod_status.spectrum); |
| dtmb_write_reg(DTMB_TOP_CTRL_FEC, 0x41444400); |
| dtmb_write_reg(DTMB_TOP_CTRL_INTLV_TIME, 0x180300); |
| dtmb_write_reg(DTMB_FRONT_DDC_BYPASS, 0x662ca0); |
| dtmb_write_reg(DTMB_FRONT_AFIFO_ADC, 0x29); |
| dtmb_write_reg(DTMB_FRONT_DC_HOLD, 0xa1066); |
| /*cci para*/ |
| dtmb_write_reg(DTMB_CHE_M_CCI_THR_CONFIG3, 0x80201f6); |
| dtmb_write_reg(DTMB_CHE_M_CCI_THR_CONFIG2, 0x3f20080); |
| dtmb_write_reg(DTMB_CHE_TPS_CONFIG, 0xc00000); |
| dtmb_write_reg(DTMB_TOP_CTRL_AGC, 0x3); |
| dtmb_write_reg(DTMB_TOP_CTRL_TS_SFO_CFO, 0x20403006); |
| dtmb_write_reg(DTMB_FRONT_AGC_CONFIG2, 0x7200a16); |
| dtmb_write_reg(DTMB_FRONT_DEBUG_CFG, 0x1e00000); |
| dtmb_write_reg(DTMB_TOP_CTRL_ENABLE, 0x7fffff); |
| /*close ts3 timing loop*/ |
| dtmb_write_reg(DTMB_TOP_CTRL_DAGC_CCI, 0x305); |
| /*dektec card issue,close f case snr drop*/ |
| dtmb_write_reg(DTMB_CHE_MC_SC_TIMING_POWTHR, 0xc06100a); |
| if (demod_enable_performance) { |
| dtmb_write_reg(DTMB_CHE_IBDFE_CONFIG1, 0x4040002); |
| temp_data = dtmb_read_reg(DTMB_CHE_FD_TD_COEFF); |
| temp_data = (temp_data & ~0x3fff)|(0x241f & 0x3fff); |
| temp_data = temp_data | (1<<21); |
| /*Set freeze_mode and reset coeff*/ |
| dtmb_write_reg(DTMB_CHE_FD_TD_COEFF, temp_data); |
| temp_data = temp_data & ~(1<<21); |
| /*Set freeze_mode and reset coeff*/ |
| dtmb_write_reg(DTMB_CHE_FD_TD_COEFF, temp_data); |
| } |
| } |
| |
| /*for non-standard signal, |
| *ignore calculatiing amplitude tps(transport parameter signalling) |
| */ |
| dtmb_write_reg(DTMB_CHE_IBDFE_CONF0, |
| dtmb_read_reg(DTMB_CHE_IBDFE_CONF0) & 0xfffff0ff); |
| |
| /*increase cfo track val to avoid dtmb playing is not smooth |
| *when temperature is over 80 degree Celsius |
| */ |
| dtmb_write_reg(DTMB_SYNC_TRACK_CFO_MAX, |
| (dtmb_read_reg(DTMB_SYNC_TRACK_CFO_MAX) & ~0xff) | 0x1f); |
| } |
| |
| void dtmb_initial(struct aml_dtvdemod *demod) |
| { |
| struct amldtvdemod_device_s *devp = (struct amldtvdemod_device_s *)demod->priv; |
| |
| /* dtmb_write_reg(0x049, memstart); //only for init */ |
| dtmb_register_reset(); |
| |
| if (devp->data->hw_ver == DTVDEMOD_HW_T3) { |
| clear_ddr_bus_data(); |
| dtmb_write_reg(0x7, 0xffffff); |
| //dtmb_write_reg(0x47, 0x133220); |
| dtmb_write_reg_bits(0x47, 0x0, 22, 1); |
| dtmb_write_reg_bits(0x47, 0x0, 23, 1); |
| } |
| dtmb_all_reset(demod); |
| } |
| |
| int check_dtmb_fec_lock(void) |
| { |
| int fec_lock, snr, status; |
| /*fec_lock = (dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) >> 14) & 0x1;*/ |
| fec_lock = dtmb_reg_r_fec_lock(); |
| /*snr = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) & 0x3fff;*/ |
| snr = dtmb_reg_r_che_snr(); |
| if (fec_lock && (snr > 4)) |
| status = 1; |
| else |
| status = 0; |
| return status; |
| } |
| |
| int check_dtmb_mobile_det(void) |
| { |
| int mobile_det = 0; |
| |
| mobile_det = (dtmb_read_reg(DTMB_TOP_CTRL_SYS_OFDM_CNT) >> 8) & 0x7ffff; |
| |
| return mobile_det; |
| } |
| |
| int dtmb_information(struct seq_file *seq) |
| { |
| int tps, snr, fec_lock, fec_bch_add, fec_ldpc_unc_acc, fec_ldpc_it_avg, che_snr; |
| unsigned int buf[3]; |
| |
| tps = dtmb_read_reg(DTMB_TOP_CTRL_CHE_WORKCNT); |
| |
| che_snr = dtmb_reg_r_che_snr(); |
| snr = che_snr; |
| snr = convert_snr(snr); |
| /* if (che_snr >= 8192) */ |
| /* che_snr = che_snr - 16384;*/ |
| /* snr = che_snr / 32;*/ |
| /* snr = 10*log10(snr)-6; */ |
| /* fec_lock = (dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR) >> 14) & 0x1; */ |
| fec_lock = dtmb_reg_r_fec_lock(); |
| fec_bch_add = dtmb_reg_r_bch(); |
| fec_ldpc_unc_acc = dtmb_read_reg(DTMB_TOP_FEC_LDPC_UNC_ACC); |
| fec_ldpc_it_avg = dtmb_read_reg(DTMB_TOP_FEC_LDPC_IT_AVG); |
| dtmb_read_agc(DTMB_D9_ALL, &buf[0]); |
| |
| if (seq) { |
| seq_printf(seq, "[FSM] : %x %x %x %x\n", |
| dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0), |
| dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE1), |
| dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE2), |
| dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE3)); |
| |
| seq_printf(seq, "[AGC]: agc_power %d,agc_if_gain %d,agc_rf_gain %d,", |
| (-((buf[2]) / 16)), buf[0], buf[1]); |
| |
| seq_printf(seq, "dagc_power %3d,dagc_gain %3d mobi_det_power %d\n", |
| ((dtmb_read_reg(DTMB_TOP_FRONT_DAGC) >> 0) & 0xff), |
| ((dtmb_read_reg(DTMB_TOP_FRONT_DAGC) >> 8) & 0xfff), |
| (dtmb_read_reg(DTMB_TOP_CTRL_SYS_OFDM_CNT) >> 8) & 0x7ffff); |
| seq_printf(seq, "[TPS] SC or MC %2d,f_r %2d qam_nr %2d ", |
| (dtmb_read_reg(DTMB_TOP_CHE_OBS_STATE1) >> 1) & 0x1, |
| (tps >> 22) & 0x1, (tps >> 21) & 0x1); |
| seq_printf(seq, "intlv %2d,cr %2d constl %2d\n", |
| (tps >> 20) & 0x1, |
| (tps >> 18) & 0x3, (tps >> 16) & 0x3); |
| |
| seq_printf(seq, "[dtmb] snr is %d,fec_lock is %d,fec_bch_add is %d,", |
| snr, fec_lock, fec_bch_add); |
| seq_printf(seq, "fec_ldpc_unc_acc is %d ,fec_ldpc_it_avg is %d\n", |
| fec_ldpc_unc_acc, |
| fec_ldpc_it_avg / 256); |
| seq_puts(seq, "------------------------------------------------------------\n"); |
| } else { |
| PR_DTMB("[FSM] : %x %x %x %x\n", |
| dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0), |
| dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE1), |
| dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE2), |
| dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE3)); |
| |
| PR_DTMB("[AGC]: agc_power %d,agc_if_gain %d,agc_rf_gain %d,", (-((buf[2]) / 16)), |
| buf[0], buf[1]); |
| |
| PR_DTMB("dagc_power %3d,dagc_gain %3d mobi_det_power %d\n", |
| ((dtmb_read_reg(DTMB_TOP_FRONT_DAGC) >> 0) & 0xff), |
| ((dtmb_read_reg(DTMB_TOP_FRONT_DAGC) >> 8) & 0xfff), |
| (dtmb_read_reg(DTMB_TOP_CTRL_SYS_OFDM_CNT) >> 8) & 0x7ffff); |
| PR_DTMB("[TPS] SC or MC %2d,f_r %2d qam_nr %2d ", |
| (dtmb_read_reg(DTMB_TOP_CHE_OBS_STATE1) >> 1) & 0x1, |
| (tps >> 22) & 0x1, (tps >> 21) & 0x1); |
| PR_DTMB("intlv %2d,cr %2d constl %2d\n", |
| (tps >> 20) & 0x1, |
| (tps >> 18) & 0x3, (tps >> 16) & 0x3); |
| |
| PR_DTMB("[dtmb] snr is %d,fec_lock is %d,fec_bch_add is %d,", |
| snr, fec_lock, fec_bch_add); |
| PR_DTMB("fec_ldpc_unc_acc is %d ,fec_ldpc_it_avg is %d\n", |
| fec_ldpc_unc_acc, |
| fec_ldpc_it_avg / 256); |
| PR_DTMB("------------------------------------------------------------\n"); |
| } |
| |
| return 0; |
| } |
| |
| int dtmb_check_cci(void) |
| { |
| int cci_det = 0; |
| |
| cci_det = |
| ((dtmb_read_reg(DTMB_TOP_SYNC_CCI_NF2_POSITION) >> 22) |
| & 0x3); |
| |
| if (cci_det > 0) { |
| PR_DTMB("find cci\n"); |
| dtmb_write_reg(DTMB_CHE_CCIDET_CONFIG, 0x20210290); |
| dtmb_write_reg(DTMB_CHE_M_CCI_THR_CONFIG3, 0x20081f6); |
| dtmb_write_reg(DTMB_CHE_M_CCI_THR_CONFIG2, 0x3f08020); |
| } |
| return cci_det; |
| } |
| |
| int dtmb_bch_check(void) |
| { |
| int fec_bch_add, i; |
| char *info1 = "fec lock,but bch add ,need reset,wait not to reset"; |
| char *info2 = "fec lock,but bch add ,need reset,now is lock"; |
| |
| fec_bch_add = dtmb_reg_r_bch(); |
| |
| /*PR_DTMB("[debug]fec lock,fec_bch_add is %d\n", fec_bch_add);*/ |
| msleep(100); |
| if ((dtmb_reg_r_bch()-fec_bch_add) >= 50) { |
| PR_DTMB("%s\n", info1); |
| dtmb_reset(); |
| for (i = 0; i < 30; i++) { |
| msleep(100); |
| if (check_dtmb_fec_lock() == 1) { |
| PR_DTMB("%s\n", info2); |
| return 0; |
| } |
| } |
| } |
| return 0; |
| } |
| |
| int dtmb_constell_check(void) |
| { |
| int constell; |
| |
| constell = dtmb_read_reg(DTMB_TOP_CTRL_CHE_WORKCNT)>>16 & 0x3; |
| if (constell == 0)/*4qam*/ |
| dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x333221); |
| else if (constell == 1)/*16qam*/ |
| dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x332821); |
| else if (constell == 2)/*32qam*/ |
| dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x331e21); |
| else if (constell == 3)/*64qam*/ |
| dtmb_write_reg(DTMB_FRONT_47_CONFIG, 0x331a31); |
| |
| return 0; |
| } |
| |
| |
| int dtmb_check_fsm(void) |
| { |
| int tmp, fsm_status, i, has_signal; |
| |
| tmp = dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0); |
| fsm_status = tmp&0xffffffff; |
| has_signal = 0; |
| PR_DTMB("fsm_status is %x\n", fsm_status); |
| for (i = 0 ; i < 8 ; i++) { |
| if (((fsm_status >> (i*4)) & 0xf) > 3) { |
| /*has signal*/ |
| /* PR_DTMB("has signal\n");*/ |
| has_signal = 1; |
| } |
| } |
| return has_signal; |
| |
| } |
| |
| int patch_ts3(int delay1_us, int delay2_us) |
| { |
| if (((dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0)&0xf) == 0x7)&1) { |
| dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x300f); |
| dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x310f); |
| msleep(delay1_us); |
| dtmb_write_reg(DTMB_TOP_CTRL_ENABLE, 0xffdfff); |
| dtmb_write_reg(DTMB_TOP_CTRL_ENABLE, 0xffffff); |
| dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x3110); |
| dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x3010); |
| dtmb_write_reg(DTMB_TOP_CTRL_FSM, 0x3000); |
| return 1; |
| } else |
| return 0; |
| } |
| |
| |
| int read_cfo_all(void) |
| { |
| int icfo_all, fcfo_all; |
| |
| icfo_all = dtmb_read_reg(DTMB_TOP_CTRL_ICFO_ALL) & 0xfffff; |
| fcfo_all = dtmb_read_reg(DTMB_TOP_CTRL_FCFO_ALL) & 0x3fff; |
| if (icfo_all > (1 << 19)) |
| icfo_all = icfo_all - (1 << 20); |
| if (fcfo_all > (1 << 13)) |
| fcfo_all = fcfo_all - (1 << 14); |
| |
| return (int)(icfo_all*4+fcfo_all); |
| |
| } |
| |
| |
| int dtmb_v3_soft_sync(int cfo_init) |
| { |
| |
| /* int cfo_all;*/ |
| /* int cfo_setting;*/ |
| |
| if (cfo_init == 0) { |
| cfo_init = patch_ts3(11, 0); |
| #if 0 |
| if (cfo_init == 1) { |
| cfo_all = read_cfo_all(); |
| cfo_setting = dtmb_read_reg(DTMB_FRONT_DDC_BYPASS); |
| dtmb_write_reg(DTMB_FRONT_DDC_BYPASS, |
| cfo_setting+cfo_all); |
| dtmb_write_reg(DTMB_TOP_CTRL_LOOP, 0x3); |
| dtmb_reset(); |
| } |
| #endif |
| } |
| return cfo_init; |
| |
| } |
| |
| int dtmb_check_status_gxtv(struct dvb_frontend *fe) |
| { |
| struct aml_dtvdemod *demod = (struct aml_dtvdemod *)fe->demodulator_priv; |
| int local_state; |
| int time_cnt;/* cci_det, src_config;*/ |
| int cfo_init, count; |
| |
| dtmb_information(NULL); |
| time_cnt = 0; |
| local_state = 0; |
| cfo_init = 0; |
| if (check_dtmb_fec_lock() != 1) { |
| dtmb_register_reset(); |
| dtmb_all_reset(demod); |
| count = 15; |
| while ((count) && |
| ((dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0)&0xf) < 0x6)) { |
| msleep(20); |
| count--; |
| } |
| |
| count = demod_sync_count; |
| while ((count) && (cfo_init == 0)) { |
| |
| cfo_init = dtmb_v3_soft_sync(cfo_init); |
| |
| msleep(demod_sync_delay_time); |
| count--; |
| } |
| if ((cfo_init == 0) && |
| ((dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0)&0xf) <= 7)) { |
| PR_DTMB("over 400ms,status is %x, need reset\n", |
| (dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0)&0xf)); |
| return 0; |
| } |
| while ((time_cnt < 10) && (check_dtmb_fec_lock() != 1)) { |
| msleep(demod_timeout); |
| time_cnt++; |
| local_state = AMLOGIC_DTMB_STEP3; |
| dtmb_information(NULL); |
| dtmb_check_cci(); |
| if (time_cnt > 8) |
| PR_DTMB |
| ("* local_state = %d\n", local_state); |
| } |
| if (time_cnt >= 10 && (check_dtmb_fec_lock() != 1)) { |
| local_state = AMLOGIC_DTMB_STEP4; |
| time_cnt = 0; |
| PR_DTMB |
| ("*all reset,timeout is %d\n", demod_timeout); |
| } |
| } else { |
| dtmb_check_cci(); |
| dtmb_bch_check(); |
| #if 0 |
| cci_det = dtmb_check_cci(); |
| if ((check_dtmb_mobile_det() <= demod_mobile_power) |
| && (cci_det == 0)) { |
| /* open */ |
| src_config = (dtmb_read_reg(DTMB_FRONT_SRC_CONFIG1)); |
| dtmb_write_reg(DTMB_FRONT_SRC_CONFIG1, |
| src_config & (~(0x1 << 28))); |
| } else { |
| /* close */ |
| src_config = (dtmb_read_reg(DTMB_FRONT_SRC_CONFIG1)); |
| dtmb_write_reg(DTMB_FRONT_SRC_CONFIG1, |
| src_config | (0x1 << 28)); |
| } |
| #endif |
| } |
| if (check_dtmb_fec_lock() == 1) |
| dtmb_write_reg(DTMB_TOP_CTRL_LOOP, 0xf); |
| return 0; |
| } |
| |
| |
| int dtmb_check_status_txl(struct dvb_frontend *fe) |
| { |
| struct aml_dtvdemod *demod = (struct aml_dtvdemod *)fe->demodulator_priv; |
| int time_cnt; |
| |
| time_cnt = 0; |
| dtmb_information(NULL); |
| if (check_dtmb_fec_lock() != 1) { |
| while ((time_cnt < 10) && (check_dtmb_fec_lock() != 1)) { |
| msleep(demod_timeout); |
| time_cnt++; |
| dtmb_information(NULL); |
| if (((dtmb_read_reg(DTMB_TOP_CTRL_CHE_WORKCNT) |
| >> 21) & 0x1) == 0x1) { |
| PR_DTMB("4qam-nr,need set spectrum\n"); |
| if (demod->demod_status.spectrum == 1) { |
| dtmb_write_reg |
| (DTMB_TOP_CTRL_TPS, 0x1010406); |
| } else if (demod->demod_status.spectrum == 0) { |
| dtmb_write_reg |
| (DTMB_TOP_CTRL_TPS, 0x1010402); |
| } else { |
| dtmb_write_reg |
| (DTMB_TOP_CTRL_TPS, 0x1010002); |
| } |
| } |
| if (time_cnt > 8) |
| PR_DTMB("* time_cnt = %d\n", time_cnt); |
| } |
| if (time_cnt >= 10 && (check_dtmb_fec_lock() != 1)) { |
| time_cnt = 0; |
| dtmb_register_reset(); |
| dtmb_all_reset(demod); |
| if (demod->demod_status.spectrum == 0) |
| demod->demod_status.spectrum = 1; |
| else |
| demod->demod_status.spectrum = 0; |
| PR_DTMB("*all reset,timeout is %d\n", demod_timeout); |
| } |
| } else { |
| dtmb_bch_check(); |
| dtmb_constell_check(); |
| } |
| return 0; |
| } |
| |
| #ifdef DVB_CORE_ORI |
| |
| |
| |
| void dtmb_no_signal_check_v3(struct aml_dtvdemod *demod) |
| { |
| |
| if (((dtmb_read_reg(DTMB_TOP_CTRL_CHE_WORKCNT) |
| >> 21) & 0x1) == 0x1) { |
| PR_DTMB("4qam-nr,need set spectrum\n"); |
| if (demod->demod_status.spectrum == 1) { |
| dtmb_write_reg |
| (DTMB_TOP_CTRL_TPS, 0x1010406); |
| } else if (demod->demod_status.spectrum == 0) { |
| dtmb_write_reg |
| (DTMB_TOP_CTRL_TPS, 0x1010402); |
| } else { |
| dtmb_write_reg |
| (DTMB_TOP_CTRL_TPS, 0x1010002); |
| } |
| } |
| |
| } |
| |
| void dtmb_no_signal_check_finishi_v3(struct aml_dtvdemod *demod) |
| { |
| dtmb_register_reset(); |
| dtmb_all_reset(demod); |
| if (demod->demod_status.spectrum == 0) |
| demod->demod_status.spectrum = 1; |
| else |
| demod->demod_status.spectrum = 0; |
| |
| } |
| #endif |
| |
| void dtmb_reset(void) |
| { |
| union DTMB_TOP_CTRL_SW_RST_BITS sw_rst; |
| |
| sw_rst.b.ctrl_sw_rst = 1; |
| sw_rst.b.ctrl_sw_rst_noreg = 1; |
| dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32); |
| sw_rst.b.ctrl_sw_rst = 0; |
| sw_rst.b.ctrl_sw_rst_noreg = 0; |
| dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32); |
| } |
| |
| void dtmb_register_reset(void) |
| { |
| union DTMB_TOP_CTRL_SW_RST_BITS sw_rst; |
| sw_rst.b.ctrl_sw_rst = 1; |
| dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32); |
| sw_rst.b.ctrl_sw_rst = 0; |
| dtmb_write_reg(DTMB_TOP_CTRL_SW_RST, sw_rst.d32); |
| } |
| |
| int dtmb_set_ch(struct aml_dtvdemod *demod, |
| struct aml_demod_dtmb *demod_dtmb) |
| { |
| int ret = 0; |
| u8 demod_mode; |
| u8 bw, sr, ifreq, agc_mode; |
| u32 ch_freq; |
| |
| bw = demod_dtmb->bw; |
| sr = demod_dtmb->sr; |
| ifreq = demod_dtmb->ifreq; |
| agc_mode = demod_dtmb->agc_mode; |
| ch_freq = demod_dtmb->ch_freq; |
| demod_mode = demod_dtmb->dat0; |
| demod->demod_status.ch_mode = demod_dtmb->mode; /* TODO */ |
| demod->demod_status.agc_mode = agc_mode; |
| demod->demod_status.ch_freq = ch_freq; |
| demod->demod_status.ch_bw = (8 - bw) * 1000; |
| dtmb_initial(demod); |
| PR_DTMB("DTMB mode\n"); |
| return ret; |
| } |
| |
| void dtmb_set_mem_st(int mem_start) |
| { |
| PR_DTMB("[im]memstart is %x\n", mem_start); |
| dtmb_write_reg(DTMB_FRONT_MEM_ADDR, mem_start); |
| PR_DTMB("[dtmb]mem_buf is 0x%x\n", dtmb_read_reg(DTMB_FRONT_MEM_ADDR)); |
| } |
| |
| int dtmb_read_agc(enum REG_DTMB_D9 type, unsigned int *buf) |
| { |
| union DTMB_TOP_FRONT_AGC_BITS rval; |
| |
| rval.d32 = dtmb_read_reg(DTMB_TOP_FRONT_AGC); |
| |
| /*PR_DTMB("%s:type=%d,val=0x%x\n", __func__, type, rval.d32);*/ |
| /*PR_DTMB("if=0x%x,rf=0x%x,pw=0x%x", rval.b.front_agc_if_gain,*/ |
| /* rval.b.front_agc_rf_gain,*/ |
| /* rval.b.front_agc_power);*/ |
| switch (type) { |
| case DTMB_D9_IF_GAIN: |
| *buf = rval.b.front_agc_if_gain; |
| break; |
| case DTMB_D9_RF_GAIN: |
| *buf = rval.b.front_agc_rf_gain; |
| break; |
| case DTMB_D9_POWER: |
| *buf = rval.b.front_agc_power; |
| break; |
| case DTMB_D9_ALL: |
| buf[0] = rval.b.front_agc_if_gain; |
| buf[1] = rval.b.front_agc_rf_gain; |
| buf[2] = rval.b.front_agc_power; |
| break; |
| } |
| |
| return 0; |
| |
| } |
| |
| unsigned int dtmb_reg_r_fec_lock(void) |
| { |
| |
| union DTMB_TOP_FEC_LOCK_SNR_BITS rval; |
| unsigned int fec_lock; |
| |
| rval.d32 = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR); |
| |
| if (is_meson_gxtvbb_cpu()) |
| fec_lock = rval.b_v2.fec_lock; |
| else |
| fec_lock = rval.b.fec_lock; |
| |
| return fec_lock; |
| } |
| unsigned int dtmb_reg_r_che_snr(void) |
| { |
| union DTMB_TOP_FEC_LOCK_SNR_BITS rval; |
| unsigned int che_snr; |
| |
| rval.d32 = dtmb_read_reg(DTMB_TOP_FEC_LOCK_SNR); |
| |
| if (is_meson_gxtvbb_cpu()) |
| che_snr = rval.b_v2.che_snr; |
| else |
| che_snr = rval.b.che_snr; |
| |
| return che_snr; |
| |
| } |
| |
| unsigned int dtmb_reg_r_bch(void) |
| { |
| return dtmb_read_reg(DTMB_TOP_FEC_BCH_ACC); |
| } |
| |
| /*move from dvb-core dvb_frontend.c dvb_frontend_swzigzag*/ |
| /*1: timeout;2:have signal*/ |
| unsigned int dtmb_detect_first(void) |
| { |
| int has_signal, i; |
| unsigned int dtmb_status; |
| |
| unsigned int timeout = 0; |
| |
| PR_DTMB("%s\n", __func__); |
| /*printk("k:%s\n",__func__);*/ |
| |
| has_signal = 0; |
| msleep(200); |
| |
| /*fsm status is 4,maybe analog signal*/ |
| dtmb_status = dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0); |
| PR_DTMB("fsm_status is %x\n", dtmb_status); |
| |
| for (i = 0 ; i < 8 ; i++) { |
| if (((dtmb_status >> (i*4)) & 0xf) > 4) { |
| /*has signal*/ |
| /* dprintk("has signal\n");*/ |
| has_signal = 0x1; |
| } |
| } |
| |
| if (has_signal == 0x1) { |
| /*fsm status is 6,digital signal*/ |
| /*fsm (1->4) 30ms,(4->5) 20ms,*/ |
| /*(5->6) 10ms,(6->7) 75ms,*/ |
| /*(7->8) 8ms,(8->9) 55ms, (9->a) 350ms*/ |
| msleep(500); |
| dtmb_status = dtmb_read_reg(DTMB_TOP_CTRL_FSM_STATE0); |
| PR_DTMB("fsm_status2 is %x\n", dtmb_status); |
| for (i = 0 ; i < 8 ; i++) { |
| if (((dtmb_status >> (i*4)) |
| & 0xf) > 6) { |
| /*has signal*/ |
| /* dprintk("has signal\n");*/ |
| has_signal = 0x3; |
| } |
| } |
| } |
| |
| PR_DTMB("[DTV]has_signal is %d\n", has_signal); |
| if ((has_signal == 0) || (has_signal == 0x1)) { |
| //timeout = 1; /*FE_TIMEDOUT;*/ |
| timeout = 0; /*FE_TIMEDOUT;*/ |
| PR_DTMB("\t timeout\n"); |
| |
| } else { |
| /*timeout = 2; *//*have signal*/ |
| PR_DTMB("\thave signal\n"); |
| } |
| |
| return timeout; |
| } |