powerpc, qe: fix codingstyle issues for drivers/qe
[platform/kernel/u-boot.git] / drivers / qe / uec_phy.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2005,2010-2011 Freescale Semiconductor, Inc.
4  *
5  * Author: Shlomi Gridish
6  *
7  * Description: UCC GETH Driver -- PHY handling
8  *              Driver for UEC on QE
9  *              Based on 8260_io/fcc_enet.c
10  */
11
12 #include <common.h>
13 #include <net.h>
14 #include <malloc.h>
15 #include <linux/delay.h>
16 #include <linux/errno.h>
17 #include <linux/immap_qe.h>
18 #include <asm/io.h>
19 #include "uccf.h"
20 #include "uec.h"
21 #include "uec_phy.h"
22 #include "miiphy.h"
23 #include <fsl_qe.h>
24 #include <phy.h>
25
26 #define ugphy_printk(format, arg...)  \
27         printf(format "\n", ## arg)
28
29 #define ugphy_dbg(format, arg...)            \
30         ugphy_printk(format, ## arg)
31 #define ugphy_err(format, arg...)            \
32         ugphy_printk(format, ## arg)
33 #define ugphy_info(format, arg...)           \
34         ugphy_printk(format, ## arg)
35 #define ugphy_warn(format, arg...)           \
36         ugphy_printk(format, ## arg)
37
38 #ifdef UEC_VERBOSE_DEBUG
39 #define ugphy_vdbg ugphy_dbg
40 #else
41 #define ugphy_vdbg(ugeth, fmt, args...) do { } while (0)
42 #endif /* UEC_VERBOSE_DEBUG */
43
44 /*
45  * --------------------------------------------------------------------
46  * Fixed PHY (PHY-less) support for Ethernet Ports.
47  *
48  * Copied from arch/powerpc/cpu/ppc4xx/4xx_enet.c
49  *--------------------------------------------------------------------
50  *
51  * Some boards do not have a PHY for each ethernet port. These ports are known
52  * as Fixed PHY (or PHY-less) ports. For such ports, set the appropriate
53  * CONFIG_SYS_UECx_PHY_ADDR equal to CONFIG_FIXED_PHY_ADDR (an unused address)
54  * When the drver tries to identify the PHYs, CONFIG_FIXED_PHY will be returned
55  * and the driver will search CONFIG_SYS_FIXED_PHY_PORTS to find what network
56  * speed and duplex should be for the port.
57  *
58  * Example board header configuration file:
59  *     #define CONFIG_FIXED_PHY   0xFFFFFFFF
60  *     #define CONFIG_SYS_FIXED_PHY_ADDR 0x1E (pick an unused phy address)
61  *
62  *     #define CONFIG_SYS_UEC1_PHY_ADDR CONFIG_SYS_FIXED_PHY_ADDR
63  *     #define CONFIG_SYS_UEC2_PHY_ADDR 0x02
64  *     #define CONFIG_SYS_UEC3_PHY_ADDR CONFIG_SYS_FIXED_PHY_ADDR
65  *     #define CONFIG_SYS_UEC4_PHY_ADDR 0x04
66  *
67  *     #define CONFIG_SYS_FIXED_PHY_PORT(name,speed,duplex) \
68  *                 {name, speed, duplex},
69  *
70  *     #define CONFIG_SYS_FIXED_PHY_PORTS \
71  *                 CONFIG_SYS_FIXED_PHY_PORT("UEC0",SPEED_100,DUPLEX_FULL) \
72  *                 CONFIG_SYS_FIXED_PHY_PORT("UEC2",SPEED_100,DUPLEX_HALF)
73  */
74
75 #ifndef CONFIG_FIXED_PHY
76 #define CONFIG_FIXED_PHY        0xFFFFFFFF /* Fixed PHY (PHY-less) */
77 #endif
78
79 #ifndef CONFIG_SYS_FIXED_PHY_PORTS
80 #define CONFIG_SYS_FIXED_PHY_PORTS      /* default is an empty array */
81 #endif
82
83 struct fixed_phy_port {
84         char name[16];  /* ethernet port name */
85         unsigned int speed;     /* specified speed 10,100 or 1000 */
86         unsigned int duplex;    /* specified duplex FULL or HALF */
87 };
88
89 static const struct fixed_phy_port fixed_phy_port[] = {
90         CONFIG_SYS_FIXED_PHY_PORTS /* defined in board configuration file */
91 };
92
93 /*
94  * -------------------------------------------------------------------
95  * BitBang MII support for ethernet ports
96  *
97  * Based from MPC8560ADS implementation
98  *--------------------------------------------------------------------
99  *
100  * Example board header file to define bitbang ethernet ports:
101  *
102  * #define CONFIG_SYS_BITBANG_PHY_PORT(name) name,
103  * #define CONFIG_SYS_BITBANG_PHY_PORTS CONFIG_SYS_BITBANG_PHY_PORT("UEC0")
104  */
105 #ifndef CONFIG_SYS_BITBANG_PHY_PORTS
106 #define CONFIG_SYS_BITBANG_PHY_PORTS    /* default is an empty array */
107 #endif
108
109 #if defined(CONFIG_BITBANGMII)
110 static const char * const bitbang_phy_port[] = {
111         CONFIG_SYS_BITBANG_PHY_PORTS /* defined in board configuration file */
112 };
113 #endif /* CONFIG_BITBANGMII */
114
115 static void config_genmii_advert(struct uec_mii_info *mii_info);
116 static void genmii_setup_forced(struct uec_mii_info *mii_info);
117 static void genmii_restart_aneg(struct uec_mii_info *mii_info);
118 static int gbit_config_aneg(struct uec_mii_info *mii_info);
119 static int genmii_config_aneg(struct uec_mii_info *mii_info);
120 static int genmii_update_link(struct uec_mii_info *mii_info);
121 static int genmii_read_status(struct uec_mii_info *mii_info);
122 static u16 uec_phy_read(struct uec_mii_info *mii_info, u16 regnum);
123 static void uec_phy_write(struct uec_mii_info *mii_info, u16 regnum,
124                           u16 val);
125
126 /*
127  * Write value to the PHY for this device to the register at regnum,
128  * waiting until the write is done before it returns.  All PHY
129  * configuration has to be done through the TSEC1 MIIM regs
130  */
131 void uec_write_phy_reg(struct eth_device *dev, int mii_id, int regnum,
132                        int value)
133 {
134         struct uec_priv *ugeth = (struct uec_priv *)dev->priv;
135         uec_mii_t *ug_regs;
136         enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg)regnum;
137         u32 tmp_reg;
138
139 #if defined(CONFIG_BITBANGMII)
140         u32 i = 0;
141
142         for (i = 0; i < ARRAY_SIZE(bitbang_phy_port); i++) {
143                 if (strncmp(dev->name, bitbang_phy_port[i],
144                             sizeof(dev->name)) == 0) {
145                         (void)bb_miiphy_write(NULL, mii_id, regnum, value);
146                         return;
147                 }
148         }
149 #endif /* CONFIG_BITBANGMII */
150
151         ug_regs = ugeth->uec_mii_regs;
152
153         /* Stop the MII management read cycle */
154         out_be32 (&ug_regs->miimcom, 0);
155         /* Setting up the MII Management Address Register */
156         tmp_reg = ((u32)mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg;
157         out_be32 (&ug_regs->miimadd, tmp_reg);
158
159         /* Setting up the MII Management Control Register with the value */
160         out_be32 (&ug_regs->miimcon, (u32)value);
161         sync();
162
163         /* Wait till MII management write is complete */
164         while ((in_be32 (&ug_regs->miimind)) & MIIMIND_BUSY)
165                 ;
166 }
167
168 /*
169  * Reads from register regnum in the PHY for device dev,
170  * returning the value.  Clears miimcom first.  All PHY
171  * configuration has to be done through the TSEC1 MIIM regs
172  */
173 int uec_read_phy_reg(struct eth_device *dev, int mii_id, int regnum)
174 {
175         struct uec_priv *ugeth = (struct uec_priv *)dev->priv;
176         uec_mii_t *ug_regs;
177         enum enet_tbi_mii_reg mii_reg = (enum enet_tbi_mii_reg)regnum;
178         u32 tmp_reg;
179         u16 value;
180
181 #if defined(CONFIG_BITBANGMII)
182         u32 i = 0;
183
184         for (i = 0; i < ARRAY_SIZE(bitbang_phy_port); i++) {
185                 if (strncmp(dev->name, bitbang_phy_port[i],
186                             sizeof(dev->name)) == 0) {
187                         (void)bb_miiphy_read(NULL, mii_id, regnum, &value);
188                         return value;
189                 }
190         }
191 #endif /* CONFIG_BITBANGMII */
192
193         ug_regs = ugeth->uec_mii_regs;
194
195         /* Setting up the MII Management Address Register */
196         tmp_reg = ((u32)mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg;
197         out_be32 (&ug_regs->miimadd, tmp_reg);
198
199         /* clear MII management command cycle */
200         out_be32 (&ug_regs->miimcom, 0);
201         sync();
202
203         /* Perform an MII management read cycle */
204         out_be32 (&ug_regs->miimcom, MIIMCOM_READ_CYCLE);
205
206         /* Wait till MII management write is complete */
207         while ((in_be32 (&ug_regs->miimind)) &
208                (MIIMIND_NOT_VALID | MIIMIND_BUSY))
209                 ;
210
211         /* Read MII management status  */
212         value = (u16)in_be32 (&ug_regs->miimstat);
213         if (value == 0xffff)
214                 ugphy_vdbg
215                         ("read wrong value : mii_id %d,mii_reg %d, base %08x",
216                          mii_id, mii_reg, (u32)&ug_regs->miimcfg);
217
218         return value;
219 }
220
221 void mii_clear_phy_interrupt(struct uec_mii_info *mii_info)
222 {
223         if (mii_info->phyinfo->ack_interrupt)
224                 mii_info->phyinfo->ack_interrupt(mii_info);
225 }
226
227 void mii_configure_phy_interrupt(struct uec_mii_info *mii_info,
228                                  u32 interrupts)
229 {
230         mii_info->interrupts = interrupts;
231         if (mii_info->phyinfo->config_intr)
232                 mii_info->phyinfo->config_intr(mii_info);
233 }
234
235 /* Writes MII_ADVERTISE with the appropriate values, after
236  * sanitizing advertise to make sure only supported features
237  * are advertised
238  */
239 static void config_genmii_advert(struct uec_mii_info *mii_info)
240 {
241         u32 advertise;
242         u16 adv;
243
244         /* Only allow advertising what this PHY supports */
245         mii_info->advertising &= mii_info->phyinfo->features;
246         advertise = mii_info->advertising;
247
248         /* Setup standard advertisement */
249         adv = uec_phy_read(mii_info, MII_ADVERTISE);
250         adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
251         if (advertise & ADVERTISED_10baseT_Half)
252                 adv |= ADVERTISE_10HALF;
253         if (advertise & ADVERTISED_10baseT_Full)
254                 adv |= ADVERTISE_10FULL;
255         if (advertise & ADVERTISED_100baseT_Half)
256                 adv |= ADVERTISE_100HALF;
257         if (advertise & ADVERTISED_100baseT_Full)
258                 adv |= ADVERTISE_100FULL;
259         uec_phy_write(mii_info, MII_ADVERTISE, adv);
260 }
261
262 static void genmii_setup_forced(struct uec_mii_info *mii_info)
263 {
264         u16 ctrl;
265         u32 features = mii_info->phyinfo->features;
266
267         ctrl = uec_phy_read(mii_info, MII_BMCR);
268
269         ctrl &= ~(BMCR_FULLDPLX | BMCR_SPEED100 |
270                   BMCR_SPEED1000 | BMCR_ANENABLE);
271         ctrl |= BMCR_RESET;
272
273         switch (mii_info->speed) {
274         case SPEED_1000:
275                 if (features & (SUPPORTED_1000baseT_Half
276                                 | SUPPORTED_1000baseT_Full)) {
277                         ctrl |= BMCR_SPEED1000;
278                         break;
279                 }
280                 mii_info->speed = SPEED_100;
281         case SPEED_100:
282                 if (features & (SUPPORTED_100baseT_Half
283                                 | SUPPORTED_100baseT_Full)) {
284                         ctrl |= BMCR_SPEED100;
285                         break;
286                 }
287                 mii_info->speed = SPEED_10;
288         case SPEED_10:
289                 if (features & (SUPPORTED_10baseT_Half
290                                 | SUPPORTED_10baseT_Full))
291                         break;
292         default:                /* Unsupported speed! */
293                 ugphy_err("%s: Bad speed!", mii_info->dev->name);
294                 break;
295         }
296
297         uec_phy_write(mii_info, MII_BMCR, ctrl);
298 }
299
300 /* Enable and Restart Autonegotiation */
301 static void genmii_restart_aneg(struct uec_mii_info *mii_info)
302 {
303         u16 ctl;
304
305         ctl = uec_phy_read(mii_info, MII_BMCR);
306         ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
307         uec_phy_write(mii_info, MII_BMCR, ctl);
308 }
309
310 static int gbit_config_aneg(struct uec_mii_info *mii_info)
311 {
312         u16 adv;
313         u32 advertise;
314
315         if (mii_info->autoneg) {
316                 /* Configure the ADVERTISE register */
317                 config_genmii_advert(mii_info);
318                 advertise = mii_info->advertising;
319
320                 adv = uec_phy_read(mii_info, MII_CTRL1000);
321                 adv &= ~(ADVERTISE_1000FULL |
322                          ADVERTISE_1000HALF);
323                 if (advertise & SUPPORTED_1000baseT_Half)
324                         adv |= ADVERTISE_1000HALF;
325                 if (advertise & SUPPORTED_1000baseT_Full)
326                         adv |= ADVERTISE_1000FULL;
327                 uec_phy_write(mii_info, MII_CTRL1000, adv);
328
329                 /* Start/Restart aneg */
330                 genmii_restart_aneg(mii_info);
331         } else {
332                 genmii_setup_forced(mii_info);
333         }
334
335         return 0;
336 }
337
338 static int marvell_config_aneg(struct uec_mii_info *mii_info)
339 {
340         /*
341          * The Marvell PHY has an errata which requires
342          * that certain registers get written in order
343          * to restart autonegotiation
344          */
345         uec_phy_write(mii_info, MII_BMCR, BMCR_RESET);
346
347         uec_phy_write(mii_info, 0x1d, 0x1f);
348         uec_phy_write(mii_info, 0x1e, 0x200c);
349         uec_phy_write(mii_info, 0x1d, 0x5);
350         uec_phy_write(mii_info, 0x1e, 0);
351         uec_phy_write(mii_info, 0x1e, 0x100);
352
353         gbit_config_aneg(mii_info);
354
355         return 0;
356 }
357
358 static int genmii_config_aneg(struct uec_mii_info *mii_info)
359 {
360         if (mii_info->autoneg) {
361                 /*
362                  * Speed up the common case, if link is already up, speed and
363                  * duplex match, skip auto neg as it already matches
364                  */
365                 if (!genmii_read_status(mii_info) && mii_info->link)
366                         if (mii_info->duplex == DUPLEX_FULL &&
367                             mii_info->speed == SPEED_100)
368                                 if (mii_info->advertising &
369                                     ADVERTISED_100baseT_Full)
370                                         return 0;
371
372                 config_genmii_advert(mii_info);
373                 genmii_restart_aneg(mii_info);
374         } else {
375                 genmii_setup_forced(mii_info);
376         }
377
378         return 0;
379 }
380
381 static int genmii_update_link(struct uec_mii_info *mii_info)
382 {
383         u16 status;
384
385         /* Status is read once to clear old link state */
386         uec_phy_read(mii_info, MII_BMSR);
387
388         /*
389          * Wait if the link is up, and autonegotiation is in progress
390          * (ie - we're capable and it's not done)
391          */
392         status = uec_phy_read(mii_info, MII_BMSR);
393         if ((status & BMSR_LSTATUS) && (status & BMSR_ANEGCAPABLE) &&
394             !(status & BMSR_ANEGCOMPLETE)) {
395                 int i = 0;
396
397                 while (!(status & BMSR_ANEGCOMPLETE)) {
398                         /*
399                          * Timeout reached ?
400                          */
401                         if (i > UGETH_AN_TIMEOUT) {
402                                 mii_info->link = 0;
403                                 return 0;
404                         }
405
406                         i++;
407                         udelay(1000);   /* 1 ms */
408                         status = uec_phy_read(mii_info, MII_BMSR);
409                 }
410                 mii_info->link = 1;
411         } else {
412                 if (status & BMSR_LSTATUS)
413                         mii_info->link = 1;
414                 else
415                         mii_info->link = 0;
416         }
417
418         return 0;
419 }
420
421 static int genmii_read_status(struct uec_mii_info *mii_info)
422 {
423         u16 status;
424         int err;
425
426         /* Update the link, but return if there was an error */
427         err = genmii_update_link(mii_info);
428         if (err)
429                 return err;
430
431         if (mii_info->autoneg) {
432                 status = uec_phy_read(mii_info, MII_STAT1000);
433
434                 if (status & (LPA_1000FULL | LPA_1000HALF)) {
435                         mii_info->speed = SPEED_1000;
436                         if (status & LPA_1000FULL)
437                                 mii_info->duplex = DUPLEX_FULL;
438                         else
439                                 mii_info->duplex = DUPLEX_HALF;
440                 } else {
441                         status = uec_phy_read(mii_info, MII_LPA);
442
443                         if (status & (LPA_10FULL | LPA_100FULL))
444                                 mii_info->duplex = DUPLEX_FULL;
445                         else
446                                 mii_info->duplex = DUPLEX_HALF;
447                         if (status & (LPA_100FULL | LPA_100HALF))
448                                 mii_info->speed = SPEED_100;
449                         else
450                                 mii_info->speed = SPEED_10;
451                 }
452                 mii_info->pause = 0;
453         }
454         /* On non-aneg, we assume what we put in BMCR is the speed,
455          * though magic-aneg shouldn't prevent this case from occurring
456          */
457
458         return 0;
459 }
460
461 static int bcm_init(struct uec_mii_info *mii_info)
462 {
463         struct eth_device *edev = mii_info->dev;
464         struct uec_priv *uec = edev->priv;
465
466         gbit_config_aneg(mii_info);
467
468         if (uec->uec_info->enet_interface_type ==
469                                 PHY_INTERFACE_MODE_RGMII_RXID &&
470                         uec->uec_info->speed == SPEED_1000) {
471                 u16 val;
472                 int cnt = 50;
473
474                 /* Wait for aneg to complete. */
475                 do
476                         val = uec_phy_read(mii_info, MII_BMSR);
477                 while (--cnt && !(val & BMSR_ANEGCOMPLETE));
478
479                 /* Set RDX clk delay. */
480                 uec_phy_write(mii_info, 0x18, 0x7 | (7 << 12));
481
482                 val = uec_phy_read(mii_info, 0x18);
483                 /* Set RDX-RXC skew. */
484                 val |= (1 << 8);
485                 val |= (7 | (7 << 12));
486                 /* Write bits 14:0. */
487                 val |= (1 << 15);
488                 uec_phy_write(mii_info, 0x18, val);
489         }
490
491         return 0;
492 }
493
494 static int uec_marvell_init(struct uec_mii_info *mii_info)
495 {
496         struct eth_device *edev = mii_info->dev;
497         struct uec_priv *uec = edev->priv;
498         phy_interface_t iface = uec->uec_info->enet_interface_type;
499         int     speed = uec->uec_info->speed;
500
501         if (speed == SPEED_1000 &&
502             (iface == PHY_INTERFACE_MODE_RGMII_ID ||
503             iface == PHY_INTERFACE_MODE_RGMII_RXID ||
504             iface == PHY_INTERFACE_MODE_RGMII_TXID)) {
505                 int temp;
506
507                 temp = uec_phy_read(mii_info, MII_M1111_PHY_EXT_CR);
508                 if (iface == PHY_INTERFACE_MODE_RGMII_ID) {
509                         temp |= MII_M1111_RX_DELAY | MII_M1111_TX_DELAY;
510                 } else if (iface == PHY_INTERFACE_MODE_RGMII_RXID) {
511                         temp &= ~MII_M1111_TX_DELAY;
512                         temp |= MII_M1111_RX_DELAY;
513                 } else if (iface == PHY_INTERFACE_MODE_RGMII_TXID) {
514                         temp &= ~MII_M1111_RX_DELAY;
515                         temp |= MII_M1111_TX_DELAY;
516                 }
517                 uec_phy_write(mii_info, MII_M1111_PHY_EXT_CR, temp);
518
519                 temp = uec_phy_read(mii_info, MII_M1111_PHY_EXT_SR);
520                 temp &= ~MII_M1111_HWCFG_MODE_MASK;
521                 temp |= MII_M1111_HWCFG_MODE_RGMII;
522                 uec_phy_write(mii_info, MII_M1111_PHY_EXT_SR, temp);
523
524                 uec_phy_write(mii_info, MII_BMCR, BMCR_RESET);
525         }
526
527         return 0;
528 }
529
530 static int marvell_read_status(struct uec_mii_info *mii_info)
531 {
532         u16 status;
533         int err;
534
535         /* Update the link, but return if there was an error */
536         err = genmii_update_link(mii_info);
537         if (err)
538                 return err;
539
540         /*
541          * If the link is up, read the speed and duplex
542          * If we aren't autonegotiating, assume speeds
543          * are as set
544          */
545         if (mii_info->autoneg && mii_info->link) {
546                 int speed;
547
548                 status = uec_phy_read(mii_info, MII_M1011_PHY_SPEC_STATUS);
549
550                 /* Get the duplexity */
551                 if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX)
552                         mii_info->duplex = DUPLEX_FULL;
553                 else
554                         mii_info->duplex = DUPLEX_HALF;
555
556                 /* Get the speed */
557                 speed = status & MII_M1011_PHY_SPEC_STATUS_SPD_MASK;
558                 switch (speed) {
559                 case MII_M1011_PHY_SPEC_STATUS_1000:
560                         mii_info->speed = SPEED_1000;
561                         break;
562                 case MII_M1011_PHY_SPEC_STATUS_100:
563                         mii_info->speed = SPEED_100;
564                         break;
565                 default:
566                         mii_info->speed = SPEED_10;
567                         break;
568                 }
569                 mii_info->pause = 0;
570         }
571
572         return 0;
573 }
574
575 static int marvell_ack_interrupt(struct uec_mii_info *mii_info)
576 {
577         /* Clear the interrupts by reading the reg */
578         uec_phy_read(mii_info, MII_M1011_IEVENT);
579
580         return 0;
581 }
582
583 static int marvell_config_intr(struct uec_mii_info *mii_info)
584 {
585         if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
586                 uec_phy_write(mii_info, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
587         else
588                 uec_phy_write(mii_info, MII_M1011_IMASK,
589                               MII_M1011_IMASK_CLEAR);
590
591         return 0;
592 }
593
594 static int dm9161_init(struct uec_mii_info *mii_info)
595 {
596         /* Reset the PHY */
597         uec_phy_write(mii_info, MII_BMCR, uec_phy_read(mii_info, MII_BMCR) |
598                    BMCR_RESET);
599         /* PHY and MAC connect */
600         uec_phy_write(mii_info, MII_BMCR, uec_phy_read(mii_info, MII_BMCR) &
601                    ~BMCR_ISOLATE);
602
603         uec_phy_write(mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT);
604
605         config_genmii_advert(mii_info);
606         /* Start/restart aneg */
607         genmii_config_aneg(mii_info);
608
609         return 0;
610 }
611
612 static int dm9161_config_aneg(struct uec_mii_info *mii_info)
613 {
614         return 0;
615 }
616
617 static int dm9161_read_status(struct uec_mii_info *mii_info)
618 {
619         u16 status;
620         int err;
621
622         /* Update the link, but return if there was an error */
623         err = genmii_update_link(mii_info);
624         if (err)
625                 return err;
626         /*
627          * If the link is up, read the speed and duplex
628          * If we aren't autonegotiating assume speeds are as set
629          */
630         if (mii_info->autoneg && mii_info->link) {
631                 status = uec_phy_read(mii_info, MII_DM9161_SCSR);
632                 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_100H))
633                         mii_info->speed = SPEED_100;
634                 else
635                         mii_info->speed = SPEED_10;
636
637                 if (status & (MII_DM9161_SCSR_100F | MII_DM9161_SCSR_10F))
638                         mii_info->duplex = DUPLEX_FULL;
639                 else
640                         mii_info->duplex = DUPLEX_HALF;
641         }
642
643         return 0;
644 }
645
646 static int dm9161_ack_interrupt(struct uec_mii_info *mii_info)
647 {
648         /* Clear the interrupt by reading the reg */
649         uec_phy_read(mii_info, MII_DM9161_INTR);
650
651         return 0;
652 }
653
654 static int dm9161_config_intr(struct uec_mii_info *mii_info)
655 {
656         if (mii_info->interrupts == MII_INTERRUPT_ENABLED)
657                 uec_phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_INIT);
658         else
659                 uec_phy_write(mii_info, MII_DM9161_INTR, MII_DM9161_INTR_STOP);
660
661         return 0;
662 }
663
664 static void dm9161_close(struct uec_mii_info *mii_info)
665 {
666 }
667
668 static int fixed_phy_aneg(struct uec_mii_info *mii_info)
669 {
670         mii_info->autoneg = 0; /* Turn off auto negotiation for fixed phy */
671         return 0;
672 }
673
674 static int fixed_phy_read_status(struct uec_mii_info *mii_info)
675 {
676         int i = 0;
677
678         for (i = 0; i < ARRAY_SIZE(fixed_phy_port); i++) {
679                 if (strncmp(mii_info->dev->name, fixed_phy_port[i].name,
680                             strlen(mii_info->dev->name)) == 0) {
681                         mii_info->speed = fixed_phy_port[i].speed;
682                         mii_info->duplex = fixed_phy_port[i].duplex;
683                         mii_info->link = 1; /* Link is always UP */
684                         mii_info->pause = 0;
685                         break;
686                 }
687         }
688         return 0;
689 }
690
691 static int smsc_config_aneg(struct uec_mii_info *mii_info)
692 {
693         return 0;
694 }
695
696 static int smsc_read_status(struct uec_mii_info *mii_info)
697 {
698         u16 status;
699         int err;
700
701         /* Update the link, but return if there was an error */
702         err = genmii_update_link(mii_info);
703         if (err)
704                 return err;
705
706         /*
707          * If the link is up, read the speed and duplex
708          * If we aren't autonegotiating, assume speeds
709          * are as set
710          */
711         if (mii_info->autoneg && mii_info->link) {
712                 int     val;
713
714                 status = uec_phy_read(mii_info, 0x1f);
715                 val = (status & 0x1c) >> 2;
716
717                 switch (val) {
718                 case 1:
719                         mii_info->duplex = DUPLEX_HALF;
720                         mii_info->speed = SPEED_10;
721                         break;
722                 case 5:
723                         mii_info->duplex = DUPLEX_FULL;
724                         mii_info->speed = SPEED_10;
725                         break;
726                 case 2:
727                         mii_info->duplex = DUPLEX_HALF;
728                         mii_info->speed = SPEED_100;
729                         break;
730                 case 6:
731                         mii_info->duplex = DUPLEX_FULL;
732                         mii_info->speed = SPEED_100;
733                         break;
734                 }
735                 mii_info->pause = 0;
736         }
737
738         return 0;
739 }
740
741 static struct phy_info phy_info_dm9161 = {
742         .phy_id = 0x0181b880,
743         .phy_id_mask = 0x0ffffff0,
744         .name = "Davicom DM9161E",
745         .init = dm9161_init,
746         .config_aneg = dm9161_config_aneg,
747         .read_status = dm9161_read_status,
748         .close = dm9161_close,
749 };
750
751 static struct phy_info phy_info_dm9161a = {
752         .phy_id = 0x0181b8a0,
753         .phy_id_mask = 0x0ffffff0,
754         .name = "Davicom DM9161A",
755         .features = MII_BASIC_FEATURES,
756         .init = dm9161_init,
757         .config_aneg = dm9161_config_aneg,
758         .read_status = dm9161_read_status,
759         .ack_interrupt = dm9161_ack_interrupt,
760         .config_intr = dm9161_config_intr,
761         .close = dm9161_close,
762 };
763
764 static struct phy_info phy_info_marvell = {
765         .phy_id = 0x01410c00,
766         .phy_id_mask = 0xffffff00,
767         .name = "Marvell 88E11x1",
768         .features = MII_GBIT_FEATURES,
769         .init = &uec_marvell_init,
770         .config_aneg = &marvell_config_aneg,
771         .read_status = &marvell_read_status,
772         .ack_interrupt = &marvell_ack_interrupt,
773         .config_intr = &marvell_config_intr,
774 };
775
776 static struct phy_info phy_info_bcm5481 = {
777         .phy_id = 0x0143bca0,
778         .phy_id_mask = 0xffffff0,
779         .name = "Broadcom 5481",
780         .features = MII_GBIT_FEATURES,
781         .read_status = genmii_read_status,
782         .init = bcm_init,
783 };
784
785 static struct phy_info phy_info_fixedphy = {
786         .phy_id = CONFIG_FIXED_PHY,
787         .phy_id_mask = CONFIG_FIXED_PHY,
788         .name = "Fixed PHY",
789         .config_aneg = fixed_phy_aneg,
790         .read_status = fixed_phy_read_status,
791 };
792
793 static struct phy_info phy_info_smsclan8700 = {
794         .phy_id = 0x0007c0c0,
795         .phy_id_mask = 0xfffffff0,
796         .name = "SMSC LAN8700",
797         .features = MII_BASIC_FEATURES,
798         .config_aneg = smsc_config_aneg,
799         .read_status = smsc_read_status,
800 };
801
802 static struct phy_info phy_info_genmii = {
803         .phy_id = 0x00000000,
804         .phy_id_mask = 0x00000000,
805         .name = "Generic MII",
806         .features = MII_BASIC_FEATURES,
807         .config_aneg = genmii_config_aneg,
808         .read_status = genmii_read_status,
809 };
810
811 static struct phy_info *phy_info[] = {
812         &phy_info_dm9161,
813         &phy_info_dm9161a,
814         &phy_info_marvell,
815         &phy_info_bcm5481,
816         &phy_info_smsclan8700,
817         &phy_info_fixedphy,
818         &phy_info_genmii,
819         NULL
820 };
821
822 static u16 uec_phy_read(struct uec_mii_info *mii_info, u16 regnum)
823 {
824         return mii_info->mdio_read(mii_info->dev, mii_info->mii_id, regnum);
825 }
826
827 static void uec_phy_write(struct uec_mii_info *mii_info, u16 regnum, u16 val)
828 {
829         mii_info->mdio_write(mii_info->dev, mii_info->mii_id, regnum, val);
830 }
831
832 /* Use the PHY ID registers to determine what type of PHY is attached
833  * to device dev.  return a struct phy_info structure describing that PHY
834  */
835 struct phy_info *uec_get_phy_info(struct uec_mii_info *mii_info)
836 {
837         u16 phy_reg;
838         u32 phy_ID;
839         int i;
840         struct phy_info *info = NULL;
841
842         /* Grab the bits from PHYIR1, and put them in the upper half */
843         phy_reg = uec_phy_read(mii_info, MII_PHYSID1);
844         phy_ID = (phy_reg & 0xffff) << 16;
845
846         /* Grab the bits from PHYIR2, and put them in the lower half */
847         phy_reg = uec_phy_read(mii_info, MII_PHYSID2);
848         phy_ID |= (phy_reg & 0xffff);
849
850         /* loop through all the known PHY types, and find one that */
851         /* matches the ID we read from the PHY. */
852         for (i = 0; phy_info[i]; i++)
853                 if (phy_info[i]->phy_id ==
854                     (phy_ID & phy_info[i]->phy_id_mask)) {
855                         info = phy_info[i];
856                         break;
857                 }
858
859         /* This shouldn't happen, as we have generic PHY support */
860         if (!info) {
861                 ugphy_info("UEC: PHY id %x is not supported!", phy_ID);
862                 return NULL;
863         }
864         ugphy_info("UEC: PHY is %s (%x)", info->name, phy_ID);
865
866         return info;
867 }
868
869 void marvell_phy_interface_mode(struct eth_device *dev, phy_interface_t type,
870                                 int speed)
871 {
872         struct uec_priv *uec = (struct uec_priv *)dev->priv;
873         struct uec_mii_info *mii_info;
874         u16 status;
875
876         if (!uec->mii_info) {
877                 printf("%s: the PHY not initialized\n", __func__);
878                 return;
879         }
880         mii_info = uec->mii_info;
881
882         if (type == PHY_INTERFACE_MODE_RGMII) {
883                 if (speed == SPEED_100) {
884                         uec_phy_write(mii_info, 0x00, 0x9140);
885                         uec_phy_write(mii_info, 0x1d, 0x001f);
886                         uec_phy_write(mii_info, 0x1e, 0x200c);
887                         uec_phy_write(mii_info, 0x1d, 0x0005);
888                         uec_phy_write(mii_info, 0x1e, 0x0000);
889                         uec_phy_write(mii_info, 0x1e, 0x0100);
890                         uec_phy_write(mii_info, 0x09, 0x0e00);
891                         uec_phy_write(mii_info, 0x04, 0x01e1);
892                         uec_phy_write(mii_info, 0x00, 0x9140);
893                         uec_phy_write(mii_info, 0x00, 0x1000);
894                         mdelay(100);
895                         uec_phy_write(mii_info, 0x00, 0x2900);
896                         uec_phy_write(mii_info, 0x14, 0x0cd2);
897                         uec_phy_write(mii_info, 0x00, 0xa100);
898                         uec_phy_write(mii_info, 0x09, 0x0000);
899                         uec_phy_write(mii_info, 0x1b, 0x800b);
900                         uec_phy_write(mii_info, 0x04, 0x05e1);
901                         uec_phy_write(mii_info, 0x00, 0xa100);
902                         uec_phy_write(mii_info, 0x00, 0x2100);
903                         mdelay(1000);
904                 } else if (speed == SPEED_10) {
905                         uec_phy_write(mii_info, 0x14, 0x8e40);
906                         uec_phy_write(mii_info, 0x1b, 0x800b);
907                         uec_phy_write(mii_info, 0x14, 0x0c82);
908                         uec_phy_write(mii_info, 0x00, 0x8100);
909                         mdelay(1000);
910                 }
911         }
912
913         /* handle 88e1111 rev.B2 erratum 5.6 */
914         if (mii_info->autoneg) {
915                 status = uec_phy_read(mii_info, MII_BMCR);
916                 uec_phy_write(mii_info, MII_BMCR, status | BMCR_ANENABLE);
917         }
918         /* now the B2 will correctly report autoneg completion status */
919 }
920
921 void change_phy_interface_mode(struct eth_device *dev,
922                                phy_interface_t type, int speed)
923 {
924 #ifdef CONFIG_PHY_MODE_NEED_CHANGE
925         marvell_phy_interface_mode(dev, type, speed);
926 #endif
927 }