377 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			377 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
/****************************************************************************
 | 
						|
 | 
						|
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;
 | 
						|
}
 | 
						|
 |