ath79: ag71xx: Split gmac config into separated file and add support for ar934x/qca955x.
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
This commit is contained in:
parent
b346c37588
commit
2d081addb5
5 changed files with 121 additions and 58 deletions
|
@ -220,6 +220,11 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
gmac: gmac@18070000 {
|
||||||
|
compatible = "qca,qca9550-gmac";
|
||||||
|
reg = <0x18070000 0x14>;
|
||||||
|
};
|
||||||
|
|
||||||
wmac: wmac@18100000 {
|
wmac: wmac@18100000 {
|
||||||
compatible = "qca,qca9550-wmac";
|
compatible = "qca,qca9550-wmac";
|
||||||
reg = <0x18100000 0x10000>;
|
reg = <0x18100000 0x10000>;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
ag71xx-y += ag71xx_main.o
|
ag71xx-y += ag71xx_main.o
|
||||||
|
ag71xx-y += ag71xx_gmac.o
|
||||||
ag71xx-y += ag71xx_ethtool.o
|
ag71xx-y += ag71xx_ethtool.o
|
||||||
ag71xx-y += ag71xx_phy.o
|
ag71xx-y += ag71xx_phy.o
|
||||||
ag71xx-y += ag71xx_mdio.o
|
ag71xx-y += ag71xx_mdio.o
|
||||||
|
|
|
@ -447,6 +447,8 @@ void ag71xx_mdio_cleanup(struct ag71xx *ag);
|
||||||
int ag71xx_mdio_mii_read(struct mii_bus *bus, int addr, int reg);
|
int ag71xx_mdio_mii_read(struct mii_bus *bus, int addr, int reg);
|
||||||
int ag71xx_mdio_mii_write(struct mii_bus *bus, int addr, int reg, u16 val);
|
int ag71xx_mdio_mii_write(struct mii_bus *bus, int addr, int reg, u16 val);
|
||||||
|
|
||||||
|
int ag71xx_setup_gmac(struct device_node *np);
|
||||||
|
|
||||||
int ar7240sw_phy_read(struct mii_bus *mii, int addr, int reg);
|
int ar7240sw_phy_read(struct mii_bus *mii, int addr, int reg);
|
||||||
int ar7240sw_phy_write(struct mii_bus *mii, int addr, int reg, u16 val);
|
int ar7240sw_phy_write(struct mii_bus *mii, int addr, int reg, u16 val);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* Atheros AR71xx built-in ethernet mac driver
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 as published
|
||||||
|
* by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/sizes.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include "ag71xx.h"
|
||||||
|
|
||||||
|
static void ag71xx_of_set(struct device_node *np, const char *prop,
|
||||||
|
u32 *reg, u32 shift, u32 mask)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
if (of_property_read_u32(np, prop, &val))
|
||||||
|
return;
|
||||||
|
|
||||||
|
*reg &= ~(mask << shift);
|
||||||
|
*reg |= ((val & mask) << shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ag71xx_of_bit(struct device_node *np, const char *prop,
|
||||||
|
u32 *reg, u32 mask)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
if (of_property_read_u32(np, prop, &val))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (val)
|
||||||
|
*reg |= mask;
|
||||||
|
else
|
||||||
|
*reg &= ~mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ag71xx_setup_gmac_933x(struct device_node *np, void __iomem *base)
|
||||||
|
{
|
||||||
|
u32 val = __raw_readl(base + AR933X_GMAC_REG_ETH_CFG);
|
||||||
|
|
||||||
|
ag71xx_of_bit(np, "switch-phy-swap", &val, AR933X_ETH_CFG_SW_PHY_SWAP);
|
||||||
|
ag71xx_of_bit(np, "switch-phy-addr-swap", &val,
|
||||||
|
AR933X_ETH_CFG_SW_PHY_ADDR_SWAP);
|
||||||
|
|
||||||
|
__raw_writel(val, base + AR933X_GMAC_REG_ETH_CFG);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ag71xx_setup_gmac_934x(struct device_node *np, void __iomem *base)
|
||||||
|
{
|
||||||
|
u32 val = __raw_readl(base + AR934X_GMAC_REG_ETH_CFG);
|
||||||
|
|
||||||
|
ag71xx_of_bit(np, "rgmii-gmac0", &val, AR934X_ETH_CFG_RGMII_GMAC0);
|
||||||
|
ag71xx_of_bit(np, "mii-gmac0", &val, AR934X_ETH_CFG_MII_GMAC0);
|
||||||
|
ag71xx_of_bit(np, "gmii-gmac0", &val, AR934X_ETH_CFG_GMII_GMAC0);
|
||||||
|
ag71xx_of_bit(np, "switch-phy-swap", &val, AR934X_ETH_CFG_SW_PHY_SWAP);
|
||||||
|
ag71xx_of_bit(np, "switch-only-mode", &val,
|
||||||
|
AR934X_ETH_CFG_SW_ONLY_MODE);
|
||||||
|
|
||||||
|
__raw_writel(val, base + AR934X_GMAC_REG_ETH_CFG);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ag71xx_setup_gmac_955x(struct device_node *np, void __iomem *base)
|
||||||
|
{
|
||||||
|
u32 val = __raw_readl(base + QCA955X_GMAC_REG_ETH_CFG);
|
||||||
|
|
||||||
|
ag71xx_of_bit(np, "rgmii-enabled", &val, QCA955X_ETH_CFG_RGMII_EN);
|
||||||
|
ag71xx_of_bit(np, "ge0-sgmii", &val, QCA955X_ETH_CFG_GE0_SGMII);
|
||||||
|
ag71xx_of_set(np, "txen-delay", &val, QCA955X_ETH_CFG_TXE_DELAY_SHIFT, 0x3);
|
||||||
|
ag71xx_of_set(np, "txd-delay", &val, QCA955X_ETH_CFG_TXD_DELAY_SHIFT, 0x3);
|
||||||
|
ag71xx_of_set(np, "rxdv-delay", &val, QCA955X_ETH_CFG_RDV_DELAY_SHIFT, 0x3);
|
||||||
|
ag71xx_of_set(np, "rxd-delay", &val, QCA955X_ETH_CFG_RXD_DELAY_SHIFT, 0x3);
|
||||||
|
|
||||||
|
__raw_writel(val, base + QCA955X_GMAC_REG_ETH_CFG);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ag71xx_setup_gmac(struct device_node *np)
|
||||||
|
{
|
||||||
|
struct device_node *np_dev;
|
||||||
|
void __iomem *base;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
np = of_get_child_by_name(np, "gmac-config");
|
||||||
|
if (!np)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
np_dev = of_parse_phandle(np, "device", 0);
|
||||||
|
if (!np_dev)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
base = of_iomap(np_dev, 0);
|
||||||
|
if (!base) {
|
||||||
|
pr_err("%pOF: can't map GMAC registers\n", np_dev);
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_iomap;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (of_device_is_compatible(np_dev, "qca,ar9330-gmac"))
|
||||||
|
ag71xx_setup_gmac_933x(np, base);
|
||||||
|
else if (of_device_is_compatible(np_dev, "qca,ar9340-gmac"))
|
||||||
|
ag71xx_setup_gmac_934x(np, base);
|
||||||
|
else if (of_device_is_compatible(np_dev, "qca,qca9550-gmac"))
|
||||||
|
ag71xx_setup_gmac_955x(np, base);
|
||||||
|
|
||||||
|
iounmap(base);
|
||||||
|
|
||||||
|
err_iomap:
|
||||||
|
of_node_put(np_dev);
|
||||||
|
out:
|
||||||
|
of_node_put(np);
|
||||||
|
return err;
|
||||||
|
}
|
|
@ -1271,64 +1271,6 @@ static const char *ag71xx_get_phy_if_mode_name(phy_interface_t mode)
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ag71xx_of_bit(struct device_node *np, const char *prop,
|
|
||||||
u32 *reg, u32 mask)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
if (of_property_read_u32(np, prop, &val))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (val)
|
|
||||||
*reg |= mask;
|
|
||||||
else
|
|
||||||
*reg &= ~mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ag71xx_setup_gmac_933x(struct device_node *np, void __iomem *base)
|
|
||||||
{
|
|
||||||
u32 val = __raw_readl(base + AR933X_GMAC_REG_ETH_CFG);
|
|
||||||
|
|
||||||
ag71xx_of_bit(np, "switch-phy-swap", &val, AR933X_ETH_CFG_SW_PHY_SWAP);
|
|
||||||
ag71xx_of_bit(np, "switch-phy-addr-swap", &val,
|
|
||||||
AR933X_ETH_CFG_SW_PHY_ADDR_SWAP);
|
|
||||||
|
|
||||||
__raw_writel(val, base + AR933X_GMAC_REG_ETH_CFG);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ag71xx_setup_gmac(struct device_node *np)
|
|
||||||
{
|
|
||||||
struct device_node *np_dev;
|
|
||||||
void __iomem *base;
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
np = of_get_child_by_name(np, "gmac-config");
|
|
||||||
if (!np)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
np_dev = of_parse_phandle(np, "device", 0);
|
|
||||||
if (!np_dev)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
base = of_iomap(np_dev, 0);
|
|
||||||
if (!base) {
|
|
||||||
pr_err("%pOF: can't map GMAC registers\n", np_dev);
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto err_iomap;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (of_device_is_compatible(np_dev, "qca,ar9330-gmac"))
|
|
||||||
ag71xx_setup_gmac_933x(np, base);
|
|
||||||
|
|
||||||
iounmap(base);
|
|
||||||
|
|
||||||
err_iomap:
|
|
||||||
of_node_put(np_dev);
|
|
||||||
out:
|
|
||||||
of_node_put(np);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ag71xx_probe(struct platform_device *pdev)
|
static int ag71xx_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
|
|
Loading…
Reference in a new issue