Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fb97a846 authored by Jean-Christophe PLAGNIOL-VILLARD's avatar Jean-Christophe PLAGNIOL-VILLARD Committed by Nicolas Ferre
Browse files

net/macb: add DT support for Cadence macb/gem driver



Allow the device tree to provide the mac address and the phy mode.

Signed-off-by: default avatarJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
[nicolas.ferre@atmel.com: change "compatible" node property, doc and DT hwaddr]
Signed-off-by: default avatarNicolas Ferre <nicolas.ferre@atmel.com>
[jamie@jamieiles.com: add "gem" compatibility strings and doc]
Acked-by: default avatarJamie <Iles&lt;jamie@jamieiles.com>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0116da4f
Loading
Loading
Loading
Loading
+25 −0
Original line number Original line Diff line number Diff line
* Cadence MACB/GEM Ethernet controller

Required properties:
- compatible: Should be "cdns,[<chip>-]{macb|gem}"
  Use "cdns,at91sam9260-macb" Atmel at91sam9260 and at91sam9263 SoCs.
  Use "cdns,at32ap7000-macb" for other 10/100 usage or use the generic form: "cdns,macb".
  Use "cnds,pc302-gem" for Picochip picoXcell pc302 and later devices based on
  the Cadence GEM, or the generic form: "cdns,gem".
- reg: Address and length of the register set for the device
- interrupts: Should contain macb interrupt
- phy-mode: String, operation mode of the PHY interface.
  Supported values are: "mii", "rmii", "gmii", "rgmii".

Optional properties:
- local-mac-address: 6 bytes, mac address

Examples:

	macb0: ethernet@fffc4000 {
		compatible = "cdns,at32ap7000-macb";
		reg = <0xfffc4000 0x4000>;
		interrupts = <21>;
		phy-mode = "rmii";
		local-mac-address = [3a 0e 03 04 05 06];
	};
+65 −8
Original line number Original line Diff line number Diff line
@@ -23,6 +23,8 @@
#include <linux/platform_data/macb.h>
#include <linux/platform_data/macb.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/phy.h>
#include <linux/phy.h>
#include <linux/of_device.h>
#include <linux/of_net.h>


#include "macb.h"
#include "macb.h"


@@ -191,7 +193,6 @@ static int macb_mii_probe(struct net_device *dev)
{
{
	struct macb *bp = netdev_priv(dev);
	struct macb *bp = netdev_priv(dev);
	struct phy_device *phydev;
	struct phy_device *phydev;
	struct macb_platform_data *pdata;
	int ret;
	int ret;


	phydev = phy_find_first(bp->mii_bus);
	phydev = phy_find_first(bp->mii_bus);
@@ -200,14 +201,11 @@ static int macb_mii_probe(struct net_device *dev)
		return -1;
		return -1;
	}
	}


	pdata = bp->pdev->dev.platform_data;
	/* TODO : add pin_irq */
	/* TODO : add pin_irq */


	/* attach the mac to the phy */
	/* attach the mac to the phy */
	ret = phy_connect_direct(dev, phydev, &macb_handle_link_change, 0,
	ret = phy_connect_direct(dev, phydev, &macb_handle_link_change, 0,
				 pdata && pdata->is_rmii ?
				 bp->phy_interface);
				 PHY_INTERFACE_MODE_RMII :
				 PHY_INTERFACE_MODE_MII);
	if (ret) {
	if (ret) {
		netdev_err(dev, "Could not attach to PHY\n");
		netdev_err(dev, "Could not attach to PHY\n");
		return ret;
		return ret;
@@ -1244,6 +1242,52 @@ static const struct net_device_ops macb_netdev_ops = {
#endif
#endif
};
};


#if defined(CONFIG_OF)
static const struct of_device_id macb_dt_ids[] = {
	{ .compatible = "cdns,at32ap7000-macb" },
	{ .compatible = "cdns,at91sam9260-macb" },
	{ .compatible = "cdns,macb" },
	{ .compatible = "cdns,pc302-gem" },
	{ .compatible = "cdns,gem" },
	{ /* sentinel */ }
};

MODULE_DEVICE_TABLE(of, macb_dt_ids);

static int __devinit macb_get_phy_mode_dt(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;

	if (np)
		return of_get_phy_mode(np);

	return -ENODEV;
}

static int __devinit macb_get_hwaddr_dt(struct macb *bp)
{
	struct device_node *np = bp->pdev->dev.of_node;
	if (np) {
		const char *mac = of_get_mac_address(np);
		if (mac) {
			memcpy(bp->dev->dev_addr, mac, ETH_ALEN);
			return 0;
		}
	}

	return -ENODEV;
}
#else
static int __devinit macb_get_phy_mode_dt(struct platform_device *pdev)
{
	return -ENODEV;
}
static int __devinit macb_get_hwaddr_dt(struct macb *bp)
{
	return -ENODEV;
}
#endif

static int __init macb_probe(struct platform_device *pdev)
static int __init macb_probe(struct platform_device *pdev)
{
{
	struct macb_platform_data *pdata;
	struct macb_platform_data *pdata;
@@ -1318,10 +1362,22 @@ static int __init macb_probe(struct platform_device *pdev)
	config |= macb_dbw(bp);
	config |= macb_dbw(bp);
	macb_writel(bp, NCFGR, config);
	macb_writel(bp, NCFGR, config);


	err = macb_get_hwaddr_dt(bp);
	if (err < 0)
		macb_get_hwaddr(bp);
		macb_get_hwaddr(bp);
	pdata = pdev->dev.platform_data;


	err = macb_get_phy_mode_dt(pdev);
	if (err < 0) {
		pdata = pdev->dev.platform_data;
		if (pdata && pdata->is_rmii)
		if (pdata && pdata->is_rmii)
			bp->phy_interface = PHY_INTERFACE_MODE_RMII;
		else
			bp->phy_interface = PHY_INTERFACE_MODE_MII;
	} else {
		bp->phy_interface = err;
	}

	if (bp->phy_interface == PHY_INTERFACE_MODE_RMII)
#if defined(CONFIG_ARCH_AT91)
#if defined(CONFIG_ARCH_AT91)
		macb_or_gem_writel(bp, USRIO, (MACB_BIT(RMII) |
		macb_or_gem_writel(bp, USRIO, (MACB_BIT(RMII) |
					       MACB_BIT(CLKEN)));
					       MACB_BIT(CLKEN)));
@@ -1444,6 +1500,7 @@ static struct platform_driver macb_driver = {
	.driver		= {
	.driver		= {
		.name		= "macb",
		.name		= "macb",
		.owner	= THIS_MODULE,
		.owner	= THIS_MODULE,
		.of_match_table	= of_match_ptr(macb_dt_ids),
	},
	},
};
};


+2 −0
Original line number Original line Diff line number Diff line
@@ -532,6 +532,8 @@ struct macb {
	unsigned int 		link;
	unsigned int 		link;
	unsigned int 		speed;
	unsigned int 		speed;
	unsigned int 		duplex;
	unsigned int 		duplex;

	phy_interface_t		phy_interface;
};
};


static inline bool macb_is_gem(struct macb *bp)
static inline bool macb_is_gem(struct macb *bp)