diff options
Diffstat (limited to 'drivers/net/zynq_gem.c')
| -rw-r--r-- | drivers/net/zynq_gem.c | 95 |
1 files changed, 93 insertions, 2 deletions
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 703e22479d2..407b022508c 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -162,7 +162,9 @@ struct zynq_gem_regs { u32 idr; /* 0x2c - Interrupt Disable reg */ u32 reserved3; u32 phymntnc; /* 0x34 - Phy Maintaince reg */ - u32 reserved4[18]; + u32 reserved4[6]; + u32 hsmaccfg; /* 0x50 - HS MAC Config reg */ + u32 reserved5[11]; u32 hashl; /* 0x80 - Hash Low address reg */ u32 hashh; /* 0x84 - Hash High address reg */ #define LADDR_LOW 0 @@ -185,6 +187,10 @@ struct zynq_gem_regs { u32 upper_txqbase; /* 0x4C8 - Upper tx_q base addr */ u32 reserved11[2]; u32 upper_rxqbase; /* 0x4D4 - Upper rx_q base addr */ + u32 reserved13[362]; + u32 usxctrlreg; /* 0xA80 - Usx Control reg */ + u32 reserved14; + u32 usxstatusreg; /* 0xA88 - Usx Status reg */ }; /* BD descriptors */ @@ -209,6 +215,27 @@ struct emac_bd { /* Setup the first free TX descriptor */ #define TX_FREE_DESC 2 +#define HS_SPEED_1000M 1 +#define HS_SPEED_2500M 2 +#define HS_SPEED_5000M 3 +#define HS_SPEED_10000M 4 +#define MACB_SERDES_RATE_5G_2G5_1G 0 +#define MACB_SERDES_RATE_10G 1 +#define USX_BLOCK_LOCK BIT(0) +#define TX_SCR_BYPASS BIT(8) +#define RX_SCR_BYPASS BIT(9) +#define RX_SYNC_RESET BIT(2) +#define SPEED_5000 5000 +#define TX_EN BIT(1) +#define SIGNAL_OK BIT(0) +#define ENABLE_HS_MAC BIT(31) +#define PCSSEL BIT(11) +#define HS_MAC_SPEED_MASK 0x3 +#define USX_CONFIG_SERDES_RATE_MASK 0x3 +#define USX_CONFIG_SERDES_RATE_SHIFT 12 +#define USX_CONFIG_SPEED_MASK 0x3 +#define USX_CONFIG_SPEED_SHIFT 14 + /* Initialized, rxbd_current, rx_first_buf must be 0 after init */ struct zynq_gem_priv { struct emac_bd *tx_bd; @@ -391,9 +418,11 @@ static int zynq_phy_init(struct udevice *dev) static int zynq_gem_init(struct udevice *dev) { - u32 i, nwconfig, nwcfg; int ret; + u32 i, nwconfig, nwcfg, ctrl, ncr; unsigned long clk_rate = 0; + unsigned long speed_val, serdes_rate, config; + unsigned long clear_speed_val_mask, clear_serdes_rate_mask; struct zynq_gem_priv *priv = dev_get_priv(dev); struct zynq_gem_regs *regs = priv->iobase; struct zynq_gem_regs *regs_mdio = priv->mdiobase; @@ -499,6 +528,67 @@ static int zynq_gem_init(struct udevice *dev) nwconfig = ZYNQ_GEM_NWCFG_INIT; + if (device_is_compatible(dev, "amd,versal2-10gbe")) { + if (priv->interface == PHY_INTERFACE_MODE_10GBASER) { + ctrl = readl(®s->nwcfg); + ctrl |= PCSSEL; + writel(ctrl, ®s->nwcfg); + ncr = readl(®s->nwctrl); + ncr |= ENABLE_HS_MAC; + writel(ncr, ®s->nwctrl); + } + switch (priv->phydev->speed) { + case SPEED_1000: + speed_val = HS_SPEED_1000M; + serdes_rate = MACB_SERDES_RATE_5G_2G5_1G; + break; + case SPEED_2500: + speed_val = HS_SPEED_2500M; + serdes_rate = MACB_SERDES_RATE_5G_2G5_1G; + break; + case SPEED_5000: + speed_val = HS_SPEED_5000M; + serdes_rate = MACB_SERDES_RATE_5G_2G5_1G; + break; + case SPEED_10000: + speed_val = HS_SPEED_10000M; + serdes_rate = MACB_SERDES_RATE_10G; + break; + default: + printf("Specified speed not supported =%d\n", priv->phydev->speed); + break; + } + + config = readl(®s->hsmaccfg); + config = (config & ~HS_MAC_SPEED_MASK) | speed_val; + writel(config, ®s->hsmaccfg); + + config = readl(®s->usxctrlreg); + config |= SIGNAL_OK; + clear_serdes_rate_mask = ~(USX_CONFIG_SERDES_RATE_MASK << + USX_CONFIG_SERDES_RATE_SHIFT); + config = (config & clear_serdes_rate_mask) | + serdes_rate << USX_CONFIG_SERDES_RATE_SHIFT; + + clear_speed_val_mask = ~(USX_CONFIG_SPEED_MASK << + USX_CONFIG_SPEED_SHIFT); + config = (config & clear_speed_val_mask) | + speed_val << USX_CONFIG_SPEED_SHIFT; + config &= ~(TX_SCR_BYPASS | RX_SCR_BYPASS); + config |= RX_SYNC_RESET; + writel(config, ®s->usxctrlreg); + + mdelay(250); + config &= ~(RX_SYNC_RESET); + config |= (TX_EN); + writel(config, ®s->usxctrlreg); + + ret = wait_for_bit_le32(®s->usxstatusreg, USX_BLOCK_LOCK, + true, 20000, true); + if (ret) + printf("usx block lock failed\n"); + } + /* * Set SGMII enable PCS selection only if internal PCS/PMA * core is used and interface is SGMII. @@ -997,6 +1087,7 @@ static int zynq_gem_of_to_plat(struct udevice *dev) } static const struct udevice_id zynq_gem_ids[] = { + { .compatible = "amd,versal2-10gbe" }, { .compatible = "xlnx,versal-gem", .data = RXCLK_EN }, { .compatible = "cdns,versal-gem", .data = RXCLK_EN }, { .compatible = "xlnx,zynqmp-gem" }, |
