MLK-14438-05 net: fec: register Athreos phy AR8031 fixup
authorAndy Duan <fugang.duan@nxp.com>
Tue, 14 Mar 2017 07:04:12 +0000 (15:04 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 20:21:32 +0000 (15:21 -0500)
Register Athreos PHY AR8031 fixup.

Signed-off-by: Fugang Duan <fugang.duan@nxp.com>
(cherry picked and merged from commit:676bf1d92b3e6babdab623694fd83d54f881fc2f)

drivers/net/ethernet/freescale/Makefile
drivers/net/ethernet/freescale/fec.h
drivers/net/ethernet/freescale/fec_fixup.c [new file with mode: 0644]
drivers/net/ethernet/freescale/fec_main.c

index cbe21dc..7f022dd 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 obj-$(CONFIG_FEC) += fec.o
-fec-objs :=fec_main.o fec_ptp.o
+fec-objs :=fec_main.o fec_fixup.o fec_ptp.o
 CFLAGS_fec_main.o := -D__CHECK_ENDIAN__
 CFLAGS_fec_ptp.o := -D__CHECK_ENDIAN__
 
index 8048af9..97e842d 100644 (file)
@@ -459,6 +459,9 @@ struct bufdesc_ex {
  */
 #define FEC_QUIRK_BUG_WAITMODE         (1 << 15)
 
+/* PHY fixup flag define */
+#define FEC_QUIRK_AR8031_FIXUP         (1 << 0)
+
 struct bufdesc_prop {
        int qid;
        /* Address of Rx and Tx buffers */
@@ -555,6 +558,7 @@ struct fec_enet_private {
        int     wol_flag;
        int     wake_irq;
        u32     quirks;
+       u32     fixups;
 
        struct  napi_struct napi;
        int     csum_flags;
@@ -608,6 +612,8 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev);
 int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr);
 int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr);
 uint fec_ptp_check_pps_event(struct fec_enet_private *fep);
+void fec_enet_register_fixup(struct net_device *ndev);
+int of_fec_enet_parse_fixup(struct device_node *np);
 
 /****************************************************************************/
 #endif /* FEC_H */
diff --git a/drivers/net/ethernet/freescale/fec_fixup.c b/drivers/net/ethernet/freescale/fec_fixup.c
new file mode 100644 (file)
index 0000000..5a8497c
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2017 NXP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include "fec.h"
+
+#define PHY_ID_AR8031   0x004dd074
+
+static int ar8031_phy_fixup(struct phy_device *dev)
+{
+       u16 val;
+
+       /* Set RGMII IO voltage to 1.8V */
+       phy_write(dev, 0x1d, 0x1f);
+       phy_write(dev, 0x1e, 0x8);
+
+       /* Disable phy AR8031 SmartEEE function */
+       phy_write(dev, 0xd, 0x3);
+       phy_write(dev, 0xe, 0x805d);
+       phy_write(dev, 0xd, 0x4003);
+       val = phy_read(dev, 0xe);
+       val &= ~(0x1 << 8);
+       phy_write(dev, 0xe, val);
+
+       /* Introduce tx clock delay */
+       phy_write(dev, 0x1d, 0x5);
+       phy_write(dev, 0x1e, 0x100);
+
+       return 0;
+}
+
+void fec_enet_register_fixup(struct net_device *ndev)
+{
+       struct fec_enet_private *fep = netdev_priv(ndev);
+       static int registered = 0;
+       int err;
+
+       if (!IS_BUILTIN(CONFIG_PHYLIB))
+               return;
+
+       if (fep->fixups & FEC_QUIRK_AR8031_FIXUP) {
+               static int ar8031_registered = 0;
+
+               if (ar8031_registered)
+                       return;
+               err = phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffef,
+                                       ar8031_phy_fixup);
+               if (err)
+                       netdev_info(ndev, "Cannot register PHY board fixup\n");
+               registered = 1;
+       }
+}
+
+int of_fec_enet_parse_fixup(struct device_node *np)
+{
+       int fixups = 0;
+
+       if (of_get_property(np, "fsl,ar8031-phy-fixup", NULL))
+               fixups |= FEC_QUIRK_AR8031_FIXUP;
+
+       return fixups;
+}
index 5d6c1ad..f744a0d 100644 (file)
@@ -3654,6 +3654,9 @@ fec_probe(struct platform_device *pdev)
        if (ret)
                goto failed_register;
 
+       fep->fixups = of_fec_enet_parse_fixup(np);
+       fec_enet_register_fixup(ndev);
+
        device_init_wakeup(&ndev->dev, fep->wol_flag &
                           FEC_WOL_HAS_MAGIC_PACKET);