]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/lwIP_Demo/lwIP_port/netif/xemacpsif_physpeed.c
440101eeafe86da9f3c4b5b4897e284465da3400
[freertos] / FreeRTOS / Demo / CORTEX_A9_Zynq_ZC702 / RTOSDemo / src / lwIP_Demo / lwIP_port / netif / xemacpsif_physpeed.c
1 /*
2  * Copyright (c) 2007-2008, Advanced Micro Devices, Inc.
3  *               All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  *    * Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions and the following disclaimer.
11  *    * Redistributions in binary form must reproduce the above copyright
12  *      notice, this list of conditions and the following disclaimer in
13  *      the documentation and/or other materials provided with the
14  *      distribution.
15  *    * Neither the name of Advanced Micro Devices, Inc. nor the names
16  *      of its contributors may be used to endorse or promote products
17  *      derived from this software without specific prior written
18  *      permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 /*
34  * Some portions copyright (c) 2010-2013 Xilinx, Inc.  All rights reserved.
35  *
36  * Xilinx, Inc.
37  * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
38  * COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
39  * ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
40  * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
41  * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
42  * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
43  * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
44  * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
45  * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
46  * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
47  * AND FITNESS FOR A PARTICULAR PURPOSE.
48  *
49  */
50
51 #include "netif/xemacpsif.h"
52 #include "lwipopts.h"
53 #include "xparameters_ps.h"
54 #include "xparameters.h"
55
56 /*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
57  *** to run it on a PEEP board
58  ***/
59
60 /* Advertisement control register. */
61 #define ADVERTISE_10HALF                0x0020  /* Try for 10mbps half-duplex  */
62 #define ADVERTISE_10FULL                0x0040  /* Try for 10mbps full-duplex  */
63 #define ADVERTISE_100HALF               0x0080  /* Try for 100mbps half-duplex */
64 #define ADVERTISE_100FULL               0x0100  /* Try for 100mbps full-duplex */
65
66 #define ADVERTISE_100_AND_10    (ADVERTISE_10FULL | ADVERTISE_100FULL | \
67                                                                 ADVERTISE_10HALF | ADVERTISE_100HALF)
68 #define ADVERTISE_100                   (ADVERTISE_100FULL | ADVERTISE_100HALF)
69 #define ADVERTISE_10                    (ADVERTISE_10FULL | ADVERTISE_10HALF)
70
71 #define ADVERTISE_1000                  0x0300
72
73
74 #define IEEE_CONTROL_REG_OFFSET                         0
75 #define IEEE_STATUS_REG_OFFSET                          1
76 #define IEEE_AUTONEGO_ADVERTISE_REG                     4
77 #define IEEE_PARTNER_ABILITIES_1_REG_OFFSET     5
78 #define IEEE_1000_ADVERTISE_REG_OFFSET          9
79 #define IEEE_PARTNER_ABILITIES_3_REG_OFFSET     10
80 #define IEEE_COPPER_SPECIFIC_CONTROL_REG        16
81 #define IEEE_SPECIFIC_STATUS_REG                        17
82 #define IEEE_COPPER_SPECIFIC_STATUS_REG_2       19
83 #define IEEE_CONTROL_REG_MAC                            21
84 #define IEEE_PAGE_ADDRESS_REGISTER                      22
85
86
87 #define IEEE_CTRL_1GBPS_LINKSPEED_MASK          0x2040
88 #define IEEE_CTRL_LINKSPEED_MASK                        0x0040
89 #define IEEE_CTRL_LINKSPEED_1000M                       0x0040
90 #define IEEE_CTRL_LINKSPEED_100M                        0x2000
91 #define IEEE_CTRL_LINKSPEED_10M                         0x0000
92 #define IEEE_CTRL_RESET_MASK                            0x8000
93 #define IEEE_CTRL_AUTONEGOTIATE_ENABLE          0x1000
94 #if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
95 #define IEEE_CTRL_RESET                         0x9140
96 #define IEEE_CTRL_ISOLATE_DISABLE               0xFBFF
97 #endif
98 #define IEEE_STAT_AUTONEGOTIATE_CAPABLE         0x0008
99 #define IEEE_STAT_AUTONEGOTIATE_COMPLETE        0x0020
100 #define IEEE_STAT_AUTONEGOTIATE_RESTART         0x0200
101 #define IEEE_STAT_1GBPS_EXTENSIONS                      0x0100
102 #define IEEE_AN1_ABILITY_MASK                           0x1FE0
103 #define IEEE_AN3_ABILITY_MASK_1GBPS                     0x0C00
104 #define IEEE_AN1_ABILITY_MASK_100MBPS           0x0380
105 #define IEEE_AN1_ABILITY_MASK_10MBPS            0x0060
106 #define IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK      0x0030
107
108 #define IEEE_ASYMMETRIC_PAUSE_MASK                      0x0800
109 #define IEEE_PAUSE_MASK                                         0x0400
110 #define IEEE_AUTONEG_ERROR_MASK                         0x8000
111
112 #define PHY_DETECT_REG  1
113 #define PHY_DETECT_MASK 0x1808
114
115 #define XEMACPS_GMII2RGMII_SPEED1000_FD         0x140
116 #define XEMACPS_GMII2RGMII_SPEED100_FD          0x2100
117 #define XEMACPS_GMII2RGMII_SPEED10_FD           0x100
118 #define XEMACPS_GMII2RGMII_REG_NUM                      0x10
119
120 /* Frequency setting */
121 #define SLCR_LOCK_ADDR                  (XPS_SYS_CTRL_BASEADDR + 0x4)
122 #define SLCR_UNLOCK_ADDR                (XPS_SYS_CTRL_BASEADDR + 0x8)
123 #define SLCR_GEM0_CLK_CTRL_ADDR (XPS_SYS_CTRL_BASEADDR + 0x140)
124 #define SLCR_GEM1_CLK_CTRL_ADDR (XPS_SYS_CTRL_BASEADDR + 0x144)
125 #ifdef PEEP
126 #define SLCR_GEM_10M_CLK_CTRL_VALUE             0x00103031
127 #define SLCR_GEM_100M_CLK_CTRL_VALUE    0x00103001
128 #define SLCR_GEM_1G_CLK_CTRL_VALUE              0x00103011
129 #endif
130 #define SLCR_LOCK_KEY_VALUE                     0x767B
131 #define SLCR_UNLOCK_KEY_VALUE                   0xDF0D
132 #define SLCR_ADDR_GEM_RST_CTRL                  (XPS_SYS_CTRL_BASEADDR + 0x214)
133 #define EMACPS_SLCR_DIV_MASK                    0xFC0FC0FF
134
135 #define EMAC0_BASE_ADDRESS                              0xE000B000
136 #define EMAC1_BASE_ADDRESS                              0xE000C000
137
138 static int detect_phy(XEmacPs *xemacpsp)
139 {
140         u16 phy_reg;
141         u32 phy_addr;
142
143         for (phy_addr = 31; phy_addr > 0; phy_addr--) {
144                 XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_DETECT_REG,
145                                                         &phy_reg);
146
147                 if ((phy_reg != 0xFFFF) &&
148                         ((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
149                         /* Found a valid PHY address */
150                         LWIP_DEBUGF(NETIF_DEBUG, ("XEmacPs detect_phy: PHY detected at address %d.\r\n",
151                                                                                                                                         phy_addr));
152                         LWIP_DEBUGF(NETIF_DEBUG, ("XEmacPs detect_phy: PHY detected.\r\n"));
153                         return phy_addr;
154                 }
155         }
156
157         LWIP_DEBUGF(NETIF_DEBUG, ("XEmacPs detect_phy: No PHY detected.  Assuming a PHY at address 0\r\n"));
158
159         /* default to zero */
160         return 0;
161 }
162
163 #ifdef PEEP
164 unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
165 {
166
167         u16 control;
168         u16 status;
169         u16 partner_capabilities;
170         u16 partner_capabilities_1000;
171         u16 phylinkspeed;
172         u32 phy_addr = detect_phy(xemacpsp);
173
174         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
175                                                                                                                         ADVERTISE_1000);
176         /* Advertise PHY speed of 100 and 10 Mbps */
177         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
178                                                                                                         ADVERTISE_100_AND_10);
179
180         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
181                                                                                                                                 &control);
182         control |= (IEEE_CTRL_AUTONEGOTIATE_ENABLE |
183                                         IEEE_STAT_AUTONEGOTIATE_RESTART);
184
185         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
186
187         /* Read PHY control and status registers is successful. */
188         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
189         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
190
191         if ((control & IEEE_CTRL_AUTONEGOTIATE_ENABLE) && (status &
192                                         IEEE_STAT_AUTONEGOTIATE_CAPABLE)) {
193
194                 while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
195                         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
196                                                                                                                                 &status);
197                 }
198
199                 XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_1_REG_OFFSET,
200                                                                                                                         &partner_capabilities);
201
202                 if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
203                         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_3_REG_OFFSET,
204                                                                                                                 &partner_capabilities_1000);
205                         if (partner_capabilities_1000 & IEEE_AN3_ABILITY_MASK_1GBPS)
206                                 return 1000;
207                 }
208
209                 if (partner_capabilities & IEEE_AN1_ABILITY_MASK_100MBPS)
210                         return 100;
211                 if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
212                         return 10;
213
214                 xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",
215                                 __FUNCTION__);
216                 return 10;
217
218         } else {
219
220                 /* Update TEMAC speed accordingly */
221                 if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
222                         /* Get commanded link speed */
223                         phylinkspeed = control & IEEE_CTRL_1GBPS_LINKSPEED_MASK;
224
225                         switch (phylinkspeed) {
226                                 case (IEEE_CTRL_LINKSPEED_1000M):
227                                         return 1000;
228                                 case (IEEE_CTRL_LINKSPEED_100M):
229                                         return 100;
230                                 case (IEEE_CTRL_LINKSPEED_10M):
231                                         return 10;
232                                 default:
233                                         xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",
234                                                         __FUNCTION__, phylinkspeed);
235                                         return 10;
236                         }
237
238                 } else {
239
240                         return (control & IEEE_CTRL_LINKSPEED_MASK) ? 100 : 10;
241
242                 }
243         }
244 }
245
246 #else /* Zynq */
247 unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
248 {
249         u16 temp;
250         u16 control;
251         u16 status;
252         u16 partner_capabilities;
253 #if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
254         u32 phy_addr = XPAR_PCSPMA_SGMII_PHYADDR;
255 #else
256         u32 phy_addr = detect_phy(xemacpsp);
257 #endif
258         xil_printf("Start PHY autonegotiation \r\n");
259
260 #if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
261 #else
262         XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
263         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
264         control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
265         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
266
267         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
268
269         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
270         control |= IEEE_ASYMMETRIC_PAUSE_MASK;
271         control |= IEEE_PAUSE_MASK;
272         control |= ADVERTISE_100;
273         control |= ADVERTISE_10;
274         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
275
276         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
277                                                                                                                                         &control);
278         control |= ADVERTISE_1000;
279         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
280                                                                                                                                         control);
281
282         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
283         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
284                                                                                                                                 &control);
285         control |= (7 << 12);   /* max number of gigabit attempts */
286         control |= (1 << 11);   /* enable downshift */
287         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
288                                                                                                                                 control);
289 #endif
290         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
291         control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
292         control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
293 #if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
294     control &= IEEE_CTRL_ISOLATE_DISABLE;
295 #endif
296
297         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
298
299
300 #if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
301 #else
302         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
303         control |= IEEE_CTRL_RESET_MASK;
304         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
305
306         while (1) {
307                 XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
308                 if (control & IEEE_CTRL_RESET_MASK)
309                         continue;
310                 else
311                         break;
312         }
313 #endif
314         xil_printf("Waiting for PHY to complete autonegotiation.\r\n");
315
316         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
317         while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
318                 sleep(1);
319 #if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
320 #else
321                 XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
322                                                                                                                                         &temp);
323                 if (temp & IEEE_AUTONEG_ERROR_MASK) {
324                         xil_printf("Auto negotiation error \r\n");
325                 }
326 #endif
327                 XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
328                                                                                                                                 &status);
329                 }
330
331         xil_printf("autonegotiation complete \r\n");
332
333 #if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
334 #else
335         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_SPECIFIC_STATUS_REG, &partner_capabilities);
336 #endif
337
338 #if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
339         xil_printf("Waiting for Link to be up; Polling for SGMII core Reg \r\n");
340         XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
341         while(!(temp & 0x8000)) {
342                 XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
343         }
344         if((temp & 0x0C00) == 0x0800) {
345                 XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
346                 return 1000;
347         }
348         else if((temp & 0x0C00) == 0x0400) {
349                 XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
350                 return 100;
351         }
352         else if((temp & 0x0C00) == 0x0000) {
353                 XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
354                 return 10;
355         } else {
356                 xil_printf("get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\r\n");
357                 XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
358                 XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
359                 return 10;
360         }
361 #else
362         if ( ((partner_capabilities >> 14) & 3) == 2)/* 1000Mbps */
363                 return 1000;
364         else if ( ((partner_capabilities >> 14) & 3) == 1)/* 100Mbps */
365                 return 100;
366         else                                    /* 10Mbps */
367                 return 10;
368 #endif
369 }
370 #endif
371
372 unsigned configure_IEEE_phy_speed(XEmacPs *xemacpsp, unsigned speed)
373 {
374         u16 control;
375         u32 phy_addr = detect_phy(xemacpsp);
376
377         XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
378         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
379         control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
380         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
381
382         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
383
384         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
385         control |= IEEE_ASYMMETRIC_PAUSE_MASK;
386         control |= IEEE_PAUSE_MASK;
387         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
388
389         XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
390         control &= ~IEEE_CTRL_LINKSPEED_1000M;
391         control &= ~IEEE_CTRL_LINKSPEED_100M;
392         control &= ~IEEE_CTRL_LINKSPEED_10M;
393
394         if (speed == 1000) {
395                 control |= IEEE_CTRL_LINKSPEED_1000M;
396         }
397
398         else if (speed == 100) {
399                 control |= IEEE_CTRL_LINKSPEED_100M;
400                 /* Dont advertise PHY speed of 1000 Mbps */
401                 XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, 0);
402                 /* Dont advertise PHY speed of 10 Mbps */
403                 XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
404                                                                                                                                 ADVERTISE_100);
405         }
406
407         else if (speed == 10) {
408                 control |= IEEE_CTRL_LINKSPEED_10M;
409                 /* Dont advertise PHY speed of 1000 Mbps */
410                 XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
411                                                                                                                                                         0);
412                 /* Dont advertise PHY speed of 100 Mbps */
413                 XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
414                                                                                                                                 ADVERTISE_10);
415         }
416
417         XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
418                                                                                         control | IEEE_CTRL_RESET_MASK);
419         {
420                 volatile int wait;
421                 for (wait=0; wait < 100000; wait++);
422         }
423         return 0;
424 }
425
426 static void SetUpSLCRDivisors(int mac_baseaddr, int speed)
427 {
428         volatile u32 slcrBaseAddress;
429 #ifndef PEEP
430         u32 SlcrDiv0;
431         u32 SlcrDiv1=0;
432         u32 SlcrTxClkCntrl;
433 #endif
434
435         *(volatile unsigned int *)(SLCR_UNLOCK_ADDR) = SLCR_UNLOCK_KEY_VALUE;
436
437         if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
438                 slcrBaseAddress = SLCR_GEM0_CLK_CTRL_ADDR;
439         } else {
440                 slcrBaseAddress = SLCR_GEM1_CLK_CTRL_ADDR;
441         }
442 #ifdef PEEP
443         if (speed == 1000) {
444                 *(volatile unsigned int *)(slcrBaseAddress) =
445                                                                                         SLCR_GEM_1G_CLK_CTRL_VALUE;
446         } else if (speed == 100) {
447                 *(volatile unsigned int *)(slcrBaseAddress) =
448                                                                                         SLCR_GEM_100M_CLK_CTRL_VALUE;
449         } else {
450                 *(volatile unsigned int *)(slcrBaseAddress) =
451                                                                                         SLCR_GEM_10M_CLK_CTRL_VALUE;
452         }
453 #else
454         if (speed == 1000) {
455                 if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
456 #ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0
457                         SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0;
458                         SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV1;
459 #endif
460                 } else {
461 #ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0
462                         SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0;
463                         SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV1;
464 #endif
465                 }
466         } else if (speed == 100) {
467                 if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
468 #ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0
469                         SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0;
470                         SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV1;
471 #endif
472                 } else {
473 #ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0
474                         SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0;
475                         SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV1;
476 #endif
477                 }
478         } else {
479                 if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
480 #ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0
481                         SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0;
482                         SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV1;
483 #endif
484                 } else {
485 #ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0
486                         SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0;
487                         SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV1;
488 #endif
489                 }
490         }
491         SlcrTxClkCntrl = *(volatile unsigned int *)(slcrBaseAddress);
492         SlcrTxClkCntrl &= EMACPS_SLCR_DIV_MASK;
493         SlcrTxClkCntrl |= (SlcrDiv1 << 20);
494         SlcrTxClkCntrl |= (SlcrDiv0 << 8);
495         *(volatile unsigned int *)(slcrBaseAddress) = SlcrTxClkCntrl;
496 #endif
497         *(volatile unsigned int *)(SLCR_LOCK_ADDR) = SLCR_LOCK_KEY_VALUE;
498         return;
499 }
500
501
502 unsigned Phy_Setup (XEmacPs *xemacpsp)
503 {
504         unsigned link_speed;
505         unsigned long conv_present = 0;
506         unsigned long convspeeddupsetting = 0;
507         unsigned long convphyaddr = 0;
508
509 #ifdef XPAR_GMII2RGMIICON_0N_ETH0_ADDR
510         convphyaddr = XPAR_GMII2RGMIICON_0N_ETH0_ADDR;
511         conv_present = 1;
512 #else
513 #ifdef XPAR_GMII2RGMIICON_0N_ETH1_ADDR
514         convphyaddr = XPAR_GMII2RGMIICON_0N_ETH1_ADDR;
515         conv_present = 1;
516 #endif
517 #endif
518
519 #ifdef  CONFIG_LINKSPEED_AUTODETECT
520         link_speed = get_IEEE_phy_speed(xemacpsp);
521         if (link_speed == 1000) {
522                 SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
523                 convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
524         } else if (link_speed == 100) {
525                 SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
526                 convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
527         } else {
528                 SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
529                 convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
530         }
531 #elif   defined(CONFIG_LINKSPEED1000)
532         SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
533         link_speed = 1000;
534         configure_IEEE_phy_speed(xemacpsp, link_speed);
535         convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
536         sleep(1);
537 #elif   defined(CONFIG_LINKSPEED100)
538         SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
539         link_speed = 100;
540         configure_IEEE_phy_speed(xemacpsp, link_speed);
541         convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
542         sleep(1);
543 #elif   defined(CONFIG_LINKSPEED10)
544         SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
545         link_speed = 10;
546         configure_IEEE_phy_speed(xemacpsp, link_speed);
547         convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
548         sleep(1);
549 #endif
550         if (conv_present) {
551                 XEmacPs_PhyWrite(xemacpsp, convphyaddr,
552                 XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
553         }
554
555         xil_printf("link speed: %d\r\n", link_speed);
556         return link_speed;
557 }
558