292 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			292 lines
		
	
	
		
			8.5 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 "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); | ||
|  | } |