diff options
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r-- | arch/powerpc/platforms/85xx/mpc85xx_mds.c | 119 |
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 | ||
62 | static 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 | |||
93 | static 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 | |||
232 | static 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 | } | ||
258 | machine_arch_initcall(mpc85xx_mds, board_fixups); | ||
259 | |||
141 | static struct of_device_id mpc85xx_ids[] = { | 260 | static struct of_device_id mpc85xx_ids[] = { |
142 | { .type = "soc", }, | 261 | { .type = "soc", }, |
143 | { .compatible = "soc", }, | 262 | { .compatible = "soc", }, |