377 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			377 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | /****************************************************************************
 | ||
|  | 
 | ||
|  | Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED. | ||
|  | 
 | ||
|  | This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT | ||
|  | be copied by any method or incorporated into another program without | ||
|  | the express written consent of Aerospace C.Power. This Information or any portion | ||
|  | thereof remains the property of Aerospace C.Power. The Information contained herein | ||
|  | is believed to be accurate and Aerospace C.Power assumes no responsibility or | ||
|  | liability for its use in any way and conveys no license or title under | ||
|  | any patent or copyright and makes no representation or warranty that this | ||
|  | Information is free from patent or copyright infringement. | ||
|  | 
 | ||
|  | ****************************************************************************/ | ||
|  | #include "chip_reg_base.h"
 | ||
|  | #include "hw_reg_api.h"
 | ||
|  | #include "iot_errno_api.h"
 | ||
|  | #include "phy_pm.h"
 | ||
|  | #include "phy_bb.h"
 | ||
|  | #include "granite_reg.h"
 | ||
|  | #include "iot_io.h"
 | ||
|  | #include "phy_reg.h"
 | ||
|  | #include "iot_config.h"
 | ||
|  | #include "phy_dfe_reg.h"
 | ||
|  | #include "phy_ana.h"
 | ||
|  | #include "hw_phy_api.h"
 | ||
|  | #include "ahb.h"
 | ||
|  | #include "phy_tx_reg.h"
 | ||
|  | 
 | ||
|  | /**
 | ||
|  | * don't case for now, when need do Low-power, | ||
|  | * need analog co-workers check it. | ||
|  | **/ | ||
|  | void phy_pm_bias_sel_set(phy_pm_bias_sel_id sel_ic) | ||
|  | { | ||
|  |     (void)sel_ic; | ||
|  | } | ||
|  | 
 | ||
|  | void phy_pm_bias_adj_set( \ | ||
|  |     phy_pm_bias_adj_id adj_id, \ | ||
|  |     phy_pm_bias_adj_current_id current_id) | ||
|  | { | ||
|  | #if HW_PLATFORM == HW_PLATFORM_SILICON
 | ||
|  |     /* bias current */ | ||
|  |     if(adj_id == PHY_PM_BIAS_ADJ_IR) | ||
|  |     { | ||
|  |         switch(current_id) | ||
|  |         { | ||
|  |             case PHY_PM_BIAS_ADJ_31P25UA: | ||
|  |                 /* bit0 */ | ||
|  |                 phy_ana_bias_ir0_cfg(0); | ||
|  |                 /* bit1 */ | ||
|  |                 phy_ana_bias_ir1_cfg(0); | ||
|  |                 break; | ||
|  |             case PHY_PM_BIAS_ADJ_25UA: | ||
|  |                 /* bit0 */ | ||
|  |                 phy_ana_bias_ir0_cfg(BIAS_ADJ_IR25U_BIT0_MASK); | ||
|  |                 /* bit1 */ | ||
|  |                 phy_ana_bias_ir1_cfg(0); | ||
|  |                 break; | ||
|  |             case PHY_PM_BIAS_ADJ_18P75UA: | ||
|  |                 /* bit0 */ | ||
|  |                 phy_ana_bias_ir0_cfg(BIAS_ADJ_IR25U_BIT0_MASK); | ||
|  |                 /* bit1 */ | ||
|  |                 phy_ana_bias_ir1_cfg(BIAS_ADJ_IR25U_BIT1_MASK); | ||
|  |                 break; | ||
|  |             default: | ||
|  |                 break; | ||
|  |         } | ||
|  |     } | ||
|  |     else if(adj_id == PHY_PM_BIAS_ADJ_IC) | ||
|  |     { | ||
|  |         switch(current_id) | ||
|  |         { | ||
|  |             case PHY_PM_BIAS_ADJ_31P25UA: | ||
|  |                 /* bit0 */ | ||
|  |                 phy_ana_bias_ic0_cfg(0); | ||
|  |                 /* bit1 */ | ||
|  |                 phy_ana_bias_ic1_cfg(0); | ||
|  |                 break; | ||
|  |             case PHY_PM_BIAS_ADJ_25UA: | ||
|  |                 /* bit0 */ | ||
|  |                 phy_ana_bias_ic0_cfg(BIAS_ADJ_IC25U_BIT0_MASK); | ||
|  |                 /* bit1 */ | ||
|  |                 phy_ana_bias_ic1_cfg(0); | ||
|  |                 break; | ||
|  |             case PHY_PM_BIAS_ADJ_18P75UA: | ||
|  |                 /* bit0 */ | ||
|  |                 phy_ana_bias_ic0_cfg(BIAS_ADJ_IC25U_BIT0_MASK); | ||
|  |                 /* bit1 */ | ||
|  |                 phy_ana_bias_ic1_cfg(BIAS_ADJ_IC25U_BIT1_MASK); | ||
|  |                 break; | ||
|  |             default: | ||
|  |                 break; | ||
|  |         } | ||
|  |     } | ||
|  | #else
 | ||
|  |     (void)adj_id; | ||
|  |     (void)current_id; | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | void phy_bias_init_lic_io() | ||
|  | { | ||
|  | } | ||
|  | 
 | ||
|  | void phy_bias_txrx_set() | ||
|  | { | ||
|  | #if PHY_BIAS_ADJUST_AUTO_EN == 0
 | ||
|  |     /* config bias sel to 25uA*/ | ||
|  |     phy_pm_bias_sel_set(PHY_PM_BIAS_SEL_25UA); | ||
|  |     /* config bias adj to 18.75uA */ | ||
|  |     phy_pm_bias_adj_set(PHY_PM_BIAS_ADJ_IR, PHY_PM_BIAS_ADJ_18P75UA); | ||
|  |     phy_pm_bias_adj_set(PHY_PM_BIAS_ADJ_IC, PHY_PM_BIAS_ADJ_18P75UA); | ||
|  | #else
 | ||
|  |     /* config bias sel to 50uA*/ | ||
|  |     phy_pm_bias_sel_set(PHY_PM_BIAS_SEL_50UA); | ||
|  |     /* config bias adj to 25uA */ | ||
|  |     phy_pm_bias_adj_set(PHY_PM_BIAS_ADJ_IR, PHY_PM_BIAS_ADJ_25UA); | ||
|  |     phy_pm_bias_adj_set(PHY_PM_BIAS_ADJ_IC, PHY_PM_BIAS_ADJ_25UA); | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | void phy_bias_rx_set() | ||
|  | { | ||
|  |     /* config bias sel to 25uA*/ | ||
|  |     phy_pm_bias_sel_set(PHY_PM_BIAS_SEL_25UA); | ||
|  |     /* config bias adj to 18.75uA */ | ||
|  |     phy_pm_bias_adj_set(PHY_PM_BIAS_ADJ_IR, PHY_PM_BIAS_ADJ_18P75UA); | ||
|  |     phy_pm_bias_adj_set(PHY_PM_BIAS_ADJ_IC, PHY_PM_BIAS_ADJ_18P75UA); | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t phy_pm_pwr_update(phy_pm_pwr_sts_id id) | ||
|  | { | ||
|  |     uint32_t ret = ERR_FAIL; | ||
|  | 
 | ||
|  |     switch(id) | ||
|  |     { | ||
|  |         case PHY_PM_PWR_STS_TX: | ||
|  |             break; | ||
|  |         case PHY_PM_PWR_STS_RX: | ||
|  |             if(g_phy_ctxt.indep.pm_sts != PHY_PM_PWR_STS_RX) { | ||
|  |                 phy_bias_rx_set(); | ||
|  |                 /* update glb pwr status */ | ||
|  |                 g_phy_ctxt.indep.pm_sts = PHY_PM_PWR_STS_RX; | ||
|  |             } | ||
|  |             ret = ERR_OK; | ||
|  |             break; | ||
|  |         case PHY_PM_PWR_STS_TXRX: | ||
|  |             if(g_phy_ctxt.indep.pm_sts != PHY_PM_PWR_STS_TXRX) { | ||
|  |                 phy_bias_txrx_set(); | ||
|  |                 /* update glb pwr status */ | ||
|  |                 g_phy_ctxt.indep.pm_sts = PHY_PM_PWR_STS_TXRX; | ||
|  |             } | ||
|  |             ret = ERR_OK; | ||
|  |             break; | ||
|  |         default: | ||
|  |             break; | ||
|  |     } | ||
|  | 
 | ||
|  |     return ret; | ||
|  | } | ||
|  | 
 | ||
|  | void phy_pm_clk_auto_gate_en(bool_t en) | ||
|  | { | ||
|  | #if HW_PLATFORM == HW_PLATFORM_SILICON
 | ||
|  |     uint32_t tmp = 0; | ||
|  | 
 | ||
|  |     /* enable clk auto gate */ | ||
|  |     tmp = PHY_READ_REG(CFG_BB_CLOCK_CTRL_ADDR); | ||
|  |     if(en) { | ||
|  |         //REG_FIELD_SET(SW_CLK_EN_FC_PARSE, tmp, 0);
 | ||
|  |         REG_FIELD_SET(SW_CLK_EN_DFE_RX, tmp, 0); | ||
|  |         REG_FIELD_SET(SW_CLK_EN_DFE_TX, tmp, 0); | ||
|  |         REG_FIELD_SET(SW_MEM_FORCE_ON, tmp, 0); | ||
|  |         REG_FIELD_SET(SW_CLK_EN_TD_TX, tmp, 0); | ||
|  |         REG_FIELD_SET(SW_CLK_EN_FFT, tmp, 0); | ||
|  |         REG_FIELD_SET(SW_CLK_EN_TX_FEC, tmp, 0); | ||
|  |         REG_FIELD_SET(SW_CLK_EN_TURBO_ENC, tmp, 0); | ||
|  |     } else { | ||
|  |         //REG_FIELD_SET(SW_CLK_EN_FC_PARSE, tmp, 1);
 | ||
|  |         REG_FIELD_SET(SW_CLK_EN_DFE_RX, tmp, 1); | ||
|  |         REG_FIELD_SET(SW_CLK_EN_DFE_TX, tmp, 1); | ||
|  |         REG_FIELD_SET(SW_MEM_FORCE_ON, tmp, 1); | ||
|  |         REG_FIELD_SET(SW_CLK_EN_TD_TX, tmp, 1); | ||
|  |         REG_FIELD_SET(SW_CLK_EN_FFT, tmp, 1); | ||
|  |         REG_FIELD_SET(SW_CLK_EN_TX_FEC, tmp, 1); | ||
|  |         REG_FIELD_SET(SW_CLK_EN_TURBO_ENC, tmp, 1); | ||
|  |     } | ||
|  |     PHY_WRITE_REG(CFG_BB_CLOCK_CTRL_ADDR, tmp); | ||
|  | #else
 | ||
|  |     (void)en; | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | void phy_pm_start() | ||
|  | { | ||
|  |     //TODO:will be finished after ana low power
 | ||
|  | #if 0
 | ||
|  | #if HW_PLATFORM == HW_PLATFORM_SILICON
 | ||
|  |     uint32_t tmp = 0; | ||
|  |     uint8_t reg_id = 0; | ||
|  |     uint8_t rodata = 0; | ||
|  |     uint32_t rdata = 0; | ||
|  | 
 | ||
|  |     /* rx start */ | ||
|  |     tmp = PHY_DFE_READ_REG(CFG_BB_ANA_RX_START_EXT_CFG_ADDR); | ||
|  |     REG_FIELD_SET(SW_RX_START_EXT_CFG_DATA,tmp,0xFFFFFFFF); | ||
|  |     PHY_DFE_WRITE_REG(CFG_BB_ANA_RX_START_EXT_CFG_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* rx end */ | ||
|  |     tmp = PHY_DFE_READ_REG(CFG_BB_ANA_RX_END_EXT_CFG_ADDR); | ||
|  |     REG_FIELD_SET(SW_RX_END_EXT_CFG_DATA,tmp,0); | ||
|  |     PHY_DFE_WRITE_REG(CFG_BB_ANA_RX_END_EXT_CFG_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* read bit30~0 */ | ||
|  |     reg_id = CFG_ANA_BIAS_REG_2_ADDR; | ||
|  |     phy_ana_i2c_read(reg_id, &rdata, &rodata); | ||
|  | 
 | ||
|  |     /* tx start */ | ||
|  |     tmp = PHY_DFE_READ_REG(CFG_BB_ANA_TX_START_EXT_CFG_ADDR); | ||
|  |     REG_FIELD_SET(SW_TX_START_EXT_CFG_DATA,tmp,(1 << 31) | rdata); | ||
|  |     PHY_DFE_WRITE_REG(CFG_BB_ANA_TX_START_EXT_CFG_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* tx end */ | ||
|  |     tmp = PHY_DFE_READ_REG(CFG_BB_ANA_TX_END_EXT_CFG_ADDR); | ||
|  |     REG_FIELD_SET(SW_TX_END_EXT_CFG_DATA,tmp,~(1 << 31) & rdata); | ||
|  |     PHY_DFE_WRITE_REG(CFG_BB_ANA_TX_END_EXT_CFG_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* EXT ADDR */ | ||
|  |     tmp = PHY_DFE_READ_REG(CFG_BB_ANA_EXT_ADDR_CFG_ADDR); | ||
|  |     REG_FIELD_SET(SW_TX_START_EXT_CFG_ADDR, tmp, 9); | ||
|  |     REG_FIELD_SET(SW_TX_END_EXT_CFG_ADDR, tmp, 9); | ||
|  |     REG_FIELD_SET(SW_RX_START_EXT_CFG_ADDR, tmp, 8); | ||
|  |     REG_FIELD_SET(SW_RX_END_EXT_CFG_ADDR, tmp, 8); | ||
|  |     PHY_DFE_WRITE_REG(CFG_BB_ANA_EXT_ADDR_CFG_ADDR, tmp); | ||
|  | 
 | ||
|  |     /* init glb sts */ | ||
|  |     g_phy_ctxt.indep.pm_sts = PHY_PM_PWR_STS_TXRX; | ||
|  | 
 | ||
|  |     /* turn down tx bias */ | ||
|  |     phy_pm_pwr_update(PHY_PM_PWR_STS_RX); | ||
|  | 
 | ||
|  |     /* enable clk auto gate */ | ||
|  |     phy_pm_clk_auto_gate_en(true); | ||
|  | #endif
 | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | void phy_idle_set() | ||
|  | { | ||
|  | #if HW_PLATFORM != HW_PLATFORM_SIMU && \
 | ||
|  |     IOT_ENERGE_METER_ENABLE != 1 | ||
|  |     uint32_t tmp; | ||
|  | 
 | ||
|  |     /* disable HW control analog */ | ||
|  |     PHY_DFE_WRITE_REG(CFG_BB_ANA_RX_START_CFG_ADDR, 0); | ||
|  |     PHY_DFE_WRITE_REG(CFG_BB_ANA_TX_START_CFG_ADDR, 0); | ||
|  | 
 | ||
|  |     /* disable TX/RX of granite */ | ||
|  |     phy_ana_tx_en(false); | ||
|  |     phy_ana_rx_en(false); | ||
|  |     phy_ana_enlic_en(false); | ||
|  | 
 | ||
|  |     phy_txrx_ovr_set(true,0); | ||
|  |     (void)tmp; | ||
|  | #if 0
 | ||
|  |     /* if phy keep in reset state,
 | ||
|  |      * the sadc would be not working, | ||
|  |      * which result in problem of detecting | ||
|  |      * power charging of super capacity. | ||
|  |      * disable it currently | ||
|  |      */ | ||
|  |     /* warm reset PHY, delete clk */ | ||
|  |     tmp = AHB_RF_READ_REG(CFG_AHB_REG0_ADDR); | ||
|  |     REG_FIELD_SET(PHY_SOFT_RST, tmp, 1); | ||
|  |     AHB_RF_WRITE_REG(CFG_AHB_REG0_ADDR, tmp); | ||
|  | #endif
 | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | void phy_idle_clr() | ||
|  | { | ||
|  | #if HW_PLATFORM != HW_PLATFORM_SIMU && \
 | ||
|  |     IOT_ENERGE_METER_ENABLE != 1 | ||
|  |     /* enable RX disable TX */ | ||
|  |     phy_ana_rx_en(true); | ||
|  |     phy_ana_tx_en(false); | ||
|  |     phy_ana_top_enlic_rx_set(true); | ||
|  |     phy_ana_top_enlic_tx_set(false); | ||
|  | #if (HW_PLATFORM == HW_PLATFORM_FPGA)
 | ||
|  |     uint32_t wdata = 0; | ||
|  | 
 | ||
|  |     /* Enable sw control analog */ | ||
|  |     wdata = 1 << TOP_EN_RX_OFFSET  | \ | ||
|  |             0 << TOP_EN_TX_OFFSET  | \ | ||
|  |             1 << TOP_ENLIC_OFFSET  | \ | ||
|  |             1 << TOP_EN_ADC_OFFSET | \ | ||
|  |             0 << TOP_EN_DAC_OFFSET   ; | ||
|  |     PHY_DFE_WRITE_REG(CFG_BB_ANA_RX_START_CFG_ADDR, wdata); | ||
|  | 
 | ||
|  |     wdata = 0 << TOP_EN_RX_OFFSET  | \ | ||
|  |             1 << TOP_EN_TX_OFFSET  | \ | ||
|  |             2 << TOP_ENLIC_OFFSET  | \ | ||
|  |             0 << TOP_EN_ADC_OFFSET | \ | ||
|  |             1 << TOP_EN_DAC_OFFSET   ; | ||
|  |     PHY_DFE_WRITE_REG(CFG_BB_ANA_TX_START_CFG_ADDR, wdata); | ||
|  | #else
 | ||
|  |     PHY_DFE_WRITE_REG(CFG_BB_ANA_RX_START_CFG_ADDR, 0x78); | ||
|  |     PHY_DFE_WRITE_REG(CFG_BB_ANA_TX_START_CFG_ADDR, 0x7); | ||
|  | #endif
 | ||
|  | 
 | ||
|  |     /* warm reset PHY, delete clk */ | ||
|  |     ahb_phy_reset(); | ||
|  |     phy_txrx_ovr_set(false,0); | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #if IOT_DTEST_ONLY_SUPPORT == 0
 | ||
|  |     /* clear flag */ | ||
|  |     g_phy_cpu_share_ctxt.pm_status.fc_ok_found = 0; | ||
|  | #endif
 | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t phy_force_ana_td_power(uint32_t value) | ||
|  | { | ||
|  | #if HW_PLATFORM != HW_PLATFORM_SIMU
 | ||
|  |     uint32_t tmp = PHY_TX_READ_REG(CFG_BB_TX_VECTOR_FORCE_1_ADDR); | ||
|  |     REG_FIELD_SET(SW_FORCE_TX_POWER_TD_EN, tmp, value); | ||
|  |     REG_FIELD_SET(SW_FORCE_TX_POWER_ANA_EN, tmp, value); | ||
|  |     REG_FIELD_SET(SW_FORCE_TX_POWER_FD_FRAC_EN, tmp, value); | ||
|  |     REG_FIELD_SET(SW_FORCE_TX_POWER_FD_INT_EN, tmp, value); | ||
|  |     PHY_TX_WRITE_REG(CFG_BB_TX_VECTOR_FORCE_1_ADDR, tmp); | ||
|  | #endif
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t phy_set_tx_pwr_td(uint32_t value) | ||
|  | { | ||
|  | #if HW_PLATFORM != HW_PLATFORM_SIMU
 | ||
|  |     uint32_t tmp = PHY_TX_READ_REG(CFG_BB_TX_VECTOR_FORCE_1_ADDR); | ||
|  |     REG_FIELD_SET(SW_FORCE_TX_POWER_TD, tmp, value); | ||
|  |     PHY_TX_WRITE_REG(CFG_BB_TX_VECTOR_FORCE_1_ADDR, tmp); | ||
|  | #endif
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t phy_set_tx_pwr_ana(uint32_t value) | ||
|  | { | ||
|  | #if HW_PLATFORM != HW_PLATFORM_SIMU
 | ||
|  |     uint32_t tmp = PHY_TX_READ_REG(CFG_BB_TX_VECTOR_FORCE_1_ADDR); | ||
|  |     REG_FIELD_SET(SW_FORCE_TX_POWER_ANA, tmp, value); | ||
|  |     PHY_TX_WRITE_REG(CFG_BB_TX_VECTOR_FORCE_1_ADDR, tmp); | ||
|  | #endif
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t phy_set_tx_pwr_fd_frac(uint32_t value) | ||
|  | { | ||
|  | #if HW_PLATFORM != HW_PLATFORM_SIMU
 | ||
|  |     uint32_t tmp = PHY_TX_READ_REG(CFG_BB_TX_VECTOR_FORCE_1_ADDR); | ||
|  |     REG_FIELD_SET(SW_FORCE_TX_POWER_FD_FRAC, tmp, value); | ||
|  |     PHY_TX_WRITE_REG(CFG_BB_TX_VECTOR_FORCE_1_ADDR, tmp); | ||
|  | #endif
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 | ||
|  | uint32_t phy_set_tx_pwr_fd_int(uint32_t value) | ||
|  | { | ||
|  | #if HW_PLATFORM != HW_PLATFORM_SIMU
 | ||
|  |     uint32_t tmp = PHY_TX_READ_REG(CFG_BB_TX_VECTOR_FORCE_1_ADDR); | ||
|  |     REG_FIELD_SET(SW_FORCE_TX_POWER_FD_INT, tmp, value); | ||
|  |     PHY_TX_WRITE_REG(CFG_BB_TX_VECTOR_FORCE_1_ADDR, tmp); | ||
|  | #endif
 | ||
|  |     return 0; | ||
|  | } | ||
|  | 
 |