Commit 9fafe7dab9bc8a9e33e1ba5e28a3ec870d689b82

Authored by Troy Kisky
Committed by Albert ARIBAUD
1 parent 8682aba7da
Exists in master and in 55 other branches 8qm-imx_v2020.04_5.4.70_2.3.0, emb_lf_v2022.04, emb_lf_v2023.04, imx_v2015.04_4.1.15_1.0.0_ga, pitx_8mp_lf_v2020.04, smarc-8m-android-10.0.0_2.6.0, smarc-8m-android-11.0.0_2.0.0, smarc-8mp-android-11.0.0_2.0.0, smarc-emmc-imx_v2014.04_3.10.53_1.1.0_ga, smarc-emmc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx-l5.0.0_1.0.0-ga, smarc-imx6_v2018.03_4.14.98_2.0.0_ga, smarc-imx7_v2017.03_4.9.11_1.0.0_ga, smarc-imx7_v2018.03_4.14.98_2.0.0_ga, smarc-imx_v2014.04_3.14.28_1.0.0_ga, smarc-imx_v2015.04_4.1.15_1.0.0_ga, smarc-imx_v2017.03_4.9.11_1.0.0_ga, smarc-imx_v2017.03_4.9.88_2.0.0_ga, smarc-imx_v2017.03_o8.1.0_1.3.0_8m, smarc-imx_v2018.03_4.14.78_1.0.0_ga, smarc-m6.0.1_2.1.0-ga, smarc-n7.1.2_2.0.0-ga, smarc-rel_imx_4.1.15_2.0.0_ga, smarc_8m-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8m-imx_v2019.04_4.19.35_1.1.0, smarc_8m_00d0-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga, smarc_8mm-imx_v2019.04_4.19.35_1.1.0, smarc_8mm-imx_v2020.04_5.4.24_2.1.0, smarc_8mp_lf_v2020.04, smarc_8mq-imx_v2020.04_5.4.24_2.1.0, smarc_8mq_lf_v2020.04, ti-u-boot-2015.07, u-boot-2013.01.y, v2013.10, v2013.10-smarct33, v2013.10-smartmen, v2014.01, v2014.04, v2014.04-smarct33, v2014.04-smarct33-emmc, v2014.04-smartmen, v2014.07, v2014.07-smarct33, v2014.07-smartmen, v2015.07-smarct33, v2015.07-smarct33-emmc, v2015.07-smarct4x, v2016.05-dlt, v2016.05-smarct3x, v2016.05-smarct3x-emmc, v2016.05-smarct4x, v2017.01-smarct3x, v2017.01-smarct3x-emmc, v2017.01-smarct4x

net: phy: make board_phy_config responsible for calling drv->config

Boards may have things they want done before or after normal phy config.
Letting the boards call drv->config allows them more flexibilty.
Boards affected by this change are corenet_ds and mpc8544ds.

Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
Acked-by: Dirk Behme <dirk.behme@de.bosch.com>

Showing 3 changed files with 6 additions and 3 deletions Inline Diff

board/freescale/corenet_ds/eth_p4080.c
1 /* 1 /*
2 * Copyright 2009-2011 Freescale Semiconductor, Inc. 2 * Copyright 2009-2011 Freescale Semiconductor, Inc.
3 * 3 *
4 * See file CREDITS for list of people who contributed to this 4 * See file CREDITS for list of people who contributed to this
5 * project. 5 * project.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as 8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of 9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version. 10 * the License, or (at your option) any later version.
11 * 11 *
12 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA 20 * MA 02111-1307 USA
21 */ 21 */
22 22
23 #include <common.h> 23 #include <common.h>
24 #include <command.h> 24 #include <command.h>
25 #include <netdev.h> 25 #include <netdev.h>
26 #include <asm/mmu.h> 26 #include <asm/mmu.h>
27 #include <asm/processor.h> 27 #include <asm/processor.h>
28 #include <asm/cache.h> 28 #include <asm/cache.h>
29 #include <asm/immap_85xx.h> 29 #include <asm/immap_85xx.h>
30 #include <asm/fsl_law.h> 30 #include <asm/fsl_law.h>
31 #include <asm/fsl_ddr_sdram.h> 31 #include <asm/fsl_ddr_sdram.h>
32 #include <asm/fsl_serdes.h> 32 #include <asm/fsl_serdes.h>
33 #include <asm/fsl_portals.h> 33 #include <asm/fsl_portals.h>
34 #include <asm/fsl_liodn.h> 34 #include <asm/fsl_liodn.h>
35 #include <malloc.h> 35 #include <malloc.h>
36 #include <fm_eth.h> 36 #include <fm_eth.h>
37 #include <fsl_mdio.h> 37 #include <fsl_mdio.h>
38 #include <miiphy.h> 38 #include <miiphy.h>
39 #include <phy.h> 39 #include <phy.h>
40 40
41 #include "../common/ngpixis.h" 41 #include "../common/ngpixis.h"
42 #include "../common/fman.h" 42 #include "../common/fman.h"
43 #include <asm/fsl_dtsec.h> 43 #include <asm/fsl_dtsec.h>
44 44
45 #define EMI_NONE 0xffffffff 45 #define EMI_NONE 0xffffffff
46 #define EMI_MASK 0xf0000000 46 #define EMI_MASK 0xf0000000
47 #define EMI1_RGMII 0x0 47 #define EMI1_RGMII 0x0
48 #define EMI1_SLOT3 0x80000000 /* bank1 EFGH */ 48 #define EMI1_SLOT3 0x80000000 /* bank1 EFGH */
49 #define EMI1_SLOT4 0x40000000 /* bank2 ABCD */ 49 #define EMI1_SLOT4 0x40000000 /* bank2 ABCD */
50 #define EMI1_SLOT5 0xc0000000 /* bank3 ABCD */ 50 #define EMI1_SLOT5 0xc0000000 /* bank3 ABCD */
51 #define EMI2_SLOT4 0x10000000 /* bank2 ABCD */ 51 #define EMI2_SLOT4 0x10000000 /* bank2 ABCD */
52 #define EMI2_SLOT5 0x30000000 /* bank3 ABCD */ 52 #define EMI2_SLOT5 0x30000000 /* bank3 ABCD */
53 #define EMI1_MASK 0xc0000000 53 #define EMI1_MASK 0xc0000000
54 #define EMI2_MASK 0x30000000 54 #define EMI2_MASK 0x30000000
55 55
56 static int mdio_mux[NUM_FM_PORTS]; 56 static int mdio_mux[NUM_FM_PORTS];
57 57
58 static char *mdio_names[16] = { 58 static char *mdio_names[16] = {
59 "P4080DS_MDIO0", 59 "P4080DS_MDIO0",
60 "P4080DS_MDIO1", 60 "P4080DS_MDIO1",
61 NULL, 61 NULL,
62 "P4080DS_MDIO3", 62 "P4080DS_MDIO3",
63 "P4080DS_MDIO4", 63 "P4080DS_MDIO4",
64 NULL, NULL, NULL, 64 NULL, NULL, NULL,
65 "P4080DS_MDIO8", 65 "P4080DS_MDIO8",
66 NULL, NULL, NULL, 66 NULL, NULL, NULL,
67 "P4080DS_MDIO12", 67 "P4080DS_MDIO12",
68 NULL, NULL, NULL, 68 NULL, NULL, NULL,
69 }; 69 };
70 70
71 static char *p4080ds_mdio_name_for_muxval(u32 muxval) 71 static char *p4080ds_mdio_name_for_muxval(u32 muxval)
72 { 72 {
73 return mdio_names[(muxval & EMI_MASK) >> 28]; 73 return mdio_names[(muxval & EMI_MASK) >> 28];
74 } 74 }
75 75
76 struct mii_dev *mii_dev_for_muxval(u32 muxval) 76 struct mii_dev *mii_dev_for_muxval(u32 muxval)
77 { 77 {
78 struct mii_dev *bus; 78 struct mii_dev *bus;
79 char *name = p4080ds_mdio_name_for_muxval(muxval); 79 char *name = p4080ds_mdio_name_for_muxval(muxval);
80 80
81 if (!name) { 81 if (!name) {
82 printf("No bus for muxval %x\n", muxval); 82 printf("No bus for muxval %x\n", muxval);
83 return NULL; 83 return NULL;
84 } 84 }
85 85
86 bus = miiphy_get_dev_by_name(name); 86 bus = miiphy_get_dev_by_name(name);
87 87
88 if (!bus) { 88 if (!bus) {
89 printf("No bus by name %s\n", name); 89 printf("No bus by name %s\n", name);
90 return NULL; 90 return NULL;
91 } 91 }
92 92
93 return bus; 93 return bus;
94 } 94 }
95 95
96 #if defined(CONFIG_SYS_P4080_ERRATUM_SERDES9) && defined(CONFIG_PHY_TERANETICS) 96 #if defined(CONFIG_SYS_P4080_ERRATUM_SERDES9) && defined(CONFIG_PHY_TERANETICS)
97 int board_phy_config(struct phy_device *phydev) 97 int board_phy_config(struct phy_device *phydev)
98 { 98 {
99 if (phydev->drv->config)
100 phydev->drv->config(phydev);
99 if (phydev->drv->uid == PHY_UID_TN2020) { 101 if (phydev->drv->uid == PHY_UID_TN2020) {
100 unsigned long timeout = 1 * 1000; /* 1 seconds */ 102 unsigned long timeout = 1 * 1000; /* 1 seconds */
101 enum srds_prtcl device; 103 enum srds_prtcl device;
102 104
103 /* 105 /*
104 * Wait for the XAUI to come out of reset. This is when it 106 * Wait for the XAUI to come out of reset. This is when it
105 * starts transmitting alignment signals. 107 * starts transmitting alignment signals.
106 */ 108 */
107 while (--timeout) { 109 while (--timeout) {
108 int reg = phy_read(phydev, MDIO_MMD_PHYXS, MDIO_CTRL1); 110 int reg = phy_read(phydev, MDIO_MMD_PHYXS, MDIO_CTRL1);
109 if (reg < 0) { 111 if (reg < 0) {
110 printf("TN2020: Error reading from PHY at " 112 printf("TN2020: Error reading from PHY at "
111 "address %u\n", phydev->addr); 113 "address %u\n", phydev->addr);
112 break; 114 break;
113 } 115 }
114 /* 116 /*
115 * Note that we've never actually seen 117 * Note that we've never actually seen
116 * MDIO_CTRL1_RESET set to 1. 118 * MDIO_CTRL1_RESET set to 1.
117 */ 119 */
118 if ((reg & MDIO_CTRL1_RESET) == 0) 120 if ((reg & MDIO_CTRL1_RESET) == 0)
119 break; 121 break;
120 udelay(1000); 122 udelay(1000);
121 } 123 }
122 124
123 if (!timeout) { 125 if (!timeout) {
124 printf("TN2020: Timeout waiting for PHY at address %u " 126 printf("TN2020: Timeout waiting for PHY at address %u "
125 " to reset.\n", phydev->addr); 127 " to reset.\n", phydev->addr);
126 } 128 }
127 129
128 switch (phydev->addr) { 130 switch (phydev->addr) {
129 case CONFIG_SYS_FM1_10GEC1_PHY_ADDR: 131 case CONFIG_SYS_FM1_10GEC1_PHY_ADDR:
130 device = XAUI_FM1; 132 device = XAUI_FM1;
131 break; 133 break;
132 case CONFIG_SYS_FM2_10GEC1_PHY_ADDR: 134 case CONFIG_SYS_FM2_10GEC1_PHY_ADDR:
133 device = XAUI_FM2; 135 device = XAUI_FM2;
134 break; 136 break;
135 default: 137 default:
136 device = NONE; 138 device = NONE;
137 } 139 }
138 140
139 serdes_reset_rx(device); 141 serdes_reset_rx(device);
140 } 142 }
141 143
142 return 0; 144 return 0;
143 } 145 }
144 #endif 146 #endif
145 147
146 struct p4080ds_mdio { 148 struct p4080ds_mdio {
147 u32 muxval; 149 u32 muxval;
148 struct mii_dev *realbus; 150 struct mii_dev *realbus;
149 }; 151 };
150 152
151 static void p4080ds_mux_mdio(u32 muxval) 153 static void p4080ds_mux_mdio(u32 muxval)
152 { 154 {
153 ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); 155 ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
154 uint gpioval = in_be32(&pgpio->gpdat) & ~(EMI_MASK); 156 uint gpioval = in_be32(&pgpio->gpdat) & ~(EMI_MASK);
155 gpioval |= muxval; 157 gpioval |= muxval;
156 158
157 out_be32(&pgpio->gpdat, gpioval); 159 out_be32(&pgpio->gpdat, gpioval);
158 } 160 }
159 161
160 static int p4080ds_mdio_read(struct mii_dev *bus, int addr, int devad, 162 static int p4080ds_mdio_read(struct mii_dev *bus, int addr, int devad,
161 int regnum) 163 int regnum)
162 { 164 {
163 struct p4080ds_mdio *priv = bus->priv; 165 struct p4080ds_mdio *priv = bus->priv;
164 166
165 p4080ds_mux_mdio(priv->muxval); 167 p4080ds_mux_mdio(priv->muxval);
166 168
167 return priv->realbus->read(priv->realbus, addr, devad, regnum); 169 return priv->realbus->read(priv->realbus, addr, devad, regnum);
168 } 170 }
169 171
170 static int p4080ds_mdio_write(struct mii_dev *bus, int addr, int devad, 172 static int p4080ds_mdio_write(struct mii_dev *bus, int addr, int devad,
171 int regnum, u16 value) 173 int regnum, u16 value)
172 { 174 {
173 struct p4080ds_mdio *priv = bus->priv; 175 struct p4080ds_mdio *priv = bus->priv;
174 176
175 p4080ds_mux_mdio(priv->muxval); 177 p4080ds_mux_mdio(priv->muxval);
176 178
177 return priv->realbus->write(priv->realbus, addr, devad, regnum, value); 179 return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
178 } 180 }
179 181
180 static int p4080ds_mdio_reset(struct mii_dev *bus) 182 static int p4080ds_mdio_reset(struct mii_dev *bus)
181 { 183 {
182 struct p4080ds_mdio *priv = bus->priv; 184 struct p4080ds_mdio *priv = bus->priv;
183 185
184 return priv->realbus->reset(priv->realbus); 186 return priv->realbus->reset(priv->realbus);
185 } 187 }
186 188
187 static int p4080ds_mdio_init(char *realbusname, u32 muxval) 189 static int p4080ds_mdio_init(char *realbusname, u32 muxval)
188 { 190 {
189 struct p4080ds_mdio *pmdio; 191 struct p4080ds_mdio *pmdio;
190 struct mii_dev *bus = mdio_alloc(); 192 struct mii_dev *bus = mdio_alloc();
191 193
192 if (!bus) { 194 if (!bus) {
193 printf("Failed to allocate P4080DS MDIO bus\n"); 195 printf("Failed to allocate P4080DS MDIO bus\n");
194 return -1; 196 return -1;
195 } 197 }
196 198
197 pmdio = malloc(sizeof(*pmdio)); 199 pmdio = malloc(sizeof(*pmdio));
198 if (!pmdio) { 200 if (!pmdio) {
199 printf("Failed to allocate P4080DS private data\n"); 201 printf("Failed to allocate P4080DS private data\n");
200 free(bus); 202 free(bus);
201 return -1; 203 return -1;
202 } 204 }
203 205
204 bus->read = p4080ds_mdio_read; 206 bus->read = p4080ds_mdio_read;
205 bus->write = p4080ds_mdio_write; 207 bus->write = p4080ds_mdio_write;
206 bus->reset = p4080ds_mdio_reset; 208 bus->reset = p4080ds_mdio_reset;
207 sprintf(bus->name, p4080ds_mdio_name_for_muxval(muxval)); 209 sprintf(bus->name, p4080ds_mdio_name_for_muxval(muxval));
208 210
209 pmdio->realbus = miiphy_get_dev_by_name(realbusname); 211 pmdio->realbus = miiphy_get_dev_by_name(realbusname);
210 212
211 if (!pmdio->realbus) { 213 if (!pmdio->realbus) {
212 printf("No bus with name %s\n", realbusname); 214 printf("No bus with name %s\n", realbusname);
213 free(bus); 215 free(bus);
214 free(pmdio); 216 free(pmdio);
215 return -1; 217 return -1;
216 } 218 }
217 219
218 pmdio->muxval = muxval; 220 pmdio->muxval = muxval;
219 bus->priv = pmdio; 221 bus->priv = pmdio;
220 222
221 return mdio_register(bus); 223 return mdio_register(bus);
222 } 224 }
223 225
224 void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, 226 void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa,
225 enum fm_port port, int offset) 227 enum fm_port port, int offset)
226 { 228 {
227 if (mdio_mux[port] == EMI1_RGMII) 229 if (mdio_mux[port] == EMI1_RGMII)
228 fdt_set_phy_handle(blob, prop, pa, "phy_rgmii"); 230 fdt_set_phy_handle(blob, prop, pa, "phy_rgmii");
229 231
230 if (mdio_mux[port] == EMI1_SLOT3) { 232 if (mdio_mux[port] == EMI1_SLOT3) {
231 int idx = port - FM2_DTSEC1 + 5; 233 int idx = port - FM2_DTSEC1 + 5;
232 char phy[16]; 234 char phy[16];
233 235
234 sprintf(phy, "phy%d_slot3", idx); 236 sprintf(phy, "phy%d_slot3", idx);
235 237
236 fdt_set_phy_handle(blob, prop, pa, phy); 238 fdt_set_phy_handle(blob, prop, pa, phy);
237 } 239 }
238 } 240 }
239 241
240 void fdt_fixup_board_enet(void *fdt) 242 void fdt_fixup_board_enet(void *fdt)
241 { 243 {
242 int i; 244 int i;
243 245
244 /* 246 /*
245 * P4080DS can be configured in many different ways, supporting a number 247 * P4080DS can be configured in many different ways, supporting a number
246 * of combinations of ethernet devices and phy types. In order to 248 * of combinations of ethernet devices and phy types. In order to
247 * have just one device tree for all of those configurations, we fix up 249 * have just one device tree for all of those configurations, we fix up
248 * the tree here. By default, the device tree configures FM1 and FM2 250 * the tree here. By default, the device tree configures FM1 and FM2
249 * for SGMII, and configures XAUI on both 10G interfaces. So we have 251 * for SGMII, and configures XAUI on both 10G interfaces. So we have
250 * a number of different variables to track: 252 * a number of different variables to track:
251 * 253 *
252 * 1) Whether the device is configured at all. Whichever devices are 254 * 1) Whether the device is configured at all. Whichever devices are
253 * not enabled should be disabled by setting the "status" property 255 * not enabled should be disabled by setting the "status" property
254 * to "disabled". 256 * to "disabled".
255 * 2) What the PHY interface is. If this is an RGMII connection, 257 * 2) What the PHY interface is. If this is an RGMII connection,
256 * we should change the "phy-connection-type" property to 258 * we should change the "phy-connection-type" property to
257 * "rgmii" 259 * "rgmii"
258 * 3) Which PHY is being used. Because the MDIO buses are muxed, 260 * 3) Which PHY is being used. Because the MDIO buses are muxed,
259 * we need to redirect the "phy-handle" property to point at the 261 * we need to redirect the "phy-handle" property to point at the
260 * PHY on the right slot/bus. 262 * PHY on the right slot/bus.
261 */ 263 */
262 264
263 /* We've got six MDIO nodes that may or may not need to exist */ 265 /* We've got six MDIO nodes that may or may not need to exist */
264 fdt_status_disabled_by_alias(fdt, "emi1_slot3"); 266 fdt_status_disabled_by_alias(fdt, "emi1_slot3");
265 fdt_status_disabled_by_alias(fdt, "emi1_slot4"); 267 fdt_status_disabled_by_alias(fdt, "emi1_slot4");
266 fdt_status_disabled_by_alias(fdt, "emi1_slot5"); 268 fdt_status_disabled_by_alias(fdt, "emi1_slot5");
267 fdt_status_disabled_by_alias(fdt, "emi2_slot4"); 269 fdt_status_disabled_by_alias(fdt, "emi2_slot4");
268 fdt_status_disabled_by_alias(fdt, "emi2_slot5"); 270 fdt_status_disabled_by_alias(fdt, "emi2_slot5");
269 271
270 for (i = 0; i < NUM_FM_PORTS; i++) { 272 for (i = 0; i < NUM_FM_PORTS; i++) {
271 switch (mdio_mux[i]) { 273 switch (mdio_mux[i]) {
272 case EMI1_SLOT3: 274 case EMI1_SLOT3:
273 fdt_status_okay_by_alias(fdt, "emi1_slot3"); 275 fdt_status_okay_by_alias(fdt, "emi1_slot3");
274 break; 276 break;
275 case EMI1_SLOT4: 277 case EMI1_SLOT4:
276 fdt_status_okay_by_alias(fdt, "emi1_slot4"); 278 fdt_status_okay_by_alias(fdt, "emi1_slot4");
277 break; 279 break;
278 case EMI1_SLOT5: 280 case EMI1_SLOT5:
279 fdt_status_okay_by_alias(fdt, "emi1_slot5"); 281 fdt_status_okay_by_alias(fdt, "emi1_slot5");
280 break; 282 break;
281 case EMI2_SLOT4: 283 case EMI2_SLOT4:
282 fdt_status_okay_by_alias(fdt, "emi2_slot4"); 284 fdt_status_okay_by_alias(fdt, "emi2_slot4");
283 break; 285 break;
284 case EMI2_SLOT5: 286 case EMI2_SLOT5:
285 fdt_status_okay_by_alias(fdt, "emi2_slot5"); 287 fdt_status_okay_by_alias(fdt, "emi2_slot5");
286 break; 288 break;
287 } 289 }
288 } 290 }
289 } 291 }
290 292
291 enum board_slots { 293 enum board_slots {
292 SLOT1 = 1, 294 SLOT1 = 1,
293 SLOT2, 295 SLOT2,
294 SLOT3, 296 SLOT3,
295 SLOT4, 297 SLOT4,
296 SLOT5, 298 SLOT5,
297 SLOT6, 299 SLOT6,
298 }; 300 };
299 301
300 int board_eth_init(bd_t *bis) 302 int board_eth_init(bd_t *bis)
301 { 303 {
302 #ifdef CONFIG_FMAN_ENET 304 #ifdef CONFIG_FMAN_ENET
303 ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); 305 ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
304 int i; 306 int i;
305 struct fsl_pq_mdio_info dtsec_mdio_info; 307 struct fsl_pq_mdio_info dtsec_mdio_info;
306 struct tgec_mdio_info tgec_mdio_info; 308 struct tgec_mdio_info tgec_mdio_info;
307 309
308 u8 lane_to_slot[] = { 310 u8 lane_to_slot[] = {
309 SLOT1, /* 0 - Bank 1:A */ 311 SLOT1, /* 0 - Bank 1:A */
310 SLOT1, /* 1 - Bank 1:B */ 312 SLOT1, /* 1 - Bank 1:B */
311 SLOT2, /* 2 - Bank 1:C */ 313 SLOT2, /* 2 - Bank 1:C */
312 SLOT2, /* 3 - Bank 1:D */ 314 SLOT2, /* 3 - Bank 1:D */
313 SLOT3, /* 4 - Bank 1:E */ 315 SLOT3, /* 4 - Bank 1:E */
314 SLOT3, /* 5 - Bank 1:F */ 316 SLOT3, /* 5 - Bank 1:F */
315 SLOT3, /* 6 - Bank 1:G */ 317 SLOT3, /* 6 - Bank 1:G */
316 SLOT3, /* 7 - Bank 1:H */ 318 SLOT3, /* 7 - Bank 1:H */
317 SLOT6, /* 8 - Bank 1:I */ 319 SLOT6, /* 8 - Bank 1:I */
318 SLOT6, /* 9 - Bank 1:J */ 320 SLOT6, /* 9 - Bank 1:J */
319 SLOT4, /* 10 - Bank 2:A */ 321 SLOT4, /* 10 - Bank 2:A */
320 SLOT4, /* 11 - Bank 2:B */ 322 SLOT4, /* 11 - Bank 2:B */
321 SLOT4, /* 12 - Bank 2:C */ 323 SLOT4, /* 12 - Bank 2:C */
322 SLOT4, /* 13 - Bank 2:D */ 324 SLOT4, /* 13 - Bank 2:D */
323 SLOT5, /* 14 - Bank 3:A */ 325 SLOT5, /* 14 - Bank 3:A */
324 SLOT5, /* 15 - Bank 3:B */ 326 SLOT5, /* 15 - Bank 3:B */
325 SLOT5, /* 16 - Bank 3:C */ 327 SLOT5, /* 16 - Bank 3:C */
326 SLOT5, /* 17 - Bank 3:D */ 328 SLOT5, /* 17 - Bank 3:D */
327 }; 329 };
328 330
329 /* Initialize the mdio_mux array so we can recognize empty elements */ 331 /* Initialize the mdio_mux array so we can recognize empty elements */
330 for (i = 0; i < NUM_FM_PORTS; i++) 332 for (i = 0; i < NUM_FM_PORTS; i++)
331 mdio_mux[i] = EMI_NONE; 333 mdio_mux[i] = EMI_NONE;
332 334
333 /* The first 4 GPIOs are outputs to control MDIO bus muxing */ 335 /* The first 4 GPIOs are outputs to control MDIO bus muxing */
334 out_be32(&pgpio->gpdir, EMI_MASK); 336 out_be32(&pgpio->gpdir, EMI_MASK);
335 337
336 dtsec_mdio_info.regs = 338 dtsec_mdio_info.regs =
337 (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR; 339 (struct tsec_mii_mng *)CONFIG_SYS_FM1_DTSEC1_MDIO_ADDR;
338 dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME; 340 dtsec_mdio_info.name = DEFAULT_FM_MDIO_NAME;
339 341
340 /* Register the 1G MDIO bus */ 342 /* Register the 1G MDIO bus */
341 fsl_pq_mdio_init(bis, &dtsec_mdio_info); 343 fsl_pq_mdio_init(bis, &dtsec_mdio_info);
342 344
343 tgec_mdio_info.regs = 345 tgec_mdio_info.regs =
344 (struct tgec_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR; 346 (struct tgec_mdio_controller *)CONFIG_SYS_FM1_TGEC_MDIO_ADDR;
345 tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME; 347 tgec_mdio_info.name = DEFAULT_FM_TGEC_MDIO_NAME;
346 348
347 /* Register the 10G MDIO bus */ 349 /* Register the 10G MDIO bus */
348 fm_tgec_mdio_init(bis, &tgec_mdio_info); 350 fm_tgec_mdio_init(bis, &tgec_mdio_info);
349 351
350 /* Register the 6 muxing front-ends to the MDIO buses */ 352 /* Register the 6 muxing front-ends to the MDIO buses */
351 p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII); 353 p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_RGMII);
352 p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3); 354 p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT3);
353 p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4); 355 p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT4);
354 p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5); 356 p4080ds_mdio_init(DEFAULT_FM_MDIO_NAME, EMI1_SLOT5);
355 p4080ds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2_SLOT4); 357 p4080ds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2_SLOT4);
356 p4080ds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2_SLOT5); 358 p4080ds_mdio_init(DEFAULT_FM_TGEC_MDIO_NAME, EMI2_SLOT5);
357 359
358 fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR); 360 fm_info_set_phy_address(FM1_DTSEC1, CONFIG_SYS_FM1_DTSEC1_PHY_ADDR);
359 fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR); 361 fm_info_set_phy_address(FM1_DTSEC2, CONFIG_SYS_FM1_DTSEC2_PHY_ADDR);
360 fm_info_set_phy_address(FM1_DTSEC3, CONFIG_SYS_FM1_DTSEC3_PHY_ADDR); 362 fm_info_set_phy_address(FM1_DTSEC3, CONFIG_SYS_FM1_DTSEC3_PHY_ADDR);
361 fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR); 363 fm_info_set_phy_address(FM1_DTSEC4, CONFIG_SYS_FM1_DTSEC4_PHY_ADDR);
362 fm_info_set_phy_address(FM1_10GEC1, CONFIG_SYS_FM1_10GEC1_PHY_ADDR); 364 fm_info_set_phy_address(FM1_10GEC1, CONFIG_SYS_FM1_10GEC1_PHY_ADDR);
363 365
364 #if (CONFIG_SYS_NUM_FMAN == 2) 366 #if (CONFIG_SYS_NUM_FMAN == 2)
365 fm_info_set_phy_address(FM2_DTSEC1, CONFIG_SYS_FM2_DTSEC1_PHY_ADDR); 367 fm_info_set_phy_address(FM2_DTSEC1, CONFIG_SYS_FM2_DTSEC1_PHY_ADDR);
366 fm_info_set_phy_address(FM2_DTSEC2, CONFIG_SYS_FM2_DTSEC2_PHY_ADDR); 368 fm_info_set_phy_address(FM2_DTSEC2, CONFIG_SYS_FM2_DTSEC2_PHY_ADDR);
367 fm_info_set_phy_address(FM2_DTSEC3, CONFIG_SYS_FM2_DTSEC3_PHY_ADDR); 369 fm_info_set_phy_address(FM2_DTSEC3, CONFIG_SYS_FM2_DTSEC3_PHY_ADDR);
368 fm_info_set_phy_address(FM2_DTSEC4, CONFIG_SYS_FM2_DTSEC4_PHY_ADDR); 370 fm_info_set_phy_address(FM2_DTSEC4, CONFIG_SYS_FM2_DTSEC4_PHY_ADDR);
369 fm_info_set_phy_address(FM2_10GEC1, CONFIG_SYS_FM2_10GEC1_PHY_ADDR); 371 fm_info_set_phy_address(FM2_10GEC1, CONFIG_SYS_FM2_10GEC1_PHY_ADDR);
370 #endif 372 #endif
371 373
372 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) { 374 for (i = FM1_DTSEC1; i < FM1_DTSEC1 + CONFIG_SYS_NUM_FM1_DTSEC; i++) {
373 int idx = i - FM1_DTSEC1, lane, slot; 375 int idx = i - FM1_DTSEC1, lane, slot;
374 switch (fm_info_get_enet_if(i)) { 376 switch (fm_info_get_enet_if(i)) {
375 case PHY_INTERFACE_MODE_SGMII: 377 case PHY_INTERFACE_MODE_SGMII:
376 lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx); 378 lane = serdes_get_first_lane(SGMII_FM1_DTSEC1 + idx);
377 if (lane < 0) 379 if (lane < 0)
378 break; 380 break;
379 slot = lane_to_slot[lane]; 381 slot = lane_to_slot[lane];
380 switch (slot) { 382 switch (slot) {
381 case SLOT3: 383 case SLOT3:
382 mdio_mux[i] = EMI1_SLOT3; 384 mdio_mux[i] = EMI1_SLOT3;
383 fm_info_set_mdio(i, 385 fm_info_set_mdio(i,
384 mii_dev_for_muxval(mdio_mux[i])); 386 mii_dev_for_muxval(mdio_mux[i]));
385 break; 387 break;
386 case SLOT4: 388 case SLOT4:
387 mdio_mux[i] = EMI1_SLOT4; 389 mdio_mux[i] = EMI1_SLOT4;
388 fm_info_set_mdio(i, 390 fm_info_set_mdio(i,
389 mii_dev_for_muxval(mdio_mux[i])); 391 mii_dev_for_muxval(mdio_mux[i]));
390 break; 392 break;
391 case SLOT5: 393 case SLOT5:
392 mdio_mux[i] = EMI1_SLOT5; 394 mdio_mux[i] = EMI1_SLOT5;
393 fm_info_set_mdio(i, 395 fm_info_set_mdio(i,
394 mii_dev_for_muxval(mdio_mux[i])); 396 mii_dev_for_muxval(mdio_mux[i]));
395 break; 397 break;
396 }; 398 };
397 break; 399 break;
398 case PHY_INTERFACE_MODE_RGMII: 400 case PHY_INTERFACE_MODE_RGMII:
399 fm_info_set_phy_address(i, 0); 401 fm_info_set_phy_address(i, 0);
400 mdio_mux[i] = EMI1_RGMII; 402 mdio_mux[i] = EMI1_RGMII;
401 fm_info_set_mdio(i, 403 fm_info_set_mdio(i,
402 mii_dev_for_muxval(mdio_mux[i])); 404 mii_dev_for_muxval(mdio_mux[i]));
403 break; 405 break;
404 default: 406 default:
405 break; 407 break;
406 } 408 }
407 } 409 }
408 410
409 for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) { 411 for (i = FM1_10GEC1; i < FM1_10GEC1 + CONFIG_SYS_NUM_FM1_10GEC; i++) {
410 int idx = i - FM1_10GEC1, lane, slot; 412 int idx = i - FM1_10GEC1, lane, slot;
411 switch (fm_info_get_enet_if(i)) { 413 switch (fm_info_get_enet_if(i)) {
412 case PHY_INTERFACE_MODE_XGMII: 414 case PHY_INTERFACE_MODE_XGMII:
413 lane = serdes_get_first_lane(XAUI_FM1 + idx); 415 lane = serdes_get_first_lane(XAUI_FM1 + idx);
414 if (lane < 0) 416 if (lane < 0)
415 break; 417 break;
416 slot = lane_to_slot[lane]; 418 slot = lane_to_slot[lane];
417 switch (slot) { 419 switch (slot) {
418 case SLOT4: 420 case SLOT4:
419 mdio_mux[i] = EMI2_SLOT4; 421 mdio_mux[i] = EMI2_SLOT4;
420 fm_info_set_mdio(i, 422 fm_info_set_mdio(i,
421 mii_dev_for_muxval(mdio_mux[i])); 423 mii_dev_for_muxval(mdio_mux[i]));
422 break; 424 break;
423 case SLOT5: 425 case SLOT5:
424 mdio_mux[i] = EMI2_SLOT5; 426 mdio_mux[i] = EMI2_SLOT5;
425 fm_info_set_mdio(i, 427 fm_info_set_mdio(i,
426 mii_dev_for_muxval(mdio_mux[i])); 428 mii_dev_for_muxval(mdio_mux[i]));
427 break; 429 break;
428 }; 430 };
429 break; 431 break;
430 default: 432 default:
431 break; 433 break;
432 } 434 }
433 } 435 }
434 436
435 #if (CONFIG_SYS_NUM_FMAN == 2) 437 #if (CONFIG_SYS_NUM_FMAN == 2)
436 for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) { 438 for (i = FM2_DTSEC1; i < FM2_DTSEC1 + CONFIG_SYS_NUM_FM2_DTSEC; i++) {
437 int idx = i - FM2_DTSEC1, lane, slot; 439 int idx = i - FM2_DTSEC1, lane, slot;
438 switch (fm_info_get_enet_if(i)) { 440 switch (fm_info_get_enet_if(i)) {
439 case PHY_INTERFACE_MODE_SGMII: 441 case PHY_INTERFACE_MODE_SGMII:
440 lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx); 442 lane = serdes_get_first_lane(SGMII_FM2_DTSEC1 + idx);
441 if (lane < 0) 443 if (lane < 0)
442 break; 444 break;
443 slot = lane_to_slot[lane]; 445 slot = lane_to_slot[lane];
444 switch (slot) { 446 switch (slot) {
445 case SLOT3: 447 case SLOT3:
446 mdio_mux[i] = EMI1_SLOT3; 448 mdio_mux[i] = EMI1_SLOT3;
447 fm_info_set_mdio(i, 449 fm_info_set_mdio(i,
448 mii_dev_for_muxval(mdio_mux[i])); 450 mii_dev_for_muxval(mdio_mux[i]));
449 break; 451 break;
450 case SLOT4: 452 case SLOT4:
451 mdio_mux[i] = EMI1_SLOT4; 453 mdio_mux[i] = EMI1_SLOT4;
452 fm_info_set_mdio(i, 454 fm_info_set_mdio(i,
453 mii_dev_for_muxval(mdio_mux[i])); 455 mii_dev_for_muxval(mdio_mux[i]));
454 break; 456 break;
455 case SLOT5: 457 case SLOT5:
456 mdio_mux[i] = EMI1_SLOT5; 458 mdio_mux[i] = EMI1_SLOT5;
457 fm_info_set_mdio(i, 459 fm_info_set_mdio(i,
458 mii_dev_for_muxval(mdio_mux[i])); 460 mii_dev_for_muxval(mdio_mux[i]));
459 break; 461 break;
460 }; 462 };
461 break; 463 break;
462 case PHY_INTERFACE_MODE_RGMII: 464 case PHY_INTERFACE_MODE_RGMII:
463 fm_info_set_phy_address(i, 0); 465 fm_info_set_phy_address(i, 0);
464 mdio_mux[i] = EMI1_RGMII; 466 mdio_mux[i] = EMI1_RGMII;
465 fm_info_set_mdio(i, 467 fm_info_set_mdio(i,
466 mii_dev_for_muxval(mdio_mux[i])); 468 mii_dev_for_muxval(mdio_mux[i]));
467 break; 469 break;
468 default: 470 default:
469 break; 471 break;
470 } 472 }
471 } 473 }
472 474
473 for (i = FM2_10GEC1; i < FM2_10GEC1 + CONFIG_SYS_NUM_FM2_10GEC; i++) { 475 for (i = FM2_10GEC1; i < FM2_10GEC1 + CONFIG_SYS_NUM_FM2_10GEC; i++) {
474 int idx = i - FM2_10GEC1, lane, slot; 476 int idx = i - FM2_10GEC1, lane, slot;
475 switch (fm_info_get_enet_if(i)) { 477 switch (fm_info_get_enet_if(i)) {
476 case PHY_INTERFACE_MODE_XGMII: 478 case PHY_INTERFACE_MODE_XGMII:
477 lane = serdes_get_first_lane(XAUI_FM2 + idx); 479 lane = serdes_get_first_lane(XAUI_FM2 + idx);
478 if (lane < 0) 480 if (lane < 0)
479 break; 481 break;
480 slot = lane_to_slot[lane]; 482 slot = lane_to_slot[lane];
481 switch (slot) { 483 switch (slot) {
482 case SLOT4: 484 case SLOT4:
483 mdio_mux[i] = EMI2_SLOT4; 485 mdio_mux[i] = EMI2_SLOT4;
484 fm_info_set_mdio(i, 486 fm_info_set_mdio(i,
485 mii_dev_for_muxval(mdio_mux[i])); 487 mii_dev_for_muxval(mdio_mux[i]));
486 break; 488 break;
487 case SLOT5: 489 case SLOT5:
488 mdio_mux[i] = EMI2_SLOT5; 490 mdio_mux[i] = EMI2_SLOT5;
489 fm_info_set_mdio(i, 491 fm_info_set_mdio(i,
490 mii_dev_for_muxval(mdio_mux[i])); 492 mii_dev_for_muxval(mdio_mux[i]));
491 break; 493 break;
492 }; 494 };
493 break; 495 break;
494 default: 496 default:
495 break; 497 break;
496 } 498 }
497 } 499 }
498 #endif 500 #endif
499 501
500 cpu_eth_init(bis); 502 cpu_eth_init(bis);
501 #endif /* CONFIG_FMAN_ENET */ 503 #endif /* CONFIG_FMAN_ENET */
502 504
503 return pci_eth_init(bis); 505 return pci_eth_init(bis);
504 } 506 }
505 507
board/freescale/mpc8544ds/mpc8544ds.c
1 /* 1 /*
2 * Copyright 2007,2009-2010 Freescale Semiconductor, Inc. 2 * Copyright 2007,2009-2010 Freescale Semiconductor, Inc.
3 * 3 *
4 * See file CREDITS for list of people who contributed to this 4 * See file CREDITS for list of people who contributed to this
5 * project. 5 * project.
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as 8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of 9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version. 10 * the License, or (at your option) any later version.
11 * 11 *
12 * This program is distributed in the hope that it will be useful, 12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details. 15 * GNU General Public License for more details.
16 * 16 *
17 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA 20 * MA 02111-1307 USA
21 */ 21 */
22 22
23 #include <common.h> 23 #include <common.h>
24 #include <command.h> 24 #include <command.h>
25 #include <pci.h> 25 #include <pci.h>
26 #include <asm/processor.h> 26 #include <asm/processor.h>
27 #include <asm/mmu.h> 27 #include <asm/mmu.h>
28 #include <asm/immap_85xx.h> 28 #include <asm/immap_85xx.h>
29 #include <asm/fsl_pci.h> 29 #include <asm/fsl_pci.h>
30 #include <asm/fsl_ddr_sdram.h> 30 #include <asm/fsl_ddr_sdram.h>
31 #include <asm/fsl_serdes.h> 31 #include <asm/fsl_serdes.h>
32 #include <asm/io.h> 32 #include <asm/io.h>
33 #include <miiphy.h> 33 #include <miiphy.h>
34 #include <libfdt.h> 34 #include <libfdt.h>
35 #include <fdt_support.h> 35 #include <fdt_support.h>
36 #include <fsl_mdio.h> 36 #include <fsl_mdio.h>
37 #include <tsec.h> 37 #include <tsec.h>
38 #include <netdev.h> 38 #include <netdev.h>
39 39
40 #include "../common/sgmii_riser.h" 40 #include "../common/sgmii_riser.h"
41 41
42 int checkboard (void) 42 int checkboard (void)
43 { 43 {
44 volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 44 volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
45 volatile fsl_lbc_t *lbc = LBC_BASE_ADDR; 45 volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;
46 volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR); 46 volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR);
47 u8 vboot; 47 u8 vboot;
48 u8 *pixis_base = (u8 *)PIXIS_BASE; 48 u8 *pixis_base = (u8 *)PIXIS_BASE;
49 49
50 if ((uint)&gur->porpllsr != 0xe00e0000) { 50 if ((uint)&gur->porpllsr != 0xe00e0000) {
51 printf("immap size error %lx\n",(ulong)&gur->porpllsr); 51 printf("immap size error %lx\n",(ulong)&gur->porpllsr);
52 } 52 }
53 printf ("Board: MPC8544DS, Sys ID: 0x%02x, " 53 printf ("Board: MPC8544DS, Sys ID: 0x%02x, "
54 "Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ", 54 "Sys Ver: 0x%02x, FPGA Ver: 0x%02x, ",
55 in_8(pixis_base + PIXIS_ID), in_8(pixis_base + PIXIS_VER), 55 in_8(pixis_base + PIXIS_ID), in_8(pixis_base + PIXIS_VER),
56 in_8(pixis_base + PIXIS_PVER)); 56 in_8(pixis_base + PIXIS_PVER));
57 57
58 vboot = in_8(pixis_base + PIXIS_VBOOT); 58 vboot = in_8(pixis_base + PIXIS_VBOOT);
59 if (vboot & PIXIS_VBOOT_FMAP) 59 if (vboot & PIXIS_VBOOT_FMAP)
60 printf ("vBank: %d\n", ((vboot & PIXIS_VBOOT_FBANK) >> 6)); 60 printf ("vBank: %d\n", ((vboot & PIXIS_VBOOT_FBANK) >> 6));
61 else 61 else
62 puts ("Promjet\n"); 62 puts ("Promjet\n");
63 63
64 lbc->ltesr = 0xffffffff; /* Clear LBC error interrupts */ 64 lbc->ltesr = 0xffffffff; /* Clear LBC error interrupts */
65 lbc->lteir = 0xffffffff; /* Enable LBC error interrupts */ 65 lbc->lteir = 0xffffffff; /* Enable LBC error interrupts */
66 ecm->eedr = 0xffffffff; /* Clear ecm errors */ 66 ecm->eedr = 0xffffffff; /* Clear ecm errors */
67 ecm->eeer = 0xffffffff; /* Enable ecm errors */ 67 ecm->eeer = 0xffffffff; /* Enable ecm errors */
68 68
69 return 0; 69 return 0;
70 } 70 }
71 71
72 #ifdef CONFIG_PCI1 72 #ifdef CONFIG_PCI1
73 static struct pci_controller pci1_hose; 73 static struct pci_controller pci1_hose;
74 #endif 74 #endif
75 75
76 #ifdef CONFIG_PCIE3 76 #ifdef CONFIG_PCIE3
77 static struct pci_controller pcie3_hose; 77 static struct pci_controller pcie3_hose;
78 #endif 78 #endif
79 79
80 void pci_init_board(void) 80 void pci_init_board(void)
81 { 81 {
82 volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); 82 volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
83 struct fsl_pci_info pci_info; 83 struct fsl_pci_info pci_info;
84 u32 devdisr, pordevsr, io_sel; 84 u32 devdisr, pordevsr, io_sel;
85 u32 porpllsr, pci_agent, pci_speed, pci_32, pci_arb, pci_clk_sel; 85 u32 porpllsr, pci_agent, pci_speed, pci_32, pci_arb, pci_clk_sel;
86 int first_free_busno = 0; 86 int first_free_busno = 0;
87 87
88 int pcie_ep, pcie_configured; 88 int pcie_ep, pcie_configured;
89 89
90 devdisr = in_be32(&gur->devdisr); 90 devdisr = in_be32(&gur->devdisr);
91 pordevsr = in_be32(&gur->pordevsr); 91 pordevsr = in_be32(&gur->pordevsr);
92 porpllsr = in_be32(&gur->porpllsr); 92 porpllsr = in_be32(&gur->porpllsr);
93 io_sel = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> 19; 93 io_sel = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> 19;
94 94
95 debug (" pci_init_board: devdisr=%x, io_sel=%x\n", devdisr, io_sel); 95 debug (" pci_init_board: devdisr=%x, io_sel=%x\n", devdisr, io_sel);
96 96
97 puts("\n"); 97 puts("\n");
98 98
99 #ifdef CONFIG_PCIE3 99 #ifdef CONFIG_PCIE3
100 pcie_configured = is_serdes_configured(PCIE3); 100 pcie_configured = is_serdes_configured(PCIE3);
101 101
102 if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE3)){ 102 if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE3)){
103 /* contains both PCIE3 MEM & IO space */ 103 /* contains both PCIE3 MEM & IO space */
104 set_next_law(CONFIG_SYS_PCIE3_MEM_PHYS, LAW_SIZE_4M, 104 set_next_law(CONFIG_SYS_PCIE3_MEM_PHYS, LAW_SIZE_4M,
105 LAW_TRGT_IF_PCIE_3); 105 LAW_TRGT_IF_PCIE_3);
106 SET_STD_PCIE_INFO(pci_info, 3); 106 SET_STD_PCIE_INFO(pci_info, 3);
107 pcie_ep = fsl_setup_hose(&pcie3_hose, pci_info.regs); 107 pcie_ep = fsl_setup_hose(&pcie3_hose, pci_info.regs);
108 108
109 /* outbound memory */ 109 /* outbound memory */
110 pci_set_region(&pcie3_hose.regions[0], 110 pci_set_region(&pcie3_hose.regions[0],
111 CONFIG_SYS_PCIE3_MEM_BUS2, 111 CONFIG_SYS_PCIE3_MEM_BUS2,
112 CONFIG_SYS_PCIE3_MEM_PHYS2, 112 CONFIG_SYS_PCIE3_MEM_PHYS2,
113 CONFIG_SYS_PCIE3_MEM_SIZE2, 113 CONFIG_SYS_PCIE3_MEM_SIZE2,
114 PCI_REGION_MEM); 114 PCI_REGION_MEM);
115 115
116 pcie3_hose.region_count = 1; 116 pcie3_hose.region_count = 1;
117 117
118 printf("PCIE3: connected to ULI as %s (base addr %lx)\n", 118 printf("PCIE3: connected to ULI as %s (base addr %lx)\n",
119 pcie_ep ? "Endpoint" : "Root Complex", 119 pcie_ep ? "Endpoint" : "Root Complex",
120 pci_info.regs); 120 pci_info.regs);
121 first_free_busno = fsl_pci_init_port(&pci_info, 121 first_free_busno = fsl_pci_init_port(&pci_info,
122 &pcie3_hose, first_free_busno); 122 &pcie3_hose, first_free_busno);
123 123
124 /* 124 /*
125 * Activate ULI1575 legacy chip by performing a fake 125 * Activate ULI1575 legacy chip by performing a fake
126 * memory access. Needed to make ULI RTC work. 126 * memory access. Needed to make ULI RTC work.
127 */ 127 */
128 in_be32((u32 *)CONFIG_SYS_PCIE3_MEM_BUS); 128 in_be32((u32 *)CONFIG_SYS_PCIE3_MEM_BUS);
129 } else { 129 } else {
130 printf("PCIE3: disabled\n"); 130 printf("PCIE3: disabled\n");
131 } 131 }
132 puts("\n"); 132 puts("\n");
133 #else 133 #else
134 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCIE3); /* disable */ 134 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCIE3); /* disable */
135 #endif 135 #endif
136 136
137 #ifdef CONFIG_PCIE1 137 #ifdef CONFIG_PCIE1
138 SET_STD_PCIE_INFO(pci_info, 1); 138 SET_STD_PCIE_INFO(pci_info, 1);
139 first_free_busno = fsl_pcie_init_ctrl(first_free_busno, devdisr, PCIE1, &pci_info); 139 first_free_busno = fsl_pcie_init_ctrl(first_free_busno, devdisr, PCIE1, &pci_info);
140 #else 140 #else
141 setbits_be32(&gur->devdisr, _DEVDISR_PCIE1); /* disable */ 141 setbits_be32(&gur->devdisr, _DEVDISR_PCIE1); /* disable */
142 #endif 142 #endif
143 143
144 #ifdef CONFIG_PCIE2 144 #ifdef CONFIG_PCIE2
145 SET_STD_PCIE_INFO(pci_info, 2); 145 SET_STD_PCIE_INFO(pci_info, 2);
146 first_free_busno = fsl_pcie_init_ctrl(first_free_busno, devdisr, PCIE2, &pci_info); 146 first_free_busno = fsl_pcie_init_ctrl(first_free_busno, devdisr, PCIE2, &pci_info);
147 #else 147 #else
148 setbits_be32(&gur->devdisr, _DEVDISR_PCIE2); /* disable */ 148 setbits_be32(&gur->devdisr, _DEVDISR_PCIE2); /* disable */
149 #endif 149 #endif
150 150
151 #ifdef CONFIG_PCI1 151 #ifdef CONFIG_PCI1
152 pci_speed = 66666000; 152 pci_speed = 66666000;
153 pci_32 = 1; 153 pci_32 = 1;
154 pci_arb = pordevsr & MPC85xx_PORDEVSR_PCI1_ARB; 154 pci_arb = pordevsr & MPC85xx_PORDEVSR_PCI1_ARB;
155 pci_clk_sel = porpllsr & MPC85xx_PORDEVSR_PCI1_SPD; 155 pci_clk_sel = porpllsr & MPC85xx_PORDEVSR_PCI1_SPD;
156 156
157 if (!(devdisr & MPC85xx_DEVDISR_PCI1)) { 157 if (!(devdisr & MPC85xx_DEVDISR_PCI1)) {
158 SET_STD_PCI_INFO(pci_info, 1); 158 SET_STD_PCI_INFO(pci_info, 1);
159 set_next_law(pci_info.mem_phys, 159 set_next_law(pci_info.mem_phys,
160 law_size_bits(pci_info.mem_size), pci_info.law); 160 law_size_bits(pci_info.mem_size), pci_info.law);
161 set_next_law(pci_info.io_phys, 161 set_next_law(pci_info.io_phys,
162 law_size_bits(pci_info.io_size), pci_info.law); 162 law_size_bits(pci_info.io_size), pci_info.law);
163 163
164 pci_agent = fsl_setup_hose(&pci1_hose, pci_info.regs); 164 pci_agent = fsl_setup_hose(&pci1_hose, pci_info.regs);
165 printf("PCI: %d bit, %s MHz, %s, %s, %s (base address %lx)\n", 165 printf("PCI: %d bit, %s MHz, %s, %s, %s (base address %lx)\n",
166 (pci_32) ? 32 : 64, 166 (pci_32) ? 32 : 64,
167 (pci_speed == 33333000) ? "33" : 167 (pci_speed == 33333000) ? "33" :
168 (pci_speed == 66666000) ? "66" : "unknown", 168 (pci_speed == 66666000) ? "66" : "unknown",
169 pci_clk_sel ? "sync" : "async", 169 pci_clk_sel ? "sync" : "async",
170 pci_agent ? "agent" : "host", 170 pci_agent ? "agent" : "host",
171 pci_arb ? "arbiter" : "external-arbiter", 171 pci_arb ? "arbiter" : "external-arbiter",
172 pci_info.regs); 172 pci_info.regs);
173 173
174 first_free_busno = fsl_pci_init_port(&pci_info, 174 first_free_busno = fsl_pci_init_port(&pci_info,
175 &pci1_hose, first_free_busno); 175 &pci1_hose, first_free_busno);
176 } else { 176 } else {
177 printf("PCI: disabled\n"); 177 printf("PCI: disabled\n");
178 } 178 }
179 179
180 puts("\n"); 180 puts("\n");
181 #else 181 #else
182 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCI1); /* disable */ 182 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCI1); /* disable */
183 #endif 183 #endif
184 } 184 }
185 185
186 int last_stage_init(void) 186 int last_stage_init(void)
187 { 187 {
188 return 0; 188 return 0;
189 } 189 }
190 190
191 191
192 unsigned long 192 unsigned long
193 get_board_sys_clk(ulong dummy) 193 get_board_sys_clk(ulong dummy)
194 { 194 {
195 u8 i, go_bit, rd_clks; 195 u8 i, go_bit, rd_clks;
196 ulong val = 0; 196 ulong val = 0;
197 u8 *pixis_base = (u8 *)PIXIS_BASE; 197 u8 *pixis_base = (u8 *)PIXIS_BASE;
198 198
199 go_bit = in_8(pixis_base + PIXIS_VCTL); 199 go_bit = in_8(pixis_base + PIXIS_VCTL);
200 go_bit &= 0x01; 200 go_bit &= 0x01;
201 201
202 rd_clks = in_8(pixis_base + PIXIS_VCFGEN0); 202 rd_clks = in_8(pixis_base + PIXIS_VCFGEN0);
203 rd_clks &= 0x1C; 203 rd_clks &= 0x1C;
204 204
205 /* 205 /*
206 * Only if both go bit and the SCLK bit in VCFGEN0 are set 206 * Only if both go bit and the SCLK bit in VCFGEN0 are set
207 * should we be using the AUX register. Remember, we also set the 207 * should we be using the AUX register. Remember, we also set the
208 * GO bit to boot from the alternate bank on the on-board flash 208 * GO bit to boot from the alternate bank on the on-board flash
209 */ 209 */
210 210
211 if (go_bit) { 211 if (go_bit) {
212 if (rd_clks == 0x1c) 212 if (rd_clks == 0x1c)
213 i = in_8(pixis_base + PIXIS_AUX); 213 i = in_8(pixis_base + PIXIS_AUX);
214 else 214 else
215 i = in_8(pixis_base + PIXIS_SPD); 215 i = in_8(pixis_base + PIXIS_SPD);
216 } else { 216 } else {
217 i = in_8(pixis_base + PIXIS_SPD); 217 i = in_8(pixis_base + PIXIS_SPD);
218 } 218 }
219 219
220 i &= 0x07; 220 i &= 0x07;
221 221
222 switch (i) { 222 switch (i) {
223 case 0: 223 case 0:
224 val = 33333333; 224 val = 33333333;
225 break; 225 break;
226 case 1: 226 case 1:
227 val = 40000000; 227 val = 40000000;
228 break; 228 break;
229 case 2: 229 case 2:
230 val = 50000000; 230 val = 50000000;
231 break; 231 break;
232 case 3: 232 case 3:
233 val = 66666666; 233 val = 66666666;
234 break; 234 break;
235 case 4: 235 case 4:
236 val = 83000000; 236 val = 83000000;
237 break; 237 break;
238 case 5: 238 case 5:
239 val = 100000000; 239 val = 100000000;
240 break; 240 break;
241 case 6: 241 case 6:
242 val = 133333333; 242 val = 133333333;
243 break; 243 break;
244 case 7: 244 case 7:
245 val = 166666666; 245 val = 166666666;
246 break; 246 break;
247 } 247 }
248 248
249 return val; 249 return val;
250 } 250 }
251 251
252 252
253 #define MIIM_CIS8204_SLED_CON 0x1b 253 #define MIIM_CIS8204_SLED_CON 0x1b
254 #define MIIM_CIS8204_SLEDCON_INIT 0x1115 254 #define MIIM_CIS8204_SLEDCON_INIT 0x1115
255 /* 255 /*
256 * Hack to write all 4 PHYs with the LED values 256 * Hack to write all 4 PHYs with the LED values
257 */ 257 */
258 int board_phy_config(struct phy_device *phydev) 258 int board_phy_config(struct phy_device *phydev)
259 { 259 {
260 static int do_once; 260 static int do_once;
261 uint phyid; 261 uint phyid;
262 struct mii_dev *bus = phydev->bus; 262 struct mii_dev *bus = phydev->bus;
263 263
264 if (phydev->drv->config)
265 phydev->drv->config(phydev);
264 if (do_once) 266 if (do_once)
265 return 0; 267 return 0;
266 268
267 for (phyid = 0; phyid < 4; phyid++) 269 for (phyid = 0; phyid < 4; phyid++)
268 bus->write(bus, phyid, MDIO_DEVAD_NONE, MIIM_CIS8204_SLED_CON, 270 bus->write(bus, phyid, MDIO_DEVAD_NONE, MIIM_CIS8204_SLED_CON,
269 MIIM_CIS8204_SLEDCON_INIT); 271 MIIM_CIS8204_SLEDCON_INIT);
270 272
271 do_once = 1; 273 do_once = 1;
272 274
273 return 0; 275 return 0;
274 } 276 }
275 277
276 278
277 int board_eth_init(bd_t *bis) 279 int board_eth_init(bd_t *bis)
278 { 280 {
279 #ifdef CONFIG_TSEC_ENET 281 #ifdef CONFIG_TSEC_ENET
280 struct fsl_pq_mdio_info mdio_info; 282 struct fsl_pq_mdio_info mdio_info;
281 struct tsec_info_struct tsec_info[2]; 283 struct tsec_info_struct tsec_info[2];
282 int num = 0; 284 int num = 0;
283 285
284 #ifdef CONFIG_TSEC1 286 #ifdef CONFIG_TSEC1
285 SET_STD_TSEC_INFO(tsec_info[num], 1); 287 SET_STD_TSEC_INFO(tsec_info[num], 1);
286 if (is_serdes_configured(SGMII_TSEC1)) { 288 if (is_serdes_configured(SGMII_TSEC1)) {
287 puts("eTSEC1 is in sgmii mode.\n"); 289 puts("eTSEC1 is in sgmii mode.\n");
288 tsec_info[num].flags |= TSEC_SGMII; 290 tsec_info[num].flags |= TSEC_SGMII;
289 } 291 }
290 num++; 292 num++;
291 #endif 293 #endif
292 #ifdef CONFIG_TSEC3 294 #ifdef CONFIG_TSEC3
293 SET_STD_TSEC_INFO(tsec_info[num], 3); 295 SET_STD_TSEC_INFO(tsec_info[num], 3);
294 if (is_serdes_configured(SGMII_TSEC3)) { 296 if (is_serdes_configured(SGMII_TSEC3)) {
295 puts("eTSEC3 is in sgmii mode.\n"); 297 puts("eTSEC3 is in sgmii mode.\n");
296 tsec_info[num].flags |= TSEC_SGMII; 298 tsec_info[num].flags |= TSEC_SGMII;
297 } 299 }
298 num++; 300 num++;
299 #endif 301 #endif
300 302
301 if (!num) { 303 if (!num) {
302 printf("No TSECs initialized\n"); 304 printf("No TSECs initialized\n");
303 305
304 return 0; 306 return 0;
305 } 307 }
306 308
307 if (is_serdes_configured(SGMII_TSEC1) || 309 if (is_serdes_configured(SGMII_TSEC1) ||
308 is_serdes_configured(SGMII_TSEC3)) { 310 is_serdes_configured(SGMII_TSEC3)) {
309 fsl_sgmii_riser_init(tsec_info, num); 311 fsl_sgmii_riser_init(tsec_info, num);
310 } 312 }
311 313
312 mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; 314 mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR;
313 mdio_info.name = DEFAULT_MII_NAME; 315 mdio_info.name = DEFAULT_MII_NAME;
314 fsl_pq_mdio_init(bis, &mdio_info); 316 fsl_pq_mdio_init(bis, &mdio_info);
315 317
316 tsec_eth_init(bis, tsec_info, num); 318 tsec_eth_init(bis, tsec_info, num);
317 #endif 319 #endif
318 return pci_eth_init(bis); 320 return pci_eth_init(bis);
319 } 321 }
320 322
321 #if defined(CONFIG_OF_BOARD_SETUP) 323 #if defined(CONFIG_OF_BOARD_SETUP)
322 void ft_board_setup(void *blob, bd_t *bd) 324 void ft_board_setup(void *blob, bd_t *bd)
323 { 325 {
324 ft_cpu_setup(blob, bd); 326 ft_cpu_setup(blob, bd);
325 327
326 FT_FSL_PCI_SETUP; 328 FT_FSL_PCI_SETUP;
327 329
328 #ifdef CONFIG_FSL_SGMII_RISER 330 #ifdef CONFIG_FSL_SGMII_RISER
329 fsl_sgmii_riser_fdt_fixup(blob); 331 fsl_sgmii_riser_fdt_fixup(blob);
330 #endif 332 #endif
331 } 333 }
332 #endif 334 #endif
333 335
drivers/net/phy/phy.c
1 /* 1 /*
2 * Generic PHY Management code 2 * Generic PHY Management code
3 * 3 *
4 * This program is free software; you can redistribute it and/or 4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as 5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of 6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version. 7 * the License, or (at your option) any later version.
8 * 8 *
9 * This program is distributed in the hope that it will be useful, 9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software 15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA 17 * MA 02111-1307 USA
18 * 18 *
19 * 19 *
20 * Copyright 2011 Freescale Semiconductor, Inc. 20 * Copyright 2011 Freescale Semiconductor, Inc.
21 * author Andy Fleming 21 * author Andy Fleming
22 * 22 *
23 * Based loosely off of Linux's PHY Lib 23 * Based loosely off of Linux's PHY Lib
24 */ 24 */
25 25
26 #include <config.h> 26 #include <config.h>
27 #include <common.h> 27 #include <common.h>
28 #include <malloc.h> 28 #include <malloc.h>
29 #include <net.h> 29 #include <net.h>
30 #include <command.h> 30 #include <command.h>
31 #include <miiphy.h> 31 #include <miiphy.h>
32 #include <phy.h> 32 #include <phy.h>
33 #include <errno.h> 33 #include <errno.h>
34 34
35 /* Generic PHY support and helper functions */ 35 /* Generic PHY support and helper functions */
36 36
37 /** 37 /**
38 * genphy_config_advert - sanitize and advertise auto-negotation parameters 38 * genphy_config_advert - sanitize and advertise auto-negotation parameters
39 * @phydev: target phy_device struct 39 * @phydev: target phy_device struct
40 * 40 *
41 * Description: Writes MII_ADVERTISE with the appropriate values, 41 * Description: Writes MII_ADVERTISE with the appropriate values,
42 * after sanitizing the values to make sure we only advertise 42 * after sanitizing the values to make sure we only advertise
43 * what is supported. Returns < 0 on error, 0 if the PHY's advertisement 43 * what is supported. Returns < 0 on error, 0 if the PHY's advertisement
44 * hasn't changed, and > 0 if it has changed. 44 * hasn't changed, and > 0 if it has changed.
45 */ 45 */
46 int genphy_config_advert(struct phy_device *phydev) 46 int genphy_config_advert(struct phy_device *phydev)
47 { 47 {
48 u32 advertise; 48 u32 advertise;
49 int oldadv, adv; 49 int oldadv, adv;
50 int err, changed = 0; 50 int err, changed = 0;
51 51
52 /* Only allow advertising what 52 /* Only allow advertising what
53 * this PHY supports */ 53 * this PHY supports */
54 phydev->advertising &= phydev->supported; 54 phydev->advertising &= phydev->supported;
55 advertise = phydev->advertising; 55 advertise = phydev->advertising;
56 56
57 /* Setup standard advertisement */ 57 /* Setup standard advertisement */
58 oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE); 58 oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
59 59
60 if (adv < 0) 60 if (adv < 0)
61 return adv; 61 return adv;
62 62
63 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | 63 adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
64 ADVERTISE_PAUSE_ASYM); 64 ADVERTISE_PAUSE_ASYM);
65 if (advertise & ADVERTISED_10baseT_Half) 65 if (advertise & ADVERTISED_10baseT_Half)
66 adv |= ADVERTISE_10HALF; 66 adv |= ADVERTISE_10HALF;
67 if (advertise & ADVERTISED_10baseT_Full) 67 if (advertise & ADVERTISED_10baseT_Full)
68 adv |= ADVERTISE_10FULL; 68 adv |= ADVERTISE_10FULL;
69 if (advertise & ADVERTISED_100baseT_Half) 69 if (advertise & ADVERTISED_100baseT_Half)
70 adv |= ADVERTISE_100HALF; 70 adv |= ADVERTISE_100HALF;
71 if (advertise & ADVERTISED_100baseT_Full) 71 if (advertise & ADVERTISED_100baseT_Full)
72 adv |= ADVERTISE_100FULL; 72 adv |= ADVERTISE_100FULL;
73 if (advertise & ADVERTISED_Pause) 73 if (advertise & ADVERTISED_Pause)
74 adv |= ADVERTISE_PAUSE_CAP; 74 adv |= ADVERTISE_PAUSE_CAP;
75 if (advertise & ADVERTISED_Asym_Pause) 75 if (advertise & ADVERTISED_Asym_Pause)
76 adv |= ADVERTISE_PAUSE_ASYM; 76 adv |= ADVERTISE_PAUSE_ASYM;
77 77
78 if (adv != oldadv) { 78 if (adv != oldadv) {
79 err = phy_write(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE, adv); 79 err = phy_write(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE, adv);
80 80
81 if (err < 0) 81 if (err < 0)
82 return err; 82 return err;
83 changed = 1; 83 changed = 1;
84 } 84 }
85 85
86 /* Configure gigabit if it's supported */ 86 /* Configure gigabit if it's supported */
87 if (phydev->supported & (SUPPORTED_1000baseT_Half | 87 if (phydev->supported & (SUPPORTED_1000baseT_Half |
88 SUPPORTED_1000baseT_Full)) { 88 SUPPORTED_1000baseT_Full)) {
89 oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000); 89 oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
90 90
91 if (adv < 0) 91 if (adv < 0)
92 return adv; 92 return adv;
93 93
94 adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); 94 adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
95 if (advertise & SUPPORTED_1000baseT_Half) 95 if (advertise & SUPPORTED_1000baseT_Half)
96 adv |= ADVERTISE_1000HALF; 96 adv |= ADVERTISE_1000HALF;
97 if (advertise & SUPPORTED_1000baseT_Full) 97 if (advertise & SUPPORTED_1000baseT_Full)
98 adv |= ADVERTISE_1000FULL; 98 adv |= ADVERTISE_1000FULL;
99 99
100 if (adv != oldadv) { 100 if (adv != oldadv) {
101 err = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, 101 err = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000,
102 adv); 102 adv);
103 103
104 if (err < 0) 104 if (err < 0)
105 return err; 105 return err;
106 changed = 1; 106 changed = 1;
107 } 107 }
108 } 108 }
109 109
110 return changed; 110 return changed;
111 } 111 }
112 112
113 113
114 /** 114 /**
115 * genphy_setup_forced - configures/forces speed/duplex from @phydev 115 * genphy_setup_forced - configures/forces speed/duplex from @phydev
116 * @phydev: target phy_device struct 116 * @phydev: target phy_device struct
117 * 117 *
118 * Description: Configures MII_BMCR to force speed/duplex 118 * Description: Configures MII_BMCR to force speed/duplex
119 * to the values in phydev. Assumes that the values are valid. 119 * to the values in phydev. Assumes that the values are valid.
120 */ 120 */
121 int genphy_setup_forced(struct phy_device *phydev) 121 int genphy_setup_forced(struct phy_device *phydev)
122 { 122 {
123 int err; 123 int err;
124 int ctl = 0; 124 int ctl = 0;
125 125
126 phydev->pause = phydev->asym_pause = 0; 126 phydev->pause = phydev->asym_pause = 0;
127 127
128 if (SPEED_1000 == phydev->speed) 128 if (SPEED_1000 == phydev->speed)
129 ctl |= BMCR_SPEED1000; 129 ctl |= BMCR_SPEED1000;
130 else if (SPEED_100 == phydev->speed) 130 else if (SPEED_100 == phydev->speed)
131 ctl |= BMCR_SPEED100; 131 ctl |= BMCR_SPEED100;
132 132
133 if (DUPLEX_FULL == phydev->duplex) 133 if (DUPLEX_FULL == phydev->duplex)
134 ctl |= BMCR_FULLDPLX; 134 ctl |= BMCR_FULLDPLX;
135 135
136 err = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl); 136 err = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
137 137
138 return err; 138 return err;
139 } 139 }
140 140
141 141
142 /** 142 /**
143 * genphy_restart_aneg - Enable and Restart Autonegotiation 143 * genphy_restart_aneg - Enable and Restart Autonegotiation
144 * @phydev: target phy_device struct 144 * @phydev: target phy_device struct
145 */ 145 */
146 int genphy_restart_aneg(struct phy_device *phydev) 146 int genphy_restart_aneg(struct phy_device *phydev)
147 { 147 {
148 int ctl; 148 int ctl;
149 149
150 ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); 150 ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
151 151
152 if (ctl < 0) 152 if (ctl < 0)
153 return ctl; 153 return ctl;
154 154
155 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); 155 ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
156 156
157 /* Don't isolate the PHY if we're negotiating */ 157 /* Don't isolate the PHY if we're negotiating */
158 ctl &= ~(BMCR_ISOLATE); 158 ctl &= ~(BMCR_ISOLATE);
159 159
160 ctl = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl); 160 ctl = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
161 161
162 return ctl; 162 return ctl;
163 } 163 }
164 164
165 165
166 /** 166 /**
167 * genphy_config_aneg - restart auto-negotiation or write BMCR 167 * genphy_config_aneg - restart auto-negotiation or write BMCR
168 * @phydev: target phy_device struct 168 * @phydev: target phy_device struct
169 * 169 *
170 * Description: If auto-negotiation is enabled, we configure the 170 * Description: If auto-negotiation is enabled, we configure the
171 * advertising, and then restart auto-negotiation. If it is not 171 * advertising, and then restart auto-negotiation. If it is not
172 * enabled, then we write the BMCR. 172 * enabled, then we write the BMCR.
173 */ 173 */
174 int genphy_config_aneg(struct phy_device *phydev) 174 int genphy_config_aneg(struct phy_device *phydev)
175 { 175 {
176 int result; 176 int result;
177 177
178 if (AUTONEG_ENABLE != phydev->autoneg) 178 if (AUTONEG_ENABLE != phydev->autoneg)
179 return genphy_setup_forced(phydev); 179 return genphy_setup_forced(phydev);
180 180
181 result = genphy_config_advert(phydev); 181 result = genphy_config_advert(phydev);
182 182
183 if (result < 0) /* error */ 183 if (result < 0) /* error */
184 return result; 184 return result;
185 185
186 if (result == 0) { 186 if (result == 0) {
187 /* Advertisment hasn't changed, but maybe aneg was never on to 187 /* Advertisment hasn't changed, but maybe aneg was never on to
188 * begin with? Or maybe phy was isolated? */ 188 * begin with? Or maybe phy was isolated? */
189 int ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); 189 int ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
190 190
191 if (ctl < 0) 191 if (ctl < 0)
192 return ctl; 192 return ctl;
193 193
194 if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE)) 194 if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
195 result = 1; /* do restart aneg */ 195 result = 1; /* do restart aneg */
196 } 196 }
197 197
198 /* Only restart aneg if we are advertising something different 198 /* Only restart aneg if we are advertising something different
199 * than we were before. */ 199 * than we were before. */
200 if (result > 0) 200 if (result > 0)
201 result = genphy_restart_aneg(phydev); 201 result = genphy_restart_aneg(phydev);
202 202
203 return result; 203 return result;
204 } 204 }
205 205
206 /** 206 /**
207 * genphy_update_link - update link status in @phydev 207 * genphy_update_link - update link status in @phydev
208 * @phydev: target phy_device struct 208 * @phydev: target phy_device struct
209 * 209 *
210 * Description: Update the value in phydev->link to reflect the 210 * Description: Update the value in phydev->link to reflect the
211 * current link value. In order to do this, we need to read 211 * current link value. In order to do this, we need to read
212 * the status register twice, keeping the second value. 212 * the status register twice, keeping the second value.
213 */ 213 */
214 int genphy_update_link(struct phy_device *phydev) 214 int genphy_update_link(struct phy_device *phydev)
215 { 215 {
216 unsigned int mii_reg; 216 unsigned int mii_reg;
217 217
218 /* 218 /*
219 * Wait if the link is up, and autonegotiation is in progress 219 * Wait if the link is up, and autonegotiation is in progress
220 * (ie - we're capable and it's not done) 220 * (ie - we're capable and it's not done)
221 */ 221 */
222 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); 222 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
223 223
224 /* 224 /*
225 * If we already saw the link up, and it hasn't gone down, then 225 * If we already saw the link up, and it hasn't gone down, then
226 * we don't need to wait for autoneg again 226 * we don't need to wait for autoneg again
227 */ 227 */
228 if (phydev->link && mii_reg & BMSR_LSTATUS) 228 if (phydev->link && mii_reg & BMSR_LSTATUS)
229 return 0; 229 return 0;
230 230
231 if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) { 231 if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
232 int i = 0; 232 int i = 0;
233 233
234 printf("%s Waiting for PHY auto negotiation to complete", 234 printf("%s Waiting for PHY auto negotiation to complete",
235 phydev->dev->name); 235 phydev->dev->name);
236 while (!(mii_reg & BMSR_ANEGCOMPLETE)) { 236 while (!(mii_reg & BMSR_ANEGCOMPLETE)) {
237 /* 237 /*
238 * Timeout reached ? 238 * Timeout reached ?
239 */ 239 */
240 if (i > PHY_ANEG_TIMEOUT) { 240 if (i > PHY_ANEG_TIMEOUT) {
241 printf(" TIMEOUT !\n"); 241 printf(" TIMEOUT !\n");
242 phydev->link = 0; 242 phydev->link = 0;
243 return 0; 243 return 0;
244 } 244 }
245 245
246 if (ctrlc()) { 246 if (ctrlc()) {
247 puts("user interrupt!\n"); 247 puts("user interrupt!\n");
248 phydev->link = 0; 248 phydev->link = 0;
249 return -EINTR; 249 return -EINTR;
250 } 250 }
251 251
252 if ((i++ % 500) == 0) 252 if ((i++ % 500) == 0)
253 printf("."); 253 printf(".");
254 254
255 udelay(1000); /* 1 ms */ 255 udelay(1000); /* 1 ms */
256 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); 256 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
257 } 257 }
258 printf(" done\n"); 258 printf(" done\n");
259 phydev->link = 1; 259 phydev->link = 1;
260 } else { 260 } else {
261 /* Read the link a second time to clear the latched state */ 261 /* Read the link a second time to clear the latched state */
262 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); 262 mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
263 263
264 if (mii_reg & BMSR_LSTATUS) 264 if (mii_reg & BMSR_LSTATUS)
265 phydev->link = 1; 265 phydev->link = 1;
266 else 266 else
267 phydev->link = 0; 267 phydev->link = 0;
268 } 268 }
269 269
270 return 0; 270 return 0;
271 } 271 }
272 272
273 /* 273 /*
274 * Generic function which updates the speed and duplex. If 274 * Generic function which updates the speed and duplex. If
275 * autonegotiation is enabled, it uses the AND of the link 275 * autonegotiation is enabled, it uses the AND of the link
276 * partner's advertised capabilities and our advertised 276 * partner's advertised capabilities and our advertised
277 * capabilities. If autonegotiation is disabled, we use the 277 * capabilities. If autonegotiation is disabled, we use the
278 * appropriate bits in the control register. 278 * appropriate bits in the control register.
279 * 279 *
280 * Stolen from Linux's mii.c and phy_device.c 280 * Stolen from Linux's mii.c and phy_device.c
281 */ 281 */
282 static int genphy_parse_link(struct phy_device *phydev) 282 static int genphy_parse_link(struct phy_device *phydev)
283 { 283 {
284 int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); 284 int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
285 285
286 /* We're using autonegotiation */ 286 /* We're using autonegotiation */
287 if (mii_reg & BMSR_ANEGCAPABLE) { 287 if (mii_reg & BMSR_ANEGCAPABLE) {
288 u32 lpa = 0; 288 u32 lpa = 0;
289 u32 gblpa = 0; 289 u32 gblpa = 0;
290 290
291 /* Check for gigabit capability */ 291 /* Check for gigabit capability */
292 if (mii_reg & BMSR_ERCAP) { 292 if (mii_reg & BMSR_ERCAP) {
293 /* We want a list of states supported by 293 /* We want a list of states supported by
294 * both PHYs in the link 294 * both PHYs in the link
295 */ 295 */
296 gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000); 296 gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
297 gblpa &= phy_read(phydev, 297 gblpa &= phy_read(phydev,
298 MDIO_DEVAD_NONE, MII_CTRL1000) << 2; 298 MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
299 } 299 }
300 300
301 /* Set the baseline so we only have to set them 301 /* Set the baseline so we only have to set them
302 * if they're different 302 * if they're different
303 */ 303 */
304 phydev->speed = SPEED_10; 304 phydev->speed = SPEED_10;
305 phydev->duplex = DUPLEX_HALF; 305 phydev->duplex = DUPLEX_HALF;
306 306
307 /* Check the gigabit fields */ 307 /* Check the gigabit fields */
308 if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) { 308 if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
309 phydev->speed = SPEED_1000; 309 phydev->speed = SPEED_1000;
310 310
311 if (gblpa & PHY_1000BTSR_1000FD) 311 if (gblpa & PHY_1000BTSR_1000FD)
312 phydev->duplex = DUPLEX_FULL; 312 phydev->duplex = DUPLEX_FULL;
313 313
314 /* We're done! */ 314 /* We're done! */
315 return 0; 315 return 0;
316 } 316 }
317 317
318 lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE); 318 lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
319 lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA); 319 lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
320 320
321 if (lpa & (LPA_100FULL | LPA_100HALF)) { 321 if (lpa & (LPA_100FULL | LPA_100HALF)) {
322 phydev->speed = SPEED_100; 322 phydev->speed = SPEED_100;
323 323
324 if (lpa & LPA_100FULL) 324 if (lpa & LPA_100FULL)
325 phydev->duplex = DUPLEX_FULL; 325 phydev->duplex = DUPLEX_FULL;
326 326
327 } else if (lpa & LPA_10FULL) 327 } else if (lpa & LPA_10FULL)
328 phydev->duplex = DUPLEX_FULL; 328 phydev->duplex = DUPLEX_FULL;
329 } else { 329 } else {
330 u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); 330 u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
331 331
332 phydev->speed = SPEED_10; 332 phydev->speed = SPEED_10;
333 phydev->duplex = DUPLEX_HALF; 333 phydev->duplex = DUPLEX_HALF;
334 334
335 if (bmcr & BMCR_FULLDPLX) 335 if (bmcr & BMCR_FULLDPLX)
336 phydev->duplex = DUPLEX_FULL; 336 phydev->duplex = DUPLEX_FULL;
337 337
338 if (bmcr & BMCR_SPEED1000) 338 if (bmcr & BMCR_SPEED1000)
339 phydev->speed = SPEED_1000; 339 phydev->speed = SPEED_1000;
340 else if (bmcr & BMCR_SPEED100) 340 else if (bmcr & BMCR_SPEED100)
341 phydev->speed = SPEED_100; 341 phydev->speed = SPEED_100;
342 } 342 }
343 343
344 return 0; 344 return 0;
345 } 345 }
346 346
347 int genphy_config(struct phy_device *phydev) 347 int genphy_config(struct phy_device *phydev)
348 { 348 {
349 int val; 349 int val;
350 u32 features; 350 u32 features;
351 351
352 /* For now, I'll claim that the generic driver supports 352 /* For now, I'll claim that the generic driver supports
353 * all possible port types */ 353 * all possible port types */
354 features = (SUPPORTED_TP | SUPPORTED_MII 354 features = (SUPPORTED_TP | SUPPORTED_MII
355 | SUPPORTED_AUI | SUPPORTED_FIBRE | 355 | SUPPORTED_AUI | SUPPORTED_FIBRE |
356 SUPPORTED_BNC); 356 SUPPORTED_BNC);
357 357
358 /* Do we support autonegotiation? */ 358 /* Do we support autonegotiation? */
359 val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); 359 val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
360 360
361 if (val < 0) 361 if (val < 0)
362 return val; 362 return val;
363 363
364 if (val & BMSR_ANEGCAPABLE) 364 if (val & BMSR_ANEGCAPABLE)
365 features |= SUPPORTED_Autoneg; 365 features |= SUPPORTED_Autoneg;
366 366
367 if (val & BMSR_100FULL) 367 if (val & BMSR_100FULL)
368 features |= SUPPORTED_100baseT_Full; 368 features |= SUPPORTED_100baseT_Full;
369 if (val & BMSR_100HALF) 369 if (val & BMSR_100HALF)
370 features |= SUPPORTED_100baseT_Half; 370 features |= SUPPORTED_100baseT_Half;
371 if (val & BMSR_10FULL) 371 if (val & BMSR_10FULL)
372 features |= SUPPORTED_10baseT_Full; 372 features |= SUPPORTED_10baseT_Full;
373 if (val & BMSR_10HALF) 373 if (val & BMSR_10HALF)
374 features |= SUPPORTED_10baseT_Half; 374 features |= SUPPORTED_10baseT_Half;
375 375
376 if (val & BMSR_ESTATEN) { 376 if (val & BMSR_ESTATEN) {
377 val = phy_read(phydev, MDIO_DEVAD_NONE, MII_ESTATUS); 377 val = phy_read(phydev, MDIO_DEVAD_NONE, MII_ESTATUS);
378 378
379 if (val < 0) 379 if (val < 0)
380 return val; 380 return val;
381 381
382 if (val & ESTATUS_1000_TFULL) 382 if (val & ESTATUS_1000_TFULL)
383 features |= SUPPORTED_1000baseT_Full; 383 features |= SUPPORTED_1000baseT_Full;
384 if (val & ESTATUS_1000_THALF) 384 if (val & ESTATUS_1000_THALF)
385 features |= SUPPORTED_1000baseT_Half; 385 features |= SUPPORTED_1000baseT_Half;
386 } 386 }
387 387
388 phydev->supported = features; 388 phydev->supported = features;
389 phydev->advertising = features; 389 phydev->advertising = features;
390 390
391 genphy_config_aneg(phydev); 391 genphy_config_aneg(phydev);
392 392
393 return 0; 393 return 0;
394 } 394 }
395 395
396 int genphy_startup(struct phy_device *phydev) 396 int genphy_startup(struct phy_device *phydev)
397 { 397 {
398 genphy_update_link(phydev); 398 genphy_update_link(phydev);
399 genphy_parse_link(phydev); 399 genphy_parse_link(phydev);
400 400
401 return 0; 401 return 0;
402 } 402 }
403 403
404 int genphy_shutdown(struct phy_device *phydev) 404 int genphy_shutdown(struct phy_device *phydev)
405 { 405 {
406 return 0; 406 return 0;
407 } 407 }
408 408
409 static struct phy_driver genphy_driver = { 409 static struct phy_driver genphy_driver = {
410 .uid = 0xffffffff, 410 .uid = 0xffffffff,
411 .mask = 0xffffffff, 411 .mask = 0xffffffff,
412 .name = "Generic PHY", 412 .name = "Generic PHY",
413 .features = 0, 413 .features = 0,
414 .config = genphy_config, 414 .config = genphy_config,
415 .startup = genphy_startup, 415 .startup = genphy_startup,
416 .shutdown = genphy_shutdown, 416 .shutdown = genphy_shutdown,
417 }; 417 };
418 418
419 static LIST_HEAD(phy_drivers); 419 static LIST_HEAD(phy_drivers);
420 420
421 int phy_init(void) 421 int phy_init(void)
422 { 422 {
423 #ifdef CONFIG_PHY_ATHEROS 423 #ifdef CONFIG_PHY_ATHEROS
424 phy_atheros_init(); 424 phy_atheros_init();
425 #endif 425 #endif
426 #ifdef CONFIG_PHY_BROADCOM 426 #ifdef CONFIG_PHY_BROADCOM
427 phy_broadcom_init(); 427 phy_broadcom_init();
428 #endif 428 #endif
429 #ifdef CONFIG_PHY_DAVICOM 429 #ifdef CONFIG_PHY_DAVICOM
430 phy_davicom_init(); 430 phy_davicom_init();
431 #endif 431 #endif
432 #ifdef CONFIG_PHY_LXT 432 #ifdef CONFIG_PHY_LXT
433 phy_lxt_init(); 433 phy_lxt_init();
434 #endif 434 #endif
435 #ifdef CONFIG_PHY_MARVELL 435 #ifdef CONFIG_PHY_MARVELL
436 phy_marvell_init(); 436 phy_marvell_init();
437 #endif 437 #endif
438 #ifdef CONFIG_PHY_MICREL 438 #ifdef CONFIG_PHY_MICREL
439 phy_micrel_init(); 439 phy_micrel_init();
440 #endif 440 #endif
441 #ifdef CONFIG_PHY_NATSEMI 441 #ifdef CONFIG_PHY_NATSEMI
442 phy_natsemi_init(); 442 phy_natsemi_init();
443 #endif 443 #endif
444 #ifdef CONFIG_PHY_REALTEK 444 #ifdef CONFIG_PHY_REALTEK
445 phy_realtek_init(); 445 phy_realtek_init();
446 #endif 446 #endif
447 #ifdef CONFIG_PHY_SMSC 447 #ifdef CONFIG_PHY_SMSC
448 phy_smsc_init(); 448 phy_smsc_init();
449 #endif 449 #endif
450 #ifdef CONFIG_PHY_TERANETICS 450 #ifdef CONFIG_PHY_TERANETICS
451 phy_teranetics_init(); 451 phy_teranetics_init();
452 #endif 452 #endif
453 #ifdef CONFIG_PHY_VITESSE 453 #ifdef CONFIG_PHY_VITESSE
454 phy_vitesse_init(); 454 phy_vitesse_init();
455 #endif 455 #endif
456 456
457 return 0; 457 return 0;
458 } 458 }
459 459
460 int phy_register(struct phy_driver *drv) 460 int phy_register(struct phy_driver *drv)
461 { 461 {
462 INIT_LIST_HEAD(&drv->list); 462 INIT_LIST_HEAD(&drv->list);
463 list_add_tail(&drv->list, &phy_drivers); 463 list_add_tail(&drv->list, &phy_drivers);
464 464
465 return 0; 465 return 0;
466 } 466 }
467 467
468 int phy_probe(struct phy_device *phydev) 468 int phy_probe(struct phy_device *phydev)
469 { 469 {
470 int err = 0; 470 int err = 0;
471 471
472 phydev->advertising = phydev->supported = phydev->drv->features; 472 phydev->advertising = phydev->supported = phydev->drv->features;
473 phydev->mmds = phydev->drv->mmds; 473 phydev->mmds = phydev->drv->mmds;
474 474
475 if (phydev->drv->probe) 475 if (phydev->drv->probe)
476 err = phydev->drv->probe(phydev); 476 err = phydev->drv->probe(phydev);
477 477
478 return err; 478 return err;
479 } 479 }
480 480
481 static struct phy_driver *generic_for_interface(phy_interface_t interface) 481 static struct phy_driver *generic_for_interface(phy_interface_t interface)
482 { 482 {
483 #ifdef CONFIG_PHYLIB_10G 483 #ifdef CONFIG_PHYLIB_10G
484 if (is_10g_interface(interface)) 484 if (is_10g_interface(interface))
485 return &gen10g_driver; 485 return &gen10g_driver;
486 #endif 486 #endif
487 487
488 return &genphy_driver; 488 return &genphy_driver;
489 } 489 }
490 490
491 struct phy_driver *get_phy_driver(struct phy_device *phydev, 491 struct phy_driver *get_phy_driver(struct phy_device *phydev,
492 phy_interface_t interface) 492 phy_interface_t interface)
493 { 493 {
494 struct list_head *entry; 494 struct list_head *entry;
495 int phy_id = phydev->phy_id; 495 int phy_id = phydev->phy_id;
496 struct phy_driver *drv = NULL; 496 struct phy_driver *drv = NULL;
497 497
498 list_for_each(entry, &phy_drivers) { 498 list_for_each(entry, &phy_drivers) {
499 drv = list_entry(entry, struct phy_driver, list); 499 drv = list_entry(entry, struct phy_driver, list);
500 if ((drv->uid & drv->mask) == (phy_id & drv->mask)) 500 if ((drv->uid & drv->mask) == (phy_id & drv->mask))
501 return drv; 501 return drv;
502 } 502 }
503 503
504 /* If we made it here, there's no driver for this PHY */ 504 /* If we made it here, there's no driver for this PHY */
505 return generic_for_interface(interface); 505 return generic_for_interface(interface);
506 } 506 }
507 507
508 struct phy_device *phy_device_create(struct mii_dev *bus, int addr, int phy_id, 508 struct phy_device *phy_device_create(struct mii_dev *bus, int addr, int phy_id,
509 phy_interface_t interface) 509 phy_interface_t interface)
510 { 510 {
511 struct phy_device *dev; 511 struct phy_device *dev;
512 512
513 /* We allocate the device, and initialize the 513 /* We allocate the device, and initialize the
514 * default values */ 514 * default values */
515 dev = malloc(sizeof(*dev)); 515 dev = malloc(sizeof(*dev));
516 if (!dev) { 516 if (!dev) {
517 printf("Failed to allocate PHY device for %s:%d\n", 517 printf("Failed to allocate PHY device for %s:%d\n",
518 bus->name, addr); 518 bus->name, addr);
519 return NULL; 519 return NULL;
520 } 520 }
521 521
522 memset(dev, 0, sizeof(*dev)); 522 memset(dev, 0, sizeof(*dev));
523 523
524 dev->duplex = -1; 524 dev->duplex = -1;
525 dev->link = 1; 525 dev->link = 1;
526 dev->interface = interface; 526 dev->interface = interface;
527 527
528 dev->autoneg = AUTONEG_ENABLE; 528 dev->autoneg = AUTONEG_ENABLE;
529 529
530 dev->addr = addr; 530 dev->addr = addr;
531 dev->phy_id = phy_id; 531 dev->phy_id = phy_id;
532 dev->bus = bus; 532 dev->bus = bus;
533 533
534 dev->drv = get_phy_driver(dev, interface); 534 dev->drv = get_phy_driver(dev, interface);
535 535
536 phy_probe(dev); 536 phy_probe(dev);
537 537
538 bus->phymap[addr] = dev; 538 bus->phymap[addr] = dev;
539 539
540 return dev; 540 return dev;
541 } 541 }
542 542
543 /** 543 /**
544 * get_phy_id - reads the specified addr for its ID. 544 * get_phy_id - reads the specified addr for its ID.
545 * @bus: the target MII bus 545 * @bus: the target MII bus
546 * @addr: PHY address on the MII bus 546 * @addr: PHY address on the MII bus
547 * @phy_id: where to store the ID retrieved. 547 * @phy_id: where to store the ID retrieved.
548 * 548 *
549 * Description: Reads the ID registers of the PHY at @addr on the 549 * Description: Reads the ID registers of the PHY at @addr on the
550 * @bus, stores it in @phy_id and returns zero on success. 550 * @bus, stores it in @phy_id and returns zero on success.
551 */ 551 */
552 int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id) 552 int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
553 { 553 {
554 int phy_reg; 554 int phy_reg;
555 555
556 /* Grab the bits from PHYIR1, and put them 556 /* Grab the bits from PHYIR1, and put them
557 * in the upper half */ 557 * in the upper half */
558 phy_reg = bus->read(bus, addr, devad, MII_PHYSID1); 558 phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
559 559
560 if (phy_reg < 0) 560 if (phy_reg < 0)
561 return -EIO; 561 return -EIO;
562 562
563 *phy_id = (phy_reg & 0xffff) << 16; 563 *phy_id = (phy_reg & 0xffff) << 16;
564 564
565 /* Grab the bits from PHYIR2, and put them in the lower half */ 565 /* Grab the bits from PHYIR2, and put them in the lower half */
566 phy_reg = bus->read(bus, addr, devad, MII_PHYSID2); 566 phy_reg = bus->read(bus, addr, devad, MII_PHYSID2);
567 567
568 if (phy_reg < 0) 568 if (phy_reg < 0)
569 return -EIO; 569 return -EIO;
570 570
571 *phy_id |= (phy_reg & 0xffff); 571 *phy_id |= (phy_reg & 0xffff);
572 572
573 return 0; 573 return 0;
574 } 574 }
575 575
576 /** 576 /**
577 * get_phy_device - reads the specified PHY device and returns its @phy_device struct 577 * get_phy_device - reads the specified PHY device and returns its @phy_device struct
578 * @bus: the target MII bus 578 * @bus: the target MII bus
579 * @addr: PHY address on the MII bus 579 * @addr: PHY address on the MII bus
580 * 580 *
581 * Description: Reads the ID registers of the PHY at @addr on the 581 * Description: Reads the ID registers of the PHY at @addr on the
582 * @bus, then allocates and returns the phy_device to represent it. 582 * @bus, then allocates and returns the phy_device to represent it.
583 */ 583 */
584 struct phy_device *get_phy_device(struct mii_dev *bus, int addr, 584 struct phy_device *get_phy_device(struct mii_dev *bus, int addr,
585 phy_interface_t interface) 585 phy_interface_t interface)
586 { 586 {
587 u32 phy_id = 0x1fffffff; 587 u32 phy_id = 0x1fffffff;
588 int i; 588 int i;
589 int r; 589 int r;
590 590
591 /* If we have one, return the existing device, with new interface */ 591 /* If we have one, return the existing device, with new interface */
592 if (bus->phymap[addr]) { 592 if (bus->phymap[addr]) {
593 bus->phymap[addr]->interface = interface; 593 bus->phymap[addr]->interface = interface;
594 594
595 return bus->phymap[addr]; 595 return bus->phymap[addr];
596 } 596 }
597 597
598 /* Try Standard (ie Clause 22) access */ 598 /* Try Standard (ie Clause 22) access */
599 r = get_phy_id(bus, addr, MDIO_DEVAD_NONE, &phy_id); 599 r = get_phy_id(bus, addr, MDIO_DEVAD_NONE, &phy_id);
600 if (r) 600 if (r)
601 return NULL; 601 return NULL;
602 602
603 /* If the PHY ID is mostly f's, we didn't find anything */ 603 /* If the PHY ID is mostly f's, we didn't find anything */
604 if ((phy_id & 0x1fffffff) != 0x1fffffff) 604 if ((phy_id & 0x1fffffff) != 0x1fffffff)
605 return phy_device_create(bus, addr, phy_id, interface); 605 return phy_device_create(bus, addr, phy_id, interface);
606 606
607 /* Otherwise we have to try Clause 45 */ 607 /* Otherwise we have to try Clause 45 */
608 for (i = 1; i < 5; i++) { 608 for (i = 1; i < 5; i++) {
609 r = get_phy_id(bus, addr, i, &phy_id); 609 r = get_phy_id(bus, addr, i, &phy_id);
610 if (r) 610 if (r)
611 return NULL; 611 return NULL;
612 612
613 /* If the phy_id is mostly Fs, there is no device there */ 613 /* If the phy_id is mostly Fs, there is no device there */
614 if ((phy_id & 0x1fffffff) != 0x1fffffff) 614 if ((phy_id & 0x1fffffff) != 0x1fffffff)
615 break; 615 break;
616 } 616 }
617 617
618 return phy_device_create(bus, addr, phy_id, interface); 618 return phy_device_create(bus, addr, phy_id, interface);
619 } 619 }
620 620
621 int phy_reset(struct phy_device *phydev) 621 int phy_reset(struct phy_device *phydev)
622 { 622 {
623 int reg; 623 int reg;
624 int timeout = 500; 624 int timeout = 500;
625 int devad = MDIO_DEVAD_NONE; 625 int devad = MDIO_DEVAD_NONE;
626 626
627 #ifdef CONFIG_PHYLIB_10G 627 #ifdef CONFIG_PHYLIB_10G
628 /* If it's 10G, we need to issue reset through one of the MMDs */ 628 /* If it's 10G, we need to issue reset through one of the MMDs */
629 if (is_10g_interface(phydev->interface)) { 629 if (is_10g_interface(phydev->interface)) {
630 if (!phydev->mmds) 630 if (!phydev->mmds)
631 gen10g_discover_mmds(phydev); 631 gen10g_discover_mmds(phydev);
632 632
633 devad = ffs(phydev->mmds) - 1; 633 devad = ffs(phydev->mmds) - 1;
634 } 634 }
635 #endif 635 #endif
636 636
637 reg = phy_read(phydev, devad, MII_BMCR); 637 reg = phy_read(phydev, devad, MII_BMCR);
638 if (reg < 0) { 638 if (reg < 0) {
639 debug("PHY status read failed\n"); 639 debug("PHY status read failed\n");
640 return -1; 640 return -1;
641 } 641 }
642 642
643 reg |= BMCR_RESET; 643 reg |= BMCR_RESET;
644 644
645 if (phy_write(phydev, devad, MII_BMCR, reg) < 0) { 645 if (phy_write(phydev, devad, MII_BMCR, reg) < 0) {
646 debug("PHY reset failed\n"); 646 debug("PHY reset failed\n");
647 return -1; 647 return -1;
648 } 648 }
649 649
650 #ifdef CONFIG_PHY_RESET_DELAY 650 #ifdef CONFIG_PHY_RESET_DELAY
651 udelay(CONFIG_PHY_RESET_DELAY); /* Intel LXT971A needs this */ 651 udelay(CONFIG_PHY_RESET_DELAY); /* Intel LXT971A needs this */
652 #endif 652 #endif
653 /* 653 /*
654 * Poll the control register for the reset bit to go to 0 (it is 654 * Poll the control register for the reset bit to go to 0 (it is
655 * auto-clearing). This should happen within 0.5 seconds per the 655 * auto-clearing). This should happen within 0.5 seconds per the
656 * IEEE spec. 656 * IEEE spec.
657 */ 657 */
658 while ((reg & BMCR_RESET) && timeout--) { 658 while ((reg & BMCR_RESET) && timeout--) {
659 reg = phy_read(phydev, devad, MII_BMCR); 659 reg = phy_read(phydev, devad, MII_BMCR);
660 660
661 if (reg < 0) { 661 if (reg < 0) {
662 debug("PHY status read failed\n"); 662 debug("PHY status read failed\n");
663 return -1; 663 return -1;
664 } 664 }
665 udelay(1000); 665 udelay(1000);
666 } 666 }
667 667
668 if (reg & BMCR_RESET) { 668 if (reg & BMCR_RESET) {
669 puts("PHY reset timed out\n"); 669 puts("PHY reset timed out\n");
670 return -1; 670 return -1;
671 } 671 }
672 672
673 return 0; 673 return 0;
674 } 674 }
675 675
676 int miiphy_reset(const char *devname, unsigned char addr) 676 int miiphy_reset(const char *devname, unsigned char addr)
677 { 677 {
678 struct mii_dev *bus = miiphy_get_dev_by_name(devname); 678 struct mii_dev *bus = miiphy_get_dev_by_name(devname);
679 struct phy_device *phydev; 679 struct phy_device *phydev;
680 680
681 /* 681 /*
682 * miiphy_reset was only used on standard PHYs, so we'll fake it here. 682 * miiphy_reset was only used on standard PHYs, so we'll fake it here.
683 * If later code tries to connect with the right interface, this will 683 * If later code tries to connect with the right interface, this will
684 * be corrected by get_phy_device in phy_connect() 684 * be corrected by get_phy_device in phy_connect()
685 */ 685 */
686 phydev = get_phy_device(bus, addr, PHY_INTERFACE_MODE_MII); 686 phydev = get_phy_device(bus, addr, PHY_INTERFACE_MODE_MII);
687 687
688 return phy_reset(phydev); 688 return phy_reset(phydev);
689 } 689 }
690 690
691 struct phy_device *phy_connect(struct mii_dev *bus, int addr, 691 struct phy_device *phy_connect(struct mii_dev *bus, int addr,
692 struct eth_device *dev, 692 struct eth_device *dev,
693 phy_interface_t interface) 693 phy_interface_t interface)
694 { 694 {
695 struct phy_device *phydev; 695 struct phy_device *phydev;
696 696
697 /* Reset the bus */ 697 /* Reset the bus */
698 if (bus->reset) 698 if (bus->reset)
699 bus->reset(bus); 699 bus->reset(bus);
700 700
701 /* Wait 15ms to make sure the PHY has come out of hard reset */ 701 /* Wait 15ms to make sure the PHY has come out of hard reset */
702 udelay(15000); 702 udelay(15000);
703 703
704 phydev = get_phy_device(bus, addr, interface); 704 phydev = get_phy_device(bus, addr, interface);
705 705
706 if (!phydev) { 706 if (!phydev) {
707 printf("Could not get PHY for %s:%d\n", bus->name, addr); 707 printf("Could not get PHY for %s:%d\n", bus->name, addr);
708 708
709 return NULL; 709 return NULL;
710 } 710 }
711 711
712 /* Soft Reset the PHY */ 712 /* Soft Reset the PHY */
713 phy_reset(phydev); 713 phy_reset(phydev);
714 714
715 if (phydev->dev) 715 if (phydev->dev)
716 printf("%s:%d is connected to %s. Reconnecting to %s\n", 716 printf("%s:%d is connected to %s. Reconnecting to %s\n",
717 bus->name, addr, phydev->dev->name, dev->name); 717 bus->name, addr, phydev->dev->name, dev->name);
718 718
719 phydev->dev = dev; 719 phydev->dev = dev;
720 720
721 debug("%s connected to %s\n", dev->name, phydev->drv->name); 721 debug("%s connected to %s\n", dev->name, phydev->drv->name);
722 722
723 return phydev; 723 return phydev;
724 } 724 }
725 725
726 int phy_startup(struct phy_device *phydev) 726 int phy_startup(struct phy_device *phydev)
727 { 727 {
728 if (phydev->drv->startup) 728 if (phydev->drv->startup)
729 phydev->drv->startup(phydev); 729 phydev->drv->startup(phydev);
730 730
731 return 0; 731 return 0;
732 } 732 }
733 733
734 static int __board_phy_config(struct phy_device *phydev) 734 static int __board_phy_config(struct phy_device *phydev)
735 { 735 {
736 if (phydev->drv->config)
737 return phydev->drv->config(phydev);
736 return 0; 738 return 0;
737 } 739 }
738 740
739 int board_phy_config(struct phy_device *phydev) 741 int board_phy_config(struct phy_device *phydev)
740 __attribute__((weak, alias("__board_phy_config"))); 742 __attribute__((weak, alias("__board_phy_config")));
741 743
742 int phy_config(struct phy_device *phydev) 744 int phy_config(struct phy_device *phydev)
743 { 745 {
744 if (phydev->drv->config)
745 phydev->drv->config(phydev);
746
747 /* Invoke an optional board-specific helper */ 746 /* Invoke an optional board-specific helper */
748 board_phy_config(phydev); 747 board_phy_config(phydev);
749 748
750 return 0; 749 return 0;
751 } 750 }
752 751
753 int phy_shutdown(struct phy_device *phydev) 752 int phy_shutdown(struct phy_device *phydev)
754 { 753 {
755 if (phydev->drv->shutdown) 754 if (phydev->drv->shutdown)
756 phydev->drv->shutdown(phydev); 755 phydev->drv->shutdown(phydev);
757 756
758 return 0; 757 return 0;