diff options
author | Wolfgang Denk <wd@denx.de> | 2009-07-16 22:27:07 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-07-17 12:47:29 -0400 |
commit | 652f6787c082a174f0bbfa7f895b65b03d8d46c9 (patch) | |
tree | d131b92e10357adad9322ec9a89246fca2ce12fb /drivers/net/fs_enet | |
parent | da8120355e80ddaf534adb8ed910871d97512d56 (diff) |
fs_enet/mii-fec.c: fix MII speed calculation
The MII speed calculation was based on the CPU clock (ppc_proc_freq),
but for MPC512x we must use the bus clock instead.
This patch makes it use the correct clock and makes sure we don't
clobber reserved bits in the MII_SPEED register.
Signed-off-by: Wolfgang Denk <wd@denx.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: <netdev@vger.kernel.org>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/fs_enet')
-rw-r--r-- | drivers/net/fs_enet/mii-fec.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index 75a09994d665..a2d69c1cd07e 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <asm/pgtable.h> | 36 | #include <asm/pgtable.h> |
37 | #include <asm/irq.h> | 37 | #include <asm/irq.h> |
38 | #include <asm/uaccess.h> | 38 | #include <asm/uaccess.h> |
39 | #include <asm/mpc5xxx.h> | ||
39 | 40 | ||
40 | #include "fs_enet.h" | 41 | #include "fs_enet.h" |
41 | #include "fec.h" | 42 | #include "fec.h" |
@@ -103,11 +104,11 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus) | |||
103 | static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, | 104 | static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, |
104 | const struct of_device_id *match) | 105 | const struct of_device_id *match) |
105 | { | 106 | { |
106 | struct device_node *np = NULL; | ||
107 | struct resource res; | 107 | struct resource res; |
108 | struct mii_bus *new_bus; | 108 | struct mii_bus *new_bus; |
109 | struct fec_info *fec; | 109 | struct fec_info *fec; |
110 | int ret = -ENOMEM, i; | 110 | int (*get_bus_freq)(struct device_node *) = match->data; |
111 | int ret = -ENOMEM, clock, speed; | ||
111 | 112 | ||
112 | new_bus = mdiobus_alloc(); | 113 | new_bus = mdiobus_alloc(); |
113 | if (!new_bus) | 114 | if (!new_bus) |
@@ -133,13 +134,35 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, | |||
133 | if (!fec->fecp) | 134 | if (!fec->fecp) |
134 | goto out_fec; | 135 | goto out_fec; |
135 | 136 | ||
136 | fec->mii_speed = ((ppc_proc_freq + 4999999) / 5000000) << 1; | 137 | if (get_bus_freq) { |
138 | clock = get_bus_freq(ofdev->node); | ||
139 | if (!clock) { | ||
140 | /* Use maximum divider if clock is unknown */ | ||
141 | dev_warn(&ofdev->dev, "could not determine IPS clock\n"); | ||
142 | clock = 0x3F * 5000000; | ||
143 | } | ||
144 | } else | ||
145 | clock = ppc_proc_freq; | ||
146 | |||
147 | /* | ||
148 | * Scale for a MII clock <= 2.5 MHz | ||
149 | * Note that only 6 bits (25:30) are available for MII speed. | ||
150 | */ | ||
151 | speed = (clock + 4999999) / 5000000; | ||
152 | if (speed > 0x3F) { | ||
153 | speed = 0x3F; | ||
154 | dev_err(&ofdev->dev, | ||
155 | "MII clock (%d Hz) exceeds max (2.5 MHz)\n", | ||
156 | clock / speed); | ||
157 | } | ||
158 | |||
159 | fec->mii_speed = speed << 1; | ||
137 | 160 | ||
138 | setbits32(&fec->fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE); | 161 | setbits32(&fec->fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE); |
139 | setbits32(&fec->fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | | 162 | setbits32(&fec->fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | |
140 | FEC_ECNTRL_ETHER_EN); | 163 | FEC_ECNTRL_ETHER_EN); |
141 | out_be32(&fec->fecp->fec_ievent, FEC_ENET_MII); | 164 | out_be32(&fec->fecp->fec_ievent, FEC_ENET_MII); |
142 | out_be32(&fec->fecp->fec_mii_speed, fec->mii_speed); | 165 | clrsetbits_be32(&fec->fecp->fec_mii_speed, 0x7E, fec->mii_speed); |
143 | 166 | ||
144 | new_bus->phy_mask = ~0; | 167 | new_bus->phy_mask = ~0; |
145 | new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); | 168 | new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); |
@@ -188,6 +211,12 @@ static struct of_device_id fs_enet_mdio_fec_match[] = { | |||
188 | { | 211 | { |
189 | .compatible = "fsl,pq1-fec-mdio", | 212 | .compatible = "fsl,pq1-fec-mdio", |
190 | }, | 213 | }, |
214 | #if defined(CONFIG_PPC_MPC512x) | ||
215 | { | ||
216 | .compatible = "fsl,mpc5121-fec-mdio", | ||
217 | .data = mpc5xxx_get_bus_frequency, | ||
218 | }, | ||
219 | #endif | ||
191 | {}, | 220 | {}, |
192 | }; | 221 | }; |
193 | 222 | ||