Commit 4fb99cd6 authored by stephen hemminger's avatar stephen hemminger Committed by David S. Miller

sky2: support for new Optima chipsets (EXPERIMENTAL)

This is a backport from the vendor driver of support for the newer Optima
(Prime and 2) chipsets. It also includes some setup changes for the
current Optima chip as well. The code and comments intentionally
mirror the vendor sk98lin driver to allow for easier maintenance.

Although this adds support for new chip id's, these chip id's are not
used by any of the current PCI device id's listed in the driver.
The patch is just to get initial infrastructure in place to handle them
when they come.

I don't have access to any of this hardware to actually test it yet.
Signed-off-by: default avatarStephen Hemminger <shemminger@vyatta.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8e11680f
...@@ -365,6 +365,17 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) ...@@ -365,6 +365,17 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec); gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec);
} }
} else { } else {
if (hw->chip_id >= CHIP_ID_YUKON_OPT) {
u16 ctrl2 = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL_2);
/* enable PHY Reverse Auto-Negotiation */
ctrl2 |= 1u << 13;
/* Write PHY changes (SW-reset must follow) */
gm_phy_write(hw, port, PHY_MARV_EXT_CTRL_2, ctrl2);
}
/* disable energy detect */ /* disable energy detect */
ctrl &= ~PHY_M_PC_EN_DET_MSK; ctrl &= ~PHY_M_PC_EN_DET_MSK;
...@@ -626,6 +637,63 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) ...@@ -626,6 +637,63 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
if (ledover) if (ledover)
gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover);
} else if (hw->chip_id == CHIP_ID_YUKON_PRM &&
(sky2_read8(hw, B2_MAC_CFG) & 0xf) == 0x7) {
int i;
/* This a phy register setup workaround copied from vendor driver. */
static const struct {
u16 reg, val;
} eee_afe[] = {
{ 0x156, 0x58ce },
{ 0x153, 0x99eb },
{ 0x141, 0x8064 },
/* { 0x155, 0x130b },*/
{ 0x000, 0x0000 },
{ 0x151, 0x8433 },
{ 0x14b, 0x8c44 },
{ 0x14c, 0x0f90 },
{ 0x14f, 0x39aa },
/* { 0x154, 0x2f39 },*/
{ 0x14d, 0xba33 },
{ 0x144, 0x0048 },
{ 0x152, 0x2010 },
/* { 0x158, 0x1223 },*/
{ 0x140, 0x4444 },
{ 0x154, 0x2f3b },
{ 0x158, 0xb203 },
{ 0x157, 0x2029 },
};
/* Start Workaround for OptimaEEE Rev.Z0 */
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00fb);
gm_phy_write(hw, port, 1, 0x4099);
gm_phy_write(hw, port, 3, 0x1120);
gm_phy_write(hw, port, 11, 0x113c);
gm_phy_write(hw, port, 14, 0x8100);
gm_phy_write(hw, port, 15, 0x112a);
gm_phy_write(hw, port, 17, 0x1008);
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00fc);
gm_phy_write(hw, port, 1, 0x20b0);
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0x00ff);
for (i = 0; i < ARRAY_SIZE(eee_afe); i++) {
/* apply AFE settings */
gm_phy_write(hw, port, 17, eee_afe[i].val);
gm_phy_write(hw, port, 16, eee_afe[i].reg | 1u<<13);
}
/* End Workaround for OptimaEEE */
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
/* Enable 10Base-Te (EEE) */
if (hw->chip_id >= CHIP_ID_YUKON_PRM) {
reg = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
gm_phy_write(hw, port, PHY_MARV_EXT_CTRL,
reg | PHY_M_10B_TE_ENABLE);
}
} }
/* Enable phy interrupt on auto-negotiation complete (or link up) */ /* Enable phy interrupt on auto-negotiation complete (or link up) */
...@@ -2959,6 +3027,8 @@ static u32 sky2_mhz(const struct sky2_hw *hw) ...@@ -2959,6 +3027,8 @@ static u32 sky2_mhz(const struct sky2_hw *hw)
case CHIP_ID_YUKON_SUPR: case CHIP_ID_YUKON_SUPR:
case CHIP_ID_YUKON_UL_2: case CHIP_ID_YUKON_UL_2:
case CHIP_ID_YUKON_OPT: case CHIP_ID_YUKON_OPT:
case CHIP_ID_YUKON_PRM:
case CHIP_ID_YUKON_OP_2:
return 125; return 125;
case CHIP_ID_YUKON_FE: case CHIP_ID_YUKON_FE:
...@@ -3064,6 +3134,8 @@ static int __devinit sky2_init(struct sky2_hw *hw) ...@@ -3064,6 +3134,8 @@ static int __devinit sky2_init(struct sky2_hw *hw)
break; break;
case CHIP_ID_YUKON_OPT: case CHIP_ID_YUKON_OPT:
case CHIP_ID_YUKON_PRM:
case CHIP_ID_YUKON_OP_2:
hw->flags = SKY2_HW_GIGABIT hw->flags = SKY2_HW_GIGABIT
| SKY2_HW_NEW_LE | SKY2_HW_NEW_LE
| SKY2_HW_ADV_POWER_CTL; | SKY2_HW_ADV_POWER_CTL;
...@@ -3163,30 +3235,33 @@ static void sky2_reset(struct sky2_hw *hw) ...@@ -3163,30 +3235,33 @@ static void sky2_reset(struct sky2_hw *hw)
sky2_pci_write32(hw, PCI_DEV_REG3, P_CLK_MACSEC_DIS); sky2_pci_write32(hw, PCI_DEV_REG3, P_CLK_MACSEC_DIS);
} }
if (hw->chip_id == CHIP_ID_YUKON_OPT) { if (hw->chip_id == CHIP_ID_YUKON_OPT ||
hw->chip_id == CHIP_ID_YUKON_PRM ||
hw->chip_id == CHIP_ID_YUKON_OP_2) {
u16 reg; u16 reg;
u32 msk; u32 msk;
if (hw->chip_rev == 0) { if (hw->chip_id == CHIP_ID_YUKON_OPT && hw->chip_rev == 0) {
/* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */ /* disable PCI-E PHY power down (set PHY reg 0x80, bit 7 */
sky2_write32(hw, Y2_PEX_PHY_DATA, (0x80UL << 16) | (1 << 7)); sky2_write32(hw, Y2_PEX_PHY_DATA, (0x80UL << 16) | (1 << 7));
/* set PHY Link Detect Timer to 1.1 second (11x 100ms) */ /* set PHY Link Detect Timer to 1.1 second (11x 100ms) */
reg = 10; reg = 10;
/* re-enable PEX PM in PEX PHY debug reg. 8 (clear bit 12) */
sky2_write32(hw, Y2_PEX_PHY_DATA, PEX_DB_ACCESS | (0x08UL << 16));
} else { } else {
/* set PHY Link Detect Timer to 0.4 second (4x 100ms) */ /* set PHY Link Detect Timer to 0.4 second (4x 100ms) */
reg = 3; reg = 3;
} }
reg <<= PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_BASE; reg <<= PSM_CONFIG_REG4_TIMER_PHY_LINK_DETECT_BASE;
reg |= PSM_CONFIG_REG4_RST_PHY_LINK_DETECT;
/* reset PHY Link Detect */ /* reset PHY Link Detect */
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
sky2_pci_write16(hw, PSM_CONFIG_REG4,
reg | PSM_CONFIG_REG4_RST_PHY_LINK_DETECT);
sky2_pci_write16(hw, PSM_CONFIG_REG4, reg); sky2_pci_write16(hw, PSM_CONFIG_REG4, reg);
/* enable PHY Quick Link */ /* enable PHY Quick Link */
msk = sky2_read32(hw, B0_IMSK); msk = sky2_read32(hw, B0_IMSK);
msk |= Y2_IS_PHY_QLNK; msk |= Y2_IS_PHY_QLNK;
...@@ -4710,9 +4785,11 @@ static const char *sky2_name(u8 chipid, char *buf, int sz) ...@@ -4710,9 +4785,11 @@ static const char *sky2_name(u8 chipid, char *buf, int sz)
"UL 2", /* 0xba */ "UL 2", /* 0xba */
"Unknown", /* 0xbb */ "Unknown", /* 0xbb */
"Optima", /* 0xbc */ "Optima", /* 0xbc */
"Optima Prime", /* 0xbd */
"Optima 2", /* 0xbe */
}; };
if (chipid >= CHIP_ID_YUKON_XL && chipid <= CHIP_ID_YUKON_OPT) if (chipid >= CHIP_ID_YUKON_XL && chipid <= CHIP_ID_YUKON_OP_2)
strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz); strncpy(buf, name[chipid - CHIP_ID_YUKON_XL], sz);
else else
snprintf(buf, sz, "(chip %#x)", chipid); snprintf(buf, sz, "(chip %#x)", chipid);
......
...@@ -412,7 +412,7 @@ enum { ...@@ -412,7 +412,7 @@ enum {
Y2_IS_HW_ERR = 1<<31, /* Interrupt HW Error */ Y2_IS_HW_ERR = 1<<31, /* Interrupt HW Error */
Y2_IS_STAT_BMU = 1<<30, /* Status BMU Interrupt */ Y2_IS_STAT_BMU = 1<<30, /* Status BMU Interrupt */
Y2_IS_ASF = 1<<29, /* ASF subsystem Interrupt */ Y2_IS_ASF = 1<<29, /* ASF subsystem Interrupt */
Y2_IS_CPU_TO = 1<<28, /* CPU Timeout */
Y2_IS_POLL_CHK = 1<<27, /* Check IRQ from polling unit */ Y2_IS_POLL_CHK = 1<<27, /* Check IRQ from polling unit */
Y2_IS_TWSI_RDY = 1<<26, /* IRQ on end of TWSI Tx */ Y2_IS_TWSI_RDY = 1<<26, /* IRQ on end of TWSI Tx */
Y2_IS_IRQ_SW = 1<<25, /* SW forced IRQ */ Y2_IS_IRQ_SW = 1<<25, /* SW forced IRQ */
...@@ -547,6 +547,8 @@ enum { ...@@ -547,6 +547,8 @@ enum {
CHIP_ID_YUKON_SUPR = 0xb9, /* YUKON-2 Supreme */ CHIP_ID_YUKON_SUPR = 0xb9, /* YUKON-2 Supreme */
CHIP_ID_YUKON_UL_2 = 0xba, /* YUKON-2 Ultra 2 */ CHIP_ID_YUKON_UL_2 = 0xba, /* YUKON-2 Ultra 2 */
CHIP_ID_YUKON_OPT = 0xbc, /* YUKON-2 Optima */ CHIP_ID_YUKON_OPT = 0xbc, /* YUKON-2 Optima */
CHIP_ID_YUKON_PRM = 0xbd, /* YUKON-2 Optima Prime */
CHIP_ID_YUKON_OP_2 = 0xbe, /* YUKON-2 Optima 2 */
}; };
enum yukon_xl_rev { enum yukon_xl_rev {
...@@ -1420,8 +1422,10 @@ enum { ...@@ -1420,8 +1422,10 @@ enum {
PHY_M_EC_FIB_AN_ENA = 1<<3, /* Fiber Auto-Neg. Enable (88E1011S only) */ PHY_M_EC_FIB_AN_ENA = 1<<3, /* Fiber Auto-Neg. Enable (88E1011S only) */
PHY_M_EC_DTE_D_ENA = 1<<2, /* DTE Detect Enable (88E1111 only) */ PHY_M_EC_DTE_D_ENA = 1<<2, /* DTE Detect Enable (88E1111 only) */
PHY_M_EC_TX_TIM_CT = 1<<1, /* RGMII Tx Timing Control */ PHY_M_EC_TX_TIM_CT = 1<<1, /* RGMII Tx Timing Control */
PHY_M_EC_TRANS_DIS = 1<<0, /* Transmitter Disable (88E1111 only) */}; PHY_M_EC_TRANS_DIS = 1<<0, /* Transmitter Disable (88E1111 only) */
PHY_M_10B_TE_ENABLE = 1<<7, /* 10Base-Te Enable (88E8079 and above) */
};
#define PHY_M_EC_M_DSC(x) ((u16)(x)<<10 & PHY_M_EC_M_DSC_MSK) #define PHY_M_EC_M_DSC(x) ((u16)(x)<<10 & PHY_M_EC_M_DSC_MSK)
/* 00=1x; 01=2x; 10=3x; 11=4x */ /* 00=1x; 01=2x; 10=3x; 11=4x */
#define PHY_M_EC_S_DSC(x) ((u16)(x)<<8 & PHY_M_EC_S_DSC_MSK) #define PHY_M_EC_S_DSC(x) ((u16)(x)<<8 & PHY_M_EC_S_DSC_MSK)
......
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