2 * Xilinx PCS/PMA Core phy driver
4 * Copyright (C) 2015 - 2016 Xilinx, Inc.
6 * SPDX-License-Identifier: GPL-2.0+
14 DECLARE_GLOBAL_DATA_PTR;
16 #define MII_PHY_STATUS_SPD_MASK 0x0C00
17 #define MII_PHY_STATUS_FULLDUPLEX 0x1000
18 #define MII_PHY_STATUS_1000 0x0800
19 #define MII_PHY_STATUS_100 0x0400
20 #define XPCSPMA_PHY_CTRL_ISOLATE_DISABLE 0xFBFF
22 /* Mask used for ID comparisons */
23 #define XILINX_PHY_ID_MASK 0xfffffff0
26 #define XILINX_PHY_ID 0x01740c00
28 /* struct phy_device dev_flags definitions */
29 #define XAE_PHY_TYPE_MII 0
30 #define XAE_PHY_TYPE_GMII 1
31 #define XAE_PHY_TYPE_RGMII_1_3 2
32 #define XAE_PHY_TYPE_RGMII_2_0 3
33 #define XAE_PHY_TYPE_SGMII 4
34 #define XAE_PHY_TYPE_1000BASE_X 5
36 static int xilinxphy_startup(struct phy_device *phydev)
41 debug("%s\n", __func__);
42 /* Update the link, but return if there
45 err = genphy_update_link(phydev);
49 if (AUTONEG_ENABLE == phydev->autoneg) {
50 status = phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
51 status = status & MII_PHY_STATUS_SPD_MASK;
53 if (status & MII_PHY_STATUS_FULLDUPLEX)
54 phydev->duplex = DUPLEX_FULL;
56 phydev->duplex = DUPLEX_HALF;
59 case MII_PHY_STATUS_1000:
60 phydev->speed = SPEED_1000;
63 case MII_PHY_STATUS_100:
64 phydev->speed = SPEED_100;
68 phydev->speed = SPEED_10;
72 int bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
77 if (bmcr & BMCR_FULLDPLX)
78 phydev->duplex = DUPLEX_FULL;
80 phydev->duplex = DUPLEX_HALF;
82 if (bmcr & BMCR_SPEED1000)
83 phydev->speed = SPEED_1000;
84 else if (bmcr & BMCR_SPEED100)
85 phydev->speed = SPEED_100;
87 phydev->speed = SPEED_10;
91 * For 1000BASE-X Phy Mode the speed/duplex will always be
94 if (phydev->flags == XAE_PHY_TYPE_1000BASE_X) {
95 phydev->duplex = DUPLEX_FULL;
96 phydev->speed = SPEED_1000;
102 static int xilinxphy_of_init(struct phy_device *phydev)
106 debug("%s\n", __func__);
107 phytype = fdtdec_get_int(gd->fdt_blob, phydev->dev->of_offset,
109 if (phytype == XAE_PHY_TYPE_1000BASE_X)
110 phydev->flags |= XAE_PHY_TYPE_1000BASE_X;
115 static int xilinxphy_config(struct phy_device *phydev)
119 debug("%s\n", __func__);
120 xilinxphy_of_init(phydev);
121 temp = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
122 temp &= XPCSPMA_PHY_CTRL_ISOLATE_DISABLE;
123 phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, temp);
128 static struct phy_driver xilinxphy_driver = {
129 .uid = XILINX_PHY_ID,
130 .mask = XILINX_PHY_ID_MASK,
131 .name = "Xilinx PCS/PMA PHY",
132 .features = PHY_GBIT_FEATURES,
133 .config = &xilinxphy_config,
134 .startup = &xilinxphy_startup,
135 .shutdown = &genphy_shutdown,
138 int phy_xilinx_init(void)
140 debug("%s\n", __func__);
141 phy_register(&xilinxphy_driver);