xref: /linux/drivers/net/phy/xpowers/ac200.c (revision 2d7eaeb05ae265bd64270376e6a2c0d80244771f)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * X-Powers AC200 Ethernet PHY package backend
4  *
5  * Copyright (c) 2022 Arm Ltd. (Andre Przywara <andre.przywara@arm.com>)
6  * Copyright (C) 2026 James Hilliard <james.hilliard1@gmail.com>
7  */
8 
9 #include <linux/bitfield.h>
10 #include <linux/clk.h>
11 #include <linux/i2c.h>
12 #include <linux/of.h>
13 #include <linux/phy.h>
14 #include <linux/regmap.h>
15 #include <linux/regulator/consumer.h>
16 #include <linux/slab.h>
17 
18 #include "acx00.h"
19 
20 #define AC200_EPHY_BPS_EFFUSE_OFFSET	3
21 #define AC200_EPHY_CLK_RATE_24_MHZ	24000000
22 #define AC200_EPHY_CLK_RATE_27_MHZ	27000000
23 
24 #define AC200_SYS_EPHY_CTL0_REG			0x0014
25 #define AC200_EPHY_RESET_DEASSERT		BIT(0)
26 #define AC200_EPHY_SYSCLK_ENABLE			BIT(1)
27 
28 #define AC200_SYS_EPHY_CTL1_REG			0x0016
29 #define AC200_EPHY_MII_IO_ENABLE			BIT(0)
30 
31 /* AC200-internal copy of the Ethernet PHY calibration eFuse. */
32 #define AC200_EFUSE_EPHY_REG			0x8004
33 
34 #define AC200_EPHY_CTL_REG			0x6000
35 #define AC200_EPHY_SHUTDOWN			BIT(0)
36 #define AC200_EPHY_CLK_SEL_24_MHZ		BIT(2)
37 #define AC200_EPHY_PHY_ADDR_MASK			GENMASK(8, 4)
38 #define AC200_EPHY_RMII_SEL			BIT(11)
39 #define AC200_EPHY_BPS_EFFUSE_MASK		GENMASK(15, 12)
40 
41 struct ac200_ephy_ctl {
42 	struct acx00_ephy_control control;
43 	struct regmap *regmap;
44 	struct regulator *vcc;
45 	struct device *dev;
46 	u16 ephy_ctl;
47 	unsigned int phy_addr;
48 	phy_interface_t interface;
49 	bool supply_enabled;
50 	bool powered;
51 };
52 
53 static u16 ac200_ephy_ctl_config(const struct ac200_ephy_ctl *priv)
54 {
55 	return priv->ephy_ctl |
56 		(priv->interface == PHY_INTERFACE_MODE_RMII ?
57 		 AC200_EPHY_RMII_SEL : 0) |
58 		FIELD_PREP(AC200_EPHY_PHY_ADDR_MASK, priv->phy_addr);
59 }
60 
61 static int ac200_ephy_ctl_write(struct ac200_ephy_ctl *priv,
62 				unsigned int reg, u16 value)
63 {
64 	int ret;
65 
66 	ret = regmap_write(priv->regmap, reg, value);
67 	if (ret)
68 		dev_err(priv->dev, "failed to write register %#x: %pe\n",
69 			reg, ERR_PTR(ret));
70 
71 	return ret;
72 }
73 
74 static int ac200_ephy_ctl_disable(struct ac200_ephy_ctl *priv)
75 {
76 	int err;
77 	int ret = 0;
78 
79 	if (priv->powered) {
80 		ret = ac200_ephy_ctl_write(priv, AC200_EPHY_CTL_REG,
81 					   ac200_ephy_ctl_config(priv) |
82 					   AC200_EPHY_SHUTDOWN);
83 		err = ac200_ephy_ctl_write(priv, AC200_SYS_EPHY_CTL1_REG, 0);
84 		if (!ret)
85 			ret = err;
86 		err = ac200_ephy_ctl_write(priv, AC200_SYS_EPHY_CTL0_REG, 0);
87 		if (!ret)
88 			ret = err;
89 
90 		priv->powered = false;
91 	}
92 
93 	if (priv->supply_enabled) {
94 		err = regulator_disable(priv->vcc);
95 		if (!err)
96 			priv->supply_enabled = false;
97 		else if (!ret)
98 			ret = err;
99 	}
100 
101 	return ret;
102 }
103 
104 static int ac200_ephy_ctl_power_off(struct acx00_ephy_control *control)
105 {
106 	struct ac200_ephy_ctl *priv =
107 		container_of(control, struct ac200_ephy_ctl, control);
108 
109 	return ac200_ephy_ctl_disable(priv);
110 }
111 
112 static int
113 ac200_ephy_ctl_set_interface(struct acx00_ephy_control *control,
114 			     phy_interface_t interface)
115 {
116 	struct ac200_ephy_ctl *priv =
117 		container_of(control, struct ac200_ephy_ctl, control);
118 	int ret = 0;
119 
120 	if (interface != PHY_INTERFACE_MODE_MII &&
121 	    interface != PHY_INTERFACE_MODE_RMII)
122 		return -EINVAL;
123 
124 	if (priv->interface == interface)
125 		return 0;
126 
127 	if (priv->powered)
128 		ret = regmap_update_bits(priv->regmap, AC200_EPHY_CTL_REG,
129 					 AC200_EPHY_RMII_SEL,
130 					 interface == PHY_INTERFACE_MODE_RMII ?
131 					 AC200_EPHY_RMII_SEL : 0);
132 	if (!ret)
133 		priv->interface = interface;
134 
135 	return ret;
136 }
137 
138 static int ac200_ephy_ctl_power_on(struct acx00_ephy_control *control,
139 				   unsigned int phy_addr)
140 {
141 	struct ac200_ephy_ctl *priv =
142 		container_of(control, struct ac200_ephy_ctl, control);
143 	u16 ephy_ctl;
144 	int ret;
145 
146 	if (phy_addr > FIELD_MAX(AC200_EPHY_PHY_ADDR_MASK))
147 		return -EINVAL;
148 
149 	if (priv->powered && priv->phy_addr == phy_addr)
150 		return 0;
151 
152 	if (priv->powered) {
153 		ret = ac200_ephy_ctl_disable(priv);
154 		if (ret)
155 			return ret;
156 	}
157 	priv->phy_addr = phy_addr;
158 
159 	if (!priv->supply_enabled) {
160 		ret = regulator_enable(priv->vcc);
161 		if (ret)
162 			return ret;
163 		priv->supply_enabled = true;
164 	}
165 
166 	ephy_ctl = ac200_ephy_ctl_config(priv);
167 
168 	/*
169 	 * Start from a disabled state before applying the configuration. AC200
170 	 * specifies no additional delay between these controls. The companion
171 	 * MFD provider has completed its input-clock startup delay before
172 	 * publishing the regmap.
173 	 */
174 	ret = ac200_ephy_ctl_write(priv, AC200_SYS_EPHY_CTL0_REG, 0);
175 	if (ret)
176 		goto err_disable;
177 
178 	ret = ac200_ephy_ctl_write(priv, AC200_SYS_EPHY_CTL1_REG,
179 				   AC200_EPHY_MII_IO_ENABLE);
180 	if (ret)
181 		goto err_disable;
182 
183 	ret = ac200_ephy_ctl_write(priv, AC200_EPHY_CTL_REG,
184 				   ephy_ctl | AC200_EPHY_SHUTDOWN);
185 	if (ret)
186 		goto err_disable;
187 
188 	ret = ac200_ephy_ctl_write(priv, AC200_SYS_EPHY_CTL0_REG,
189 				   AC200_EPHY_RESET_DEASSERT |
190 				   AC200_EPHY_SYSCLK_ENABLE);
191 	if (ret)
192 		goto err_disable;
193 
194 	ret = ac200_ephy_ctl_write(priv, AC200_EPHY_CTL_REG, ephy_ctl);
195 	if (ret)
196 		goto err_disable;
197 
198 	priv->powered = true;
199 	return 0;
200 
201 err_disable:
202 	/* Attempt every step of the shutdown sequence after a partial start. */
203 	priv->powered = true;
204 	ac200_ephy_ctl_disable(priv);
205 
206 	return ret;
207 }
208 
209 struct acx00_ephy_control *
210 ac200_ephy_ctl_create(struct phy_device *phydev,
211 		      struct device_node *package_node,
212 		      bool has_calibration, u8 calibration)
213 {
214 	struct device *dev = &phydev->mdio.dev;
215 	unsigned int internal_calibration;
216 	struct device_node *ac200_node;
217 	struct ac200_ephy_ctl *priv;
218 	struct i2c_client *client;
219 	unsigned long clk_rate;
220 	u8 bps_effuse_code;
221 	struct clk *clk;
222 	int ret;
223 
224 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
225 	if (!priv)
226 		return ERR_PTR(-ENOMEM);
227 	priv->dev = dev;
228 	priv->vcc = devm_of_regulator_get(dev, package_node, "vcc");
229 	if (IS_ERR(priv->vcc))
230 		return ERR_PTR(dev_err_probe(dev, PTR_ERR(priv->vcc),
231 					     "failed to get package supply\n"));
232 
233 	ac200_node = of_parse_phandle(package_node, "x-powers,ac200", 0);
234 	if (!ac200_node)
235 		return ERR_PTR(dev_err_probe(dev, -EINVAL,
236 					     "missing x-powers,ac200 reference\n"));
237 	client = of_find_i2c_device_by_node(ac200_node);
238 	of_node_put(ac200_node);
239 	if (!client) {
240 		ret = IS_ENABLED(CONFIG_I2C) ? -EPROBE_DEFER : -ENODEV;
241 		return ERR_PTR(dev_err_probe(dev, ret,
242 					     "AC200 device is not registered\n"));
243 	}
244 
245 	if (!device_link_add(dev, &client->dev,
246 			     DL_FLAG_AUTOREMOVE_CONSUMER)) {
247 		ret = dev_err_probe(dev, -EINVAL,
248 				    "failed to link AC200 device\n");
249 		goto out_put_client;
250 	}
251 
252 	device_lock(&client->dev);
253 	if (device_is_bound(&client->dev))
254 		priv->regmap = dev_get_regmap(&client->dev, NULL);
255 	device_unlock(&client->dev);
256 	if (!priv->regmap) {
257 		ret = dev_err_probe(dev, -EPROBE_DEFER,
258 				    "AC200 driver is not ready\n");
259 		goto out_put_client;
260 	}
261 
262 	if (!has_calibration) {
263 		ret = regmap_read(priv->regmap, AC200_EFUSE_EPHY_REG,
264 				  &internal_calibration);
265 		if (ret)
266 			goto out_error;
267 		calibration = internal_calibration;
268 	}
269 
270 	/* The vendor driver supplies no transfer function beyond this offset. */
271 	bps_effuse_code = (calibration + AC200_EPHY_BPS_EFFUSE_OFFSET) &
272 			   FIELD_MAX(AC200_EPHY_BPS_EFFUSE_MASK);
273 	priv->ephy_ctl =
274 		FIELD_PREP(AC200_EPHY_BPS_EFFUSE_MASK, bps_effuse_code);
275 	/* EPHY_MODE and BIST_CLK_EN stay clear for normal operation. */
276 
277 	clk = clk_get(&client->dev, NULL);
278 	if (IS_ERR(clk)) {
279 		ret = PTR_ERR(clk);
280 		goto out_error;
281 	}
282 
283 	/* The bound AC200 provider enables and exclusively pins this rate. */
284 	clk_rate = clk_get_rate(clk);
285 	clk_put(clk);
286 
287 	switch (clk_rate) {
288 	case AC200_EPHY_CLK_RATE_24_MHZ:
289 		priv->ephy_ctl |= AC200_EPHY_CLK_SEL_24_MHZ;
290 		break;
291 	case AC200_EPHY_CLK_RATE_27_MHZ:
292 		break;
293 	default:
294 		ret = dev_err_probe(dev, -EINVAL,
295 				    "unsupported AC200 clock rate %lu Hz\n",
296 				    clk_rate);
297 		goto out_put_client;
298 	}
299 
300 	priv->control.power_on = ac200_ephy_ctl_power_on;
301 	priv->control.power_off = ac200_ephy_ctl_power_off;
302 	priv->control.set_interface = ac200_ephy_ctl_set_interface;
303 	/* MII is the reset default used until the MAC supplies its interface. */
304 	priv->interface = PHY_INTERFACE_MODE_MII;
305 	put_device(&client->dev);
306 
307 	return &priv->control;
308 
309 out_error:
310 	ret = dev_err_probe(dev, ret, "failed to initialize AC200 control\n");
311 out_put_client:
312 	put_device(&client->dev);
313 	return ERR_PTR(ret);
314 }
315