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,
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))
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;
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;
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);
return t;
}
+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)
{
.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,
#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,