sandbox: Make map_to_sysmem() use a constant pointer
[oweals/u-boot.git] / drivers / net / phy / micrel.c
1 /*
2  * Micrel PHY drivers
3  *
4  * SPDX-License-Identifier:     GPL-2.0+
5  *
6  * Copyright 2010-2011 Freescale Semiconductor, Inc.
7  * author Andy Fleming
8  * (C) 2012 NetModule AG, David Andrey, added KSZ9031
9  */
10 #include <config.h>
11 #include <common.h>
12 #include <micrel.h>
13 #include <phy.h>
14
15 static struct phy_driver KSZ804_driver = {
16         .name = "Micrel KSZ804",
17         .uid = 0x221510,
18         .mask = 0xfffff0,
19         .features = PHY_BASIC_FEATURES,
20         .config = &genphy_config,
21         .startup = &genphy_startup,
22         .shutdown = &genphy_shutdown,
23 };
24
25 #ifndef CONFIG_PHY_MICREL_KSZ9021
26 /*
27  * I can't believe Micrel used the exact same part number
28  * for the KSZ9021
29  * Shame Micrel, Shame!!!!!
30  */
31 static struct phy_driver KS8721_driver = {
32         .name = "Micrel KS8721BL",
33         .uid = 0x221610,
34         .mask = 0xfffff0,
35         .features = PHY_BASIC_FEATURES,
36         .config = &genphy_config,
37         .startup = &genphy_startup,
38         .shutdown = &genphy_shutdown,
39 };
40 #endif
41
42
43 /**
44  * KSZ9021 - KSZ9031 common
45  */
46
47 #define MII_KSZ90xx_PHY_CTL             0x1f
48 #define MIIM_KSZ90xx_PHYCTL_1000        (1 << 6)
49 #define MIIM_KSZ90xx_PHYCTL_100         (1 << 5)
50 #define MIIM_KSZ90xx_PHYCTL_10          (1 << 4)
51 #define MIIM_KSZ90xx_PHYCTL_DUPLEX      (1 << 3)
52
53 static int ksz90xx_startup(struct phy_device *phydev)
54 {
55         unsigned phy_ctl;
56         genphy_update_link(phydev);
57         phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ90xx_PHY_CTL);
58
59         if (phy_ctl & MIIM_KSZ90xx_PHYCTL_DUPLEX)
60                 phydev->duplex = DUPLEX_FULL;
61         else
62                 phydev->duplex = DUPLEX_HALF;
63
64         if (phy_ctl & MIIM_KSZ90xx_PHYCTL_1000)
65                 phydev->speed = SPEED_1000;
66         else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_100)
67                 phydev->speed = SPEED_100;
68         else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_10)
69                 phydev->speed = SPEED_10;
70         return 0;
71 }
72 #ifdef CONFIG_PHY_MICREL_KSZ9021
73
74 /*
75  * KSZ9021
76  */
77
78 /* PHY Registers */
79 #define MII_KSZ9021_EXTENDED_CTRL       0x0b
80 #define MII_KSZ9021_EXTENDED_DATAW      0x0c
81 #define MII_KSZ9021_EXTENDED_DATAR      0x0d
82
83 #define CTRL1000_PREFER_MASTER          (1 << 10)
84 #define CTRL1000_CONFIG_MASTER          (1 << 11)
85 #define CTRL1000_MANUAL_CONFIG          (1 << 12)
86
87 int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val)
88 {
89         /* extended registers */
90         phy_write(phydev, MDIO_DEVAD_NONE,
91                 MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000);
92         return phy_write(phydev, MDIO_DEVAD_NONE,
93                 MII_KSZ9021_EXTENDED_DATAW, val);
94 }
95
96 int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum)
97 {
98         /* extended registers */
99         phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum);
100         return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);
101 }
102
103 /* Micrel ksz9021 */
104 static int ksz9021_config(struct phy_device *phydev)
105 {
106         unsigned ctrl1000 = 0;
107         const unsigned master = CTRL1000_PREFER_MASTER |
108                         CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
109         unsigned features = phydev->drv->features;
110
111         if (getenv("disable_giga"))
112                 features &= ~(SUPPORTED_1000baseT_Half |
113                                 SUPPORTED_1000baseT_Full);
114         /* force master mode for 1000BaseT due to chip errata */
115         if (features & SUPPORTED_1000baseT_Half)
116                 ctrl1000 |= ADVERTISE_1000HALF | master;
117         if (features & SUPPORTED_1000baseT_Full)
118                 ctrl1000 |= ADVERTISE_1000FULL | master;
119         phydev->advertising = phydev->supported = features;
120         phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
121         genphy_config_aneg(phydev);
122         genphy_restart_aneg(phydev);
123         return 0;
124 }
125
126 static struct phy_driver ksz9021_driver = {
127         .name = "Micrel ksz9021",
128         .uid  = 0x221610,
129         .mask = 0xfffff0,
130         .features = PHY_GBIT_FEATURES,
131         .config = &ksz9021_config,
132         .startup = &ksz90xx_startup,
133         .shutdown = &genphy_shutdown,
134 };
135 #endif
136
137 /**
138  * KSZ9031
139  */
140 /* PHY Registers */
141 #define MII_KSZ9031_MMD_ACCES_CTRL      0x0d
142 #define MII_KSZ9031_MMD_REG_DATA        0x0e
143
144 /* Accessors to extended registers*/
145 int ksz9031_phy_extended_write(struct phy_device *phydev,
146                                int devaddr, int regnum, u16 mode, u16 val)
147 {
148         /*select register addr for mmd*/
149         phy_write(phydev, MDIO_DEVAD_NONE,
150                   MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
151         /*select register for mmd*/
152         phy_write(phydev, MDIO_DEVAD_NONE,
153                   MII_KSZ9031_MMD_REG_DATA, regnum);
154         /*setup mode*/
155         phy_write(phydev, MDIO_DEVAD_NONE,
156                   MII_KSZ9031_MMD_ACCES_CTRL, (mode | devaddr));
157         /*write the value*/
158         return  phy_write(phydev, MDIO_DEVAD_NONE,
159                 MII_KSZ9031_MMD_REG_DATA, val);
160 }
161
162 int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr,
163                               int regnum, u16 mode)
164 {
165         phy_write(phydev, MDIO_DEVAD_NONE,
166                   MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
167         phy_write(phydev, MDIO_DEVAD_NONE,
168                   MII_KSZ9031_MMD_REG_DATA, regnum);
169         phy_write(phydev, MDIO_DEVAD_NONE,
170                   MII_KSZ9031_MMD_ACCES_CTRL, (devaddr | mode));
171         return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA);
172 }
173
174 static struct phy_driver ksz9031_driver = {
175         .name = "Micrel ksz9031",
176         .uid  = 0x221620,
177         .mask = 0xfffffe,
178         .features = PHY_GBIT_FEATURES,
179         .config   = &genphy_config,
180         .startup  = &ksz90xx_startup,
181         .shutdown = &genphy_shutdown,
182 };
183
184 int phy_micrel_init(void)
185 {
186         phy_register(&KSZ804_driver);
187 #ifdef CONFIG_PHY_MICREL_KSZ9021
188         phy_register(&ksz9021_driver);
189 #else
190         phy_register(&KS8721_driver);
191 #endif
192         phy_register(&ksz9031_driver);
193         return 0;
194 }