ipq40xx: net: phy: ar40xx: remove PHY handling
authorRobert Marko <robert.marko@sartura.hr>
Thu, 8 Oct 2020 10:20:39 +0000 (12:20 +0200)
committerPetr Štetiar <ynezz@true.cz>
Wed, 23 Dec 2020 15:36:08 +0000 (16:36 +0100)
Since we now have proper PHY driver for the QCA807x PHY-s, lets remove
PHY handling from AR40xx.

This removes PHY driver, PHY GPIO driver and PHY init code.
AR40xx still needs to handle PSGMII calibration as that requires R/W
from the switch, so I am unable to move it into PHY driver.

This also converted the AR40xx driver to use OF_MDIO to find the MDIO
bus as it now cant be set through the PHY driver.
So lets depend on OF_MDIO in KConfig.

Signed-off-by: Robert Marko <robert.marko@sartura.hr>
target/linux/ipq40xx/files/drivers/net/phy/ar40xx.c
target/linux/ipq40xx/patches-5.4/705-net-add-qualcomm-ar40xx-phy.patch

index 18ff26affc24daf2846472a705bf95a91db8ec60..c35ba2799f06792eeb3e446e42098b6f77a182f3 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/workqueue.h>
 #include <linux/of_device.h>
 #include <linux/of_address.h>
+#include <linux/of_mdio.h>
 #include <linux/mdio.h>
 #include <linux/gpio.h>
 
@@ -1245,42 +1246,6 @@ ar40xx_init_globals(struct ar40xx_priv *priv)
        ar40xx_write(priv, AR40XX_REG_PORT_FLOWCTRL_THRESH(0), t);
 }
 
-static void
-ar40xx_malibu_init(struct ar40xx_priv *priv)
-{
-       int i;
-       struct mii_bus *bus;
-       u16 val;
-
-       bus = priv->mii_bus;
-
-       /* war to enable AZ transmitting ability */
-       ar40xx_phy_mmd_write(priv, AR40XX_PSGMII_ID, 1,
-                            AR40XX_MALIBU_PSGMII_MODE_CTRL,
-                            AR40XX_MALIBU_PHY_PSGMII_MODE_CTRL_ADJUST_VAL);
-       for (i = 0; i < AR40XX_NUM_PORTS - 1; i++) {
-               /* change malibu control_dac */
-               val = ar40xx_phy_mmd_read(priv, i, 7,
-                                         AR40XX_MALIBU_PHY_MMD7_DAC_CTRL);
-               val &= ~AR40XX_MALIBU_DAC_CTRL_MASK;
-               val |= AR40XX_MALIBU_DAC_CTRL_VALUE;
-               ar40xx_phy_mmd_write(priv, i, 7,
-                                    AR40XX_MALIBU_PHY_MMD7_DAC_CTRL, val);
-               if (i == AR40XX_MALIBU_PHY_LAST_ADDR) {
-                       /* to avoid goes into hibernation */
-                       val = ar40xx_phy_mmd_read(priv, i, 3,
-                                                 AR40XX_MALIBU_PHY_RLP_CTRL);
-                       val &= (~(1<<1));
-                       ar40xx_phy_mmd_write(priv, i, 3,
-                                            AR40XX_MALIBU_PHY_RLP_CTRL, val);
-               }
-       }
-
-       /* adjust psgmii serdes tx amp */
-       mdiobus_write(bus, AR40XX_PSGMII_ID, AR40XX_PSGMII_TX_DRIVER_1_CTRL,
-                     AR40XX_MALIBU_PHY_PSGMII_REDUCE_SERDES_TX_AMP);
-}
-
 static int
 ar40xx_hw_init(struct ar40xx_priv *priv)
 {
@@ -1288,9 +1253,7 @@ ar40xx_hw_init(struct ar40xx_priv *priv)
 
        ar40xx_ess_reset(priv);
 
-       if (priv->mii_bus)
-               ar40xx_malibu_init(priv);
-       else
+       if (!priv->mii_bus)
                return -1;
 
        ar40xx_psgmii_self_test(priv);
@@ -1763,183 +1726,13 @@ static const struct switch_dev_ops ar40xx_sw_ops = {
        .get_port_link = ar40xx_sw_get_port_link,
 };
 
-/* Start of phy driver support */
-
-static const u32 ar40xx_phy_ids[] = {
-       0x004dd0b1,
-       0x004dd0b2, /* AR40xx */
-};
-
-static bool
-ar40xx_phy_match(u32 phy_id)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(ar40xx_phy_ids); i++)
-               if (phy_id == ar40xx_phy_ids[i])
-                       return true;
-
-       return false;
-}
-
-static bool
-is_ar40xx_phy(struct mii_bus *bus)
-{
-       unsigned i;
-
-       for (i = 0; i < 4; i++) {
-               u32 phy_id;
-
-               phy_id = mdiobus_read(bus, i, MII_PHYSID1) << 16;
-               phy_id |= mdiobus_read(bus, i, MII_PHYSID2);
-               if (!ar40xx_phy_match(phy_id))
-                       return false;
-       }
-
-       return true;
-}
-
-static int
-ar40xx_phy_probe(struct phy_device *phydev)
-{
-       if (!is_ar40xx_phy(phydev->mdio.bus))
-               return -ENODEV;
-
-       ar40xx_priv->mii_bus = phydev->mdio.bus;
-       phydev->priv = ar40xx_priv;
-       if (phydev->mdio.addr == 0)
-               ar40xx_priv->phy = phydev;
-
-       linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, phydev->supported);
-       linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, phydev->advertising);
-       return 0;
-}
-
-static void
-ar40xx_phy_remove(struct phy_device *phydev)
-{
-       ar40xx_priv->mii_bus = NULL;
-       phydev->priv = NULL;
-}
-
-static int
-ar40xx_phy_config_init(struct phy_device *phydev)
-{
-       return 0;
-}
-
-static int
-ar40xx_phy_read_status(struct phy_device *phydev)
-{
-       if (phydev->mdio.addr != 0)
-               return genphy_read_status(phydev);
-
-       return 0;
-}
-
-static int
-ar40xx_phy_config_aneg(struct phy_device *phydev)
-{
-       if (phydev->mdio.addr == 0)
-               return 0;
-
-       return genphy_config_aneg(phydev);
-}
-
-static struct phy_driver ar40xx_phy_driver = {
-       .phy_id         = 0x004d0000,
-       .name           = "QCA Malibu",
-       .phy_id_mask    = 0xffff0000,
-       .features       = PHY_GBIT_FEATURES,
-       .probe          = ar40xx_phy_probe,
-       .remove         = ar40xx_phy_remove,
-       .config_init    = ar40xx_phy_config_init,
-       .config_aneg    = ar40xx_phy_config_aneg,
-       .read_status    = ar40xx_phy_read_status,
-};
-
-static uint16_t ar40xx_gpio_get_phy(unsigned int offset)
-{
-       return offset / 4;
-}
-
-static uint16_t ar40xx_gpio_get_reg(unsigned int offset)
-{
-       return 0x8074 + offset % 4;
-}
-
-static void ar40xx_gpio_set(struct gpio_chip *gc, unsigned int offset,
-                           int value)
-{
-       struct ar40xx_priv *priv = gpiochip_get_data(gc);
-
-       ar40xx_phy_mmd_write(priv, ar40xx_gpio_get_phy(offset), 0x7,
-                            ar40xx_gpio_get_reg(offset),
-                            value ? 0xA000 : 0x8000);
-}
-
-static int ar40xx_gpio_get(struct gpio_chip *gc, unsigned offset)
-{
-       struct ar40xx_priv *priv = gpiochip_get_data(gc);
-
-       return ar40xx_phy_mmd_read(priv, ar40xx_gpio_get_phy(offset), 0x7,
-                                  ar40xx_gpio_get_reg(offset)) == 0xA000;
-}
-
-static int ar40xx_gpio_get_dir(struct gpio_chip *gc, unsigned offset)
-{
-       return 0; /* only out direction */
-}
-
-static int ar40xx_gpio_dir_out(struct gpio_chip *gc, unsigned offset,
-                              int value)
-{
-       /*
-        * the direction out value is used to set the initial value.
-        * support of this function is required by leds-gpio.c
-        */
-       ar40xx_gpio_set(gc, offset, value);
-       return 0;
-}
-
-static void ar40xx_register_gpio(struct device *pdev,
-                                struct ar40xx_priv *priv,
-                                struct device_node *switch_node)
-{
-       struct gpio_chip *gc;
-       int err;
-
-       gc = devm_kzalloc(pdev, sizeof(*gc), GFP_KERNEL);
-       if (!gc)
-               return;
-
-       gc->label = "ar40xx_gpio",
-       gc->base = -1,
-       gc->ngpio = 5 /* mmd 0 - 4 */ * 4 /* 0x8074 - 0x8077 */,
-       gc->parent = pdev;
-       gc->owner = THIS_MODULE;
-
-       gc->get_direction = ar40xx_gpio_get_dir;
-       gc->direction_output = ar40xx_gpio_dir_out;
-       gc->get = ar40xx_gpio_get;
-       gc->set = ar40xx_gpio_set;
-       gc->can_sleep = true;
-       gc->label = priv->dev.name;
-       gc->of_node = switch_node;
-
-       err = devm_gpiochip_add_data(pdev, gc, priv);
-       if (err != 0)
-               dev_err(pdev, "Failed to register gpio %d.\n", err);
-}
-
-/* End of phy driver support */
-
 /* Platform driver probe function */
 
 static int ar40xx_probe(struct platform_device *pdev)
 {
        struct device_node *switch_node;
        struct device_node *psgmii_node;
+       struct device_node *mdio_node;
        const __be32 *mac_mode;
        struct clk *ess_clk;
        struct switch_dev *swdev;
@@ -2010,12 +1803,6 @@ static int ar40xx_probe(struct platform_device *pdev)
                return -EIO;
        }
 
-       ret = phy_driver_register(&ar40xx_phy_driver, THIS_MODULE);
-       if (ret) {
-               dev_err(&pdev->dev, "Failed to register ar40xx phy driver!\n");
-               return -EIO;
-       }
-
        mutex_init(&priv->reg_mutex);
        mutex_init(&priv->mib_lock);
        INIT_DELAYED_WORK(&priv->mib_work, ar40xx_mib_work_func);
@@ -2023,6 +1810,15 @@ static int ar40xx_probe(struct platform_device *pdev)
        /* register switch */
        swdev = &priv->dev;
 
+       mdio_node = of_find_compatible_node(NULL, NULL, "qcom,ipq4019-mdio");
+       if (!mdio_node) {
+               dev_err(&pdev->dev, "Probe failed - Cannot find mdio node by phandle!\n");
+               ret = -ENODEV;
+               goto err_missing_phy;
+       }
+
+       priv->mii_bus = of_mdio_find_bus(mdio_node);
+
        if (priv->mii_bus == NULL) {
                dev_err(&pdev->dev, "Probe failed - Missing PHYs!\n");
                ret = -ENODEV;
@@ -2037,8 +1833,10 @@ static int ar40xx_probe(struct platform_device *pdev)
        swdev->ports = AR40XX_NUM_PORTS;
        swdev->ops = &ar40xx_sw_ops;
        ret = register_switch(swdev, NULL);
-       if (ret)
-               goto err_unregister_phy;
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Switch registration failed!\n");
+               return ret;
+       }
 
        num_mibs = ARRAY_SIZE(ar40xx_mibs);
        len = priv->dev.ports * num_mibs *
@@ -2051,15 +1849,10 @@ static int ar40xx_probe(struct platform_device *pdev)
 
        ar40xx_start(priv);
 
-       if (of_property_read_bool(switch_node, "gpio-controller"))
-               ar40xx_register_gpio(&pdev->dev, ar40xx_priv, switch_node);
-
        return 0;
 
 err_unregister_switch:
        unregister_switch(&priv->dev);
-err_unregister_phy:
-       phy_driver_unregister(&ar40xx_phy_driver);
 err_missing_phy:
        platform_set_drvdata(pdev, NULL);
        return ret;
@@ -2074,8 +1867,6 @@ static int ar40xx_remove(struct platform_device *pdev)
 
        unregister_switch(&priv->dev);
 
-       phy_driver_unregister(&ar40xx_phy_driver);
-
        return 0;
 }
 
index 6f080892d55a8497adc0a0e280a438d69737fdf3..9adddcabc3867cefe6362f37bef5e20fed717907 100644 (file)
@@ -1,12 +1,12 @@
 --- a/drivers/net/phy/Kconfig
 +++ b/drivers/net/phy/Kconfig
-@@ -584,6 +584,13 @@ config MDIO_IPQ40XX
-         This driver supports the MDIO interface found in Qualcomm
-         Atheros ipq40xx Soc chip.
+@@ -584,6 +584,13 @@ config XILINX_GMII2RGMII
+         the Reduced Gigabit Media Independent Interface(RGMII) between
+         Ethernet physical media devices and the Gigabit Ethernet controller.
  
 +config AR40XX_PHY
 +      tristate "Driver for Qualcomm Atheros IPQ40XX switches"
-+      depends on HAS_IOMEM && OF
++      depends on HAS_IOMEM && OF && OF_MDIO
 +      select SWCONFIG
 +      help
 +         This is the driver for Qualcomm Atheros IPQ40XX ESS switches.