2 * Copyright (C) 2005,2010-2011 Freescale Semiconductor, Inc.
4 * Author: Shlomi Gridish
6 * Description: UCC GETH Driver -- PHY handling
8 * Based on 8260_io/fcc_enet.c
10 * SPDX-License-Identifier: GPL-2.0+
16 #include <linux/errno.h>
17 #include <linux/immap_qe.h>
26 #define ugphy_printk(format, arg...) \
27 printf(format "\n", ## arg)
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)
38 #ifdef UEC_VERBOSE_DEBUG
39 #define ugphy_vdbg ugphy_dbg
41 #define ugphy_vdbg(ugeth, fmt, args...) do { } while (0)
42 #endif /* UEC_VERBOSE_DEBUG */
44 /*--------------------------------------------------------------------+
45 * Fixed PHY (PHY-less) support for Ethernet Ports.
47 * Copied from arch/powerpc/cpu/ppc4xx/4xx_enet.c
48 *--------------------------------------------------------------------*/
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.
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)
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
67 * #define CONFIG_SYS_FIXED_PHY_PORT(name,speed,duplex) \
68 * {name, speed, duplex},
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)
75 #ifndef CONFIG_FIXED_PHY
76 #define CONFIG_FIXED_PHY 0xFFFFFFFF /* Fixed PHY (PHY-less) */
79 #ifndef CONFIG_SYS_FIXED_PHY_PORTS
80 #define CONFIG_SYS_FIXED_PHY_PORTS /* default is an empty array */
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 */
89 static const struct fixed_phy_port fixed_phy_port
[] = {
90 CONFIG_SYS_FIXED_PHY_PORTS
/* defined in board configuration file */
93 /*--------------------------------------------------------------------+
94 * BitBang MII support for ethernet ports
96 * Based from MPC8560ADS implementation
97 *--------------------------------------------------------------------*/
99 * Example board header file to define bitbang ethernet ports:
101 * #define CONFIG_SYS_BITBANG_PHY_PORT(name) name,
102 * #define CONFIG_SYS_BITBANG_PHY_PORTS CONFIG_SYS_BITBANG_PHY_PORT("UEC0")
104 #ifndef CONFIG_SYS_BITBANG_PHY_PORTS
105 #define CONFIG_SYS_BITBANG_PHY_PORTS /* default is an empty array */
108 #if defined(CONFIG_BITBANGMII)
109 static const char *bitbang_phy_port
[] = {
110 CONFIG_SYS_BITBANG_PHY_PORTS
/* defined in board configuration file */
112 #endif /* CONFIG_BITBANGMII */
114 static void config_genmii_advert (struct uec_mii_info
*mii_info
);
115 static void genmii_setup_forced (struct uec_mii_info
*mii_info
);
116 static void genmii_restart_aneg (struct uec_mii_info
*mii_info
);
117 static int gbit_config_aneg (struct uec_mii_info
*mii_info
);
118 static int genmii_config_aneg (struct uec_mii_info
*mii_info
);
119 static int genmii_update_link (struct uec_mii_info
*mii_info
);
120 static int genmii_read_status (struct uec_mii_info
*mii_info
);
121 u16
uec_phy_read(struct uec_mii_info
*mii_info
, u16 regnum
);
122 void uec_phy_write(struct uec_mii_info
*mii_info
, u16 regnum
, u16 val
);
124 /* Write value to the PHY for this device to the register at regnum, */
125 /* waiting until the write is done before it returns. All PHY */
126 /* configuration has to be done through the TSEC1 MIIM regs */
127 void uec_write_phy_reg (struct eth_device
*dev
, int mii_id
, int regnum
, int value
)
129 uec_private_t
*ugeth
= (uec_private_t
*) dev
->priv
;
131 enet_tbi_mii_reg_e mii_reg
= (enet_tbi_mii_reg_e
) regnum
;
135 #if defined(CONFIG_BITBANGMII)
138 for (i
= 0; i
< ARRAY_SIZE(bitbang_phy_port
); i
++) {
139 if (strncmp(dev
->name
, bitbang_phy_port
[i
],
140 sizeof(dev
->name
)) == 0) {
141 (void)bb_miiphy_write(NULL
, mii_id
, regnum
, value
);
145 #endif /* CONFIG_BITBANGMII */
147 ug_regs
= ugeth
->uec_mii_regs
;
149 /* Stop the MII management read cycle */
150 out_be32 (&ug_regs
->miimcom
, 0);
151 /* Setting up the MII Mangement Address Register */
152 tmp_reg
= ((u32
) mii_id
<< MIIMADD_PHY_ADDRESS_SHIFT
) | mii_reg
;
153 out_be32 (&ug_regs
->miimadd
, tmp_reg
);
155 /* Setting up the MII Mangement Control Register with the value */
156 out_be32 (&ug_regs
->miimcon
, (u32
) value
);
159 /* Wait till MII management write is complete */
160 while ((in_be32 (&ug_regs
->miimind
)) & MIIMIND_BUSY
);
163 /* Reads from register regnum in the PHY for device dev, */
164 /* returning the value. Clears miimcom first. All PHY */
165 /* configuration has to be done through the TSEC1 MIIM regs */
166 int uec_read_phy_reg (struct eth_device
*dev
, int mii_id
, int regnum
)
168 uec_private_t
*ugeth
= (uec_private_t
*) dev
->priv
;
170 enet_tbi_mii_reg_e mii_reg
= (enet_tbi_mii_reg_e
) regnum
;
175 #if defined(CONFIG_BITBANGMII)
178 for (i
= 0; i
< ARRAY_SIZE(bitbang_phy_port
); i
++) {
179 if (strncmp(dev
->name
, bitbang_phy_port
[i
],
180 sizeof(dev
->name
)) == 0) {
181 (void)bb_miiphy_read(NULL
, mii_id
, regnum
, &value
);
185 #endif /* CONFIG_BITBANGMII */
187 ug_regs
= ugeth
->uec_mii_regs
;
189 /* Setting up the MII Mangement Address Register */
190 tmp_reg
= ((u32
) mii_id
<< MIIMADD_PHY_ADDRESS_SHIFT
) | mii_reg
;
191 out_be32 (&ug_regs
->miimadd
, tmp_reg
);
193 /* clear MII management command cycle */
194 out_be32 (&ug_regs
->miimcom
, 0);
197 /* Perform an MII management read cycle */
198 out_be32 (&ug_regs
->miimcom
, MIIMCOM_READ_CYCLE
);
200 /* Wait till MII management write is complete */
201 while ((in_be32 (&ug_regs
->miimind
)) &
202 (MIIMIND_NOT_VALID
| MIIMIND_BUSY
));
204 /* Read MII management status */
205 value
= (u16
) in_be32 (&ug_regs
->miimstat
);
208 ("read wrong value : mii_id %d,mii_reg %d, base %08x",
209 mii_id
, mii_reg
, (u32
) & (ug_regs
->miimcfg
));
214 void mii_clear_phy_interrupt (struct uec_mii_info
*mii_info
)
216 if (mii_info
->phyinfo
->ack_interrupt
)
217 mii_info
->phyinfo
->ack_interrupt (mii_info
);
220 void mii_configure_phy_interrupt (struct uec_mii_info
*mii_info
,
223 mii_info
->interrupts
= interrupts
;
224 if (mii_info
->phyinfo
->config_intr
)
225 mii_info
->phyinfo
->config_intr (mii_info
);
228 /* Writes MII_ADVERTISE with the appropriate values, after
229 * sanitizing advertise to make sure only supported features
232 static void config_genmii_advert (struct uec_mii_info
*mii_info
)
237 /* Only allow advertising what this PHY supports */
238 mii_info
->advertising
&= mii_info
->phyinfo
->features
;
239 advertise
= mii_info
->advertising
;
241 /* Setup standard advertisement */
242 adv
= uec_phy_read(mii_info
, MII_ADVERTISE
);
243 adv
&= ~(ADVERTISE_ALL
| ADVERTISE_100BASE4
);
244 if (advertise
& ADVERTISED_10baseT_Half
)
245 adv
|= ADVERTISE_10HALF
;
246 if (advertise
& ADVERTISED_10baseT_Full
)
247 adv
|= ADVERTISE_10FULL
;
248 if (advertise
& ADVERTISED_100baseT_Half
)
249 adv
|= ADVERTISE_100HALF
;
250 if (advertise
& ADVERTISED_100baseT_Full
)
251 adv
|= ADVERTISE_100FULL
;
252 uec_phy_write(mii_info
, MII_ADVERTISE
, adv
);
255 static void genmii_setup_forced (struct uec_mii_info
*mii_info
)
258 u32 features
= mii_info
->phyinfo
->features
;
260 ctrl
= uec_phy_read(mii_info
, MII_BMCR
);
262 ctrl
&= ~(BMCR_FULLDPLX
| BMCR_SPEED100
|
263 BMCR_SPEED1000
| BMCR_ANENABLE
);
266 switch (mii_info
->speed
) {
268 if (features
& (SUPPORTED_1000baseT_Half
269 | SUPPORTED_1000baseT_Full
)) {
270 ctrl
|= BMCR_SPEED1000
;
273 mii_info
->speed
= SPEED_100
;
275 if (features
& (SUPPORTED_100baseT_Half
276 | SUPPORTED_100baseT_Full
)) {
277 ctrl
|= BMCR_SPEED100
;
280 mii_info
->speed
= SPEED_10
;
282 if (features
& (SUPPORTED_10baseT_Half
283 | SUPPORTED_10baseT_Full
))
285 default: /* Unsupported speed! */
286 ugphy_err ("%s: Bad speed!", mii_info
->dev
->name
);
290 uec_phy_write(mii_info
, MII_BMCR
, ctrl
);
293 /* Enable and Restart Autonegotiation */
294 static void genmii_restart_aneg (struct uec_mii_info
*mii_info
)
298 ctl
= uec_phy_read(mii_info
, MII_BMCR
);
299 ctl
|= (BMCR_ANENABLE
| BMCR_ANRESTART
);
300 uec_phy_write(mii_info
, MII_BMCR
, ctl
);
303 static int gbit_config_aneg (struct uec_mii_info
*mii_info
)
308 if (mii_info
->autoneg
) {
309 /* Configure the ADVERTISE register */
310 config_genmii_advert (mii_info
);
311 advertise
= mii_info
->advertising
;
313 adv
= uec_phy_read(mii_info
, MII_CTRL1000
);
314 adv
&= ~(ADVERTISE_1000FULL
|
316 if (advertise
& SUPPORTED_1000baseT_Half
)
317 adv
|= ADVERTISE_1000HALF
;
318 if (advertise
& SUPPORTED_1000baseT_Full
)
319 adv
|= ADVERTISE_1000FULL
;
320 uec_phy_write(mii_info
, MII_CTRL1000
, adv
);
322 /* Start/Restart aneg */
323 genmii_restart_aneg (mii_info
);
325 genmii_setup_forced (mii_info
);
330 static int marvell_config_aneg (struct uec_mii_info
*mii_info
)
332 /* The Marvell PHY has an errata which requires
333 * that certain registers get written in order
334 * to restart autonegotiation */
335 uec_phy_write(mii_info
, MII_BMCR
, BMCR_RESET
);
337 uec_phy_write(mii_info
, 0x1d, 0x1f);
338 uec_phy_write(mii_info
, 0x1e, 0x200c);
339 uec_phy_write(mii_info
, 0x1d, 0x5);
340 uec_phy_write(mii_info
, 0x1e, 0);
341 uec_phy_write(mii_info
, 0x1e, 0x100);
343 gbit_config_aneg (mii_info
);
348 static int genmii_config_aneg (struct uec_mii_info
*mii_info
)
350 if (mii_info
->autoneg
) {
351 /* Speed up the common case, if link is already up, speed and
352 duplex match, skip auto neg as it already matches */
353 if (!genmii_read_status(mii_info
) && mii_info
->link
)
354 if (mii_info
->duplex
== DUPLEX_FULL
&&
355 mii_info
->speed
== SPEED_100
)
356 if (mii_info
->advertising
&
357 ADVERTISED_100baseT_Full
)
360 config_genmii_advert (mii_info
);
361 genmii_restart_aneg (mii_info
);
363 genmii_setup_forced (mii_info
);
368 static int genmii_update_link (struct uec_mii_info
*mii_info
)
372 /* Status is read once to clear old link state */
373 uec_phy_read(mii_info
, MII_BMSR
);
376 * Wait if the link is up, and autonegotiation is in progress
377 * (ie - we're capable and it's not done)
379 status
= uec_phy_read(mii_info
, MII_BMSR
);
380 if ((status
& BMSR_LSTATUS
) && (status
& BMSR_ANEGCAPABLE
)
381 && !(status
& BMSR_ANEGCOMPLETE
)) {
384 while (!(status
& BMSR_ANEGCOMPLETE
)) {
388 if (i
> UGETH_AN_TIMEOUT
) {
394 udelay(1000); /* 1 ms */
395 status
= uec_phy_read(mii_info
, MII_BMSR
);
399 if (status
& BMSR_LSTATUS
)
408 static int genmii_read_status (struct uec_mii_info
*mii_info
)
413 /* Update the link, but return if there
415 err
= genmii_update_link (mii_info
);
419 if (mii_info
->autoneg
) {
420 status
= uec_phy_read(mii_info
, MII_STAT1000
);
422 if (status
& (LPA_1000FULL
| LPA_1000HALF
)) {
423 mii_info
->speed
= SPEED_1000
;
424 if (status
& LPA_1000FULL
)
425 mii_info
->duplex
= DUPLEX_FULL
;
427 mii_info
->duplex
= DUPLEX_HALF
;
429 status
= uec_phy_read(mii_info
, MII_LPA
);
431 if (status
& (LPA_10FULL
| LPA_100FULL
))
432 mii_info
->duplex
= DUPLEX_FULL
;
434 mii_info
->duplex
= DUPLEX_HALF
;
435 if (status
& (LPA_100FULL
| LPA_100HALF
))
436 mii_info
->speed
= SPEED_100
;
438 mii_info
->speed
= SPEED_10
;
442 /* On non-aneg, we assume what we put in BMCR is the speed,
443 * though magic-aneg shouldn't prevent this case from occurring
449 static int bcm_init(struct uec_mii_info
*mii_info
)
451 struct eth_device
*edev
= mii_info
->dev
;
452 uec_private_t
*uec
= edev
->priv
;
454 gbit_config_aneg(mii_info
);
456 if ((uec
->uec_info
->enet_interface_type
==
457 PHY_INTERFACE_MODE_RGMII_RXID
) &&
458 (uec
->uec_info
->speed
== SPEED_1000
)) {
462 /* Wait for aneg to complete. */
464 val
= uec_phy_read(mii_info
, MII_BMSR
);
465 while (--cnt
&& !(val
& BMSR_ANEGCOMPLETE
));
467 /* Set RDX clk delay. */
468 uec_phy_write(mii_info
, 0x18, 0x7 | (7 << 12));
470 val
= uec_phy_read(mii_info
, 0x18);
471 /* Set RDX-RXC skew. */
473 val
|= (7 | (7 << 12));
474 /* Write bits 14:0. */
476 uec_phy_write(mii_info
, 0x18, val
);
482 static int uec_marvell_init(struct uec_mii_info
*mii_info
)
484 struct eth_device
*edev
= mii_info
->dev
;
485 uec_private_t
*uec
= edev
->priv
;
486 phy_interface_t iface
= uec
->uec_info
->enet_interface_type
;
487 int speed
= uec
->uec_info
->speed
;
489 if ((speed
== SPEED_1000
) &&
490 (iface
== PHY_INTERFACE_MODE_RGMII_ID
||
491 iface
== PHY_INTERFACE_MODE_RGMII_RXID
||
492 iface
== PHY_INTERFACE_MODE_RGMII_TXID
)) {
495 temp
= uec_phy_read(mii_info
, MII_M1111_PHY_EXT_CR
);
496 if (iface
== PHY_INTERFACE_MODE_RGMII_ID
) {
497 temp
|= MII_M1111_RX_DELAY
| MII_M1111_TX_DELAY
;
498 } else if (iface
== PHY_INTERFACE_MODE_RGMII_RXID
) {
499 temp
&= ~MII_M1111_TX_DELAY
;
500 temp
|= MII_M1111_RX_DELAY
;
501 } else if (iface
== PHY_INTERFACE_MODE_RGMII_TXID
) {
502 temp
&= ~MII_M1111_RX_DELAY
;
503 temp
|= MII_M1111_TX_DELAY
;
505 uec_phy_write(mii_info
, MII_M1111_PHY_EXT_CR
, temp
);
507 temp
= uec_phy_read(mii_info
, MII_M1111_PHY_EXT_SR
);
508 temp
&= ~MII_M1111_HWCFG_MODE_MASK
;
509 temp
|= MII_M1111_HWCFG_MODE_RGMII
;
510 uec_phy_write(mii_info
, MII_M1111_PHY_EXT_SR
, temp
);
512 uec_phy_write(mii_info
, MII_BMCR
, BMCR_RESET
);
518 static int marvell_read_status (struct uec_mii_info
*mii_info
)
523 /* Update the link, but return if there
525 err
= genmii_update_link (mii_info
);
529 /* If the link is up, read the speed and duplex */
530 /* If we aren't autonegotiating, assume speeds
532 if (mii_info
->autoneg
&& mii_info
->link
) {
535 status
= uec_phy_read(mii_info
, MII_M1011_PHY_SPEC_STATUS
);
537 /* Get the duplexity */
538 if (status
& MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX
)
539 mii_info
->duplex
= DUPLEX_FULL
;
541 mii_info
->duplex
= DUPLEX_HALF
;
544 speed
= status
& MII_M1011_PHY_SPEC_STATUS_SPD_MASK
;
546 case MII_M1011_PHY_SPEC_STATUS_1000
:
547 mii_info
->speed
= SPEED_1000
;
549 case MII_M1011_PHY_SPEC_STATUS_100
:
550 mii_info
->speed
= SPEED_100
;
553 mii_info
->speed
= SPEED_10
;
562 static int marvell_ack_interrupt (struct uec_mii_info
*mii_info
)
564 /* Clear the interrupts by reading the reg */
565 uec_phy_read(mii_info
, MII_M1011_IEVENT
);
570 static int marvell_config_intr (struct uec_mii_info
*mii_info
)
572 if (mii_info
->interrupts
== MII_INTERRUPT_ENABLED
)
573 uec_phy_write(mii_info
, MII_M1011_IMASK
, MII_M1011_IMASK_INIT
);
575 uec_phy_write(mii_info
, MII_M1011_IMASK
,
576 MII_M1011_IMASK_CLEAR
);
581 static int dm9161_init (struct uec_mii_info
*mii_info
)
584 uec_phy_write(mii_info
, MII_BMCR
, uec_phy_read(mii_info
, MII_BMCR
) |
586 /* PHY and MAC connect */
587 uec_phy_write(mii_info
, MII_BMCR
, uec_phy_read(mii_info
, MII_BMCR
) &
590 uec_phy_write(mii_info
, MII_DM9161_SCR
, MII_DM9161_SCR_INIT
);
592 config_genmii_advert (mii_info
);
593 /* Start/restart aneg */
594 genmii_config_aneg (mii_info
);
599 static int dm9161_config_aneg (struct uec_mii_info
*mii_info
)
604 static int dm9161_read_status (struct uec_mii_info
*mii_info
)
609 /* Update the link, but return if there was an error */
610 err
= genmii_update_link (mii_info
);
613 /* If the link is up, read the speed and duplex
614 If we aren't autonegotiating assume speeds are as set */
615 if (mii_info
->autoneg
&& mii_info
->link
) {
616 status
= uec_phy_read(mii_info
, MII_DM9161_SCSR
);
617 if (status
& (MII_DM9161_SCSR_100F
| MII_DM9161_SCSR_100H
))
618 mii_info
->speed
= SPEED_100
;
620 mii_info
->speed
= SPEED_10
;
622 if (status
& (MII_DM9161_SCSR_100F
| MII_DM9161_SCSR_10F
))
623 mii_info
->duplex
= DUPLEX_FULL
;
625 mii_info
->duplex
= DUPLEX_HALF
;
631 static int dm9161_ack_interrupt (struct uec_mii_info
*mii_info
)
633 /* Clear the interrupt by reading the reg */
634 uec_phy_read(mii_info
, MII_DM9161_INTR
);
639 static int dm9161_config_intr (struct uec_mii_info
*mii_info
)
641 if (mii_info
->interrupts
== MII_INTERRUPT_ENABLED
)
642 uec_phy_write(mii_info
, MII_DM9161_INTR
, MII_DM9161_INTR_INIT
);
644 uec_phy_write(mii_info
, MII_DM9161_INTR
, MII_DM9161_INTR_STOP
);
649 static void dm9161_close (struct uec_mii_info
*mii_info
)
653 static int fixed_phy_aneg (struct uec_mii_info
*mii_info
)
655 mii_info
->autoneg
= 0; /* Turn off auto negotiation for fixed phy */
659 static int fixed_phy_read_status (struct uec_mii_info
*mii_info
)
663 for (i
= 0; i
< ARRAY_SIZE(fixed_phy_port
); i
++) {
664 if (strncmp(mii_info
->dev
->name
, fixed_phy_port
[i
].name
,
665 strlen(mii_info
->dev
->name
)) == 0) {
666 mii_info
->speed
= fixed_phy_port
[i
].speed
;
667 mii_info
->duplex
= fixed_phy_port
[i
].duplex
;
668 mii_info
->link
= 1; /* Link is always UP */
676 static int smsc_config_aneg (struct uec_mii_info
*mii_info
)
681 static int smsc_read_status (struct uec_mii_info
*mii_info
)
686 /* Update the link, but return if there
688 err
= genmii_update_link (mii_info
);
692 /* If the link is up, read the speed and duplex */
693 /* If we aren't autonegotiating, assume speeds
695 if (mii_info
->autoneg
&& mii_info
->link
) {
698 status
= uec_phy_read(mii_info
, 0x1f);
699 val
= (status
& 0x1c) >> 2;
703 mii_info
->duplex
= DUPLEX_HALF
;
704 mii_info
->speed
= SPEED_10
;
707 mii_info
->duplex
= DUPLEX_FULL
;
708 mii_info
->speed
= SPEED_10
;
711 mii_info
->duplex
= DUPLEX_HALF
;
712 mii_info
->speed
= SPEED_100
;
715 mii_info
->duplex
= DUPLEX_FULL
;
716 mii_info
->speed
= SPEED_100
;
725 static struct phy_info phy_info_dm9161
= {
726 .phy_id
= 0x0181b880,
727 .phy_id_mask
= 0x0ffffff0,
728 .name
= "Davicom DM9161E",
730 .config_aneg
= dm9161_config_aneg
,
731 .read_status
= dm9161_read_status
,
732 .close
= dm9161_close
,
735 static struct phy_info phy_info_dm9161a
= {
736 .phy_id
= 0x0181b8a0,
737 .phy_id_mask
= 0x0ffffff0,
738 .name
= "Davicom DM9161A",
739 .features
= MII_BASIC_FEATURES
,
741 .config_aneg
= dm9161_config_aneg
,
742 .read_status
= dm9161_read_status
,
743 .ack_interrupt
= dm9161_ack_interrupt
,
744 .config_intr
= dm9161_config_intr
,
745 .close
= dm9161_close
,
748 static struct phy_info phy_info_marvell
= {
749 .phy_id
= 0x01410c00,
750 .phy_id_mask
= 0xffffff00,
751 .name
= "Marvell 88E11x1",
752 .features
= MII_GBIT_FEATURES
,
753 .init
= &uec_marvell_init
,
754 .config_aneg
= &marvell_config_aneg
,
755 .read_status
= &marvell_read_status
,
756 .ack_interrupt
= &marvell_ack_interrupt
,
757 .config_intr
= &marvell_config_intr
,
760 static struct phy_info phy_info_bcm5481
= {
761 .phy_id
= 0x0143bca0,
762 .phy_id_mask
= 0xffffff0,
763 .name
= "Broadcom 5481",
764 .features
= MII_GBIT_FEATURES
,
765 .read_status
= genmii_read_status
,
769 static struct phy_info phy_info_fixedphy
= {
770 .phy_id
= CONFIG_FIXED_PHY
,
771 .phy_id_mask
= CONFIG_FIXED_PHY
,
773 .config_aneg
= fixed_phy_aneg
,
774 .read_status
= fixed_phy_read_status
,
777 static struct phy_info phy_info_smsclan8700
= {
778 .phy_id
= 0x0007c0c0,
779 .phy_id_mask
= 0xfffffff0,
780 .name
= "SMSC LAN8700",
781 .features
= MII_BASIC_FEATURES
,
782 .config_aneg
= smsc_config_aneg
,
783 .read_status
= smsc_read_status
,
786 static struct phy_info phy_info_genmii
= {
787 .phy_id
= 0x00000000,
788 .phy_id_mask
= 0x00000000,
789 .name
= "Generic MII",
790 .features
= MII_BASIC_FEATURES
,
791 .config_aneg
= genmii_config_aneg
,
792 .read_status
= genmii_read_status
,
795 static struct phy_info
*phy_info
[] = {
800 &phy_info_smsclan8700
,
806 u16
uec_phy_read(struct uec_mii_info
*mii_info
, u16 regnum
)
808 return mii_info
->mdio_read (mii_info
->dev
, mii_info
->mii_id
, regnum
);
811 void uec_phy_write(struct uec_mii_info
*mii_info
, u16 regnum
, u16 val
)
813 mii_info
->mdio_write (mii_info
->dev
, mii_info
->mii_id
, regnum
, val
);
816 /* Use the PHY ID registers to determine what type of PHY is attached
817 * to device dev. return a struct phy_info structure describing that PHY
819 struct phy_info
*uec_get_phy_info (struct uec_mii_info
*mii_info
)
824 struct phy_info
*theInfo
= NULL
;
826 /* Grab the bits from PHYIR1, and put them in the upper half */
827 phy_reg
= uec_phy_read(mii_info
, MII_PHYSID1
);
828 phy_ID
= (phy_reg
& 0xffff) << 16;
830 /* Grab the bits from PHYIR2, and put them in the lower half */
831 phy_reg
= uec_phy_read(mii_info
, MII_PHYSID2
);
832 phy_ID
|= (phy_reg
& 0xffff);
834 /* loop through all the known PHY types, and find one that */
835 /* matches the ID we read from the PHY. */
836 for (i
= 0; phy_info
[i
]; i
++)
837 if (phy_info
[i
]->phy_id
==
838 (phy_ID
& phy_info
[i
]->phy_id_mask
)) {
839 theInfo
= phy_info
[i
];
843 /* This shouldn't happen, as we have generic PHY support */
844 if (theInfo
== NULL
) {
845 ugphy_info ("UEC: PHY id %x is not supported!", phy_ID
);
848 ugphy_info ("UEC: PHY is %s (%x)", theInfo
->name
, phy_ID
);
854 void marvell_phy_interface_mode(struct eth_device
*dev
, phy_interface_t type
,
857 uec_private_t
*uec
= (uec_private_t
*) dev
->priv
;
858 struct uec_mii_info
*mii_info
;
861 if (!uec
->mii_info
) {
862 printf ("%s: the PHY not initialized\n", __FUNCTION__
);
865 mii_info
= uec
->mii_info
;
867 if (type
== PHY_INTERFACE_MODE_RGMII
) {
868 if (speed
== SPEED_100
) {
869 uec_phy_write(mii_info
, 0x00, 0x9140);
870 uec_phy_write(mii_info
, 0x1d, 0x001f);
871 uec_phy_write(mii_info
, 0x1e, 0x200c);
872 uec_phy_write(mii_info
, 0x1d, 0x0005);
873 uec_phy_write(mii_info
, 0x1e, 0x0000);
874 uec_phy_write(mii_info
, 0x1e, 0x0100);
875 uec_phy_write(mii_info
, 0x09, 0x0e00);
876 uec_phy_write(mii_info
, 0x04, 0x01e1);
877 uec_phy_write(mii_info
, 0x00, 0x9140);
878 uec_phy_write(mii_info
, 0x00, 0x1000);
880 uec_phy_write(mii_info
, 0x00, 0x2900);
881 uec_phy_write(mii_info
, 0x14, 0x0cd2);
882 uec_phy_write(mii_info
, 0x00, 0xa100);
883 uec_phy_write(mii_info
, 0x09, 0x0000);
884 uec_phy_write(mii_info
, 0x1b, 0x800b);
885 uec_phy_write(mii_info
, 0x04, 0x05e1);
886 uec_phy_write(mii_info
, 0x00, 0xa100);
887 uec_phy_write(mii_info
, 0x00, 0x2100);
889 } else if (speed
== SPEED_10
) {
890 uec_phy_write(mii_info
, 0x14, 0x8e40);
891 uec_phy_write(mii_info
, 0x1b, 0x800b);
892 uec_phy_write(mii_info
, 0x14, 0x0c82);
893 uec_phy_write(mii_info
, 0x00, 0x8100);
898 /* handle 88e1111 rev.B2 erratum 5.6 */
899 if (mii_info
->autoneg
) {
900 status
= uec_phy_read(mii_info
, MII_BMCR
);
901 uec_phy_write(mii_info
, MII_BMCR
, status
| BMCR_ANENABLE
);
903 /* now the B2 will correctly report autoneg completion status */
906 void change_phy_interface_mode (struct eth_device
*dev
,
907 phy_interface_t type
, int speed
)
909 #ifdef CONFIG_PHY_MODE_NEED_CHANGE
910 marvell_phy_interface_mode (dev
, type
, speed
);