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