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;
|
||
|
}
|
||
|
|