425 lines
12 KiB
C
425 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 "phy_tx_reg.h"
|
|
#include "ana_dig_wrap_rf.h"
|
|
#include "iot_system.h"
|
|
#include "iot_gpio_api.h"
|
|
#include "iot_board_api.h"
|
|
#include "phy_cal.h"
|
|
|
|
void phy_pm_bias_sel_set(phy_pm_bias_sel_id sel_ic)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
tmp = DTOP_ANA_INF_READ_REG(CFG_ANA_DIG_REG_CFG18_ADDR);
|
|
REG_FIELD_SET(D_SEL_ICLIC50U, tmp, sel_ic);
|
|
DTOP_ANA_INF_WRITE_REG(CFG_ANA_DIG_REG_CFG18_ADDR, tmp);
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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) {
|
|
/* gpio floating */
|
|
iot_gpio_close(lic_gpio);
|
|
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();
|
|
if (g_phy_ctxt.dep.raise_dcdccode_flag == 0) {
|
|
g_phy_ctxt.dep.raise_dcdccode_flag = 1;
|
|
phy_tx_increase_dcdccode(STATIC_POWER_SAVE != 0);
|
|
}
|
|
/* 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);
|
|
}
|
|
/* clock enable for channel est
|
|
*affects base band power consumption
|
|
*1:desc:snr cal work
|
|
*0:desc:snr cal not work
|
|
*/
|
|
REG_FIELD_SET(SW_CH_EST_ICG_EN, 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
|
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
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, 0x2F8);
|
|
PHY_DFE_WRITE_REG(CFG_BB_ANA_TX_START_CFG_ADDR, 0x107);
|
|
#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;
|
|
}
|
|
|
|
uint8_t phy_get_tx_pwr_td(void)
|
|
{
|
|
#if HW_PLATFORM != HW_PLATFORM_SIMU
|
|
uint32_t tmp = PHY_TX_READ_REG(CFG_BB_TX_VECTOR_FORCE_1_ADDR);
|
|
return REG_FIELD_GET(SW_FORCE_TX_POWER_TD, 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;
|
|
}
|
|
|