]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/phy/micrel.c
Merge branch 'master' of git://git.denx.de/u-boot-nios
[karo-tx-uboot.git] / drivers / net / phy / micrel.c
1 /*
2  * Micrel PHY drivers
3  *
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
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
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
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17  * MA 02111-1307 USA
18  *
19  * Copyright 2010-2011 Freescale Semiconductor, Inc.
20  * author Andy Fleming
21  *
22  */
23 #include <config.h>
24 #include <common.h>
25 #include <micrel.h>
26 #include <phy.h>
27
28 static struct phy_driver KSZ804_driver = {
29         .name = "Micrel KSZ804",
30         .uid = 0x221510,
31         .mask = 0xfffff0,
32         .features = PHY_BASIC_FEATURES,
33         .config = &genphy_config,
34         .startup = &genphy_startup,
35         .shutdown = &genphy_shutdown,
36 };
37
38 static struct phy_driver KS8721_driver = {
39         .name = "Micrel KS8721BL",
40         .uid = 0x221610,
41         .mask = 0xfffff0,
42         .features = PHY_BASIC_FEATURES,
43         .config = &genphy_config,
44         .startup = &genphy_startup,
45         .shutdown = &genphy_shutdown,
46 };
47
48 /* ksz9021 PHY Registers */
49 #define MII_KSZ9021_EXTENDED_CTRL       0x0b
50 #define MII_KSZ9021_EXTENDED_DATAW      0x0c
51 #define MII_KSZ9021_EXTENDED_DATAR      0x0d
52 #define MII_KSZ9021_PHY_CTL             0x1f
53 #define MIIM_KSZ9021_PHYCTL_1000        (1 << 6)
54 #define MIIM_KSZ9021_PHYCTL_100         (1 << 5)
55 #define MIIM_KSZ9021_PHYCTL_10          (1 << 4)
56 #define MIIM_KSZ9021_PHYCTL_DUPLEX      (1 << 3)
57
58 #define CTRL1000_PREFER_MASTER          (1 << 10)
59 #define CTRL1000_CONFIG_MASTER          (1 << 11)
60 #define CTRL1000_MANUAL_CONFIG          (1 << 12)
61
62 int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val)
63 {
64         /* extended registers */
65         phy_write(phydev, MDIO_DEVAD_NONE,
66                 MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000);
67         return phy_write(phydev, MDIO_DEVAD_NONE,
68                 MII_KSZ9021_EXTENDED_DATAW, val);
69 }
70
71 int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum)
72 {
73         /* extended registers */
74         phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum);
75         return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);
76 }
77
78 /* Micrel ksz9021 */
79 static int ksz9021_config(struct phy_device *phydev)
80 {
81         unsigned ctrl1000 = 0;
82         const unsigned master = CTRL1000_PREFER_MASTER |
83                         CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
84         unsigned features = phydev->drv->features;
85
86         if (getenv("disable_giga"))
87                 features &= ~(SUPPORTED_1000baseT_Half |
88                                 SUPPORTED_1000baseT_Full);
89         /* force master mode for 1000BaseT due to chip errata */
90         if (features & SUPPORTED_1000baseT_Half)
91                 ctrl1000 |= ADVERTISE_1000HALF | master;
92         if (features & SUPPORTED_1000baseT_Full)
93                 ctrl1000 |= ADVERTISE_1000FULL | master;
94         phydev->advertising = phydev->supported = features;
95         phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
96         genphy_config_aneg(phydev);
97         genphy_restart_aneg(phydev);
98         return 0;
99 }
100
101 static int ksz9021_startup(struct phy_device *phydev)
102 {
103         unsigned phy_ctl;
104         genphy_update_link(phydev);
105         phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_PHY_CTL);
106
107         if (phy_ctl & MIIM_KSZ9021_PHYCTL_DUPLEX)
108                 phydev->duplex = DUPLEX_FULL;
109         else
110                 phydev->duplex = DUPLEX_HALF;
111
112         if (phy_ctl & MIIM_KSZ9021_PHYCTL_1000)
113                 phydev->speed = SPEED_1000;
114         else if (phy_ctl & MIIM_KSZ9021_PHYCTL_100)
115                 phydev->speed = SPEED_100;
116         else if (phy_ctl & MIIM_KSZ9021_PHYCTL_10)
117                 phydev->speed = SPEED_10;
118         return 0;
119 }
120
121 static struct phy_driver ksz9021_driver = {
122         .name = "Micrel ksz9021",
123         .uid  = 0x221610,
124         .mask = 0xfffff0,
125         .features = PHY_GBIT_FEATURES,
126         .config = &ksz9021_config,
127         .startup = &ksz9021_startup,
128         .shutdown = &genphy_shutdown,
129 };
130
131 int phy_micrel_init(void)
132 {
133         phy_register(&KSZ804_driver);
134         phy_register(&KS8721_driver);
135         phy_register(&ksz9021_driver);
136
137         return 0;
138 }