blob: aa9cbcfffc0465075ed7574e7ac76ffea908db48 [file] [log] [blame]
Andy Fleming9082eea2011-04-07 21:56:05 -05001/*
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
David Andrey62d7dba2013-02-06 22:18:37 +010021 * (C) 2012 NetModule AG, David Andrey, added KSZ9031
Andy Fleming9082eea2011-04-07 21:56:05 -050022 *
23 */
Troy Kisky8682aba2012-02-07 14:08:48 +000024#include <config.h>
25#include <common.h>
26#include <micrel.h>
Andy Fleming9082eea2011-04-07 21:56:05 -050027#include <phy.h>
28
29static struct phy_driver KSZ804_driver = {
30 .name = "Micrel KSZ804",
31 .uid = 0x221510,
32 .mask = 0xfffff0,
33 .features = PHY_BASIC_FEATURES,
34 .config = &genphy_config,
35 .startup = &genphy_startup,
36 .shutdown = &genphy_shutdown,
37};
38
Troy Kiskycc5f5522012-06-28 08:00:28 +000039#ifndef CONFIG_PHY_MICREL_KSZ9021
40/*
41 * I can't believe Micrel used the exact same part number
42 * for the KSZ9021
43 * Shame Micrel, Shame!!!!!
44 */
Vladimir Zapolskiyfcc0c752011-12-06 02:47:57 +000045static struct phy_driver KS8721_driver = {
46 .name = "Micrel KS8721BL",
47 .uid = 0x221610,
48 .mask = 0xfffff0,
49 .features = PHY_BASIC_FEATURES,
50 .config = &genphy_config,
51 .startup = &genphy_startup,
52 .shutdown = &genphy_shutdown,
53};
Troy Kiskycc5f5522012-06-28 08:00:28 +000054#endif
Vladimir Zapolskiyfcc0c752011-12-06 02:47:57 +000055
David Andrey62d7dba2013-02-06 22:18:37 +010056
57/**
58 * KSZ9021 - KSZ9031 common
59 */
60
61#define MII_KSZ90xx_PHY_CTL 0x1f
62#define MIIM_KSZ90xx_PHYCTL_1000 (1 << 6)
63#define MIIM_KSZ90xx_PHYCTL_100 (1 << 5)
64#define MIIM_KSZ90xx_PHYCTL_10 (1 << 4)
65#define MIIM_KSZ90xx_PHYCTL_DUPLEX (1 << 3)
66
67static int ksz90xx_startup(struct phy_device *phydev)
68{
69 unsigned phy_ctl;
70 genphy_update_link(phydev);
71 phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ90xx_PHY_CTL);
72
73 if (phy_ctl & MIIM_KSZ90xx_PHYCTL_DUPLEX)
74 phydev->duplex = DUPLEX_FULL;
75 else
76 phydev->duplex = DUPLEX_HALF;
77
78 if (phy_ctl & MIIM_KSZ90xx_PHYCTL_1000)
79 phydev->speed = SPEED_1000;
80 else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_100)
81 phydev->speed = SPEED_100;
82 else if (phy_ctl & MIIM_KSZ90xx_PHYCTL_10)
83 phydev->speed = SPEED_10;
84 return 0;
85}
Troy Kiskycc5f5522012-06-28 08:00:28 +000086#ifdef CONFIG_PHY_MICREL_KSZ9021
David Andrey62d7dba2013-02-06 22:18:37 +010087
88/*
89 * KSZ9021
90 */
91
92/* PHY Registers */
Troy Kisky8682aba2012-02-07 14:08:48 +000093#define MII_KSZ9021_EXTENDED_CTRL 0x0b
94#define MII_KSZ9021_EXTENDED_DATAW 0x0c
95#define MII_KSZ9021_EXTENDED_DATAR 0x0d
Troy Kisky8682aba2012-02-07 14:08:48 +000096
97#define CTRL1000_PREFER_MASTER (1 << 10)
98#define CTRL1000_CONFIG_MASTER (1 << 11)
99#define CTRL1000_MANUAL_CONFIG (1 << 12)
100
101int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val)
102{
103 /* extended registers */
104 phy_write(phydev, MDIO_DEVAD_NONE,
105 MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000);
106 return phy_write(phydev, MDIO_DEVAD_NONE,
107 MII_KSZ9021_EXTENDED_DATAW, val);
108}
109
110int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum)
111{
112 /* extended registers */
113 phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum);
114 return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);
115}
116
117/* Micrel ksz9021 */
118static int ksz9021_config(struct phy_device *phydev)
119{
120 unsigned ctrl1000 = 0;
121 const unsigned master = CTRL1000_PREFER_MASTER |
122 CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
123 unsigned features = phydev->drv->features;
124
125 if (getenv("disable_giga"))
126 features &= ~(SUPPORTED_1000baseT_Half |
127 SUPPORTED_1000baseT_Full);
128 /* force master mode for 1000BaseT due to chip errata */
129 if (features & SUPPORTED_1000baseT_Half)
130 ctrl1000 |= ADVERTISE_1000HALF | master;
131 if (features & SUPPORTED_1000baseT_Full)
132 ctrl1000 |= ADVERTISE_1000FULL | master;
133 phydev->advertising = phydev->supported = features;
134 phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
135 genphy_config_aneg(phydev);
136 genphy_restart_aneg(phydev);
137 return 0;
138}
139
Troy Kisky8682aba2012-02-07 14:08:48 +0000140static struct phy_driver ksz9021_driver = {
141 .name = "Micrel ksz9021",
142 .uid = 0x221610,
143 .mask = 0xfffff0,
144 .features = PHY_GBIT_FEATURES,
145 .config = &ksz9021_config,
David Andrey62d7dba2013-02-06 22:18:37 +0100146 .startup = &ksz90xx_startup,
Troy Kisky8682aba2012-02-07 14:08:48 +0000147 .shutdown = &genphy_shutdown,
148};
Troy Kiskycc5f5522012-06-28 08:00:28 +0000149#endif
Troy Kisky8682aba2012-02-07 14:08:48 +0000150
SARTRE Leo42a7cb52013-04-30 16:57:25 +0200151/**
David Andrey62d7dba2013-02-06 22:18:37 +0100152 * KSZ9031
153 */
SARTRE Leo42a7cb52013-04-30 16:57:25 +0200154/* PHY Registers */
155#define MII_KSZ9031_MMD_ACCES_CTRL 0x0d
156#define MII_KSZ9031_MMD_REG_DATA 0x0e
157
158/* Accessors to extended registers*/
159int ksz9031_phy_extended_write(struct phy_device *phydev,
160 int devaddr, int regnum, u16 mode, u16 val)
161{
162 /*select register addr for mmd*/
163 phy_write(phydev, MDIO_DEVAD_NONE,
164 MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
165 /*select register for mmd*/
166 phy_write(phydev, MDIO_DEVAD_NONE,
167 MII_KSZ9031_MMD_REG_DATA, regnum);
168 /*setup mode*/
169 phy_write(phydev, MDIO_DEVAD_NONE,
170 MII_KSZ9031_MMD_ACCES_CTRL, (mode | devaddr));
171 /*write the value*/
172 return phy_write(phydev, MDIO_DEVAD_NONE,
173 MII_KSZ9031_MMD_REG_DATA, val);
174}
175
176int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr,
177 int regnum, u16 mode)
178{
179 phy_write(phydev, MDIO_DEVAD_NONE,
180 MII_KSZ9031_MMD_ACCES_CTRL, devaddr);
181 phy_write(phydev, MDIO_DEVAD_NONE,
182 MII_KSZ9031_MMD_REG_DATA, regnum);
183 phy_write(phydev, MDIO_DEVAD_NONE,
184 MII_KSZ9031_MMD_ACCES_CTRL, (devaddr | mode));
185 return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA);
186}
187
David Andrey62d7dba2013-02-06 22:18:37 +0100188static struct phy_driver ksz9031_driver = {
189 .name = "Micrel ksz9031",
190 .uid = 0x221620,
191 .mask = 0xfffffe,
192 .features = PHY_GBIT_FEATURES,
193 .config = &genphy_config,
194 .startup = &ksz90xx_startup,
195 .shutdown = &genphy_shutdown,
196};
197
Andy Fleming9082eea2011-04-07 21:56:05 -0500198int phy_micrel_init(void)
199{
200 phy_register(&KSZ804_driver);
Troy Kiskycc5f5522012-06-28 08:00:28 +0000201#ifdef CONFIG_PHY_MICREL_KSZ9021
Troy Kisky8682aba2012-02-07 14:08:48 +0000202 phy_register(&ksz9021_driver);
Troy Kiskycc5f5522012-06-28 08:00:28 +0000203#else
204 phy_register(&KS8721_driver);
205#endif
David Andrey62d7dba2013-02-06 22:18:37 +0100206 phy_register(&ksz9031_driver);
Andy Fleming9082eea2011-04-07 21:56:05 -0500207 return 0;
208}