video-uclass: Fix logical-not-parentheses warning
[platform/kernel/u-boot.git] / drivers / net / phy / xilinx_phy.c
1 /*
2  * Xilinx PCS/PMA Core phy driver
3  *
4  * Copyright (C) 2015 - 2016 Xilinx, Inc.
5  *
6  * SPDX-License-Identifier:     GPL-2.0+
7  */
8
9 #include <config.h>
10 #include <common.h>
11 #include <phy.h>
12 #include <dm.h>
13
14 DECLARE_GLOBAL_DATA_PTR;
15
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
21
22 /* Mask used for ID comparisons */
23 #define XILINX_PHY_ID_MASK              0xfffffff0
24
25 /* Known PHY IDs */
26 #define XILINX_PHY_ID                   0x01740c00
27
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
35
36 static int xilinxphy_startup(struct phy_device *phydev)
37 {
38         int err;
39         int status = 0;
40
41         debug("%s\n", __func__);
42         /* Update the link, but return if there
43          * was an error
44          */
45         err = genphy_update_link(phydev);
46         if (err)
47                 return err;
48
49         if (AUTONEG_ENABLE == phydev->autoneg) {
50                 status = phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
51                 status = status & MII_PHY_STATUS_SPD_MASK;
52
53                 if (status & MII_PHY_STATUS_FULLDUPLEX)
54                         phydev->duplex = DUPLEX_FULL;
55                 else
56                         phydev->duplex = DUPLEX_HALF;
57
58                 switch (status) {
59                 case MII_PHY_STATUS_1000:
60                         phydev->speed = SPEED_1000;
61                         break;
62
63                 case MII_PHY_STATUS_100:
64                         phydev->speed = SPEED_100;
65                         break;
66
67                 default:
68                         phydev->speed = SPEED_10;
69                         break;
70                 }
71         } else {
72                 int bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
73
74                 if (bmcr < 0)
75                         return bmcr;
76
77                 if (bmcr & BMCR_FULLDPLX)
78                         phydev->duplex = DUPLEX_FULL;
79                 else
80                         phydev->duplex = DUPLEX_HALF;
81
82                 if (bmcr & BMCR_SPEED1000)
83                         phydev->speed = SPEED_1000;
84                 else if (bmcr & BMCR_SPEED100)
85                         phydev->speed = SPEED_100;
86                 else
87                         phydev->speed = SPEED_10;
88         }
89
90         /*
91          * For 1000BASE-X Phy Mode the speed/duplex will always be
92          * 1000Mbps/fullduplex
93          */
94         if (phydev->flags == XAE_PHY_TYPE_1000BASE_X) {
95                 phydev->duplex = DUPLEX_FULL;
96                 phydev->speed = SPEED_1000;
97         }
98
99         return 0;
100 }
101
102 static int xilinxphy_of_init(struct phy_device *phydev)
103 {
104         u32 phytype;
105
106         debug("%s\n", __func__);
107         phytype = fdtdec_get_int(gd->fdt_blob, dev_of_offset(phydev->dev),
108                                  "phy-type", -1);
109         if (phytype == XAE_PHY_TYPE_1000BASE_X)
110                 phydev->flags |= XAE_PHY_TYPE_1000BASE_X;
111
112         return 0;
113 }
114
115 static int xilinxphy_config(struct phy_device *phydev)
116 {
117         int temp;
118
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);
124
125         return 0;
126 }
127
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,
136 };
137
138 int phy_xilinx_init(void)
139 {
140         debug("%s\n", __func__);
141         phy_register(&xilinxphy_driver);
142
143         return 0;
144 }