e1000/base: i210 PLL workaround
Signed-off-by: Jijiang Liu <jijiang.liu@intel.com> Acked-by: Helin Zhang <helin.zhang@intel.com> Tested-by: Waterman Cao <waterman.cao@intel.com> [Thomas: split code drop]
This commit is contained in:
parent
a304e6ed52
commit
95fe5e10ee
@ -55,7 +55,6 @@ STATIC s32 e1000_check_for_link_media_swap(struct e1000_hw *hw);
|
||||
STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw *hw);
|
||||
STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed,
|
||||
u16 *duplex);
|
||||
STATIC s32 e1000_init_hw_82575(struct e1000_hw *hw);
|
||||
STATIC s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw);
|
||||
STATIC s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset,
|
||||
u16 *data);
|
||||
@ -449,6 +448,9 @@ STATIC s32 e1000_init_mac_params_82575(struct e1000_hw *hw)
|
||||
else
|
||||
mac->ops.reset_hw = e1000_reset_hw_82575;
|
||||
/* hw initialization */
|
||||
if ((mac->type == e1000_i210) || (mac->type == e1000_i211))
|
||||
mac->ops.init_hw = e1000_init_hw_i210;
|
||||
else
|
||||
mac->ops.init_hw = e1000_init_hw_82575;
|
||||
/* link setup */
|
||||
mac->ops.setup_link = e1000_setup_link_generic;
|
||||
@ -1460,7 +1462,7 @@ STATIC s32 e1000_reset_hw_82575(struct e1000_hw *hw)
|
||||
*
|
||||
* This inits the hardware readying it for operation.
|
||||
**/
|
||||
STATIC s32 e1000_init_hw_82575(struct e1000_hw *hw)
|
||||
s32 e1000_init_hw_82575(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_mac_info *mac = &hw->mac;
|
||||
s32 ret_val;
|
||||
|
@ -479,6 +479,7 @@ void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable);
|
||||
void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf);
|
||||
void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable);
|
||||
s32 e1000_init_nvm_params_82575(struct e1000_hw *hw);
|
||||
s32 e1000_init_hw_82575(struct e1000_hw *hw);
|
||||
|
||||
enum e1000_promisc_type {
|
||||
e1000_promisc_disabled = 0, /* all promisc modes disabled */
|
||||
|
@ -76,6 +76,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
|
||||
/* Physical Func Reset Done Indication */
|
||||
#define E1000_CTRL_EXT_PFRSTD 0x00004000
|
||||
#define E1000_CTRL_EXT_SDLPE 0X00040000 /* SerDes Low Power Enable */
|
||||
#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
|
||||
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
|
||||
#define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clk Gating */
|
||||
|
@ -914,3 +914,87 @@ s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr, u16 data)
|
||||
|
||||
return __e1000_access_xmdio_reg(hw, addr, dev_addr, &data, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_pll_workaround_i210
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Works around an errata in the PLL circuit where it occasionally
|
||||
* provides the wrong clock frequency after power up.
|
||||
**/
|
||||
STATIC s32 e1000_pll_workaround_i210(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val;
|
||||
u32 wuc, mdicnfg, ctrl_ext, reg_val;
|
||||
u16 nvm_word, phy_word, pci_word, tmp_nvm;
|
||||
int i;
|
||||
|
||||
/* Get and set needed register values */
|
||||
wuc = E1000_READ_REG(hw, E1000_WUC);
|
||||
mdicnfg = E1000_READ_REG(hw, E1000_MDICNFG);
|
||||
reg_val = mdicnfg & ~E1000_MDICNFG_EXT_MDIO;
|
||||
E1000_WRITE_REG(hw, E1000_MDICNFG, reg_val);
|
||||
|
||||
/* Get data from NVM, or set default */
|
||||
ret_val = e1000_read_invm_word_i210(hw, E1000_INVM_AUTOLOAD,
|
||||
&nvm_word);
|
||||
if (ret_val != E1000_SUCCESS)
|
||||
nvm_word = E1000_INVM_DEFAULT_AL;
|
||||
tmp_nvm = nvm_word | E1000_INVM_PLL_WO_VAL;
|
||||
for (i = 0; i < E1000_MAX_PLL_TRIES; i++) {
|
||||
/* check current state */
|
||||
hw->phy.ops.read_reg(hw, (E1000_PHY_PLL_FREQ_PAGE |
|
||||
E1000_PHY_PLL_FREQ_REG), &phy_word);
|
||||
if ((phy_word & E1000_PHY_PLL_UNCONF)
|
||||
!= E1000_PHY_PLL_UNCONF) {
|
||||
ret_val = E1000_SUCCESS;
|
||||
break;
|
||||
} else {
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
}
|
||||
hw->phy.ops.reset(hw);
|
||||
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
|
||||
ctrl_ext |= (E1000_CTRL_EXT_PHYPDEN | E1000_CTRL_EXT_SDLPE);
|
||||
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
|
||||
|
||||
E1000_WRITE_REG(hw, E1000_WUC, 0);
|
||||
reg_val = (E1000_INVM_AUTOLOAD << 4) | (tmp_nvm << 16);
|
||||
E1000_WRITE_REG(hw, E1000_EEARBC, reg_val);
|
||||
|
||||
e1000_read_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
|
||||
pci_word |= E1000_PCI_PMCSR_D3;
|
||||
e1000_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
|
||||
msec_delay(1);
|
||||
pci_word &= ~E1000_PCI_PMCSR_D3;
|
||||
e1000_write_pci_cfg(hw, E1000_PCI_PMCSR, &pci_word);
|
||||
reg_val = (E1000_INVM_AUTOLOAD << 4) | (nvm_word << 16);
|
||||
E1000_WRITE_REG(hw, E1000_EEARBC, reg_val);
|
||||
|
||||
/* restore WUC register */
|
||||
E1000_WRITE_REG(hw, E1000_WUC, wuc);
|
||||
}
|
||||
/* restore MDICNFG setting */
|
||||
E1000_WRITE_REG(hw, E1000_MDICNFG, mdicnfg);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_init_hw_i210 - Init hw for I210/I211
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Called to initialize hw for i210 hw family.
|
||||
**/
|
||||
s32 e1000_init_hw_i210(struct e1000_hw *hw)
|
||||
{
|
||||
s32 ret_val;
|
||||
|
||||
DEBUGFUNC("e1000_init_hw_i210");
|
||||
if ((hw->mac.type >= e1000_i210) &&
|
||||
!(e1000_get_flash_presence_i210(hw))) {
|
||||
ret_val = e1000_pll_workaround_i210(hw);
|
||||
if (ret_val != E1000_SUCCESS)
|
||||
return ret_val;
|
||||
}
|
||||
ret_val = e1000_init_hw_82575(hw);
|
||||
return ret_val;
|
||||
}
|
||||
|
@ -50,6 +50,7 @@ s32 e1000_read_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
|
||||
u16 *data);
|
||||
s32 e1000_write_xmdio_reg(struct e1000_hw *hw, u16 addr, u8 dev_addr,
|
||||
u16 data);
|
||||
s32 e1000_init_hw_i210(struct e1000_hw *hw);
|
||||
|
||||
#define E1000_STM_OPCODE 0xDB00
|
||||
#define E1000_EEPROM_FLASH_SIZE_WORD 0x11
|
||||
@ -94,4 +95,16 @@ enum E1000_INVM_STRUCTURE_TYPE {
|
||||
#define NVM_INIT_CTRL_4_DEFAULT_I211 0x00C1
|
||||
#define NVM_LED_1_CFG_DEFAULT_I211 0x0184
|
||||
#define NVM_LED_0_2_CFG_DEFAULT_I211 0x200C
|
||||
|
||||
/* PLL Defines */
|
||||
#define E1000_PCI_PMCSR 0x44
|
||||
#define E1000_PCI_PMCSR_D3 0x03
|
||||
#define E1000_MAX_PLL_TRIES 5
|
||||
#define E1000_PHY_PLL_UNCONF 0xFF
|
||||
#define E1000_PHY_PLL_FREQ_PAGE 0xFC0000
|
||||
#define E1000_PHY_PLL_FREQ_REG 0x000E
|
||||
#define E1000_INVM_DEFAULT_AL 0x202F
|
||||
#define E1000_INVM_AUTOLOAD 0x0A
|
||||
#define E1000_INVM_PLL_WO_VAL 0x0010
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user