aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAndy Fleming <afleming@freescale.com>2008-05-02 19:56:41 -0400
committerKumar Gala <galak@kernel.crashing.org>2008-05-13 09:53:48 -0400
commit94833a42765509a7aa95ed1ba7b227ead3c29c08 (patch)
tree2d6254fe49e63fad4b2c5d4f2abcd5393f53931a /arch/powerpc
parentad12e34fe805af86b2995020bfc41a64a762acfe (diff)
[POWERPC] 85xx: Add 8568 PHY workarounds to board code
The 8568 MDS needs some configuration changes to the PHY in order to work properly. These are done in the firmware, normally, but Linux shouldn't need to rely on the firmware running such things (someone could disable the PHY support in the firmware to save space, for instance). Signed-off-by: Andy Fleming <afleming@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 25f8bc75e838..decae09e5146 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -32,6 +32,7 @@
32#include <linux/fsl_devices.h> 32#include <linux/fsl_devices.h>
33#include <linux/of_platform.h> 33#include <linux/of_platform.h>
34#include <linux/of_device.h> 34#include <linux/of_device.h>
35#include <linux/phy.h>
35 36
36#include <asm/system.h> 37#include <asm/system.h>
37#include <asm/atomic.h> 38#include <asm/atomic.h>
@@ -56,6 +57,95 @@
56#define DBG(fmt...) 57#define DBG(fmt...)
57#endif 58#endif
58 59
60#define MV88E1111_SCR 0x10
61#define MV88E1111_SCR_125CLK 0x0010
62static int mpc8568_fixup_125_clock(struct phy_device *phydev)
63{
64 int scr;
65 int err;
66
67 /* Workaround for the 125 CLK Toggle */
68 scr = phy_read(phydev, MV88E1111_SCR);
69
70 if (scr < 0)
71 return scr;
72
73 err = phy_write(phydev, MV88E1111_SCR, scr & ~(MV88E1111_SCR_125CLK));
74
75 if (err)
76 return err;
77
78 err = phy_write(phydev, MII_BMCR, BMCR_RESET);
79
80 if (err)
81 return err;
82
83 scr = phy_read(phydev, MV88E1111_SCR);
84
85 if (scr < 0)
86 return err;
87
88 err = phy_write(phydev, MV88E1111_SCR, scr | 0x0008);
89
90 return err;
91}
92
93static int mpc8568_mds_phy_fixups(struct phy_device *phydev)
94{
95 int temp;
96 int err;
97
98 /* Errata */
99 err = phy_write(phydev,29, 0x0006);
100
101 if (err)
102 return err;
103
104 temp = phy_read(phydev, 30);
105
106 if (temp < 0)
107 return temp;
108
109 temp = (temp & (~0x8000)) | 0x4000;
110 err = phy_write(phydev,30, temp);
111
112 if (err)
113 return err;
114
115 err = phy_write(phydev,29, 0x000a);
116
117 if (err)
118 return err;
119
120 temp = phy_read(phydev, 30);
121
122 if (temp < 0)
123 return temp;
124
125 temp = phy_read(phydev, 30);
126
127 if (temp < 0)
128 return temp;
129
130 temp &= ~0x0020;
131
132 err = phy_write(phydev,30,temp);
133
134 if (err)
135 return err;
136
137 /* Disable automatic MDI/MDIX selection */
138 temp = phy_read(phydev, 16);
139
140 if (temp < 0)
141 return temp;
142
143 temp &= ~0x0060;
144 err = phy_write(phydev,16,temp);
145
146 return err;
147}
148
59/* ************************************************************************ 149/* ************************************************************************
60 * 150 *
61 * Setup the architecture 151 * Setup the architecture
@@ -138,6 +228,35 @@ static void __init mpc85xx_mds_setup_arch(void)
138#endif /* CONFIG_QUICC_ENGINE */ 228#endif /* CONFIG_QUICC_ENGINE */
139} 229}
140 230
231
232static int __init board_fixups(void)
233{
234 char phy_id[BUS_ID_SIZE];
235 char *compstrs[2] = {"fsl,gianfar-mdio", "fsl,ucc-mdio"};
236 struct device_node *mdio;
237 struct resource res;
238 int i;
239
240 for (i = 0; i < ARRAY_SIZE(compstrs); i++) {
241 mdio = of_find_compatible_node(NULL, NULL, compstrs[i]);
242
243 of_address_to_resource(mdio, 0, &res);
244 snprintf(phy_id, BUS_ID_SIZE, "%x:%02x", res.start, 1);
245
246 phy_register_fixup_for_id(phy_id, mpc8568_fixup_125_clock);
247 phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups);
248
249 /* Register a workaround for errata */
250 snprintf(phy_id, BUS_ID_SIZE, "%x:%02x", res.start, 7);
251 phy_register_fixup_for_id(phy_id, mpc8568_mds_phy_fixups);
252
253 of_node_put(mdio);
254 }
255
256 return 0;
257}
258machine_arch_initcall(mpc85xx_mds, board_fixups);
259
141static struct of_device_id mpc85xx_ids[] = { 260static struct of_device_id mpc85xx_ids[] = {
142 { .type = "soc", }, 261 { .type = "soc", },
143 { .compatible = "soc", }, 262 { .compatible = "soc", },