392 lines
12 KiB
C
392 lines
12 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 "iot_gpio_api.h"
|
|
#include "iot_board_api.h"
|
|
#include "board_info.h"
|
|
|
|
void phy_pm_bias_sel_set(phy_pm_bias_sel_id sel_ic)
|
|
{
|
|
#if HW_PLATFORM == HW_PLATFORM_SILICON
|
|
uint8_t reg_id = 0;
|
|
uint32_t wdata = 0;
|
|
uint32_t wmask = 0;
|
|
|
|
/* bias current */
|
|
reg_id = CFG_ANA_BIAS_REG_2_ADDR;
|
|
wdata = sel_ic << 31;
|
|
wmask = 1 << 31;;
|
|
phy_ana_i2c_write(reg_id,wdata,wmask);
|
|
#else
|
|
(void)sel_ic;
|
|
#endif
|
|
}
|
|
|
|
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
|
|
uint8_t reg_id = 0;
|
|
uint32_t wmask = 0;
|
|
|
|
/* bias current */
|
|
if(adj_id == PHY_PM_BIAS_ADJ_IR)
|
|
{
|
|
switch(current_id)
|
|
{
|
|
case PHY_PM_BIAS_ADJ_31P25UA:
|
|
/* bit0 */
|
|
reg_id = CFG_ANA_BIAS_REG_0_ADDR;
|
|
wmask = BIAS_ADJ_IR25U_BIT0_MASK;
|
|
phy_ana_i2c_write(reg_id,0x0,wmask);
|
|
/* bit1 */
|
|
reg_id = CFG_ANA_BIAS_REG_1_ADDR;
|
|
wmask = BIAS_ADJ_IR25U_BIT1_MASK;
|
|
phy_ana_i2c_write(reg_id,0x0,wmask);
|
|
break;
|
|
case PHY_PM_BIAS_ADJ_25UA:
|
|
/* bit0 */
|
|
reg_id = CFG_ANA_BIAS_REG_0_ADDR;
|
|
wmask = BIAS_ADJ_IR25U_BIT0_MASK;
|
|
phy_ana_i2c_write(reg_id,wmask,wmask);
|
|
/* bit1 */
|
|
reg_id = CFG_ANA_BIAS_REG_1_ADDR;
|
|
wmask = BIAS_ADJ_IR25U_BIT1_MASK;
|
|
phy_ana_i2c_write(reg_id,0x0,wmask);
|
|
break;
|
|
case PHY_PM_BIAS_ADJ_18P75UA:
|
|
/* bit0 */
|
|
reg_id = CFG_ANA_BIAS_REG_0_ADDR;
|
|
wmask = BIAS_ADJ_IR25U_BIT0_MASK;
|
|
phy_ana_i2c_write(reg_id,wmask,wmask);
|
|
/* bit1 */
|
|
reg_id = CFG_ANA_BIAS_REG_1_ADDR;
|
|
wmask = BIAS_ADJ_IR25U_BIT1_MASK;
|
|
phy_ana_i2c_write(reg_id,wmask,wmask);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
else if(adj_id == PHY_PM_BIAS_ADJ_IC)
|
|
{
|
|
switch(current_id)
|
|
{
|
|
case PHY_PM_BIAS_ADJ_31P25UA:
|
|
/* bit0 */
|
|
reg_id = CFG_ANA_BIAS_REG_0_ADDR;
|
|
wmask = BIAS_ADJ_IC25U_BIT0_MASK;
|
|
phy_ana_i2c_write(reg_id,0x0,wmask);
|
|
/* bit1 */
|
|
reg_id = CFG_ANA_BIAS_REG_1_ADDR;
|
|
wmask = BIAS_ADJ_IC25U_BIT1_MASK;
|
|
phy_ana_i2c_write(reg_id,0x0,wmask);
|
|
break;
|
|
case PHY_PM_BIAS_ADJ_25UA:
|
|
/* bit0 */
|
|
reg_id = CFG_ANA_BIAS_REG_0_ADDR;
|
|
wmask = BIAS_ADJ_IC25U_BIT0_MASK;
|
|
phy_ana_i2c_write(reg_id,wmask,wmask);
|
|
/* bit1 */
|
|
reg_id = CFG_ANA_BIAS_REG_1_ADDR;
|
|
wmask = BIAS_ADJ_IC25U_BIT1_MASK;
|
|
phy_ana_i2c_write(reg_id,0x0,wmask);
|
|
break;
|
|
case PHY_PM_BIAS_ADJ_18P75UA:
|
|
/* bit0 */
|
|
reg_id = CFG_ANA_BIAS_REG_0_ADDR;
|
|
wmask = BIAS_ADJ_IC25U_BIT0_MASK;
|
|
phy_ana_i2c_write(reg_id,wmask,wmask);
|
|
/* bit1 */
|
|
reg_id = CFG_ANA_BIAS_REG_1_ADDR;
|
|
wmask = BIAS_ADJ_IC25U_BIT1_MASK;
|
|
phy_ana_i2c_write(reg_id,wmask,wmask);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
#else
|
|
(void)adj_id;
|
|
(void)current_id;
|
|
#endif
|
|
}
|
|
|
|
static uint8_t lic_gpio = GPIO_NO_VALID;
|
|
|
|
void phy_bias_init_lic_io()
|
|
{
|
|
lic_gpio = iot_board_get_gpio(GPIO_LIC_CTRL);
|
|
}
|
|
|
|
void phy_bias_txrx_set()
|
|
{
|
|
#if PHY_BIAS_ADJUST_AUTO_EN == 0
|
|
phy_bias_rx_set();
|
|
#else
|
|
|
|
if (lic_gpio != GPIO_NO_VALID) {
|
|
iot_gpio_close(lic_gpio);
|
|
iot_gpio_open_as_output(lic_gpio);
|
|
iot_gpio_value_set(lic_gpio, 0);
|
|
} 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()
|
|
{
|
|
if (lic_gpio != GPIO_NO_VALID) {
|
|
iot_gpio_close(lic_gpio);
|
|
/* gpio floating */
|
|
iot_gpio_open_as_input(lic_gpio);
|
|
iot_gpio_set_pull_mode(lic_gpio, GPIO_PULL_NONE);
|
|
} else {
|
|
/* 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()
|
|
{
|
|
#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;
|
|
phy_bias_init_lic_io();
|
|
|
|
/* 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
|
|
}
|
|
|
|
void phy_idle_set()
|
|
{
|
|
#if HW_PLATFORM != HW_PLATFORM_SIMU && \
|
|
IOT_ENERGE_METER_ENABLE != 1
|
|
uint32_t tmp;
|
|
uint32_t wdata = 0;
|
|
uint32_t wmask = 0;
|
|
|
|
(void)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);
|
|
/* set the lowest bias */
|
|
phy_ana_i2c_write(CFG_ANA_BIAS_REG_1_ADDR,0xffffffff,0xffffffff);
|
|
/* disable TX/RX of granite */
|
|
wdata = 0 << TOP_EN_RX_OFFSET | \
|
|
0 << TOP_EN_TX_OFFSET | \
|
|
0 << TOP_ENLIC_OFFSET | \
|
|
0 << TOP_EN_ADC_OFFSET | \
|
|
0 << TOP_EN_DAC_OFFSET ;
|
|
|
|
wmask = TOP_EN_RX_MASK | \
|
|
TOP_EN_TX_MASK | \
|
|
TOP_ENLIC_MASK | \
|
|
TOP_EN_ADC_MASK | \
|
|
TOP_EN_DAC_MASK ;
|
|
|
|
phy_ana_i2c_write(CFG_ANA_TOP_REG_ADDR,wdata,wmask);
|
|
phy_txrx_ovr_set(true,0);
|
|
/* warm reset PHY, delete clk */
|
|
ahb_phy_reset();
|
|
|
|
#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
|
|
uint32_t wdata = 0;
|
|
uint32_t wmask = 0;
|
|
/* enable TX/RX of granite */
|
|
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 ;
|
|
|
|
wmask = TOP_EN_RX_MASK | \
|
|
TOP_EN_TX_MASK | \
|
|
TOP_ENLIC_MASK | \
|
|
TOP_EN_ADC_MASK | \
|
|
TOP_EN_DAC_MASK ;
|
|
|
|
phy_ana_i2c_write(CFG_ANA_TOP_REG_ADDR,wdata,wmask);
|
|
/* 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);
|
|
|
|
/* 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
|
|
}
|
|
|