Files
kunlun/plc/halphy/hw/phy_phase.c
2024-09-28 14:24:04 +08:00

292 lines
8.5 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 "hw_reg_api.h"
#include "phy_phase.h"
#include "phy_bb.h"
#include "phy_dfe_reg.h"
#include "mac_sys_reg.h"
#include "hw_desc.h"
#include "os_task.h"
#include "hw_phy_api.h"
void phy_phase_ovr_set(PHY_PHASE_OVR_ID phase, bool_t en, PHY_TXRX_OVR_ID mode)
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp = 0;
/* enable a/b/c and tx & rx*/
tmp = PHY_DFE_READ_REG(CFG_BB_DFE_OPTION_0_ADDR);
switch(phase)
{
case PHY_PHASE_OVR_A:
REG_FIELD_SET(SW_ENLIC_A_OVR_EN, tmp, en);
REG_FIELD_SET(SW_ENLIC_A_OVR, tmp, mode);
break;
case PHY_PHASE_OVR_B:
REG_FIELD_SET(SW_ENLIC_B_OVR_EN, tmp, en);
REG_FIELD_SET(SW_ENLIC_B_OVR, tmp, mode);
break;
case PHY_PHASE_OVR_C:
REG_FIELD_SET(SW_ENLIC_C_OVR_EN, tmp, en);
REG_FIELD_SET(SW_ENLIC_C_OVR, tmp, mode);
break;
case PHY_PHASE_OVR_ALL:
REG_FIELD_SET(SW_ENLIC_A_OVR_EN, tmp, en);
REG_FIELD_SET(SW_ENLIC_A_OVR, tmp, mode);
REG_FIELD_SET(SW_ENLIC_B_OVR_EN, tmp, en);
REG_FIELD_SET(SW_ENLIC_B_OVR, tmp, mode);
REG_FIELD_SET(SW_ENLIC_C_OVR_EN, tmp, en);
REG_FIELD_SET(SW_ENLIC_C_OVR, tmp, mode);
break;
default:
break;
}
PHY_DFE_WRITE_REG(CFG_BB_DFE_OPTION_0_ADDR, tmp);
#else
(void)phase;
(void)en;
(void)mode;
#endif
}
void register_get_rx_phase_cb(mac_get_rx_phase_cb_t cb)
{
#if IOT_DTEST_ONLY_SUPPORT == 0
g_phy_cpu_share_ctxt.rx_phase_cb = cb;
#endif
}
uint32_t IRAM_ATTR phy_get_mac_rx_phase()
{
#if IOT_DTEST_ONLY_SUPPORT == 0
if (g_phy_cpu_share_ctxt.rx_phase_cb) {
return g_phy_cpu_share_ctxt.rx_phase_cb();
} else {
return 0;
}
#else
return 0;
#endif
}
static inline uint8_t hw_phase_map_to_rx_cmb(uint8_t hw_phase)
{
switch (hw_phase)
{
case HW_DESC_PHASE_A:
return RX_EN_CMB_A;
case HW_DESC_PHASE_B:
return RX_EN_CMB_B;
case HW_DESC_PHASE_C:
return RX_EN_CMB_C;
case HW_DESC_PHASE_ALL:
return (RX_EN_CMB_A | RX_EN_CMB_B | RX_EN_CMB_C);
default:
return 0;
}
}
static inline uint8_t hw_phase_map_to_tx_cmb(uint8_t hw_phase)
{
switch (hw_phase)
{
case HW_DESC_PHASE_A:
return TX_EN_CMB_A;
case HW_DESC_PHASE_B:
return TX_EN_CMB_B;
case HW_DESC_PHASE_C:
return TX_EN_CMB_C;
case HW_DESC_PHASE_ALL:
return (TX_EN_CMB_A | TX_EN_CMB_B | TX_EN_CMB_C);
default:
return 0;
}
}
void phy_set_phase_overwrite(bool_t is_enable,
uint8_t desc0_to_hw_phase, uint8_t desc1_to_hw_phase,
uint8_t desc2_to_hw_phase, uint8_t desc3_to_hw_phase)
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp_tx, tmp_rx;
tmp_tx = PHY_DFE_READ_REG(CFG_BB_ENLIC_TBL_0_ADDR);
tmp_rx = PHY_DFE_READ_REG(CFG_BB_ENLIC_TBL_1_ADDR);
if (is_enable) {
if ((HW_DESC_PHASE_ALL < desc0_to_hw_phase) && \
(HW_DESC_PHASE_ALL < desc1_to_hw_phase) && \
(HW_DESC_PHASE_ALL < desc2_to_hw_phase) && \
(HW_DESC_PHASE_ALL < desc3_to_hw_phase)) {
/* set rx default */
REG_FIELD_SET(SW_RX_PHASE_TBL_0, tmp_rx, \
(RX_EN_CMB_A | RX_EN_CMB_B | RX_EN_CMB_C));
REG_FIELD_SET(SW_RX_PHASE_TBL_1, tmp_rx, RX_EN_CMB_A);
REG_FIELD_SET(SW_RX_PHASE_TBL_2, tmp_rx, RX_EN_CMB_B);
REG_FIELD_SET(SW_RX_PHASE_TBL_3, tmp_rx, RX_EN_CMB_C);
/* set tx default */
REG_FIELD_SET(SW_TX_PHASE_TBL_0, tmp_tx, \
(TX_EN_CMB_A | TX_EN_CMB_B | TX_EN_CMB_C));
REG_FIELD_SET(SW_TX_PHASE_TBL_1, tmp_tx, TX_EN_CMB_A);
REG_FIELD_SET(SW_TX_PHASE_TBL_2, tmp_tx, TX_EN_CMB_B);
REG_FIELD_SET(SW_TX_PHASE_TBL_3, tmp_tx, TX_EN_CMB_C);
/*enable tx/rx phase overwrite*/
REG_FIELD_SET(SW_CFG_PHASE_EN, tmp_tx, true);
} else {
/* set rx value */
REG_FIELD_SET(SW_RX_PHASE_TBL_0, tmp_rx, \
hw_phase_map_to_rx_cmb(desc0_to_hw_phase));
REG_FIELD_SET(SW_RX_PHASE_TBL_1, tmp_rx, \
hw_phase_map_to_rx_cmb(desc1_to_hw_phase));
REG_FIELD_SET(SW_RX_PHASE_TBL_2, tmp_rx, \
hw_phase_map_to_rx_cmb(desc2_to_hw_phase));
REG_FIELD_SET(SW_RX_PHASE_TBL_3, tmp_rx, \
hw_phase_map_to_rx_cmb(desc3_to_hw_phase));
/* set tx value */
REG_FIELD_SET(SW_TX_PHASE_TBL_0, tmp_tx, \
hw_phase_map_to_tx_cmb(desc0_to_hw_phase));
REG_FIELD_SET(SW_TX_PHASE_TBL_1, tmp_tx, \
hw_phase_map_to_tx_cmb(desc1_to_hw_phase));
REG_FIELD_SET(SW_TX_PHASE_TBL_2, tmp_tx, \
hw_phase_map_to_tx_cmb(desc2_to_hw_phase));
REG_FIELD_SET(SW_TX_PHASE_TBL_3, tmp_tx, \
hw_phase_map_to_tx_cmb(desc3_to_hw_phase));
/*enable tx/rx phase overwrite*/
REG_FIELD_SET(SW_CFG_PHASE_EN, tmp_tx, true);
}
} else {
REG_FIELD_SET(SW_CFG_PHASE_EN, tmp_tx, false);
}
PHY_DFE_WRITE_REG(CFG_BB_ENLIC_TBL_0_ADDR, tmp_tx);
PHY_DFE_WRITE_REG(CFG_BB_ENLIC_TBL_1_ADDR, tmp_rx);
#else
(void)is_enable;
(void)desc0_to_hw_phase;
(void)desc1_to_hw_phase;
(void)desc2_to_hw_phase;
(void)desc3_to_hw_phase;
#endif
}
void phy_force_0_access_require()
{
/* disable irq */
os_disable_irq();
}
void phy_force_0_access_release()
{
/* enable irq */
os_enable_irq();
}
void IRAM_ATTR phy_force_0_access_require_from_isr()
{
}
void IRAM_ATTR phy_force_0_access_release_from_isr()
{
}
/* NOTE: this function cannot call in interrupt */
/* force phy rx phase */
void phy_rx_phase_force_set(bool_t enable, uint8_t hw_phase)
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp;
/* record force phase en and force phase */
g_phy_cpu_share_ctxt.rx_phase_force_en = enable;
g_phy_cpu_share_ctxt.rx_phase_force = hw_phase;
phy_force_0_access_require();
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_0_ADDR);
REG_FIELD_SET(CFG_PHY_RX_PHASE_SEL_FORCE_EN, tmp, enable);
REG_FIELD_SET(CFG_PHY_RX_PHASE_SEL, tmp, hw_phase);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_0_ADDR, tmp);
phy_force_0_access_release();
#else
(void)enable;
(void)hw_phase;
#endif
return;
}
/* force phy rx phase */
void phy_rx_phase_force_set_on_dump(bool_t enable, uint8_t hw_phase)
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp;
phy_force_0_access_require();
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_0_ADDR);
REG_FIELD_SET(CFG_PHY_RX_PHASE_SEL_FORCE_EN, tmp, enable);
REG_FIELD_SET(CFG_PHY_RX_PHASE_SEL, tmp, hw_phase);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_0_ADDR, tmp);
phy_force_0_access_release();
#else
(void)enable;
(void)hw_phase;
#endif
}
uint32_t phy_get_rx_force_phase_val()
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_0_ADDR);
return REG_FIELD_GET(CFG_PHY_RX_PHASE_SEL, tmp);
#else
return 0;
#endif
}
uint32_t phy_get_rx_phase_force_en()
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
uint32_t tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_0_ADDR);
return REG_FIELD_GET(CFG_PHY_RX_PHASE_SEL_FORCE_EN, tmp);
#else
return 0;
#endif
}
uint32_t phy_get_hw_phy_rx_phase_sel(void)
{
#if HW_PLATFORM >= HW_PLATFORM_FPGA
return (REG_FIELD_GET(PHY_RX_PHASE_SEL, \
RGF_MAC_READ_REG(CFG_RD_MACPHY_INTF_0_ADDR)));
#else
return 0;
#endif
}
void phy_set_tx_force_enable(uint8_t is_enable)
{
uint32_t tmp;
is_enable = !!is_enable;
tmp = RGF_MAC_READ_REG(CFG_PHY_FORCE_1_ADDR);
REG_FIELD_SET(CFG_PHY_TX_ENABLE, tmp, is_enable);
REG_FIELD_SET(CFG_PHY_TX_ENABLE_FORCE_EN, tmp, is_enable);
RGF_MAC_WRITE_REG(CFG_PHY_FORCE_1_ADDR, tmp);
}