blob: a9a64466ac2df4960108156caa94a60a64480e71 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Andy Fleming60ca78b2011-04-07 21:56:05 -05002/*
3 * Micrel PHY drivers
4 *
Andy Fleming60ca78b2011-04-07 21:56:05 -05005 * Copyright 2010-2011 Freescale Semiconductor, Inc.
6 * author Andy Fleming
David Andreyf0d83c42013-02-06 22:18:37 +01007 * (C) 2012 NetModule AG, David Andrey, added KSZ9031
Andy Fleming60ca78b2011-04-07 21:56:05 -05008 */
Marek Vasut1005ce52015-12-05 17:41:58 +01009#include <dm.h>
10#include <errno.h>
11#include <fdtdec.h>
Troy Kisky80b6b092012-02-07 14:08:48 +000012#include <micrel.h>
Andy Fleming60ca78b2011-04-07 21:56:05 -050013#include <phy.h>
Simon Glass4dcacfc2020-05-10 11:40:13 -060014#include <linux/bitops.h>
Andy Fleming60ca78b2011-04-07 21:56:05 -050015
Marek Vasutcbf9f5c2023-03-19 18:02:55 +010016U_BOOT_PHY_DRIVER(ksz804) = {
Andy Fleming60ca78b2011-04-07 21:56:05 -050017 .name = "Micrel KSZ804",
18 .uid = 0x221510,
19 .mask = 0xfffff0,
20 .features = PHY_BASIC_FEATURES,
21 .config = &genphy_config,
22 .startup = &genphy_startup,
23 .shutdown = &genphy_shutdown,
24};
25
Alexandre Messier94bde102016-01-22 14:06:33 -050026#define MII_KSZPHY_OMSO 0x16
Nicolas Ferre45d262d2019-10-23 10:46:44 +000027#define KSZPHY_OMSO_FACTORY_TEST BIT(15)
Alexandre Messier94bde102016-01-22 14:06:33 -050028#define KSZPHY_OMSO_B_CAST_OFF (1 << 9)
29
30static int ksz_genconfig_bcastoff(struct phy_device *phydev)
31{
32 int ret;
33
34 ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO);
35 if (ret < 0)
36 return ret;
37
38 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO,
39 ret | KSZPHY_OMSO_B_CAST_OFF);
40 if (ret < 0)
41 return ret;
42
43 return genphy_config(phydev);
44}
45
Marek Vasutcbf9f5c2023-03-19 18:02:55 +010046U_BOOT_PHY_DRIVER(ksz8031) = {
Sylvain Lemieuxbd8d3002015-09-09 16:29:51 -040047 .name = "Micrel KSZ8021/KSZ8031",
48 .uid = 0x221550,
49 .mask = 0xfffff0,
50 .features = PHY_BASIC_FEATURES,
Alexandre Messier94bde102016-01-22 14:06:33 -050051 .config = &ksz_genconfig_bcastoff,
Sylvain Lemieuxbd8d3002015-09-09 16:29:51 -040052 .startup = &genphy_startup,
53 .shutdown = &genphy_shutdown,
54};
55
Sylvain Rochet23e9d5c2015-10-07 22:54:22 +020056/**
57 * KSZ8051
58 */
59#define MII_KSZ8051_PHY_OMSO 0x16
60#define MII_KSZ8051_PHY_OMSO_NAND_TREE_ON (1 << 5)
61
62static int ksz8051_config(struct phy_device *phydev)
63{
64 unsigned val;
65
66 /* Disable NAND-tree */
67 val = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO);
68 val &= ~MII_KSZ8051_PHY_OMSO_NAND_TREE_ON;
69 phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO, val);
70
71 return genphy_config(phydev);
72}
73
Marek Vasutcbf9f5c2023-03-19 18:02:55 +010074U_BOOT_PHY_DRIVER(ksz8051) = {
Sylvain Rochet23e9d5c2015-10-07 22:54:22 +020075 .name = "Micrel KSZ8051",
76 .uid = 0x221550,
77 .mask = 0xfffff0,
78 .features = PHY_BASIC_FEATURES,
79 .config = &ksz8051_config,
80 .startup = &genphy_startup,
81 .shutdown = &genphy_shutdown,
82};
83
Bryan O'Donoghuea8267d42020-03-26 03:54:01 +000084static int ksz8061_config(struct phy_device *phydev)
85{
86 return phy_write(phydev, MDIO_MMD_PMAPMD, MDIO_DEVID1, 0xB61A);
87}
88
Marek Vasutcbf9f5c2023-03-19 18:02:55 +010089U_BOOT_PHY_DRIVER(ksz8061) = {
Bryan O'Donoghuea8267d42020-03-26 03:54:01 +000090 .name = "Micrel KSZ8061",
91 .uid = 0x00221570,
92 .mask = 0xfffff0,
93 .features = PHY_BASIC_FEATURES,
94 .config = &ksz8061_config,
95 .startup = &genphy_startup,
96 .shutdown = &genphy_shutdown,
97};
98
Nicolas Ferre45d262d2019-10-23 10:46:44 +000099static int ksz8081_config(struct phy_device *phydev)
100{
101 int ret;
102
103 ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO);
104 if (ret < 0)
105 return ret;
106
107 ret &= ~KSZPHY_OMSO_FACTORY_TEST;
108
109 ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO,
110 ret | KSZPHY_OMSO_B_CAST_OFF);
111 if (ret < 0)
112 return ret;
113
114 return genphy_config(phydev);
115}
116
Marek Vasutcbf9f5c2023-03-19 18:02:55 +0100117U_BOOT_PHY_DRIVER(ksz8081) = {
Luca Elleroadeb9ea2015-03-24 11:32:24 +0100118 .name = "Micrel KSZ8081",
119 .uid = 0x221560,
120 .mask = 0xfffff0,
121 .features = PHY_BASIC_FEATURES,
Nicolas Ferre45d262d2019-10-23 10:46:44 +0000122 .config = &ksz8081_config,
Luca Elleroadeb9ea2015-03-24 11:32:24 +0100123 .startup = &genphy_startup,
124 .shutdown = &genphy_shutdown,
125};
126
Philippe De Muyter2616b212014-02-19 17:21:59 +0100127/**
128 * KSZ8895
129 */
130
131static unsigned short smireg_to_phy(unsigned short reg)
132{
133 return ((reg & 0xc0) >> 3) + 0x06 + ((reg & 0x20) >> 5);
134}
135
136static unsigned short smireg_to_reg(unsigned short reg)
137{
138 return reg & 0x1F;
139}
140
141static void ksz8895_write_smireg(struct phy_device *phydev, int smireg, int val)
142{
143 phydev->bus->write(phydev->bus, smireg_to_phy(smireg), MDIO_DEVAD_NONE,
144 smireg_to_reg(smireg), val);
145}
146
147#if 0
148static int ksz8895_read_smireg(struct phy_device *phydev, int smireg)
149{
150 return phydev->bus->read(phydev->bus, smireg_to_phy(smireg),
151 MDIO_DEVAD_NONE, smireg_to_reg(smireg));
152}
153#endif
154
155int ksz8895_config(struct phy_device *phydev)
156{
157 /* we are connected directly to the switch without
158 * dedicated PHY. SCONF1 == 001 */
159 phydev->link = 1;
160 phydev->duplex = DUPLEX_FULL;
161 phydev->speed = SPEED_100;
162
163 /* Force the switch to start */
164 ksz8895_write_smireg(phydev, 1, 1);
165
166 return 0;
167}
168
169static int ksz8895_startup(struct phy_device *phydev)
170{
171 return 0;
172}
173
Marek Vasutcbf9f5c2023-03-19 18:02:55 +0100174U_BOOT_PHY_DRIVER(ksz8895) = {
Philippe De Muyter2616b212014-02-19 17:21:59 +0100175 .name = "Micrel KSZ8895/KSZ8864",
176 .uid = 0x221450,
177 .mask = 0xffffe1,
178 .features = PHY_BASIC_FEATURES,
179 .config = &ksz8895_config,
180 .startup = &ksz8895_startup,
181 .shutdown = &genphy_shutdown,
182};
183
James Byrnebc292c22019-03-06 12:48:27 +0000184/* Micrel used the exact same model number for the KSZ9021,
185 * so the revision number is used to distinguish them.
186 */
Marek Vasutcbf9f5c2023-03-19 18:02:55 +0100187U_BOOT_PHY_DRIVER(ks8721) = {
Vladimir Zapolskiya4baa582011-12-06 02:47:57 +0000188 .name = "Micrel KS8721BL",
James Byrnebc292c22019-03-06 12:48:27 +0000189 .uid = 0x221618,
190 .mask = 0xfffffc,
Vladimir Zapolskiya4baa582011-12-06 02:47:57 +0000191 .features = PHY_BASIC_FEATURES,
192 .config = &genphy_config,
193 .startup = &genphy_startup,
194 .shutdown = &genphy_shutdown,
195};
David Andreyf0d83c42013-02-06 22:18:37 +0100196
Alexey Firago73823fa2016-05-26 16:28:44 +0300197int ksz886x_config(struct phy_device *phydev)
198{
199 /* we are connected directly to the switch without
200 * dedicated PHY. */
201 phydev->link = 1;
202 phydev->duplex = DUPLEX_FULL;
203 phydev->speed = SPEED_100;
204 return 0;
205}
206
207static int ksz886x_startup(struct phy_device *phydev)
208{
209 return 0;
210}
211
Marek Vasutcbf9f5c2023-03-19 18:02:55 +0100212U_BOOT_PHY_DRIVER(ksz886x) = {
Alexey Firago73823fa2016-05-26 16:28:44 +0300213 .name = "Micrel KSZ886x Switch",
214 .uid = 0x00221430,
215 .mask = 0xfffff0,
216 .features = PHY_BASIC_FEATURES,
217 .config = &ksz886x_config,
218 .startup = &ksz886x_startup,
219 .shutdown = &genphy_shutdown,
220};