]>
Commit | Line | Data |
---|---|---|
1d3bb996 DG |
1 | /* |
2 | * drivers/net/ibm_newemac/rgmii.c | |
3 | * | |
4 | * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support. | |
5 | * | |
6 | * Copyright (c) 2004, 2005 Zultys Technologies. | |
7 | * Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> | |
8 | * | |
9 | * Based on original work by | |
10 | * Matt Porter <mporter@kernel.crashing.org> | |
11 | * Copyright 2004 MontaVista Software, Inc. | |
12 | * | |
13 | * This program is free software; you can redistribute it and/or modify it | |
14 | * under the terms of the GNU General Public License as published by the | |
15 | * Free Software Foundation; either version 2 of the License, or (at your | |
16 | * option) any later version. | |
17 | * | |
18 | */ | |
19 | #include <linux/kernel.h> | |
20 | #include <linux/ethtool.h> | |
21 | #include <asm/io.h> | |
22 | ||
23 | #include "emac.h" | |
24 | #include "debug.h" | |
25 | ||
26 | // XXX FIXME: Axon seems to support a subset of the RGMII, we | |
27 | // thus need to take that into account and possibly change some | |
28 | // of the bit settings below that don't seem to quite match the | |
29 | // AXON spec | |
30 | ||
31 | /* RGMIIx_FER */ | |
32 | #define RGMII_FER_MASK(idx) (0x7 << ((idx) * 4)) | |
33 | #define RGMII_FER_RTBI(idx) (0x4 << ((idx) * 4)) | |
34 | #define RGMII_FER_RGMII(idx) (0x5 << ((idx) * 4)) | |
35 | #define RGMII_FER_TBI(idx) (0x6 << ((idx) * 4)) | |
36 | #define RGMII_FER_GMII(idx) (0x7 << ((idx) * 4)) | |
37 | ||
38 | /* RGMIIx_SSR */ | |
39 | #define RGMII_SSR_MASK(idx) (0x7 << ((idx) * 8)) | |
40 | #define RGMII_SSR_100(idx) (0x2 << ((idx) * 8)) | |
41 | #define RGMII_SSR_1000(idx) (0x4 << ((idx) * 8)) | |
42 | ||
43 | /* RGMII bridge supports only GMII/TBI and RGMII/RTBI PHYs */ | |
44 | static inline int rgmii_valid_mode(int phy_mode) | |
45 | { | |
46 | return phy_mode == PHY_MODE_GMII || | |
47 | phy_mode == PHY_MODE_RGMII || | |
48 | phy_mode == PHY_MODE_TBI || | |
49 | phy_mode == PHY_MODE_RTBI; | |
50 | } | |
51 | ||
52 | static inline const char *rgmii_mode_name(int mode) | |
53 | { | |
54 | switch (mode) { | |
55 | case PHY_MODE_RGMII: | |
56 | return "RGMII"; | |
57 | case PHY_MODE_TBI: | |
58 | return "TBI"; | |
59 | case PHY_MODE_GMII: | |
60 | return "GMII"; | |
61 | case PHY_MODE_RTBI: | |
62 | return "RTBI"; | |
63 | default: | |
64 | BUG(); | |
65 | } | |
66 | } | |
67 | ||
68 | static inline u32 rgmii_mode_mask(int mode, int input) | |
69 | { | |
70 | switch (mode) { | |
71 | case PHY_MODE_RGMII: | |
72 | return RGMII_FER_RGMII(input); | |
73 | case PHY_MODE_TBI: | |
74 | return RGMII_FER_TBI(input); | |
75 | case PHY_MODE_GMII: | |
76 | return RGMII_FER_GMII(input); | |
77 | case PHY_MODE_RTBI: | |
78 | return RGMII_FER_RTBI(input); | |
79 | default: | |
80 | BUG(); | |
81 | } | |
82 | } | |
83 | ||
84 | int __devinit rgmii_attach(struct of_device *ofdev, int input, int mode) | |
85 | { | |
86 | struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); | |
eb4d84f1 | 87 | struct rgmii_regs __iomem *p = dev->base; |
1d3bb996 DG |
88 | |
89 | RGMII_DBG(dev, "attach(%d)" NL, input); | |
90 | ||
91 | /* Check if we need to attach to a RGMII */ | |
92 | if (input < 0 || !rgmii_valid_mode(mode)) { | |
93 | printk(KERN_ERR "%s: unsupported settings !\n", | |
94 | ofdev->node->full_name); | |
95 | return -ENODEV; | |
96 | } | |
97 | ||
98 | mutex_lock(&dev->lock); | |
99 | ||
100 | /* Enable this input */ | |
101 | out_be32(&p->fer, in_be32(&p->fer) | rgmii_mode_mask(mode, input)); | |
102 | ||
103 | printk(KERN_NOTICE "%s: input %d in %s mode\n", | |
104 | ofdev->node->full_name, input, rgmii_mode_name(mode)); | |
105 | ||
106 | ++dev->users; | |
107 | ||
108 | mutex_unlock(&dev->lock); | |
109 | ||
110 | return 0; | |
111 | } | |
112 | ||
113 | void rgmii_set_speed(struct of_device *ofdev, int input, int speed) | |
114 | { | |
115 | struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); | |
eb4d84f1 | 116 | struct rgmii_regs __iomem *p = dev->base; |
1d3bb996 DG |
117 | u32 ssr; |
118 | ||
119 | mutex_lock(&dev->lock); | |
120 | ||
121 | ssr = in_be32(&p->ssr) & ~RGMII_SSR_MASK(input); | |
122 | ||
123 | RGMII_DBG(dev, "speed(%d, %d)" NL, input, speed); | |
124 | ||
125 | if (speed == SPEED_1000) | |
126 | ssr |= RGMII_SSR_1000(input); | |
127 | else if (speed == SPEED_100) | |
128 | ssr |= RGMII_SSR_100(input); | |
129 | ||
130 | out_be32(&p->ssr, ssr); | |
131 | ||
132 | mutex_unlock(&dev->lock); | |
133 | } | |
134 | ||
135 | void rgmii_get_mdio(struct of_device *ofdev, int input) | |
136 | { | |
137 | struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); | |
eb4d84f1 | 138 | struct rgmii_regs __iomem *p = dev->base; |
1d3bb996 DG |
139 | u32 fer; |
140 | ||
141 | RGMII_DBG2(dev, "get_mdio(%d)" NL, input); | |
142 | ||
143 | if (dev->type != RGMII_AXON) | |
144 | return; | |
145 | ||
146 | mutex_lock(&dev->lock); | |
147 | ||
148 | fer = in_be32(&p->fer); | |
149 | fer |= 0x00080000u >> input; | |
150 | out_be32(&p->fer, fer); | |
151 | (void)in_be32(&p->fer); | |
152 | ||
153 | DBG2(dev, " fer = 0x%08x\n", fer); | |
154 | } | |
155 | ||
156 | void rgmii_put_mdio(struct of_device *ofdev, int input) | |
157 | { | |
158 | struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); | |
eb4d84f1 | 159 | struct rgmii_regs __iomem *p = dev->base; |
1d3bb996 DG |
160 | u32 fer; |
161 | ||
162 | RGMII_DBG2(dev, "put_mdio(%d)" NL, input); | |
163 | ||
164 | if (dev->type != RGMII_AXON) | |
165 | return; | |
166 | ||
167 | fer = in_be32(&p->fer); | |
168 | fer &= ~(0x00080000u >> input); | |
169 | out_be32(&p->fer, fer); | |
170 | (void)in_be32(&p->fer); | |
171 | ||
172 | DBG2(dev, " fer = 0x%08x\n", fer); | |
173 | ||
174 | mutex_unlock(&dev->lock); | |
175 | } | |
176 | ||
177 | void __devexit rgmii_detach(struct of_device *ofdev, int input) | |
178 | { | |
179 | struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); | |
eb4d84f1 | 180 | struct rgmii_regs __iomem *p = dev->base; |
1d3bb996 DG |
181 | |
182 | mutex_lock(&dev->lock); | |
183 | ||
184 | BUG_ON(!dev || dev->users == 0); | |
185 | ||
186 | RGMII_DBG(dev, "detach(%d)" NL, input); | |
187 | ||
188 | /* Disable this input */ | |
189 | out_be32(&p->fer, in_be32(&p->fer) & ~RGMII_FER_MASK(input)); | |
190 | ||
191 | --dev->users; | |
192 | ||
193 | mutex_unlock(&dev->lock); | |
194 | } | |
195 | ||
196 | int rgmii_get_regs_len(struct of_device *ofdev) | |
197 | { | |
198 | return sizeof(struct emac_ethtool_regs_subhdr) + | |
199 | sizeof(struct rgmii_regs); | |
200 | } | |
201 | ||
202 | void *rgmii_dump_regs(struct of_device *ofdev, void *buf) | |
203 | { | |
204 | struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); | |
205 | struct emac_ethtool_regs_subhdr *hdr = buf; | |
206 | struct rgmii_regs *regs = (struct rgmii_regs *)(hdr + 1); | |
207 | ||
208 | hdr->version = 0; | |
209 | hdr->index = 0; /* for now, are there chips with more than one | |
210 | * rgmii ? if yes, then we'll add a cell_index | |
211 | * like we do for emac | |
212 | */ | |
213 | memcpy_fromio(regs, dev->base, sizeof(struct rgmii_regs)); | |
214 | return regs + 1; | |
215 | } | |
216 | ||
217 | ||
218 | static int __devinit rgmii_probe(struct of_device *ofdev, | |
219 | const struct of_device_id *match) | |
220 | { | |
221 | struct device_node *np = ofdev->node; | |
222 | struct rgmii_instance *dev; | |
223 | struct resource regs; | |
224 | int rc; | |
225 | ||
226 | rc = -ENOMEM; | |
227 | dev = kzalloc(sizeof(struct rgmii_instance), GFP_KERNEL); | |
228 | if (dev == NULL) { | |
229 | printk(KERN_ERR "%s: could not allocate RGMII device!\n", | |
230 | np->full_name); | |
231 | goto err_gone; | |
232 | } | |
233 | ||
234 | mutex_init(&dev->lock); | |
235 | dev->ofdev = ofdev; | |
236 | ||
237 | rc = -ENXIO; | |
238 | if (of_address_to_resource(np, 0, ®s)) { | |
239 | printk(KERN_ERR "%s: Can't get registers address\n", | |
240 | np->full_name); | |
241 | goto err_free; | |
242 | } | |
243 | ||
244 | rc = -ENOMEM; | |
eb4d84f1 | 245 | dev->base = (struct rgmii_regs __iomem *)ioremap(regs.start, |
1d3bb996 DG |
246 | sizeof(struct rgmii_regs)); |
247 | if (dev->base == NULL) { | |
248 | printk(KERN_ERR "%s: Can't map device registers!\n", | |
249 | np->full_name); | |
250 | goto err_free; | |
251 | } | |
252 | ||
253 | /* Check for RGMII type */ | |
97be91c1 | 254 | if (of_device_is_compatible(ofdev->node, "ibm,rgmii-axon")) |
1d3bb996 DG |
255 | dev->type = RGMII_AXON; |
256 | else | |
257 | dev->type = RGMII_STANDARD; | |
258 | ||
259 | DBG2(dev, " Boot FER = 0x%08x, SSR = 0x%08x\n", | |
260 | in_be32(&dev->base->fer), in_be32(&dev->base->ssr)); | |
261 | ||
262 | /* Disable all inputs by default */ | |
263 | out_be32(&dev->base->fer, 0); | |
264 | ||
265 | printk(KERN_INFO | |
266 | "RGMII %s %s initialized\n", | |
267 | dev->type == RGMII_STANDARD ? "standard" : "axon", | |
268 | ofdev->node->full_name); | |
269 | ||
270 | wmb(); | |
271 | dev_set_drvdata(&ofdev->dev, dev); | |
272 | ||
273 | return 0; | |
274 | ||
275 | err_free: | |
276 | kfree(dev); | |
277 | err_gone: | |
278 | return rc; | |
279 | } | |
280 | ||
281 | static int __devexit rgmii_remove(struct of_device *ofdev) | |
282 | { | |
283 | struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev); | |
284 | ||
285 | dev_set_drvdata(&ofdev->dev, NULL); | |
286 | ||
287 | WARN_ON(dev->users != 0); | |
288 | ||
289 | iounmap(dev->base); | |
290 | kfree(dev); | |
291 | ||
292 | return 0; | |
293 | } | |
294 | ||
295 | static struct of_device_id rgmii_match[] = | |
296 | { | |
297 | { | |
298 | .type = "rgmii-interface", | |
299 | .compatible = "ibm,rgmii", | |
300 | }, | |
301 | { | |
302 | .type = "emac-rgmii", | |
303 | }, | |
304 | {}, | |
305 | }; | |
306 | ||
307 | static struct of_platform_driver rgmii_driver = { | |
308 | .name = "emac-rgmii", | |
309 | .match_table = rgmii_match, | |
310 | ||
311 | .probe = rgmii_probe, | |
312 | .remove = rgmii_remove, | |
313 | }; | |
314 | ||
315 | int __init rgmii_init(void) | |
316 | { | |
317 | return of_register_platform_driver(&rgmii_driver); | |
318 | } | |
319 | ||
320 | void rgmii_exit(void) | |
321 | { | |
322 | of_unregister_platform_driver(&rgmii_driver); | |
323 | } |