stmmac_mdio.c 11.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*******************************************************************************
  STMMAC Ethernet Driver -- MDIO bus implementation
  Provides Bus interface for MII registers

  Copyright (C) 2007-2009  STMicroelectronics Ltd

  This program is free software; you can redistribute it and/or modify it
  under the terms and conditions of the GNU General Public License,
  version 2, as published by the Free Software Foundation.

  This program is distributed in the hope it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  more details.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.

  The full GNU General Public License is included in this distribution in
  the file called "COPYING".

  Author: Carl Shaw <carl.shaw@st.com>
  Maintainer: Giuseppe Cavallaro <peppe.cavallaro@st.com>
*******************************************************************************/

#include <linux/mii.h>
#include <linux/phy.h>
29
#include <linux/slab.h>
30 31
#include <linux/of.h>
#include <linux/of_gpio.h>
32
#include <linux/of_mdio.h>
33
#include <asm/io.h>
34 35 36 37 38 39

#include "stmmac.h"

#define MII_BUSY 0x00000001
#define MII_WRITE 0x00000002

40 41 42 43 44 45 46 47 48 49 50 51
/* GMAC4 defines */
#define MII_GMAC4_GOC_SHIFT		2
#define MII_GMAC4_WRITE			(1 << MII_GMAC4_GOC_SHIFT)
#define MII_GMAC4_READ			(3 << MII_GMAC4_GOC_SHIFT)

#define MII_PHY_ADDR_GMAC4_SHIFT	21
#define MII_PHY_ADDR_GMAC4_MASK		GENMASK(25, 21)
#define MII_PHY_REG_GMAC4_SHIFT		16
#define MII_PHY_REG_GMAC4_MASK		GENMASK(20, 16)
#define MII_CSR_CLK_GMAC4_SHIFT		8
#define MII_CSR_CLK_GMAC4_MASK		GENMASK(11, 8)

52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
static int stmmac_mdio_busy_wait(void __iomem *ioaddr, unsigned int mii_addr)
{
	unsigned long curr;
	unsigned long finish = jiffies + 3 * HZ;

	do {
		curr = jiffies;
		if (readl(ioaddr + mii_addr) & MII_BUSY)
			cpu_relax();
		else
			return 0;
	} while (!time_after_eq(curr, finish));

	return -EBUSY;
}

68 69 70 71 72 73 74 75 76 77 78 79 80 81
/**
 * stmmac_mdio_read
 * @bus: points to the mii_bus structure
 * @phyaddr: MII addr reg bits 15-11
 * @phyreg: MII addr reg bits 10-6
 * Description: it reads data from the MII register from within the phy device.
 * For the 7111 GMAC, we must set the bit 0 in the MII address register while
 * accessing the PHY registers.
 * Fortunately, it seems this has no drawback for the 7109 MAC.
 */
static int stmmac_mdio_read(struct mii_bus *bus, int phyaddr, int phyreg)
{
	struct net_device *ndev = bus->priv;
	struct stmmac_priv *priv = netdev_priv(ndev);
82 83
	unsigned int mii_address = priv->hw->mii.addr;
	unsigned int mii_data = priv->hw->mii.data;
84 85

	int data;
86
	u16 value = (((phyaddr << 11) & (0x0000F800)) |
87
			((phyreg << 6) & (0x000007C0)));
88
	value |= MII_BUSY | ((priv->clk_csr & 0xF) << 2);
89

90 91 92
	if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
		return -EBUSY;

93
	writel(value, priv->ioaddr + mii_address);
94 95 96

	if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
		return -EBUSY;
97 98

	/* Read the data from the MII data register */
99
	data = (int)readl(priv->ioaddr + mii_data);
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116

	return data;
}

/**
 * stmmac_mdio_write
 * @bus: points to the mii_bus structure
 * @phyaddr: MII addr reg bits 15-11
 * @phyreg: MII addr reg bits 10-6
 * @phydata: phy data
 * Description: it writes the data into the MII register from within the device.
 */
static int stmmac_mdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
			     u16 phydata)
{
	struct net_device *ndev = bus->priv;
	struct stmmac_priv *priv = netdev_priv(ndev);
117 118
	unsigned int mii_address = priv->hw->mii.addr;
	unsigned int mii_data = priv->hw->mii.data;
119 120 121 122 123

	u16 value =
	    (((phyaddr << 11) & (0x0000F800)) | ((phyreg << 6) & (0x000007C0)))
	    | MII_WRITE;

124
	value |= MII_BUSY | ((priv->clk_csr & 0xF) << 2);
125

126
	/* Wait until any existing MII operation is complete */
127 128
	if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
		return -EBUSY;
129 130

	/* Set the MII address register to write */
131 132
	writel(phydata, priv->ioaddr + mii_data);
	writel(value, priv->ioaddr + mii_address);
133 134

	/* Wait until any existing MII operation is complete */
135
	return stmmac_mdio_busy_wait(priv->ioaddr, mii_address);
136 137
}

138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
/**
 * stmmac_mdio_read_gmac4
 * @bus: points to the mii_bus structure
 * @phyaddr: MII addr reg bits 25-21
 * @phyreg: MII addr reg bits 20-16
 * Description: it reads data from the MII register of GMAC4 from within
 * the phy device.
 */
static int stmmac_mdio_read_gmac4(struct mii_bus *bus, int phyaddr, int phyreg)
{
	struct net_device *ndev = bus->priv;
	struct stmmac_priv *priv = netdev_priv(ndev);
	unsigned int mii_address = priv->hw->mii.addr;
	unsigned int mii_data = priv->hw->mii.data;
	int data;
	u32 value = (((phyaddr << MII_PHY_ADDR_GMAC4_SHIFT) &
		     (MII_PHY_ADDR_GMAC4_MASK)) |
		     ((phyreg << MII_PHY_REG_GMAC4_SHIFT) &
		     (MII_PHY_REG_GMAC4_MASK))) | MII_GMAC4_READ;

	value |= MII_BUSY | ((priv->clk_csr & MII_CSR_CLK_GMAC4_MASK)
		 << MII_CSR_CLK_GMAC4_SHIFT);

	if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
		return -EBUSY;

	writel(value, priv->ioaddr + mii_address);

	if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
		return -EBUSY;

	/* Read the data from the MII data register */
	data = (int)readl(priv->ioaddr + mii_data);

	return data;
}

/**
 * stmmac_mdio_write_gmac4
 * @bus: points to the mii_bus structure
 * @phyaddr: MII addr reg bits 25-21
 * @phyreg: MII addr reg bits 20-16
 * @phydata: phy data
 * Description: it writes the data into the MII register of GMAC4 from within
 * the device.
 */
static int stmmac_mdio_write_gmac4(struct mii_bus *bus, int phyaddr, int phyreg,
				   u16 phydata)
{
	struct net_device *ndev = bus->priv;
	struct stmmac_priv *priv = netdev_priv(ndev);
	unsigned int mii_address = priv->hw->mii.addr;
	unsigned int mii_data = priv->hw->mii.data;

	u32 value = (((phyaddr << MII_PHY_ADDR_GMAC4_SHIFT) &
		     (MII_PHY_ADDR_GMAC4_MASK)) |
		     ((phyreg << MII_PHY_REG_GMAC4_SHIFT) &
		     (MII_PHY_REG_GMAC4_MASK))) | MII_GMAC4_WRITE;

	value |= MII_BUSY | ((priv->clk_csr & MII_CSR_CLK_GMAC4_MASK)
		 << MII_CSR_CLK_GMAC4_SHIFT);

	/* Wait until any existing MII operation is complete */
	if (stmmac_mdio_busy_wait(priv->ioaddr, mii_address))
		return -EBUSY;

	/* Set the MII address register to write */
	writel(phydata, priv->ioaddr + mii_data);
	writel(value, priv->ioaddr + mii_address);

	/* Wait until any existing MII operation is complete */
	return stmmac_mdio_busy_wait(priv->ioaddr, mii_address);
}

212 213 214 215 216
/**
 * stmmac_mdio_reset
 * @bus: points to the mii_bus structure
 * Description: reset the MII bus
 */
217
int stmmac_mdio_reset(struct mii_bus *bus)
218
{
219
#if defined(CONFIG_STMMAC_PLATFORM)
220 221
	struct net_device *ndev = bus->priv;
	struct stmmac_priv *priv = netdev_priv(ndev);
222
	unsigned int mii_address = priv->hw->mii.addr;
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
	struct stmmac_mdio_bus_data *data = priv->plat->mdio_bus_data;

#ifdef CONFIG_OF
	if (priv->device->of_node) {

		if (data->reset_gpio < 0) {
			struct device_node *np = priv->device->of_node;
			if (!np)
				return 0;

			data->reset_gpio = of_get_named_gpio(np,
						"snps,reset-gpio", 0);
			if (data->reset_gpio < 0)
				return 0;

			data->active_low = of_property_read_bool(np,
						"snps,reset-active-low");
			of_property_read_u32_array(np,
				"snps,reset-delays-us", data->delays, 3);

243 244 245
			if (gpio_request(data->reset_gpio, "mdio-reset"))
				return 0;
		}
246

247 248 249 250
		gpio_direction_output(data->reset_gpio,
				      data->active_low ? 1 : 0);
		if (data->delays[0])
			msleep(DIV_ROUND_UP(data->delays[0], 1000));
251

252 253 254
		gpio_set_value(data->reset_gpio, data->active_low ? 0 : 1);
		if (data->delays[1])
			msleep(DIV_ROUND_UP(data->delays[1], 1000));
255

256 257 258
		gpio_set_value(data->reset_gpio, data->active_low ? 1 : 0);
		if (data->delays[2])
			msleep(DIV_ROUND_UP(data->delays[2], 1000));
259 260
	}
#endif
261

262
	if (data->phy_reset) {
263
		netdev_dbg(ndev, "stmmac_mdio_reset: calling phy_reset\n");
264
		data->phy_reset(priv->plat->bsp_priv);
265 266 267 268
	}

	/* This is a workaround for problems with the STE101P PHY.
	 * It doesn't complete its reset until at least one clock cycle
269 270
	 * on MDC, so perform a dummy mdio read. To be upadted for GMAC4
	 * if needed.
271
	 */
272 273
	if (!priv->plat->has_gmac4)
		writel(0, priv->ioaddr + mii_address);
274
#endif
275 276 277 278 279 280 281 282 283 284 285 286 287
	return 0;
}

/**
 * stmmac_mdio_register
 * @ndev: net device structure
 * Description: it registers the MII bus
 */
int stmmac_mdio_register(struct net_device *ndev)
{
	int err = 0;
	struct mii_bus *new_bus;
	struct stmmac_priv *priv = netdev_priv(ndev);
288
	struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data;
G
Giuseppe CAVALLARO 已提交
289
	struct device_node *mdio_node = priv->plat->mdio_node;
290 291
	int addr, found;

292 293 294
	if (!mdio_bus_data)
		return 0;

295 296 297 298
	new_bus = mdiobus_alloc();
	if (new_bus == NULL)
		return -ENOMEM;

299
	if (mdio_bus_data->irqs)
300
		memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq));
301

302 303 304 305 306
#ifdef CONFIG_OF
	if (priv->device->of_node)
		mdio_bus_data->reset_gpio = -1;
#endif

307
	new_bus->name = "stmmac";
308 309 310 311 312 313 314 315
	if (priv->plat->has_gmac4) {
		new_bus->read = &stmmac_mdio_read_gmac4;
		new_bus->write = &stmmac_mdio_write_gmac4;
	} else {
		new_bus->read = &stmmac_mdio_read;
		new_bus->write = &stmmac_mdio_write;
	}

316
	new_bus->reset = &stmmac_mdio_reset;
317
	snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x",
G
Giuseppe CAVALLARO 已提交
318
		 new_bus->name, priv->plat->bus_id);
319
	new_bus->priv = ndev;
320
	new_bus->phy_mask = mdio_bus_data->phy_mask;
321
	new_bus->parent = priv->device;
322

323 324 325 326
	if (mdio_node)
		err = of_mdiobus_register(new_bus, mdio_node);
	else
		err = mdiobus_register(new_bus);
327
	if (err != 0) {
328
		netdev_err(ndev, "Cannot register the MDIO bus\n");
329 330 331
		goto bus_register_fail;
	}

332 333 334
	if (priv->plat->phy_node || mdio_node)
		goto bus_register_done;

335
	found = 0;
336
	for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
337
		struct phy_device *phydev = mdiobus_get_phy(new_bus, addr);
338
		if (phydev) {
339 340 341 342 343 344 345 346 347 348
			int act = 0;
			char irq_num[4];
			char *irq_str;

			/*
			 * If an IRQ was provided to be assigned after
			 * the bus probe, do it here.
			 */
			if ((mdio_bus_data->irqs == NULL) &&
			    (mdio_bus_data->probed_phy_irq > 0)) {
349 350
				new_bus->irq[addr] =
					mdio_bus_data->probed_phy_irq;
351
				phydev->irq = mdio_bus_data->probed_phy_irq;
352
			}
353 354

			/*
P
Pavel Machek 已提交
355
			 * If we're going to bind the MAC to this PHY bus,
356 357 358
			 * and no PHY number was provided to the MAC,
			 * use the one probed here.
			 */
359
			if (priv->plat->phy_addr == -1)
360 361
				priv->plat->phy_addr = addr;

362
			act = (priv->plat->phy_addr == addr);
363 364 365 366 367 368 369 370 371 372 373 374
			switch (phydev->irq) {
			case PHY_POLL:
				irq_str = "POLL";
				break;
			case PHY_IGNORE_INTERRUPT:
				irq_str = "IGNORE";
				break;
			default:
				sprintf(irq_num, "%d", phydev->irq);
				irq_str = irq_num;
				break;
			}
375 376 377 378
			netdev_info(ndev, "PHY ID %08x at %d IRQ %s (%s)%s\n",
				    phydev->phy_id, addr,
				    irq_str, phydev_name(phydev),
				    act ? " active" : "");
379 380 381 382
			found = 1;
		}
	}

383
	if (!found && !mdio_node) {
384
		netdev_warn(ndev, "No PHY found\n");
385 386 387 388 389
		mdiobus_unregister(new_bus);
		mdiobus_free(new_bus);
		return -ENODEV;
	}

390
bus_register_done:
391
	priv->mii = new_bus;
392 393

	return 0;
394

395
bus_register_fail:
396
	mdiobus_free(new_bus);
397 398 399 400 401 402 403 404 405 406 407 408
	return err;
}

/**
 * stmmac_mdio_unregister
 * @ndev: net device structure
 * Description: it unregisters the MII bus
 */
int stmmac_mdio_unregister(struct net_device *ndev)
{
	struct stmmac_priv *priv = netdev_priv(ndev);

409 410 411
	if (!priv->mii)
		return 0;

412 413
	mdiobus_unregister(priv->mii);
	priv->mii->priv = NULL;
414 415
	mdiobus_free(priv->mii);
	priv->mii = NULL;
416 417 418

	return 0;
}