Commit 8637034b authored by Arun Ramadoss's avatar Arun Ramadoss Committed by David S. Miller

net: phy: updated the initialization routine for LAN87xx

The new initialization sequence is the improvement to the existing init
routine. Init routine does soft reset, run init script and set
Hw_init. Added the new access_smi_poll_timeout() for polling smi
bank write.
Signed-off-by: default avatarPrasanna Vengateshan <prasanna.vengateshan@microchip.com>
Signed-off-by: default avatarArun Ramadoss <arun.ramadoss@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ccc8cc5b
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#define PHYACC_ATTR_MODE_READ 0 #define PHYACC_ATTR_MODE_READ 0
#define PHYACC_ATTR_MODE_WRITE 1 #define PHYACC_ATTR_MODE_WRITE 1
#define PHYACC_ATTR_MODE_MODIFY 2 #define PHYACC_ATTR_MODE_MODIFY 2
#define PHYACC_ATTR_MODE_POLL 3
#define PHYACC_ATTR_BANK_SMI 0 #define PHYACC_ATTR_BANK_SMI 0
#define PHYACC_ATTR_BANK_MISC 1 #define PHYACC_ATTR_BANK_MISC 1
...@@ -52,6 +53,28 @@ ...@@ -52,6 +53,28 @@
#define LAN87XX_CABLE_TEST_OPEN 1 #define LAN87XX_CABLE_TEST_OPEN 1
#define LAN87XX_CABLE_TEST_SAME_SHORT 2 #define LAN87XX_CABLE_TEST_SAME_SHORT 2
/* T1 Registers */
#define T1_AFE_PORT_CFG1_REG 0x0B
#define T1_POWER_DOWN_CONTROL_REG 0x1A
#define T1_SLV_FD_MULT_CFG_REG 0x18
#define T1_CDR_CFG_PRE_LOCK_REG 0x05
#define T1_CDR_CFG_POST_LOCK_REG 0x06
#define T1_LCK_STG2_MUFACT_CFG_REG 0x1A
#define T1_LCK_STG3_MUFACT_CFG_REG 0x1B
#define T1_POST_LCK_MUFACT_CFG_REG 0x1C
#define T1_TX_RX_FIFO_CFG_REG 0x02
#define T1_TX_LPF_FIR_CFG_REG 0x55
#define T1_SQI_CONFIG_REG 0x2E
#define T1_MDIO_CONTROL2_REG 0x10
#define T1_INTERRUPT_SOURCE_REG 0x18
#define T1_INTERRUPT2_SOURCE_REG 0x08
#define T1_EQ_FD_STG1_FRZ_CFG 0x69
#define T1_EQ_FD_STG2_FRZ_CFG 0x6A
#define T1_EQ_FD_STG3_FRZ_CFG 0x6B
#define T1_EQ_FD_STG4_FRZ_CFG 0x6C
#define T1_EQ_WT_FD_LCK_FRZ_CFG 0x6D
#define T1_PST_EQ_LCK_STG1_FRZ_CFG 0x6E
#define DRIVER_AUTHOR "Nisar Sayed <nisar.sayed@microchip.com>" #define DRIVER_AUTHOR "Nisar Sayed <nisar.sayed@microchip.com>"
#define DRIVER_DESC "Microchip LAN87XX T1 PHY driver" #define DRIVER_DESC "Microchip LAN87XX T1 PHY driver"
...@@ -119,6 +142,15 @@ static int access_ereg_modify_changed(struct phy_device *phydev, ...@@ -119,6 +142,15 @@ static int access_ereg_modify_changed(struct phy_device *phydev,
return rc; return rc;
} }
static int access_smi_poll_timeout(struct phy_device *phydev,
u8 offset, u16 mask, u16 clr)
{
int val;
return phy_read_poll_timeout(phydev, offset, val, (val & mask) == clr,
150, 30000, true);
}
static int lan87xx_config_rgmii_delay(struct phy_device *phydev) static int lan87xx_config_rgmii_delay(struct phy_device *phydev)
{ {
int rc; int rc;
...@@ -159,46 +191,146 @@ static int lan87xx_config_rgmii_delay(struct phy_device *phydev) ...@@ -159,46 +191,146 @@ static int lan87xx_config_rgmii_delay(struct phy_device *phydev)
static int lan87xx_phy_init(struct phy_device *phydev) static int lan87xx_phy_init(struct phy_device *phydev)
{ {
static const struct access_ereg_val init[] = { static const struct access_ereg_val init[] = {
/* TX Amplitude = 5 */ /* TXPD/TXAMP6 Configs */
{PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_AFE, 0x0B, { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_AFE,
0x000A, 0x001E}, T1_AFE_PORT_CFG1_REG, 0x002D, 0 },
/* Clear SMI interrupts */ /* HW_Init Hi and Force_ED */
{PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_SMI, 0x18, { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_SMI,
0, 0}, T1_POWER_DOWN_CONTROL_REG, 0x0308, 0 },
/* Clear MISC interrupts */ /* Equalizer Full Duplex Freeze - T1 Slave */
{PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_MISC, 0x08, { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
0, 0}, T1_EQ_FD_STG1_FRZ_CFG, 0x0002, 0 },
/* Turn on TC10 Ring Oscillator (ROSC) */ { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
{PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_MISC, 0x20, T1_EQ_FD_STG2_FRZ_CFG, 0x0002, 0 },
0x0020, 0x0020}, { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
/* WUR Detect Length to 1.2uS, LPC Detect Length to 1.09uS */ T1_EQ_FD_STG3_FRZ_CFG, 0x0002, 0 },
{PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_PCS, 0x20, { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
0x283C, 0}, T1_EQ_FD_STG4_FRZ_CFG, 0x0002, 0 },
/* Wake_In Debounce Length to 39uS, Wake_Out Length to 79uS */ { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
{PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x21, T1_EQ_WT_FD_LCK_FRZ_CFG, 0x0002, 0 },
0x274F, 0}, { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
/* Enable Auto Wake Forward to Wake_Out, ROSC on, Sleep, T1_PST_EQ_LCK_STG1_FRZ_CFG, 0x0002, 0 },
* and Wake_In to wake PHY /* Slave Full Duplex Multi Configs */
*/ { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
{PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x20, T1_SLV_FD_MULT_CFG_REG, 0x0D53, 0 },
0x80A7, 0}, /* CDR Pre and Post Lock Configs */
/* Enable WUP Auto Fwd, Enable Wake on MDI, Wakeup Debouncer { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
* to 128 uS T1_CDR_CFG_PRE_LOCK_REG, 0x0AB2, 0 },
*/ { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
{PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_MISC, 0x24, T1_CDR_CFG_POST_LOCK_REG, 0x0AB3, 0 },
0xF110, 0}, /* Lock Stage 2-3 Multi Factor Config */
/* Enable HW Init */ { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
{PHYACC_ATTR_MODE_MODIFY, PHYACC_ATTR_BANK_SMI, 0x1A, T1_LCK_STG2_MUFACT_CFG_REG, 0x0AEA, 0 },
0x0100, 0x0100}, { PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_LCK_STG3_MUFACT_CFG_REG, 0x0AEB, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_POST_LCK_MUFACT_CFG_REG, 0x0AEB, 0 },
/* Pointer delay */
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_RX_FIFO_CFG_REG, 0x1C00, 0 },
/* Tx iir edits */
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1000, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1861, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1061, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1922, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1122, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1983, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1183, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1944, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1144, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x18c5, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x10c5, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1846, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1046, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1807, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1007, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1808, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1008, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1809, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1009, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x180A, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x100A, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x180B, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x100B, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x180C, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x100C, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x180D, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x100D, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x180E, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x100E, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x180F, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x100F, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1810, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1010, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1811, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1011, 0 },
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_TX_LPF_FIR_CFG_REG, 0x1000, 0 },
/* SQI enable */
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_DSP,
T1_SQI_CONFIG_REG, 0x9572, 0 },
/* Flag LPS and WUR as idle errors */
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_SMI,
T1_MDIO_CONTROL2_REG, 0x0014, 0 },
/* HW_Init toggle, undo force ED, TXPD off */
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_SMI,
T1_POWER_DOWN_CONTROL_REG, 0x0200, 0 },
/* Reset PCS to trigger hardware initialization */
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_SMI,
T1_MDIO_CONTROL2_REG, 0x0094, 0 },
/* Poll till Hardware is initialized */
{ PHYACC_ATTR_MODE_POLL, PHYACC_ATTR_BANK_SMI,
T1_MDIO_CONTROL2_REG, 0x0080, 0 },
/* Tx AMP - 0x06 */
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_AFE,
T1_AFE_PORT_CFG1_REG, 0x000C, 0 },
/* Read INTERRUPT_SOURCE Register */
{ PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_SMI,
T1_INTERRUPT_SOURCE_REG, 0, 0 },
/* Read INTERRUPT_SOURCE Register */
{ PHYACC_ATTR_MODE_READ, PHYACC_ATTR_BANK_MISC,
T1_INTERRUPT2_SOURCE_REG, 0, 0 },
/* HW_Init Hi */
{ PHYACC_ATTR_MODE_WRITE, PHYACC_ATTR_BANK_SMI,
T1_POWER_DOWN_CONTROL_REG, 0x0300, 0 },
}; };
int rc, i; int rc, i;
/* Start manual initialization procedures in Managed Mode */
rc = access_ereg_modify_changed(phydev, PHYACC_ATTR_BANK_SMI,
0x1a, 0x0000, 0x0100);
if (rc < 0)
return rc;
/* phy Soft reset */ /* phy Soft reset */
rc = genphy_soft_reset(phydev); rc = genphy_soft_reset(phydev);
if (rc < 0) if (rc < 0)
...@@ -206,11 +338,12 @@ static int lan87xx_phy_init(struct phy_device *phydev) ...@@ -206,11 +338,12 @@ static int lan87xx_phy_init(struct phy_device *phydev)
/* PHY Initialization */ /* PHY Initialization */
for (i = 0; i < ARRAY_SIZE(init); i++) { for (i = 0; i < ARRAY_SIZE(init); i++) {
if (init[i].mode == PHYACC_ATTR_MODE_MODIFY) { if (init[i].mode == PHYACC_ATTR_MODE_POLL &&
rc = access_ereg_modify_changed(phydev, init[i].bank, init[i].bank == PHYACC_ATTR_BANK_SMI) {
init[i].offset, rc = access_smi_poll_timeout(phydev,
init[i].val, init[i].offset,
init[i].mask); init[i].val,
init[i].mask);
} else { } else {
rc = access_ereg(phydev, init[i].mode, init[i].bank, rc = access_ereg(phydev, init[i].mode, init[i].bank,
init[i].offset, init[i].val); init[i].offset, init[i].val);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment