fec_mxc.c 33.3 KB
Newer Older
1 2 3 4 5 6 7
/*
 * (C) Copyright 2009 Ilya Yanok, Emcraft Systems Ltd <yanok@emcraft.com>
 * (C) Copyright 2008,2009 Eric Jarrige <eric.jarrige@armadeus.org>
 * (C) Copyright 2008 Armadeus Systems nc
 * (C) Copyright 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
 * (C) Copyright 2007 Pengutronix, Juergen Beisert <j.beisert@pengutronix.de>
 *
8
 * SPDX-License-Identifier:	GPL-2.0+
9 10 11
 */

#include <common.h>
12
#include <dm.h>
13
#include <malloc.h>
14
#include <memalign.h>
J
Jagan Teki 已提交
15
#include <miiphy.h>
16
#include <net.h>
17
#include <netdev.h>
18 19 20
#include "fec_mxc.h"

#include <asm/io.h>
21
#include <linux/errno.h>
22
#include <linux/compiler.h>
23

J
Jagan Teki 已提交
24 25
#include <asm/arch/clock.h>
#include <asm/arch/imx-regs.h>
26
#include <asm/mach-imx/sys_proto.h>
J
Jagan Teki 已提交
27

28 29
DECLARE_GLOBAL_DATA_PTR;

30 31 32 33 34 35
/*
 * Timeout the transfer after 5 mS. This is usually a bit more, since
 * the code in the tightloops this timeout is used in adds some overhead.
 */
#define FEC_XFER_TIMEOUT	5000

36 37 38 39 40 41 42 43
/*
 * The standard 32-byte DMA alignment does not work on mx6solox, which requires
 * 64-byte alignment in the DMA RX FEC buffer.
 * Introduce the FEC_DMA_RX_MINALIGN which can cover mx6solox needs and also
 * satisfies the alignment on other SoCs (32-bytes)
 */
#define FEC_DMA_RX_MINALIGN	64

44 45 46 47
#ifndef CONFIG_MII
#error "CONFIG_MII has to be defined!"
#endif

48 49
#ifndef CONFIG_FEC_XCV_TYPE
#define CONFIG_FEC_XCV_TYPE MII100
50 51
#endif

M
Marek Vasut 已提交
52 53 54 55
/*
 * The i.MX28 operates with packets in big endian. We need to swap them before
 * sending and after receiving.
 */
56 57 58 59 60 61 62 63 64 65 66 67 68 69
#ifdef CONFIG_MX28
#define CONFIG_FEC_MXC_SWAP_PACKET
#endif

#define RXDESC_PER_CACHELINE (ARCH_DMA_MINALIGN/sizeof(struct fec_bd))

/* Check various alignment issues at compile time */
#if ((ARCH_DMA_MINALIGN < 16) || (ARCH_DMA_MINALIGN % 16 != 0))
#error "ARCH_DMA_MINALIGN must be multiple of 16!"
#endif

#if ((PKTALIGN < ARCH_DMA_MINALIGN) || \
	(PKTALIGN % ARCH_DMA_MINALIGN != 0))
#error "PKTALIGN must be multiple of ARCH_DMA_MINALIGN!"
M
Marek Vasut 已提交
70 71
#endif

72 73
#undef DEBUG

74
#ifdef CONFIG_FEC_MXC_SWAP_PACKET
M
Marek Vasut 已提交
75 76 77 78 79 80 81 82 83
static void swap_packet(uint32_t *packet, int length)
{
	int i;

	for (i = 0; i < DIV_ROUND_UP(length, 4); i++)
		packet[i] = __swab32(packet[i]);
}
#endif

J
Jagan Teki 已提交
84 85 86
/* MII-interface related functions */
static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyaddr,
		uint8_t regaddr)
87 88 89 90
{
	uint32_t reg;		/* convenient holder for the PHY register */
	uint32_t phy;		/* convenient holder for the PHY */
	uint32_t start;
T
Troy Kisky 已提交
91
	int val;
92 93 94 95 96

	/*
	 * reading from any PHY's register is done by properly
	 * programming the FEC's MII data register.
	 */
97
	writel(FEC_IEVENT_MII, &eth->ievent);
J
Jagan Teki 已提交
98 99
	reg = regaddr << FEC_MII_DATA_RA_SHIFT;
	phy = phyaddr << FEC_MII_DATA_PA_SHIFT;
100 101

	writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA |
102
			phy | reg, &eth->mii_data);
103

J
Jagan Teki 已提交
104
	/* wait for the related interrupt */
105
	start = get_timer(0);
106
	while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
107 108 109 110 111 112
		if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
			printf("Read MDIO failed...\n");
			return -1;
		}
	}

J
Jagan Teki 已提交
113
	/* clear mii interrupt bit */
114
	writel(FEC_IEVENT_MII, &eth->ievent);
115

J
Jagan Teki 已提交
116
	/* it's now safe to read the PHY's register */
T
Troy Kisky 已提交
117
	val = (unsigned short)readl(&eth->mii_data);
J
Jagan Teki 已提交
118 119
	debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyaddr,
	      regaddr, val);
T
Troy Kisky 已提交
120
	return val;
121 122
}

123
static void fec_mii_setspeed(struct ethernet_regs *eth)
124 125 126 127
{
	/*
	 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
	 * and do not drop the Preamble.
128 129 130 131 132 133 134 135 136 137 138
	 *
	 * The i.MX28 and i.MX6 types have another field in the MSCR (aka
	 * MII_SPEED) register that defines the MDIO output hold time. Earlier
	 * versions are RAZ there, so just ignore the difference and write the
	 * register always.
	 * The minimal hold time according to IEE802.3 (clause 22) is 10 ns.
	 * HOLDTIME + 1 is the number of clk cycles the fec is holding the
	 * output.
	 * The HOLDTIME bitfield takes values between 0 and 7 (inclusive).
	 * Given that ceil(clkrate / 5000000) <= 64, the calculation for
	 * holdtime cannot result in a value greater than 3.
139
	 */
140 141 142
	u32 pclk = imx_get_fecclk();
	u32 speed = DIV_ROUND_UP(pclk, 5000000);
	u32 hold = DIV_ROUND_UP(pclk, 100000000) - 1;
143 144 145
#ifdef FEC_QUIRK_ENET_MAC
	speed--;
#endif
146
	writel(speed << 1 | hold << 8, &eth->mii_speed);
147
	debug("%s: mii_speed %08x\n", __func__, readl(&eth->mii_speed));
148
}
149

J
Jagan Teki 已提交
150 151
static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyaddr,
		uint8_t regaddr, uint16_t data)
T
Troy Kisky 已提交
152
{
153 154 155 156
	uint32_t reg;		/* convenient holder for the PHY register */
	uint32_t phy;		/* convenient holder for the PHY */
	uint32_t start;

J
Jagan Teki 已提交
157 158
	reg = regaddr << FEC_MII_DATA_RA_SHIFT;
	phy = phyaddr << FEC_MII_DATA_PA_SHIFT;
159 160

	writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR |
161
		FEC_MII_DATA_TA | phy | reg | data, &eth->mii_data);
162

J
Jagan Teki 已提交
163
	/* wait for the MII interrupt */
164
	start = get_timer(0);
165
	while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
166 167 168 169 170 171
		if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
			printf("Write MDIO failed...\n");
			return -1;
		}
	}

J
Jagan Teki 已提交
172
	/* clear MII interrupt bit */
173
	writel(FEC_IEVENT_MII, &eth->ievent);
J
Jagan Teki 已提交
174 175
	debug("%s: phy: %02x reg:%02x val:%#x\n", __func__, phyaddr,
	      regaddr, data);
176 177 178 179

	return 0;
}

J
Jagan Teki 已提交
180 181
static int fec_phy_read(struct mii_dev *bus, int phyaddr, int dev_addr,
			int regaddr)
T
Troy Kisky 已提交
182
{
J
Jagan Teki 已提交
183
	return fec_mdio_read(bus->priv, phyaddr, regaddr);
T
Troy Kisky 已提交
184 185
}

J
Jagan Teki 已提交
186 187
static int fec_phy_write(struct mii_dev *bus, int phyaddr, int dev_addr,
			 int regaddr, u16 data)
T
Troy Kisky 已提交
188
{
J
Jagan Teki 已提交
189
	return fec_mdio_write(bus->priv, phyaddr, regaddr, data);
T
Troy Kisky 已提交
190 191 192
}

#ifndef CONFIG_PHYLIB
193 194
static int miiphy_restart_aneg(struct eth_device *dev)
{
195 196
	int ret = 0;
#if !defined(CONFIG_FEC_MXC_NO_ANEG)
M
Marek Vasut 已提交
197
	struct fec_priv *fec = (struct fec_priv *)dev->priv;
T
Troy Kisky 已提交
198
	struct ethernet_regs *eth = fec->bus->priv;
M
Marek Vasut 已提交
199

200 201 202 203
	/*
	 * Wake up from sleep if necessary
	 * Reset PHY, then delay 300ns
	 */
204
#ifdef CONFIG_MX27
T
Troy Kisky 已提交
205
	fec_mdio_write(eth, fec->phy_id, MII_DCOUNTER, 0x00FF);
206
#endif
T
Troy Kisky 已提交
207
	fec_mdio_write(eth, fec->phy_id, MII_BMCR, BMCR_RESET);
208 209
	udelay(1000);

J
Jagan Teki 已提交
210
	/* Set the auto-negotiation advertisement register bits */
T
Troy Kisky 已提交
211
	fec_mdio_write(eth, fec->phy_id, MII_ADVERTISE,
J
Jagan Teki 已提交
212 213
		       LPA_100FULL | LPA_100HALF | LPA_10FULL |
		       LPA_10HALF | PHY_ANLPAR_PSB_802_3);
T
Troy Kisky 已提交
214
	fec_mdio_write(eth, fec->phy_id, MII_BMCR,
J
Jagan Teki 已提交
215
		       BMCR_ANENABLE | BMCR_ANRESTART);
216 217 218 219

	if (fec->mii_postcall)
		ret = fec->mii_postcall(fec->phy_id);

220
#endif
221
	return ret;
222 223
}

224
#ifndef CONFIG_FEC_FIXED_SPEED
225 226 227
static int miiphy_wait_aneg(struct eth_device *dev)
{
	uint32_t start;
T
Troy Kisky 已提交
228
	int status;
M
Marek Vasut 已提交
229
	struct fec_priv *fec = (struct fec_priv *)dev->priv;
T
Troy Kisky 已提交
230
	struct ethernet_regs *eth = fec->bus->priv;
231

J
Jagan Teki 已提交
232
	/* Wait for AN completion */
233
	start = get_timer(0);
234 235 236 237 238 239
	do {
		if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
			printf("%s: Autonegotiation timeout\n", dev->name);
			return -1;
		}

T
Troy Kisky 已提交
240 241 242
		status = fec_mdio_read(eth, fec->phy_id, MII_BMSR);
		if (status < 0) {
			printf("%s: Autonegotiation failed. status: %d\n",
J
Jagan Teki 已提交
243
			       dev->name, status);
244 245
			return -1;
		}
M
Mike Frysinger 已提交
246
	} while (!(status & BMSR_LSTATUS));
247 248 249

	return 0;
}
250
#endif /* CONFIG_FEC_FIXED_SPEED */
T
Troy Kisky 已提交
251 252
#endif

253 254
static int fec_rx_task_enable(struct fec_priv *fec)
{
M
Marek Vasut 已提交
255
	writel(FEC_R_DES_ACTIVE_RDAR, &fec->eth->r_des_active);
256 257 258 259 260 261 262 263 264 265
	return 0;
}

static int fec_rx_task_disable(struct fec_priv *fec)
{
	return 0;
}

static int fec_tx_task_enable(struct fec_priv *fec)
{
M
Marek Vasut 已提交
266
	writel(FEC_X_DES_ACTIVE_TDAR, &fec->eth->x_des_active);
267 268 269 270 271 272 273 274 275 276 277 278
	return 0;
}

static int fec_tx_task_disable(struct fec_priv *fec)
{
	return 0;
}

/**
 * Initialize receive task's buffer descriptors
 * @param[in] fec all we know about the device yet
 * @param[in] count receive buffer count to be allocated
279
 * @param[in] dsize desired size of each receive buffer
280 281
 * @return 0 on success
 *
M
Marek Vasut 已提交
282
 * Init all RX descriptors to default values.
283
 */
M
Marek Vasut 已提交
284
static void fec_rbd_init(struct fec_priv *fec, int count, int dsize)
285
{
286
	uint32_t size;
M
Marek Vasut 已提交
287
	uint8_t *data;
288 289
	int i;

290
	/*
M
Marek Vasut 已提交
291 292
	 * Reload the RX descriptors with default values and wipe
	 * the RX buffers.
293
	 */
294 295
	size = roundup(dsize, ARCH_DMA_MINALIGN);
	for (i = 0; i < count; i++) {
M
Marek Vasut 已提交
296 297 298 299 300 301
		data = (uint8_t *)fec->rbd_base[i].data_pointer;
		memset(data, 0, dsize);
		flush_dcache_range((uint32_t)data, (uint32_t)data + size);

		fec->rbd_base[i].status = FEC_RBD_EMPTY;
		fec->rbd_base[i].data_length = 0;
302 303 304
	}

	/* Mark the last RBD to close the ring. */
M
Marek Vasut 已提交
305
	fec->rbd_base[i - 1].status = FEC_RBD_WRAP | FEC_RBD_EMPTY;
306 307
	fec->rbd_index = 0;

M
Marek Vasut 已提交
308 309
	flush_dcache_range((unsigned)fec->rbd_base,
			   (unsigned)fec->rbd_base + size);
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
}

/**
 * Initialize transmit task's buffer descriptors
 * @param[in] fec all we know about the device yet
 *
 * Transmit buffers are created externally. We only have to init the BDs here.\n
 * Note: There is a race condition in the hardware. When only one BD is in
 * use it must be marked with the WRAP bit to use it for every transmitt.
 * This bit in combination with the READY bit results into double transmit
 * of each data buffer. It seems the state machine checks READY earlier then
 * resetting it after the first transfer.
 * Using two BDs solves this issue.
 */
static void fec_tbd_init(struct fec_priv *fec)
{
326 327 328
	unsigned addr = (unsigned)fec->tbd_base;
	unsigned size = roundup(2 * sizeof(struct fec_bd),
				ARCH_DMA_MINALIGN);
M
Marek Vasut 已提交
329 330 331 332

	memset(fec->tbd_base, 0, size);
	fec->tbd_base[0].status = 0;
	fec->tbd_base[1].status = FEC_TBD_WRAP;
333
	fec->tbd_index = 0;
M
Marek Vasut 已提交
334
	flush_dcache_range(addr, addr + size);
335 336 337 338 339
}

/**
 * Mark the given read buffer descriptor as free
 * @param[in] last 1 if this is the last buffer descriptor in the chain, else 0
J
Jagan Teki 已提交
340
 * @param[in] prbd buffer descriptor to mark free again
341
 */
J
Jagan Teki 已提交
342
static void fec_rbd_clean(int last, struct fec_bd *prbd)
343
{
344
	unsigned short flags = FEC_RBD_EMPTY;
345
	if (last)
346
		flags |= FEC_RBD_WRAP;
J
Jagan Teki 已提交
347 348
	writew(flags, &prbd->status);
	writew(0, &prbd->data_length);
349 350
}

351
static int fec_get_hwaddr(int dev_id, unsigned char *mac)
352
{
353
	imx_get_mac_from_fuse(dev_id, mac);
354
	return !is_valid_ethaddr(mac);
355 356
}

357 358 359
#ifdef CONFIG_DM_ETH
static int fecmxc_set_hwaddr(struct udevice *dev)
#else
360
static int fec_set_hwaddr(struct eth_device *dev)
361
#endif
362
{
363 364 365 366 367
#ifdef CONFIG_DM_ETH
	struct fec_priv *fec = dev_get_priv(dev);
	struct eth_pdata *pdata = dev_get_platdata(dev);
	uchar *mac = pdata->enetaddr;
#else
368
	uchar *mac = dev->enetaddr;
369
	struct fec_priv *fec = (struct fec_priv *)dev->priv;
370
#endif
371 372 373 374 375 376

	writel(0, &fec->eth->iaddr1);
	writel(0, &fec->eth->iaddr2);
	writel(0, &fec->eth->gaddr1);
	writel(0, &fec->eth->gaddr2);

J
Jagan Teki 已提交
377
	/* Set physical address */
378
	writel((mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3],
J
Jagan Teki 已提交
379
	       &fec->eth->paddr1);
380 381 382 383 384
	writel((mac[4] << 24) + (mac[5] << 16) + 0x8808, &fec->eth->paddr2);

	return 0;
}

J
Jagan Teki 已提交
385
/* Do initial configuration of the FEC registers */
M
Marek Vasut 已提交
386 387 388 389
static void fec_reg_setup(struct fec_priv *fec)
{
	uint32_t rcntrl;

J
Jagan Teki 已提交
390
	/* Set interrupt mask register */
M
Marek Vasut 已提交
391 392
	writel(0x00000000, &fec->eth->imask);

J
Jagan Teki 已提交
393
	/* Clear FEC-Lite interrupt event register(IEVENT) */
M
Marek Vasut 已提交
394 395
	writel(0xffffffff, &fec->eth->ievent);

J
Jagan Teki 已提交
396
	/* Set FEC-Lite receive control register(R_CNTRL): */
M
Marek Vasut 已提交
397 398 399

	/* Start with frame length = 1518, common for all modes. */
	rcntrl = PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT;
400 401 402
	if (fec->xcv_type != SEVENWIRE)		/* xMII modes */
		rcntrl |= FEC_RCNTRL_FCE | FEC_RCNTRL_MII_MODE;
	if (fec->xcv_type == RGMII)
M
Marek Vasut 已提交
403 404 405 406 407 408 409
		rcntrl |= FEC_RCNTRL_RGMII;
	else if (fec->xcv_type == RMII)
		rcntrl |= FEC_RCNTRL_RMII;

	writel(rcntrl, &fec->eth->r_cntrl);
}

410 411 412 413
/**
 * Start the FEC engine
 * @param[in] dev Our device to handle
 */
414 415 416
#ifdef CONFIG_DM_ETH
static int fec_open(struct udevice *dev)
#else
417
static int fec_open(struct eth_device *edev)
418
#endif
419
{
420 421 422
#ifdef CONFIG_DM_ETH
	struct fec_priv *fec = dev_get_priv(dev);
#else
423
	struct fec_priv *fec = (struct fec_priv *)edev->priv;
424
#endif
425
	int speed;
426 427
	uint32_t addr, size;
	int i;
428 429 430 431 432 433

	debug("fec_open: fec_open(dev)\n");
	/* full-duplex, heartbeat disabled */
	writel(1 << 2, &fec->eth->x_cntrl);
	fec->rbd_index = 0;

434 435 436 437 438 439 440 441 442 443 444
	/* Invalidate all descriptors */
	for (i = 0; i < FEC_RBD_NUM - 1; i++)
		fec_rbd_clean(0, &fec->rbd_base[i]);
	fec_rbd_clean(1, &fec->rbd_base[i]);

	/* Flush the descriptors into RAM */
	size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd),
			ARCH_DMA_MINALIGN);
	addr = (uint32_t)fec->rbd_base;
	flush_dcache_range(addr, addr + size);

445
#ifdef FEC_QUIRK_ENET_MAC
446 447
	/* Enable ENET HW endian SWAP */
	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_DBSWAP,
J
Jagan Teki 已提交
448
	       &fec->eth->ecntrl);
449 450
	/* Enable ENET store and forward mode */
	writel(readl(&fec->eth->x_wmrk) | FEC_X_WMRK_STRFWD,
J
Jagan Teki 已提交
451
	       &fec->eth->x_wmrk);
452
#endif
J
Jagan Teki 已提交
453
	/* Enable FEC-Lite controller */
454
	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_ETHER_EN,
J
Jagan Teki 已提交
455 456
	       &fec->eth->ecntrl);

457
#if defined(CONFIG_MX25) || defined(CONFIG_MX53) || defined(CONFIG_MX6SL)
J
John Rigby 已提交
458 459
	udelay(100);

J
Jagan Teki 已提交
460
	/* setup the MII gasket for RMII mode */
J
John Rigby 已提交
461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
	/* disable the gasket */
	writew(0, &fec->eth->miigsk_enr);

	/* wait for the gasket to be disabled */
	while (readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY)
		udelay(2);

	/* configure gasket for RMII, 50 MHz, no loopback, and no echo */
	writew(MIIGSK_CFGR_IF_MODE_RMII, &fec->eth->miigsk_cfgr);

	/* re-enable the gasket */
	writew(MIIGSK_ENR_EN, &fec->eth->miigsk_enr);

	/* wait until MII gasket is ready */
	int max_loops = 10;
	while ((readw(&fec->eth->miigsk_enr) & MIIGSK_ENR_READY) == 0) {
		if (--max_loops <= 0) {
			printf("WAIT for MII Gasket ready timed out\n");
			break;
		}
	}
#endif
483

T
Troy Kisky 已提交
484
#ifdef CONFIG_PHYLIB
485
	{
T
Troy Kisky 已提交
486
		/* Start up the PHY */
487 488 489 490 491 492 493
		int ret = phy_startup(fec->phydev);

		if (ret) {
			printf("Could not initialize PHY %s\n",
			       fec->phydev->dev->name);
			return ret;
		}
T
Troy Kisky 已提交
494 495
		speed = fec->phydev->speed;
	}
496 497
#elif CONFIG_FEC_FIXED_SPEED
	speed = CONFIG_FEC_FIXED_SPEED;
T
Troy Kisky 已提交
498
#else
499
	miiphy_wait_aneg(edev);
500
	speed = miiphy_speed(edev->name, fec->phy_id);
M
Marek Vasut 已提交
501
	miiphy_duplex(edev->name, fec->phy_id);
T
Troy Kisky 已提交
502
#endif
503

504 505 506
#ifdef FEC_QUIRK_ENET_MAC
	{
		u32 ecr = readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_SPEED;
507
		u32 rcr = readl(&fec->eth->r_cntrl) & ~FEC_RCNTRL_RMII_10T;
508 509 510 511 512 513 514 515 516 517
		if (speed == _1000BASET)
			ecr |= FEC_ECNTRL_SPEED;
		else if (speed != _100BASET)
			rcr |= FEC_RCNTRL_RMII_10T;
		writel(ecr, &fec->eth->ecntrl);
		writel(rcr, &fec->eth->r_cntrl);
	}
#endif
	debug("%s:Speed=%i\n", __func__, speed);

J
Jagan Teki 已提交
518
	/* Enable SmartDMA receive task */
519 520 521 522 523 524
	fec_rx_task_enable(fec);

	udelay(100000);
	return 0;
}

525 526 527
#ifdef CONFIG_DM_ETH
static int fecmxc_init(struct udevice *dev)
#else
J
Jagan Teki 已提交
528
static int fec_init(struct eth_device *dev, bd_t *bd)
529
#endif
530
{
531 532 533
#ifdef CONFIG_DM_ETH
	struct fec_priv *fec = dev_get_priv(dev);
#else
534
	struct fec_priv *fec = (struct fec_priv *)dev->priv;
535
#endif
M
Marek Vasut 已提交
536
	uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
M
Marek Vasut 已提交
537
	int i;
538

539
	/* Initialize MAC address */
540 541 542
#ifdef CONFIG_DM_ETH
	fecmxc_set_hwaddr(dev);
#else
543
	fec_set_hwaddr(dev);
544
#endif
545

J
Jagan Teki 已提交
546
	/* Setup transmit descriptors, there are two in total. */
M
Marek Vasut 已提交
547
	fec_tbd_init(fec);
548

M
Marek Vasut 已提交
549 550
	/* Setup receive descriptors. */
	fec_rbd_init(fec, FEC_RBD_NUM, FEC_MAX_PKT_SIZE);
551

M
Marek Vasut 已提交
552
	fec_reg_setup(fec);
M
Marek Vasut 已提交
553

554
	if (fec->xcv_type != SEVENWIRE)
555
		fec_mii_setspeed(fec->bus->priv);
M
Marek Vasut 已提交
556

J
Jagan Teki 已提交
557
	/* Set Opcode/Pause Duration Register */
558 559
	writel(0x00010020, &fec->eth->op_pause);	/* FIXME 0xffff0020; */
	writel(0x2, &fec->eth->x_wmrk);
J
Jagan Teki 已提交
560 561

	/* Set multicast address filter */
562 563 564
	writel(0x00000000, &fec->eth->gaddr1);
	writel(0x00000000, &fec->eth->gaddr2);

565
	/* Do not access reserved register for i.MX6UL */
566
	if (!is_mx6ul() && !is_mx6ull()) {
567 568 569
		/* clear MIB RAM */
		for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4)
			writel(0, i);
570

571 572 573
		/* FIFO receive start register */
		writel(0x520, &fec->eth->r_fstart);
	}
574 575 576 577 578 579

	/* size and address of each buffer */
	writel(FEC_MAX_PKT_SIZE, &fec->eth->emrbr);
	writel((uint32_t)fec->tbd_base, &fec->eth->etdsr);
	writel((uint32_t)fec->rbd_base, &fec->eth->erdsr);

T
Troy Kisky 已提交
580
#ifndef CONFIG_PHYLIB
581 582
	if (fec->xcv_type != SEVENWIRE)
		miiphy_restart_aneg(dev);
T
Troy Kisky 已提交
583
#endif
584 585 586 587 588 589 590 591
	fec_open(dev);
	return 0;
}

/**
 * Halt the FEC engine
 * @param[in] dev Our device to handle
 */
592 593 594
#ifdef CONFIG_DM_ETH
static void fecmxc_halt(struct udevice *dev)
#else
595
static void fec_halt(struct eth_device *dev)
596
#endif
597
{
598 599 600
#ifdef CONFIG_DM_ETH
	struct fec_priv *fec = dev_get_priv(dev);
#else
M
Marek Vasut 已提交
601
	struct fec_priv *fec = (struct fec_priv *)dev->priv;
602
#endif
603 604
	int counter = 0xffff;

J
Jagan Teki 已提交
605
	/* issue graceful stop command to the FEC transmitter if necessary */
606
	writel(FEC_TCNTRL_GTS | readl(&fec->eth->x_cntrl),
J
Jagan Teki 已提交
607
	       &fec->eth->x_cntrl);
608 609

	debug("eth_halt: wait for stop regs\n");
J
Jagan Teki 已提交
610
	/* wait for graceful stop to register */
611
	while ((counter--) && (!(readl(&fec->eth->ievent) & FEC_IEVENT_GRA)))
612
		udelay(1);
613

J
Jagan Teki 已提交
614
	/* Disable SmartDMA tasks */
615 616 617 618 619 620 621
	fec_tx_task_disable(fec);
	fec_rx_task_disable(fec);

	/*
	 * Disable the Ethernet Controller
	 * Note: this will also reset the BD index counter!
	 */
J
John Rigby 已提交
622
	writel(readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_ETHER_EN,
J
Jagan Teki 已提交
623
	       &fec->eth->ecntrl);
624 625 626 627 628 629 630 631 632 633 634 635
	fec->rbd_index = 0;
	fec->tbd_index = 0;
	debug("eth_halt: done\n");
}

/**
 * Transmit one frame
 * @param[in] dev Our ethernet device to handle
 * @param[in] packet Pointer to the data to be transmitted
 * @param[in] length Data count in bytes
 * @return 0 on success
 */
636 637 638
#ifdef CONFIG_DM_ETH
static int fecmxc_send(struct udevice *dev, void *packet, int length)
#else
639
static int fec_send(struct eth_device *dev, void *packet, int length)
640
#endif
641 642
{
	unsigned int status;
643
	uint32_t size, end;
644
	uint32_t addr;
645 646
	int timeout = FEC_XFER_TIMEOUT;
	int ret = 0;
647 648 649 650 651

	/*
	 * This routine transmits one frame.  This routine only accepts
	 * 6-byte Ethernet addresses.
	 */
652 653 654
#ifdef CONFIG_DM_ETH
	struct fec_priv *fec = dev_get_priv(dev);
#else
655
	struct fec_priv *fec = (struct fec_priv *)dev->priv;
656
#endif
657 658 659 660 661

	/*
	 * Check for valid length of data.
	 */
	if ((length > 1500) || (length <= 0)) {
662
		printf("Payload (%d) too large\n", length);
663 664 665 666
		return -1;
	}

	/*
667 668 669
	 * Setup the transmit buffer. We are always using the first buffer for
	 * transmission, the second will be empty and only used to stop the DMA
	 * engine. We also flush the packet to RAM here to avoid cache trouble.
670
	 */
671
#ifdef CONFIG_FEC_MXC_SWAP_PACKET
M
Marek Vasut 已提交
672 673
	swap_packet((uint32_t *)packet, length);
#endif
674 675

	addr = (uint32_t)packet;
676 677 678
	end = roundup(addr + length, ARCH_DMA_MINALIGN);
	addr &= ~(ARCH_DMA_MINALIGN - 1);
	flush_dcache_range(addr, end);
679

680
	writew(length, &fec->tbd_base[fec->tbd_index].data_length);
681 682
	writel(addr, &fec->tbd_base[fec->tbd_index].data_pointer);

683 684 685 686 687 688 689 690 691 692 693 694
	/*
	 * update BD's status now
	 * This block:
	 * - is always the last in a chain (means no chain)
	 * - should transmitt the CRC
	 * - might be the last BD in the list, so the address counter should
	 *   wrap (-> keep the WRAP flag)
	 */
	status = readw(&fec->tbd_base[fec->tbd_index].status) & FEC_TBD_WRAP;
	status |= FEC_TBD_LAST | FEC_TBD_TC | FEC_TBD_READY;
	writew(status, &fec->tbd_base[fec->tbd_index].status);

695 696 697 698 699 700 701 702 703
	/*
	 * Flush data cache. This code flushes both TX descriptors to RAM.
	 * After this code, the descriptors will be safely in RAM and we
	 * can start DMA.
	 */
	size = roundup(2 * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
	addr = (uint32_t)fec->tbd_base;
	flush_dcache_range(addr, addr + size);

704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725
	/*
	 * Below we read the DMA descriptor's last four bytes back from the
	 * DRAM. This is important in order to make sure that all WRITE
	 * operations on the bus that were triggered by previous cache FLUSH
	 * have completed.
	 *
	 * Otherwise, on MX28, it is possible to observe a corruption of the
	 * DMA descriptors. Please refer to schematic "Figure 1-2" in MX28RM
	 * for the bus structure of MX28. The scenario is as follows:
	 *
	 * 1) ARM core triggers a series of WRITEs on the AHB_ARB2 bus going
	 *    to DRAM due to flush_dcache_range()
	 * 2) ARM core writes the FEC registers via AHB_ARB2
	 * 3) FEC DMA starts reading/writing from/to DRAM via AHB_ARB3
	 *
	 * Note that 2) does sometimes finish before 1) due to reordering of
	 * WRITE accesses on the AHB bus, therefore triggering 3) before the
	 * DMA descriptor is fully written into DRAM. This results in occasional
	 * corruption of the DMA descriptor.
	 */
	readl(addr + size - 4);

J
Jagan Teki 已提交
726
	/* Enable SmartDMA transmit task */
727 728 729
	fec_tx_task_enable(fec);

	/*
730 731 732
	 * Wait until frame is sent. On each turn of the wait cycle, we must
	 * invalidate data cache to see what's really in RAM. Also, we need
	 * barrier here.
733
	 */
M
Marek Vasut 已提交
734
	while (--timeout) {
M
Marek Vasut 已提交
735
		if (!(readl(&fec->eth->x_des_active) & FEC_X_DES_ACTIVE_TDAR))
736
			break;
737
	}
738

739
	if (!timeout) {
M
Marek Vasut 已提交
740
		ret = -EINVAL;
741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764
		goto out;
	}

	/*
	 * The TDAR bit is cleared when the descriptors are all out from TX
	 * but on mx6solox we noticed that the READY bit is still not cleared
	 * right after TDAR.
	 * These are two distinct signals, and in IC simulation, we found that
	 * TDAR always gets cleared prior than the READY bit of last BD becomes
	 * cleared.
	 * In mx6solox, we use a later version of FEC IP. It looks like that
	 * this intrinsic behaviour of TDAR bit has changed in this newer FEC
	 * version.
	 *
	 * Fix this by polling the READY bit of BD after the TDAR polling,
	 * which covers the mx6solox case and does not harm the other SoCs.
	 */
	timeout = FEC_XFER_TIMEOUT;
	while (--timeout) {
		invalidate_dcache_range(addr, addr + size);
		if (!(readw(&fec->tbd_base[fec->tbd_index].status) &
		    FEC_TBD_READY))
			break;
	}
M
Marek Vasut 已提交
765

766
	if (!timeout)
M
Marek Vasut 已提交
767 768
		ret = -EINVAL;

769
out:
M
Marek Vasut 已提交
770
	debug("fec_send: status 0x%x index %d ret %i\n",
J
Jagan Teki 已提交
771 772
	      readw(&fec->tbd_base[fec->tbd_index].status),
	      fec->tbd_index, ret);
773 774 775 776 777 778
	/* for next transmission use the other buffer */
	if (fec->tbd_index)
		fec->tbd_index = 0;
	else
		fec->tbd_index = 1;

779
	return ret;
780 781 782 783 784 785 786
}

/**
 * Pull one frame from the card
 * @param[in] dev Our ethernet device to handle
 * @return Length of packet read
 */
787 788 789
#ifdef CONFIG_DM_ETH
static int fecmxc_recv(struct udevice *dev, int flags, uchar **packetp)
#else
790
static int fec_recv(struct eth_device *dev)
791
#endif
792
{
793 794 795
#ifdef CONFIG_DM_ETH
	struct fec_priv *fec = dev_get_priv(dev);
#else
796
	struct fec_priv *fec = (struct fec_priv *)dev->priv;
797
#endif
798 799 800 801
	struct fec_bd *rbd = &fec->rbd_base[fec->rbd_index];
	unsigned long ievent;
	int frame_length, len = 0;
	uint16_t bd_status;
802
	uint32_t addr, size, end;
803
	int i;
804
	ALLOC_CACHE_ALIGN_BUFFER(uchar, buff, FEC_MAX_PKT_SIZE);
805

J
Jagan Teki 已提交
806
	/* Check if any critical events have happened */
807 808
	ievent = readl(&fec->eth->ievent);
	writel(ievent, &fec->eth->ievent);
M
Marek Vasut 已提交
809
	debug("fec_recv: ievent 0x%lx\n", ievent);
810
	if (ievent & FEC_IEVENT_BABR) {
811 812 813 814
#ifdef CONFIG_DM_ETH
		fecmxc_halt(dev);
		fecmxc_init(dev);
#else
815 816
		fec_halt(dev);
		fec_init(dev, fec->bd);
817
#endif
818 819 820 821 822 823
		printf("some error: 0x%08lx\n", ievent);
		return 0;
	}
	if (ievent & FEC_IEVENT_HBERR) {
		/* Heartbeat error */
		writel(0x00000001 | readl(&fec->eth->x_cntrl),
J
Jagan Teki 已提交
824
		       &fec->eth->x_cntrl);
825 826 827 828
	}
	if (ievent & FEC_IEVENT_GRA) {
		/* Graceful stop complete */
		if (readl(&fec->eth->x_cntrl) & 0x00000001) {
829 830 831
#ifdef CONFIG_DM_ETH
			fecmxc_halt(dev);
#else
832
			fec_halt(dev);
833
#endif
834
			writel(~0x00000001 & readl(&fec->eth->x_cntrl),
J
Jagan Teki 已提交
835
			       &fec->eth->x_cntrl);
836 837 838
#ifdef CONFIG_DM_ETH
			fecmxc_init(dev);
#else
839
			fec_init(dev, fec->bd);
840
#endif
841 842 843 844
		}
	}

	/*
845 846 847 848 849 850 851 852 853 854 855
	 * Read the buffer status. Before the status can be read, the data cache
	 * must be invalidated, because the data in RAM might have been changed
	 * by DMA. The descriptors are properly aligned to cachelines so there's
	 * no need to worry they'd overlap.
	 *
	 * WARNING: By invalidating the descriptor here, we also invalidate
	 * the descriptors surrounding this one. Therefore we can NOT change the
	 * contents of this descriptor nor the surrounding ones. The problem is
	 * that in order to mark the descriptor as processed, we need to change
	 * the descriptor. The solution is to mark the whole cache line when all
	 * descriptors in the cache line are processed.
856
	 */
857 858 859 860 861
	addr = (uint32_t)rbd;
	addr &= ~(ARCH_DMA_MINALIGN - 1);
	size = roundup(sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
	invalidate_dcache_range(addr, addr + size);

862 863 864 865 866
	bd_status = readw(&rbd->status);
	debug("fec_recv: status 0x%x\n", bd_status);

	if (!(bd_status & FEC_RBD_EMPTY)) {
		if ((bd_status & FEC_RBD_LAST) && !(bd_status & FEC_RBD_ERR) &&
J
Jagan Teki 已提交
867 868
		    ((readw(&rbd->data_length) - 4) > 14)) {
			/* Get buffer address and size */
869
			addr = readl(&rbd->data_pointer);
870
			frame_length = readw(&rbd->data_length) - 4;
J
Jagan Teki 已提交
871
			/* Invalidate data cache over the buffer */
872 873 874
			end = roundup(addr + frame_length, ARCH_DMA_MINALIGN);
			addr &= ~(ARCH_DMA_MINALIGN - 1);
			invalidate_dcache_range(addr, end);
875

J
Jagan Teki 已提交
876
			/* Fill the buffer and pass it to upper layers */
877
#ifdef CONFIG_FEC_MXC_SWAP_PACKET
878
			swap_packet((uint32_t *)addr, frame_length);
M
Marek Vasut 已提交
879
#endif
880
			memcpy(buff, (char *)addr, frame_length);
881
			net_process_received_packet(buff, frame_length);
882 883 884
			len = frame_length;
		} else {
			if (bd_status & FEC_RBD_ERR)
885 886
				printf("error frame: 0x%08x 0x%08x\n",
				       addr, bd_status);
887
		}
888

889
		/*
890 891 892 893
		 * Free the current buffer, restart the engine and move forward
		 * to the next buffer. Here we check if the whole cacheline of
		 * descriptors was already processed and if so, we mark it free
		 * as whole.
894
		 */
895 896 897 898 899 900 901 902 903
		size = RXDESC_PER_CACHELINE - 1;
		if ((fec->rbd_index & size) == size) {
			i = fec->rbd_index - size;
			addr = (uint32_t)&fec->rbd_base[i];
			for (; i <= fec->rbd_index ; i++) {
				fec_rbd_clean(i == (FEC_RBD_NUM - 1),
					      &fec->rbd_base[i]);
			}
			flush_dcache_range(addr,
J
Jagan Teki 已提交
904
					   addr + ARCH_DMA_MINALIGN);
905 906
		}

907 908 909 910 911 912 913 914
		fec_rx_task_enable(fec);
		fec->rbd_index = (fec->rbd_index + 1) % FEC_RBD_NUM;
	}
	debug("fec_recv: stop\n");

	return len;
}

915 916 917 918 919
static void fec_set_dev_name(char *dest, int dev_id)
{
	sprintf(dest, (dev_id == -1) ? "FEC" : "FEC%i", dev_id);
}

M
Marek Vasut 已提交
920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942
static int fec_alloc_descs(struct fec_priv *fec)
{
	unsigned int size;
	int i;
	uint8_t *data;

	/* Allocate TX descriptors. */
	size = roundup(2 * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
	fec->tbd_base = memalign(ARCH_DMA_MINALIGN, size);
	if (!fec->tbd_base)
		goto err_tx;

	/* Allocate RX descriptors. */
	size = roundup(FEC_RBD_NUM * sizeof(struct fec_bd), ARCH_DMA_MINALIGN);
	fec->rbd_base = memalign(ARCH_DMA_MINALIGN, size);
	if (!fec->rbd_base)
		goto err_rx;

	memset(fec->rbd_base, 0, size);

	/* Allocate RX buffers. */

	/* Maximum RX buffer size. */
943
	size = roundup(FEC_MAX_PKT_SIZE, FEC_DMA_RX_MINALIGN);
M
Marek Vasut 已提交
944
	for (i = 0; i < FEC_RBD_NUM; i++) {
945
		data = memalign(FEC_DMA_RX_MINALIGN, size);
M
Marek Vasut 已提交
946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987
		if (!data) {
			printf("%s: error allocating rxbuf %d\n", __func__, i);
			goto err_ring;
		}

		memset(data, 0, size);

		fec->rbd_base[i].data_pointer = (uint32_t)data;
		fec->rbd_base[i].status = FEC_RBD_EMPTY;
		fec->rbd_base[i].data_length = 0;
		/* Flush the buffer to memory. */
		flush_dcache_range((uint32_t)data, (uint32_t)data + size);
	}

	/* Mark the last RBD to close the ring. */
	fec->rbd_base[i - 1].status = FEC_RBD_WRAP | FEC_RBD_EMPTY;

	fec->rbd_index = 0;
	fec->tbd_index = 0;

	return 0;

err_ring:
	for (; i >= 0; i--)
		free((void *)fec->rbd_base[i].data_pointer);
	free(fec->rbd_base);
err_rx:
	free(fec->tbd_base);
err_tx:
	return -ENOMEM;
}

static void fec_free_descs(struct fec_priv *fec)
{
	int i;

	for (i = 0; i < FEC_RBD_NUM; i++)
		free((void *)fec->rbd_base[i].data_pointer);
	free(fec->rbd_base);
	free(fec->tbd_base);
}

988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id)
{
	struct ethernet_regs *eth = (struct ethernet_regs *)base_addr;
	struct mii_dev *bus;
	int ret;

	bus = mdio_alloc();
	if (!bus) {
		printf("mdio_alloc failed\n");
		return NULL;
	}
	bus->read = fec_phy_read;
	bus->write = fec_phy_write;
	bus->priv = eth;
	fec_set_dev_name(bus->name, dev_id);

	ret = mdio_register(bus);
	if (ret) {
		printf("mdio_register failed\n");
		free(bus);
		return NULL;
	}
	fec_mii_setspeed(eth);
	return bus;
}

#ifndef CONFIG_DM_ETH
1015 1016 1017 1018 1019 1020 1021
#ifdef CONFIG_PHYLIB
int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
		struct mii_dev *bus, struct phy_device *phydev)
#else
static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
		struct mii_dev *bus, int phy_id)
#endif
1022 1023
{
	struct eth_device *edev;
M
Marek Vasut 已提交
1024
	struct fec_priv *fec;
1025
	unsigned char ethaddr[6];
1026
	char mac[16];
M
Marek Vasut 已提交
1027 1028
	uint32_t start;
	int ret = 0;
1029 1030 1031 1032

	/* create and fill edev struct */
	edev = (struct eth_device *)malloc(sizeof(struct eth_device));
	if (!edev) {
M
Marek Vasut 已提交
1033
		puts("fec_mxc: not enough malloc memory for eth_device\n");
M
Marek Vasut 已提交
1034 1035
		ret = -ENOMEM;
		goto err1;
M
Marek Vasut 已提交
1036 1037 1038 1039 1040
	}

	fec = (struct fec_priv *)malloc(sizeof(struct fec_priv));
	if (!fec) {
		puts("fec_mxc: not enough malloc memory for fec_priv\n");
M
Marek Vasut 已提交
1041 1042
		ret = -ENOMEM;
		goto err2;
1043
	}
M
Marek Vasut 已提交
1044

1045
	memset(edev, 0, sizeof(*edev));
M
Marek Vasut 已提交
1046 1047
	memset(fec, 0, sizeof(*fec));

M
Marek Vasut 已提交
1048 1049 1050 1051
	ret = fec_alloc_descs(fec);
	if (ret)
		goto err3;

1052 1053 1054 1055 1056
	edev->priv = fec;
	edev->init = fec_init;
	edev->send = fec_send;
	edev->recv = fec_recv;
	edev->halt = fec_halt;
1057
	edev->write_hwaddr = fec_set_hwaddr;
1058

M
Marek Vasut 已提交
1059
	fec->eth = (struct ethernet_regs *)base_addr;
1060 1061
	fec->bd = bd;

1062
	fec->xcv_type = CONFIG_FEC_XCV_TYPE;
1063 1064

	/* Reset chip. */
1065
	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_RESET, &fec->eth->ecntrl);
M
Marek Vasut 已提交
1066 1067 1068
	start = get_timer(0);
	while (readl(&fec->eth->ecntrl) & FEC_ECNTRL_RESET) {
		if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
V
Vagrant Cascadian 已提交
1069
			printf("FEC MXC: Timeout resetting chip\n");
M
Marek Vasut 已提交
1070
			goto err4;
M
Marek Vasut 已提交
1071
		}
1072
		udelay(10);
M
Marek Vasut 已提交
1073
	}
1074

M
Marek Vasut 已提交
1075
	fec_reg_setup(fec);
1076 1077
	fec_set_dev_name(edev->name, dev_id);
	fec->dev_id = (dev_id == -1) ? 0 : dev_id;
1078 1079 1080 1081 1082 1083 1084 1085
	fec->bus = bus;
	fec_mii_setspeed(bus->priv);
#ifdef CONFIG_PHYLIB
	fec->phydev = phydev;
	phy_connect_dev(phydev, edev);
	/* Configure phy */
	phy_config(phydev);
#else
M
Marek Vasut 已提交
1086
	fec->phy_id = phy_id;
1087 1088
#endif
	eth_register(edev);
1089 1090
	/* only support one eth device, the index number pointed by dev_id */
	edev->index = fec->dev_id;
1091

1092 1093
	if (fec_get_hwaddr(fec->dev_id, ethaddr) == 0) {
		debug("got MAC%d address from fuse: %pM\n", fec->dev_id, ethaddr);
1094
		memcpy(edev->enetaddr, ethaddr, 6);
1095 1096 1097 1098 1099
		if (fec->dev_id)
			sprintf(mac, "eth%daddr", fec->dev_id);
		else
			strcpy(mac, "ethaddr");
		if (!getenv(mac))
1100
			eth_env_set_enetaddr(mac, ethaddr);
1101 1102
	}
	return ret;
M
Marek Vasut 已提交
1103 1104
err4:
	fec_free_descs(fec);
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
err3:
	free(fec);
err2:
	free(edev);
err1:
	return ret;
}

int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr)
{
	uint32_t base_mii;
	struct mii_dev *bus = NULL;
#ifdef CONFIG_PHYLIB
	struct phy_device *phydev = NULL;
#endif
	int ret;

1122
#ifdef CONFIG_MX28
T
Troy Kisky 已提交
1123 1124 1125 1126
	/*
	 * The i.MX28 has two ethernet interfaces, but they are not equal.
	 * Only the first one can access the MDIO bus.
	 */
1127
	base_mii = MXS_ENET0_BASE;
T
Troy Kisky 已提交
1128
#else
1129
	base_mii = addr;
T
Troy Kisky 已提交
1130
#endif
1131 1132 1133 1134
	debug("eth_init: fec_probe(bd, %i, %i) @ %08x\n", dev_id, phy_id, addr);
	bus = fec_get_miibus(base_mii, dev_id);
	if (!bus)
		return -ENOMEM;
1135
#ifdef CONFIG_PHYLIB
1136
	phydev = phy_find_by_mask(bus, 1 << phy_id, PHY_INTERFACE_MODE_RGMII);
1137
	if (!phydev) {
1138
		mdio_unregister(bus);
1139
		free(bus);
1140
		return -ENOMEM;
1141
	}
1142 1143 1144
	ret = fec_probe(bd, dev_id, addr, bus, phydev);
#else
	ret = fec_probe(bd, dev_id, addr, bus, phy_id);
1145
#endif
1146 1147 1148 1149
	if (ret) {
#ifdef CONFIG_PHYLIB
		free(phydev);
#endif
1150
		mdio_unregister(bus);
1151 1152
		free(bus);
	}
M
Marek Vasut 已提交
1153
	return ret;
1154
}
1155

1156 1157 1158 1159 1160
#ifdef CONFIG_FEC_MXC_PHYADDR
int fecmxc_initialize(bd_t *bd)
{
	return fecmxc_initialize_multi(bd, -1, CONFIG_FEC_MXC_PHYADDR,
			IMX_FEC_BASE);
1161
}
1162
#endif
1163

T
Troy Kisky 已提交
1164
#ifndef CONFIG_PHYLIB
1165 1166 1167 1168 1169 1170
int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int))
{
	struct fec_priv *fec = (struct fec_priv *)dev->priv;
	fec->mii_postcall = cb;
	return 0;
}
T
Troy Kisky 已提交
1171
#endif
1172 1173 1174

#else

J
Jagan Teki 已提交
1175 1176 1177 1178 1179 1180 1181 1182
static int fecmxc_read_rom_hwaddr(struct udevice *dev)
{
	struct fec_priv *priv = dev_get_priv(dev);
	struct eth_pdata *pdata = dev_get_platdata(dev);

	return fec_get_hwaddr(priv->dev_id, pdata->enetaddr);
}

1183 1184 1185 1186 1187 1188
static const struct eth_ops fecmxc_ops = {
	.start			= fecmxc_init,
	.send			= fecmxc_send,
	.recv			= fecmxc_recv,
	.stop			= fecmxc_halt,
	.write_hwaddr		= fecmxc_set_hwaddr,
J
Jagan Teki 已提交
1189
	.read_rom_hwaddr	= fecmxc_read_rom_hwaddr,
1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226
};

static int fec_phy_init(struct fec_priv *priv, struct udevice *dev)
{
	struct phy_device *phydev;
	int mask = 0xffffffff;

#ifdef CONFIG_PHYLIB
	mask = 1 << CONFIG_FEC_MXC_PHYADDR;
#endif

	phydev = phy_find_by_mask(priv->bus, mask, priv->interface);
	if (!phydev)
		return -ENODEV;

	phy_connect_dev(phydev, dev);

	priv->phydev = phydev;
	phy_config(phydev);

	return 0;
}

static int fecmxc_probe(struct udevice *dev)
{
	struct eth_pdata *pdata = dev_get_platdata(dev);
	struct fec_priv *priv = dev_get_priv(dev);
	struct mii_dev *bus = NULL;
	int dev_id = -1;
	uint32_t start;
	int ret;

	ret = fec_alloc_descs(priv);
	if (ret)
		return ret;

	/* Reset chip. */
J
Jagan Teki 已提交
1227 1228
	writel(readl(&priv->eth->ecntrl) | FEC_ECNTRL_RESET,
	       &priv->eth->ecntrl);
1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
	start = get_timer(0);
	while (readl(&priv->eth->ecntrl) & FEC_ECNTRL_RESET) {
		if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
			printf("FEC MXC: Timeout reseting chip\n");
			goto err_timeout;
		}
		udelay(10);
	}

	fec_reg_setup(priv);
	priv->dev_id = (dev_id == -1) ? 0 : dev_id;

1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253
	bus = fec_get_miibus(dev, dev_id);
	if (!bus) {
		ret = -ENOMEM;
		goto err_mii;
	}

	priv->bus = bus;
	priv->xcv_type = CONFIG_FEC_XCV_TYPE;
	priv->interface = pdata->phy_interface;
	ret = fec_phy_init(priv, dev);
	if (ret)
		goto err_phy;

1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283
	return 0;

err_timeout:
	free(priv->phydev);
err_phy:
	mdio_unregister(bus);
	free(bus);
err_mii:
	fec_free_descs(priv);
	return ret;
}

static int fecmxc_remove(struct udevice *dev)
{
	struct fec_priv *priv = dev_get_priv(dev);

	free(priv->phydev);
	fec_free_descs(priv);
	mdio_unregister(priv->bus);
	mdio_free(priv->bus);

	return 0;
}

static int fecmxc_ofdata_to_platdata(struct udevice *dev)
{
	struct eth_pdata *pdata = dev_get_platdata(dev);
	struct fec_priv *priv = dev_get_priv(dev);
	const char *phy_mode;

S
Simon Glass 已提交
1284
	pdata->iobase = (phys_addr_t)devfdt_get_addr(dev);
1285 1286 1287
	priv->eth = (struct ethernet_regs *)pdata->iobase;

	pdata->phy_interface = -1;
1288 1289
	phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
			       NULL);
1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321
	if (phy_mode)
		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
	if (pdata->phy_interface == -1) {
		debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
		return -EINVAL;
	}

	/* TODO
	 * Need to get the reset-gpio and related properties from DT
	 * and implemet the enet reset code on .probe call
	 */

	return 0;
}

static const struct udevice_id fecmxc_ids[] = {
	{ .compatible = "fsl,imx6q-fec" },
	{ }
};

U_BOOT_DRIVER(fecmxc_gem) = {
	.name	= "fecmxc",
	.id	= UCLASS_ETH,
	.of_match = fecmxc_ids,
	.ofdata_to_platdata = fecmxc_ofdata_to_platdata,
	.probe	= fecmxc_probe,
	.remove	= fecmxc_remove,
	.ops	= &fecmxc_ops,
	.priv_auto_alloc_size = sizeof(struct fec_priv),
	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
};
#endif