1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2015-2016 Freescale Semiconductor, Inc.
10 #include <dm/platform_data/pfe_dm_eth.h>
12 #include <net/pfe_eth/pfe_eth.h>
14 extern struct gemac_s gem_info[];
15 #if defined(CONFIG_PHYLIB)
17 #define MDIO_TIMEOUT 5000
18 static int pfe_write_addr(struct mii_dev *bus, int phy_addr, int dev_addr,
21 void *reg_base = bus->priv;
25 int timeout = MDIO_TIMEOUT;
27 devadr = ((dev_addr & EMAC_MII_DATA_RA_MASK) << EMAC_MII_DATA_RA_SHIFT);
28 phy = ((phy_addr & EMAC_MII_DATA_PA_MASK) << EMAC_MII_DATA_PA_SHIFT);
30 reg_data = (EMAC_MII_DATA_TA | phy | devadr | reg_addr);
32 writel(reg_data, reg_base + EMAC_MII_DATA_REG);
35 * wait for the MII interrupt
37 while (!(readl(reg_base + EMAC_IEVENT_REG) & EMAC_IEVENT_MII)) {
39 printf("Phy MDIO read/write timeout\n");
47 writel(EMAC_IEVENT_MII, reg_base + EMAC_IEVENT_REG);
52 static int pfe_phy_read(struct mii_dev *bus, int phy_addr, int dev_addr,
55 void *reg_base = bus->priv;
60 int timeout = MDIO_TIMEOUT;
62 if (dev_addr == MDIO_DEVAD_NONE) {
63 reg = ((reg_addr & EMAC_MII_DATA_RA_MASK) <<
64 EMAC_MII_DATA_RA_SHIFT);
66 pfe_write_addr(bus, phy_addr, dev_addr, reg_addr);
67 reg = ((dev_addr & EMAC_MII_DATA_RA_MASK) <<
68 EMAC_MII_DATA_RA_SHIFT);
71 phy = ((phy_addr & EMAC_MII_DATA_PA_MASK) << EMAC_MII_DATA_PA_SHIFT);
73 if (dev_addr == MDIO_DEVAD_NONE)
74 reg_data = (EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD |
75 EMAC_MII_DATA_TA | phy | reg);
77 reg_data = (EMAC_MII_DATA_OP_CL45_RD | EMAC_MII_DATA_TA |
80 writel(reg_data, reg_base + EMAC_MII_DATA_REG);
83 * wait for the MII interrupt
85 while (!(readl(reg_base + EMAC_IEVENT_REG) & EMAC_IEVENT_MII)) {
87 printf("Phy MDIO read/write timeout\n");
95 writel(EMAC_IEVENT_MII, reg_base + EMAC_IEVENT_REG);
98 * it's now safe to read the PHY's register
100 val = (u16)readl(reg_base + EMAC_MII_DATA_REG);
101 debug("%s: %p phy: 0x%x reg:0x%08x val:%#x\n", __func__, reg_base,
102 phy_addr, reg_addr, val);
107 static int pfe_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
108 int reg_addr, u16 data)
110 void *reg_base = bus->priv;
114 int timeout = MDIO_TIMEOUT;
116 if (dev_addr == MDIO_DEVAD_NONE) {
117 reg = ((reg_addr & EMAC_MII_DATA_RA_MASK) <<
118 EMAC_MII_DATA_RA_SHIFT);
120 pfe_write_addr(bus, phy_addr, dev_addr, reg_addr);
121 reg = ((dev_addr & EMAC_MII_DATA_RA_MASK) <<
122 EMAC_MII_DATA_RA_SHIFT);
125 phy = ((phy_addr & EMAC_MII_DATA_PA_MASK) << EMAC_MII_DATA_PA_SHIFT);
127 if (dev_addr == MDIO_DEVAD_NONE)
128 reg_data = (EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR |
129 EMAC_MII_DATA_TA | phy | reg | data);
131 reg_data = (EMAC_MII_DATA_OP_CL45_WR | EMAC_MII_DATA_TA |
134 writel(reg_data, reg_base + EMAC_MII_DATA_REG);
137 * wait for the MII interrupt
139 while (!(readl(reg_base + EMAC_IEVENT_REG) & EMAC_IEVENT_MII)) {
140 if (timeout-- <= 0) {
141 printf("Phy MDIO read/write timeout\n");
147 * clear MII interrupt
149 writel(EMAC_IEVENT_MII, reg_base + EMAC_IEVENT_REG);
151 debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phy_addr,
157 static void pfe_configure_serdes(struct pfe_eth_dev *priv)
160 int value, sgmii_2500 = 0;
161 struct gemac_s *gem = priv->gem;
163 if (gem->phy_mode == PHY_INTERFACE_MODE_SGMII_2500)
167 /* PCS configuration done with corresponding GEMAC */
168 bus.priv = gem_info[priv->gemac_port].gemac_base;
170 pfe_phy_read(&bus, 0, MDIO_DEVAD_NONE, 0x0);
171 pfe_phy_read(&bus, 0, MDIO_DEVAD_NONE, 0x1);
172 pfe_phy_read(&bus, 0, MDIO_DEVAD_NONE, 0x2);
173 pfe_phy_read(&bus, 0, MDIO_DEVAD_NONE, 0x3);
176 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x0, 0x8000);
178 /* SGMII IF mode + AN enable only for 1G SGMII, not for 2.5G */
179 value = PHY_SGMII_IF_MODE_SGMII;
181 value |= PHY_SGMII_IF_MODE_AN;
183 value |= PHY_SGMII_IF_MODE_SGMII_GBT;
185 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x14, value);
187 /* Dev ability according to SGMII specification */
188 value = PHY_SGMII_DEV_ABILITY_SGMII;
189 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x4, value);
191 /* These values taken from validation team */
193 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x13, 0x0);
194 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x12, 0x400);
196 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x13, 0x7);
197 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x12, 0xa120);
201 value = PHY_SGMII_CR_DEF_VAL;
203 value |= PHY_SGMII_CR_RESET_AN;
204 /* Disable Auto neg for 2.5G SGMII as it doesn't support auto neg*/
206 value &= ~PHY_SGMII_ENABLE_AN;
207 pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0, value);
210 int pfe_phy_configure(struct pfe_eth_dev *priv, int dev_id, int phy_id)
212 struct phy_device *phydev = NULL;
213 struct udevice *dev = priv->dev;
214 struct gemac_s *gem = priv->gem;
215 struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
220 /* Configure SGMII PCS */
221 if (gem->phy_mode == PHY_INTERFACE_MODE_SGMII ||
222 gem->phy_mode == PHY_INTERFACE_MODE_SGMII_2500) {
223 out_be32(&scfg->mdioselcr, 0x00000000);
224 pfe_configure_serdes(priv);
229 /* By this time on-chip SGMII initialization is done
230 * we can switch mdio interface to external PHYs
232 out_be32(&scfg->mdioselcr, 0x80000000);
234 phydev = phy_connect(gem->bus, phy_id, dev, gem->phy_mode);
236 printf("phy_connect failed\n");
242 priv->phydev = phydev;
248 struct mii_dev *pfe_mdio_init(struct pfe_mdio_info *mdio_info)
253 u32 pclk = 250000000;
257 printf("mdio_alloc failed\n");
260 bus->read = pfe_phy_read;
261 bus->write = pfe_phy_write;
263 /* MAC1 MDIO used to communicate with external PHYS */
264 bus->priv = mdio_info->reg_base;
265 sprintf(bus->name, mdio_info->name);
267 /* configure mdio speed */
268 mdio_speed = (DIV_ROUND_UP(pclk, 4000000) << EMAC_MII_SPEED_SHIFT);
269 mdio_speed |= EMAC_HOLDTIME(0x5);
270 writel(mdio_speed, mdio_info->reg_base + EMAC_MII_CTRL_REG);
272 ret = mdio_register(bus);
274 printf("mdio_register failed\n");
281 void pfe_set_mdio(int dev_id, struct mii_dev *bus)
283 gem_info[dev_id].bus = bus;
286 void pfe_set_phy_address_mode(int dev_id, int phy_id, int phy_mode)
288 gem_info[dev_id].phy_address = phy_id;
289 gem_info[dev_id].phy_mode = phy_mode;