1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2015-2016 Freescale Semiconductor, Inc.
4  * Copyright 2017 NXP
5  */
6 #include <config.h>
7 #include <dm.h>
8 #include <log.h>
9 #include <malloc.h>
10 #include <dm/platform_data/pfe_dm_eth.h>
11 #include <net.h>
12 #include <linux/delay.h>
13 #include <net/pfe_eth/pfe_eth.h>
14 
15 extern struct gemac_s gem_info[];
16 #if defined(CONFIG_PHYLIB)
17 
18 #define MDIO_TIMEOUT    5000
pfe_write_addr(struct mii_dev * bus,int phy_addr,int dev_addr,int reg_addr)19 static int pfe_write_addr(struct mii_dev *bus, int phy_addr, int dev_addr,
20 			  int reg_addr)
21 {
22 	void *reg_base = bus->priv;
23 	u32 devadr;
24 	u32 phy;
25 	u32 reg_data;
26 	int timeout = MDIO_TIMEOUT;
27 
28 	devadr = ((dev_addr & EMAC_MII_DATA_RA_MASK) << EMAC_MII_DATA_RA_SHIFT);
29 	phy = ((phy_addr & EMAC_MII_DATA_PA_MASK) << EMAC_MII_DATA_PA_SHIFT);
30 
31 	reg_data = (EMAC_MII_DATA_TA | phy | devadr | reg_addr);
32 
33 	writel(reg_data, reg_base + EMAC_MII_DATA_REG);
34 
35 	/*
36 	 * wait for the MII interrupt
37 	 */
38 	while (!(readl(reg_base + EMAC_IEVENT_REG) & EMAC_IEVENT_MII)) {
39 		if (timeout-- <= 0) {
40 			printf("Phy MDIO read/write timeout\n");
41 			return -1;
42 		}
43 	}
44 
45 	/*
46 	 * clear MII interrupt
47 	 */
48 	writel(EMAC_IEVENT_MII, reg_base + EMAC_IEVENT_REG);
49 
50 	return 0;
51 }
52 
pfe_phy_read(struct mii_dev * bus,int phy_addr,int dev_addr,int reg_addr)53 static int pfe_phy_read(struct mii_dev *bus, int phy_addr, int dev_addr,
54 			int reg_addr)
55 {
56 	void *reg_base = bus->priv;
57 	u32 reg;
58 	u32 phy;
59 	u32 reg_data;
60 	u16 val;
61 	int timeout = MDIO_TIMEOUT;
62 
63 	if (dev_addr == MDIO_DEVAD_NONE) {
64 		reg = ((reg_addr & EMAC_MII_DATA_RA_MASK) <<
65 			EMAC_MII_DATA_RA_SHIFT);
66 	} else {
67 		pfe_write_addr(bus, phy_addr, dev_addr, reg_addr);
68 		reg = ((dev_addr & EMAC_MII_DATA_RA_MASK) <<
69 		       EMAC_MII_DATA_RA_SHIFT);
70 	}
71 
72 	phy = ((phy_addr & EMAC_MII_DATA_PA_MASK) << EMAC_MII_DATA_PA_SHIFT);
73 
74 	if (dev_addr == MDIO_DEVAD_NONE)
75 		reg_data = (EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD |
76 			    EMAC_MII_DATA_TA | phy | reg);
77 	else
78 		reg_data = (EMAC_MII_DATA_OP_CL45_RD | EMAC_MII_DATA_TA |
79 			    phy | reg);
80 
81 	writel(reg_data, reg_base + EMAC_MII_DATA_REG);
82 
83 	/*
84 	 * wait for the MII interrupt
85 	 */
86 	while (!(readl(reg_base + EMAC_IEVENT_REG) & EMAC_IEVENT_MII)) {
87 		if (timeout-- <= 0) {
88 			printf("Phy MDIO read/write timeout\n");
89 			return -1;
90 		}
91 	}
92 
93 	/*
94 	 * clear MII interrupt
95 	 */
96 	writel(EMAC_IEVENT_MII, reg_base + EMAC_IEVENT_REG);
97 
98 	/*
99 	 * it's now safe to read the PHY's register
100 	 */
101 	val = (u16)readl(reg_base + EMAC_MII_DATA_REG);
102 	debug("%s: %p phy: 0x%x reg:0x%08x val:%#x\n", __func__, reg_base,
103 	      phy_addr, reg_addr, val);
104 
105 	return val;
106 }
107 
pfe_phy_write(struct mii_dev * bus,int phy_addr,int dev_addr,int reg_addr,u16 data)108 static int pfe_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
109 			 int reg_addr, u16 data)
110 {
111 	void *reg_base = bus->priv;
112 	u32 reg;
113 	u32 phy;
114 	u32 reg_data;
115 	int timeout = MDIO_TIMEOUT;
116 
117 	if (dev_addr == MDIO_DEVAD_NONE) {
118 		reg = ((reg_addr & EMAC_MII_DATA_RA_MASK) <<
119 		       EMAC_MII_DATA_RA_SHIFT);
120 	} else {
121 		pfe_write_addr(bus, phy_addr, dev_addr, reg_addr);
122 		reg = ((dev_addr & EMAC_MII_DATA_RA_MASK) <<
123 		       EMAC_MII_DATA_RA_SHIFT);
124 	}
125 
126 	phy = ((phy_addr & EMAC_MII_DATA_PA_MASK) << EMAC_MII_DATA_PA_SHIFT);
127 
128 	if (dev_addr == MDIO_DEVAD_NONE)
129 		reg_data = (EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR |
130 			    EMAC_MII_DATA_TA | phy | reg | data);
131 	else
132 		reg_data = (EMAC_MII_DATA_OP_CL45_WR | EMAC_MII_DATA_TA |
133 			    phy | reg | data);
134 
135 	writel(reg_data, reg_base + EMAC_MII_DATA_REG);
136 
137 	/*
138 	 * wait for the MII interrupt
139 	 */
140 	while (!(readl(reg_base + EMAC_IEVENT_REG) & EMAC_IEVENT_MII)) {
141 		if (timeout-- <= 0) {
142 			printf("Phy MDIO read/write timeout\n");
143 			return -1;
144 		}
145 	}
146 
147 	/*
148 	 * clear MII interrupt
149 	 */
150 	writel(EMAC_IEVENT_MII, reg_base + EMAC_IEVENT_REG);
151 
152 	debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phy_addr,
153 	      reg_addr, data);
154 
155 	return 0;
156 }
157 
pfe_configure_serdes(struct pfe_eth_dev * priv)158 static void pfe_configure_serdes(struct pfe_eth_dev *priv)
159 {
160 	struct mii_dev bus;
161 	int value, sgmii_2500 = 0;
162 	struct gemac_s *gem = priv->gem;
163 
164 	if (gem->phy_mode == PHY_INTERFACE_MODE_2500BASEX)
165 		sgmii_2500 = 1;
166 
167 	/* PCS configuration done with corresponding GEMAC */
168 	bus.priv = gem_info[priv->gemac_port].gemac_base;
169 
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);
174 
175 	/* Reset serdes */
176 	pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x0, 0x8000);
177 
178 	/* SGMII IF mode + AN enable only for 1G SGMII, not for 2.5G */
179 	value = PHY_SGMII_IF_MODE_SGMII;
180 	if (!sgmii_2500)
181 		value |= PHY_SGMII_IF_MODE_AN;
182 	else
183 		value |= PHY_SGMII_IF_MODE_SGMII_GBT;
184 
185 	pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x14, value);
186 
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);
190 
191 	/* These values taken from validation team */
192 	if (!sgmii_2500) {
193 		pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x13, 0x0);
194 		pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x12, 0x400);
195 	} else {
196 		pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x13, 0x7);
197 		pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0x12, 0xa120);
198 	}
199 
200 	/* Restart AN */
201 	value = PHY_SGMII_CR_DEF_VAL;
202 	if (!sgmii_2500)
203 		value |= PHY_SGMII_CR_RESET_AN;
204 	/* Disable Auto neg for 2.5G SGMII as it doesn't support auto neg*/
205 	if (sgmii_2500)
206 		value &= ~PHY_SGMII_ENABLE_AN;
207 	pfe_phy_write(&bus, 0, MDIO_DEVAD_NONE, 0, value);
208 }
209 
pfe_phy_configure(struct pfe_eth_dev * priv,int dev_id,int phy_id)210 int pfe_phy_configure(struct pfe_eth_dev *priv, int dev_id, int phy_id)
211 {
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 *)CFG_SYS_FSL_SCFG_ADDR;
216 
217 	if (!gem->bus)
218 		return -1;
219 
220 	/* Configure SGMII  PCS */
221 	if (gem->phy_mode == PHY_INTERFACE_MODE_SGMII ||
222 	    gem->phy_mode == PHY_INTERFACE_MODE_2500BASEX) {
223 		out_be32(&scfg->mdioselcr, 0x00000000);
224 		pfe_configure_serdes(priv);
225 	}
226 
227 	mdelay(100);
228 
229 	/* By this time on-chip SGMII initialization is done
230 	 * we can switch mdio interface to external PHYs
231 	 */
232 	out_be32(&scfg->mdioselcr, 0x80000000);
233 
234 	phydev = phy_connect(gem->bus, phy_id, dev, gem->phy_mode);
235 	if (!phydev) {
236 		printf("phy_connect failed\n");
237 		return -ENODEV;
238 	}
239 
240 	phy_config(phydev);
241 
242 	priv->phydev = phydev;
243 
244 	return 0;
245 }
246 #endif
247 
pfe_mdio_init(struct pfe_mdio_info * mdio_info)248 struct mii_dev *pfe_mdio_init(struct pfe_mdio_info *mdio_info)
249 {
250 	struct mii_dev *bus;
251 	int ret;
252 	u32 mdio_speed;
253 	u32 pclk = 250000000;
254 
255 	bus = mdio_alloc();
256 	if (!bus) {
257 		printf("mdio_alloc failed\n");
258 		return NULL;
259 	}
260 	bus->read = pfe_phy_read;
261 	bus->write = pfe_phy_write;
262 
263 	/* MAC1 MDIO used to communicate with external PHYS */
264 	bus->priv = mdio_info->reg_base;
265 	sprintf(bus->name, mdio_info->name);
266 
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);
271 
272 	ret = mdio_register(bus);
273 	if (ret) {
274 		printf("mdio_register failed\n");
275 		free(bus);
276 		return NULL;
277 	}
278 	return bus;
279 }
280 
pfe_set_mdio(int dev_id,struct mii_dev * bus)281 void pfe_set_mdio(int dev_id, struct mii_dev *bus)
282 {
283 	gem_info[dev_id].bus = bus;
284 }
285 
pfe_set_phy_address_mode(int dev_id,int phy_id,int phy_mode)286 void pfe_set_phy_address_mode(int dev_id, int phy_id, int phy_mode)
287 {
288 	gem_info[dev_id].phy_address = phy_id;
289 	gem_info[dev_id].phy_mode  = phy_mode;
290 }
291