diff options
author | Andy Fleming <afleming@freescale.com> | 2006-11-08 01:11:29 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-12-02 00:12:03 -0500 |
commit | 95d21ff4c64592bdee7f1af2925145bed849c994 (patch) | |
tree | 1ccbe1639e1253ee5386e1fe673334dbedf717fb | |
parent | f2d71c2d800e68f158a5949e38b23f5140948548 (diff) |
[PATCH] Add support for Marvell 88e1111S and 88e1145
This patch requires the new support for configurable PHY
interfaces.
Changes include:
* New support for 88e1145
* New support for 88e111s
* Fixing 88e1101 driver to not match non-88e1101 PHYs
* Increases in feature support across Marvell PHY product line
* Fixes a bunch of whitespace issues found by Lindent
Signed-off-by: Andrew Fleming <afleming@freescale.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r-- | drivers/net/phy/marvell.c | 156 |
1 files changed, 144 insertions, 12 deletions
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 0ad253282d0d..5320ab9fe018 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c | |||
@@ -43,6 +43,19 @@ | |||
43 | #define MII_M1011_IMASK_INIT 0x6400 | 43 | #define MII_M1011_IMASK_INIT 0x6400 |
44 | #define MII_M1011_IMASK_CLEAR 0x0000 | 44 | #define MII_M1011_IMASK_CLEAR 0x0000 |
45 | 45 | ||
46 | #define MII_M1011_PHY_SCR 0x10 | ||
47 | #define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060 | ||
48 | |||
49 | #define MII_M1145_PHY_EXT_CR 0x14 | ||
50 | #define MII_M1145_RGMII_RX_DELAY 0x0080 | ||
51 | #define MII_M1145_RGMII_TX_DELAY 0x0002 | ||
52 | |||
53 | #define M1145_DEV_FLAGS_RESISTANCE 0x00000001 | ||
54 | |||
55 | #define MII_M1111_PHY_LED_CONTROL 0x18 | ||
56 | #define MII_M1111_PHY_LED_DIRECT 0x4100 | ||
57 | #define MII_M1111_PHY_LED_COMBINE 0x411c | ||
58 | |||
46 | MODULE_DESCRIPTION("Marvell PHY driver"); | 59 | MODULE_DESCRIPTION("Marvell PHY driver"); |
47 | MODULE_AUTHOR("Andy Fleming"); | 60 | MODULE_AUTHOR("Andy Fleming"); |
48 | MODULE_LICENSE("GPL"); | 61 | MODULE_LICENSE("GPL"); |
@@ -64,7 +77,7 @@ static int marvell_config_intr(struct phy_device *phydev) | |||
64 | { | 77 | { |
65 | int err; | 78 | int err; |
66 | 79 | ||
67 | if(phydev->interrupts == PHY_INTERRUPT_ENABLED) | 80 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) |
68 | err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT); | 81 | err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT); |
69 | else | 82 | else |
70 | err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); | 83 | err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); |
@@ -104,34 +117,153 @@ static int marvell_config_aneg(struct phy_device *phydev) | |||
104 | if (err < 0) | 117 | if (err < 0) |
105 | return err; | 118 | return err; |
106 | 119 | ||
120 | err = phy_write(phydev, MII_M1011_PHY_SCR, | ||
121 | MII_M1011_PHY_SCR_AUTO_CROSS); | ||
122 | if (err < 0) | ||
123 | return err; | ||
124 | |||
125 | err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL, | ||
126 | MII_M1111_PHY_LED_DIRECT); | ||
127 | if (err < 0) | ||
128 | return err; | ||
107 | 129 | ||
108 | err = genphy_config_aneg(phydev); | 130 | err = genphy_config_aneg(phydev); |
109 | 131 | ||
110 | return err; | 132 | return err; |
111 | } | 133 | } |
112 | 134 | ||
135 | static int m88e1145_config_init(struct phy_device *phydev) | ||
136 | { | ||
137 | int err; | ||
138 | |||
139 | /* Take care of errata E0 & E1 */ | ||
140 | err = phy_write(phydev, 0x1d, 0x001b); | ||
141 | if (err < 0) | ||
142 | return err; | ||
143 | |||
144 | err = phy_write(phydev, 0x1e, 0x418f); | ||
145 | if (err < 0) | ||
146 | return err; | ||
147 | |||
148 | err = phy_write(phydev, 0x1d, 0x0016); | ||
149 | if (err < 0) | ||
150 | return err; | ||
151 | |||
152 | err = phy_write(phydev, 0x1e, 0xa2da); | ||
153 | if (err < 0) | ||
154 | return err; | ||
155 | |||
156 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { | ||
157 | int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR); | ||
158 | if (temp < 0) | ||
159 | return temp; | ||
160 | |||
161 | temp |= (MII_M1145_RGMII_RX_DELAY | MII_M1145_RGMII_TX_DELAY); | ||
162 | |||
163 | err = phy_write(phydev, MII_M1145_PHY_EXT_CR, temp); | ||
164 | if (err < 0) | ||
165 | return err; | ||
166 | |||
167 | if (phydev->dev_flags & M1145_DEV_FLAGS_RESISTANCE) { | ||
168 | err = phy_write(phydev, 0x1d, 0x0012); | ||
169 | if (err < 0) | ||
170 | return err; | ||
171 | |||
172 | temp = phy_read(phydev, 0x1e); | ||
173 | if (temp < 0) | ||
174 | return temp; | ||
175 | |||
176 | temp &= 0xf03f; | ||
177 | temp |= 2 << 9; /* 36 ohm */ | ||
178 | temp |= 2 << 6; /* 39 ohm */ | ||
179 | |||
180 | err = phy_write(phydev, 0x1e, temp); | ||
181 | if (err < 0) | ||
182 | return err; | ||
183 | |||
184 | err = phy_write(phydev, 0x1d, 0x3); | ||
185 | if (err < 0) | ||
186 | return err; | ||
187 | |||
188 | err = phy_write(phydev, 0x1e, 0x8000); | ||
189 | if (err < 0) | ||
190 | return err; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | return 0; | ||
195 | } | ||
113 | 196 | ||
114 | static struct phy_driver m88e1101_driver = { | 197 | static struct phy_driver m88e1101_driver = { |
115 | .phy_id = 0x01410c00, | 198 | .phy_id = 0x01410c60, |
116 | .phy_id_mask = 0xffffff00, | 199 | .phy_id_mask = 0xfffffff0, |
117 | .name = "Marvell 88E1101", | 200 | .name = "Marvell 88E1101", |
118 | .features = PHY_GBIT_FEATURES, | 201 | .features = PHY_GBIT_FEATURES, |
119 | .flags = PHY_HAS_INTERRUPT, | 202 | .flags = PHY_HAS_INTERRUPT, |
120 | .config_aneg = &marvell_config_aneg, | 203 | .config_aneg = &marvell_config_aneg, |
121 | .read_status = &genphy_read_status, | 204 | .read_status = &genphy_read_status, |
122 | .ack_interrupt = &marvell_ack_interrupt, | 205 | .ack_interrupt = &marvell_ack_interrupt, |
123 | .config_intr = &marvell_config_intr, | 206 | .config_intr = &marvell_config_intr, |
124 | .driver = { .owner = THIS_MODULE,}, | 207 | .driver = {.owner = THIS_MODULE,}, |
208 | }; | ||
209 | |||
210 | static struct phy_driver m88e1111s_driver = { | ||
211 | .phy_id = 0x01410cc0, | ||
212 | .phy_id_mask = 0xfffffff0, | ||
213 | .name = "Marvell 88E1111", | ||
214 | .features = PHY_GBIT_FEATURES, | ||
215 | .flags = PHY_HAS_INTERRUPT, | ||
216 | .config_aneg = &marvell_config_aneg, | ||
217 | .read_status = &genphy_read_status, | ||
218 | .ack_interrupt = &marvell_ack_interrupt, | ||
219 | .config_intr = &marvell_config_intr, | ||
220 | .driver = {.owner = THIS_MODULE,}, | ||
221 | }; | ||
222 | |||
223 | static struct phy_driver m88e1145_driver = { | ||
224 | .phy_id = 0x01410cd0, | ||
225 | .phy_id_mask = 0xfffffff0, | ||
226 | .name = "Marvell 88E1145", | ||
227 | .features = PHY_GBIT_FEATURES, | ||
228 | .flags = PHY_HAS_INTERRUPT, | ||
229 | .config_init = &m88e1145_config_init, | ||
230 | .config_aneg = &marvell_config_aneg, | ||
231 | .read_status = &genphy_read_status, | ||
232 | .ack_interrupt = &marvell_ack_interrupt, | ||
233 | .config_intr = &marvell_config_intr, | ||
234 | .driver = {.owner = THIS_MODULE,}, | ||
125 | }; | 235 | }; |
126 | 236 | ||
127 | static int __init marvell_init(void) | 237 | static int __init marvell_init(void) |
128 | { | 238 | { |
129 | return phy_driver_register(&m88e1101_driver); | 239 | int ret; |
240 | |||
241 | ret = phy_driver_register(&m88e1101_driver); | ||
242 | if (ret) | ||
243 | return ret; | ||
244 | |||
245 | ret = phy_driver_register(&m88e1111s_driver); | ||
246 | if (ret) | ||
247 | goto err1111s; | ||
248 | |||
249 | ret = phy_driver_register(&m88e1145_driver); | ||
250 | if (ret) | ||
251 | goto err1145; | ||
252 | |||
253 | return 0; | ||
254 | |||
255 | err1145: | ||
256 | phy_driver_unregister(&m88e1111s_driver); | ||
257 | err1111s: | ||
258 | phy_driver_unregister(&m88e1101_driver); | ||
259 | return ret; | ||
130 | } | 260 | } |
131 | 261 | ||
132 | static void __exit marvell_exit(void) | 262 | static void __exit marvell_exit(void) |
133 | { | 263 | { |
134 | phy_driver_unregister(&m88e1101_driver); | 264 | phy_driver_unregister(&m88e1101_driver); |
265 | phy_driver_unregister(&m88e1111s_driver); | ||
266 | phy_driver_unregister(&m88e1145_driver); | ||
135 | } | 267 | } |
136 | 268 | ||
137 | module_init(marvell_init); | 269 | module_init(marvell_init); |