diff options
| -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", }, |
