aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/files
diff options
context:
space:
mode:
authorRam Chandra Jangir <rjangir@codeaurora.org>2018-12-05 19:56:32 +0530
committerJohn Crispin <john@phrozen.org>2018-12-06 08:15:27 +0100
commitbf7719f22c1f189a350f845b27189efab96b0000 (patch)
treee429ddfce45849ba06329a7330dd49dcf7145553 /target/linux/generic/files
parent99e212171abf44d6e0f7e7ba50a229ad7b3f3a34 (diff)
downloadupstream-bf7719f22c1f189a350f845b27189efab96b0000.tar.gz
upstream-bf7719f22c1f189a350f845b27189efab96b0000.tar.bz2
upstream-bf7719f22c1f189a350f845b27189efab96b0000.zip
kernel: ar83xx: Add support for three GMAC's connection
We have IPQ8064 AP161 board which has three GMAC's * RGMII x2 * SGMII x1. The existing ar8327 driver does not have support for three GMAC's connection, hence this change adds support for the same. This has been verified on AP148 and AP161 board. Signed-off-by: xiaofeis <xiaofeis@codeaurora.org> Signed-off-by: Ram Chandra Jangir <rjangir@codeaurora.org>
Diffstat (limited to 'target/linux/generic/files')
-rw-r--r--target/linux/generic/files/drivers/net/phy/ar8216.c15
-rw-r--r--target/linux/generic/files/drivers/net/phy/ar8216.h4
-rw-r--r--target/linux/generic/files/drivers/net/phy/ar8327.c44
-rw-r--r--target/linux/generic/files/drivers/net/phy/ar8327.h7
4 files changed, 69 insertions, 1 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c
index 68754e6096..2f0be1b8da 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.c
@@ -295,6 +295,17 @@ ar8xxx_rmw(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val)
return ret;
}
+void
+ar8xxx_phy_dbg_read(struct ar8xxx_priv *priv, int phy_addr,
+ u16 dbg_addr, u16 *dbg_data)
+{
+ struct mii_bus *bus = priv->mii_bus;
+
+ mutex_lock(&bus->mdio_lock);
+ bus->write(bus, phy_addr, MII_ATH_DBG_ADDR, dbg_addr);
+ *dbg_data = bus->read(bus, phy_addr, MII_ATH_DBG_DATA);
+ mutex_unlock(&bus->mdio_lock);
+}
void
ar8xxx_phy_dbg_write(struct ar8xxx_priv *priv, int phy_addr,
@@ -2166,7 +2177,7 @@ ar8xxx_phy_probe(struct phy_device *phydev)
int ret;
/* skip PHYs at unused adresses */
- if (phydev->mdio.addr != 0 && phydev->mdio.addr != 4)
+ if (phydev->mdio.addr != 0 && phydev->mdio.addr != 3 && phydev->mdio.addr != 4)
return -ENODEV;
if (!ar8xxx_is_possible(phydev->mdio.bus))
@@ -2225,6 +2236,8 @@ found:
phydev->supported |= SUPPORTED_1000baseT_Full;
phydev->advertising |= ADVERTISED_1000baseT_Full;
}
+ if (priv->chip->phy_rgmii_set)
+ priv->chip->phy_rgmii_set(priv, phydev);
}
phydev->priv = priv;
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.h b/target/linux/generic/files/drivers/net/phy/ar8216.h
index 509818c50d..33f505cbe2 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.h
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.h
@@ -413,6 +413,7 @@ struct ar8xxx_chip {
void (*get_arl_entry)(struct ar8xxx_priv *priv, struct arl_entry *a,
u32 *status, enum arl_op op);
int (*sw_hw_apply)(struct switch_dev *dev);
+ void (*phy_rgmii_set)(struct ar8xxx_priv *priv, struct phy_device *phydev);
const struct ar8xxx_mib_desc *mib_decs;
unsigned num_mibs;
@@ -478,6 +479,9 @@ u32
ar8xxx_rmw(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val);
void
+ar8xxx_phy_dbg_read(struct ar8xxx_priv *priv, int phy_addr,
+ u16 dbg_addr, u16 *dbg_data);
+void
ar8xxx_phy_dbg_write(struct ar8xxx_priv *priv, int phy_addr,
u16 dbg_addr, u16 dbg_data);
void
diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.c b/target/linux/generic/files/drivers/net/phy/ar8327.c
index 803fb3d49f..170c3e43a3 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8327.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8327.c
@@ -128,6 +128,49 @@ ar8327_get_pad_cfg(struct ar8327_pad_cfg *cfg)
}
static void
+ar8327_phy_rgmii_set(struct ar8xxx_priv *priv, struct phy_device *phydev)
+{
+ u16 phy_val = 0;
+ int phyaddr = phydev->mdio.addr;
+ struct device_node *np = phydev->mdio.dev.of_node;
+
+ if (!np)
+ return;
+
+ if (!of_property_read_bool(np, "qca,phy-rgmii-en")) {
+ pr_err("ar8327: qca,phy-rgmii-en is not specified\n");
+ return -EINVAL;
+ }
+ ar8xxx_phy_dbg_read(priv, phyaddr,
+ AR8327_PHY_MODE_SEL, &phy_val);
+ phy_val |= AR8327_PHY_MODE_SEL_RGMII;
+ ar8xxx_phy_dbg_write(priv, phyaddr,
+ AR8327_PHY_MODE_SEL, phy_val);
+
+ /* set rgmii tx clock delay if needed */
+ if (!of_property_read_bool(np, "qca,txclk-delay-en")) {
+ pr_err("ar8327: qca,txclk-delay-en is not specified\n");
+ return -EINVAL;
+ }
+ ar8xxx_phy_dbg_read(priv, phyaddr,
+ AR8327_PHY_SYS_CTRL, &phy_val);
+ phy_val |= AR8327_PHY_SYS_CTRL_RGMII_TX_DELAY;
+ ar8xxx_phy_dbg_write(priv, phyaddr,
+ AR8327_PHY_SYS_CTRL, phy_val);
+
+ /* set rgmii rx clock delay if needed */
+ if (!of_property_read_bool(np, "qca,rxclk-delay-en")) {
+ pr_err("ar8327: qca,rxclk-delay-en is not specified\n");
+ return -EINVAL;
+ }
+ ar8xxx_phy_dbg_read(priv, phyaddr,
+ AR8327_PHY_TEST_CTRL, &phy_val);
+ phy_val |= AR8327_PHY_TEST_CTRL_RGMII_RX_DELAY;
+ ar8xxx_phy_dbg_write(priv, phyaddr,
+ AR8327_PHY_TEST_CTRL, phy_val);
+}
+
+static void
ar8327_phy_fixup(struct ar8xxx_priv *priv, int phy)
{
switch (priv->chip_rev) {
@@ -1490,6 +1533,7 @@ const struct ar8xxx_chip ar8337_chip = {
.set_mirror_regs = ar8327_set_mirror_regs,
.get_arl_entry = ar8327_get_arl_entry,
.sw_hw_apply = ar8327_sw_hw_apply,
+ .phy_rgmii_set = ar8327_phy_rgmii_set,
.num_mibs = ARRAY_SIZE(ar8236_mibs),
.mib_decs = ar8236_mibs,
diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.h b/target/linux/generic/files/drivers/net/phy/ar8327.h
index 38e33ea57e..a59d306d6f 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8327.h
+++ b/target/linux/generic/files/drivers/net/phy/ar8327.h
@@ -284,6 +284,13 @@
#define AR8337_PAD_MAC06_EXCHANGE_EN BIT(31)
+#define AR8327_PHY_MODE_SEL 0x12
+#define AR8327_PHY_MODE_SEL_RGMII BIT(3)
+#define AR8327_PHY_TEST_CTRL 0x0
+#define AR8327_PHY_TEST_CTRL_RGMII_RX_DELAY BIT(15)
+#define AR8327_PHY_SYS_CTRL 0x5
+#define AR8327_PHY_SYS_CTRL_RGMII_TX_DELAY BIT(8)
+
enum ar8327_led_pattern {
AR8327_LED_PATTERN_OFF = 0,
AR8327_LED_PATTERN_BLINK,