1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/
4 * Written by Jean-Jacques Hiblot <jjhiblot@ti.com>
5 */
6
7 #define LOG_CATEGORY UCLASS_PHY
8
9 #include <dm.h>
10 #include <dm/device_compat.h>
11 #include <dm/devres.h>
12 #include <generic-phy.h>
13 #include <linux/list.h>
14 #include <linux/printk.h>
15 #include <power/regulator.h>
16
17 /**
18 * struct phy_counts - Init and power-on counts of a single PHY port
19 *
20 * This structure is used to keep track of PHY initialization and power
21 * state change requests, so that we don't power off and deinitialize a
22 * PHY instance until all of its users want it done. Otherwise, multiple
23 * consumers using the same PHY port can cause problems (e.g. one might
24 * call power_off() after another's exit() and hang indefinitely).
25 *
26 * @id: The PHY ID within a PHY provider
27 * @power_on_count: Times generic_phy_power_on() was called for this ID
28 * without a matching generic_phy_power_off() afterwards
29 * @init_count: Times generic_phy_init() was called for this ID
30 * without a matching generic_phy_exit() afterwards
31 * @list: Handle for a linked list of these structures corresponding to
32 * ports of the same PHY provider
33 * @supply: Handle to a phy-supply device
34 */
35 struct phy_counts {
36 unsigned long id;
37 int power_on_count;
38 int init_count;
39 struct list_head list;
40 struct udevice *supply;
41 };
42
phy_dev_ops(struct udevice * dev)43 static inline struct phy_ops *phy_dev_ops(struct udevice *dev)
44 {
45 return (struct phy_ops *)dev->driver->ops;
46 }
47
phy_get_counts(struct phy * phy)48 static struct phy_counts *phy_get_counts(struct phy *phy)
49 {
50 struct list_head *uc_priv;
51 struct phy_counts *counts;
52
53 if (!generic_phy_valid(phy))
54 return NULL;
55
56 uc_priv = dev_get_uclass_priv(phy->dev);
57 list_for_each_entry(counts, uc_priv, list)
58 if (counts->id == phy->id)
59 return counts;
60
61 return NULL;
62 }
63
phy_alloc_counts(struct phy * phy,struct udevice * supply)64 static int phy_alloc_counts(struct phy *phy, struct udevice *supply)
65 {
66 struct list_head *uc_priv;
67 struct phy_counts *counts;
68
69 if (!generic_phy_valid(phy))
70 return 0;
71 if (phy_get_counts(phy))
72 return 0;
73
74 uc_priv = dev_get_uclass_priv(phy->dev);
75 counts = kzalloc(sizeof(*counts), GFP_KERNEL);
76 if (!counts)
77 return -ENOMEM;
78
79 counts->id = phy->id;
80 counts->power_on_count = 0;
81 counts->init_count = 0;
82 counts->supply = supply;
83 list_add(&counts->list, uc_priv);
84
85 return 0;
86 }
87
phy_uclass_pre_probe(struct udevice * dev)88 static int phy_uclass_pre_probe(struct udevice *dev)
89 {
90 struct list_head *uc_priv = dev_get_uclass_priv(dev);
91
92 INIT_LIST_HEAD(uc_priv);
93
94 return 0;
95 }
96
phy_uclass_pre_remove(struct udevice * dev)97 static int phy_uclass_pre_remove(struct udevice *dev)
98 {
99 struct list_head *uc_priv = dev_get_uclass_priv(dev);
100 struct phy_counts *counts, *next;
101
102 list_for_each_entry_safe(counts, next, uc_priv, list)
103 kfree(counts);
104
105 return 0;
106 }
107
generic_phy_xlate_offs_flags(struct phy * phy,struct ofnode_phandle_args * args)108 static int generic_phy_xlate_offs_flags(struct phy *phy,
109 struct ofnode_phandle_args *args)
110 {
111 debug("%s(phy=%p)\n", __func__, phy);
112
113 if (args->args_count > 1) {
114 debug("Invalid args_count: %d\n", args->args_count);
115 return -EINVAL;
116 }
117
118 if (args->args_count)
119 phy->id = args->args[0];
120 else
121 phy->id = 0;
122
123 return 0;
124 }
125
generic_phy_get_by_index_nodev(ofnode node,int index,struct phy * phy)126 int generic_phy_get_by_index_nodev(ofnode node, int index, struct phy *phy)
127 {
128 struct ofnode_phandle_args args;
129 struct phy_ops *ops;
130 struct udevice *phydev, *supply = NULL;
131 int i, ret;
132
133 debug("%s(node=%s, index=%d, phy=%p)\n",
134 __func__, ofnode_get_name(node), index, phy);
135
136 assert(phy);
137 phy->dev = NULL;
138 ret = ofnode_parse_phandle_with_args(node, "phys", "#phy-cells", 0,
139 index, &args);
140 if (ret) {
141 debug("%s: dev_read_phandle_with_args failed: err=%d\n",
142 __func__, ret);
143 return ret;
144 }
145
146 ret = uclass_get_device_by_ofnode(UCLASS_PHY, args.node, &phydev);
147 if (ret) {
148 debug("%s: uclass_get_device_by_ofnode failed: err=%d\n",
149 __func__, ret);
150
151 /* Check if args.node's parent is a PHY provider */
152 ret = uclass_get_device_by_ofnode(UCLASS_PHY,
153 ofnode_get_parent(args.node),
154 &phydev);
155 if (ret)
156 return ret;
157
158 /* insert phy idx at first position into args array */
159 for (i = args.args_count; i >= 1 ; i--)
160 args.args[i] = args.args[i - 1];
161
162 args.args_count++;
163 args.args[0] = ofnode_read_u32_default(args.node, "reg", -1);
164 }
165
166 phy->dev = phydev;
167
168 ops = phy_dev_ops(phydev);
169
170 if (ops->of_xlate)
171 ret = ops->of_xlate(phy, &args);
172 else
173 ret = generic_phy_xlate_offs_flags(phy, &args);
174 if (ret) {
175 debug("of_xlate() failed: %d\n", ret);
176 goto err;
177 }
178
179 if (CONFIG_IS_ENABLED(DM_REGULATOR)) {
180 ret = device_get_supply_regulator(phydev, "phy-supply",
181 &supply);
182 if (ret && ret != -ENOENT) {
183 debug("%s: device_get_supply_regulator failed: %d\n",
184 __func__, ret);
185 goto err;
186 }
187 }
188
189 ret = phy_alloc_counts(phy, supply);
190 if (ret) {
191 debug("phy_alloc_counts() failed: %d\n", ret);
192 goto err;
193 }
194
195 return 0;
196
197 err:
198 phy->dev = NULL;
199 return ret;
200 }
201
generic_phy_get_by_index(struct udevice * dev,int index,struct phy * phy)202 int generic_phy_get_by_index(struct udevice *dev, int index,
203 struct phy *phy)
204 {
205 return generic_phy_get_by_index_nodev(dev_ofnode(dev), index, phy);
206 }
207
generic_phy_get_by_name(struct udevice * dev,const char * phy_name,struct phy * phy)208 int generic_phy_get_by_name(struct udevice *dev, const char *phy_name,
209 struct phy *phy)
210 {
211 int index;
212
213 debug("%s(dev=%p, name=%s, phy=%p)\n", __func__, dev, phy_name, phy);
214
215 assert(phy);
216 phy->dev = NULL;
217
218 index = dev_read_stringlist_search(dev, "phy-names", phy_name);
219 if (index < 0) {
220 debug("dev_read_stringlist_search() failed: %d\n", index);
221 return index;
222 }
223
224 return generic_phy_get_by_index(dev, index, phy);
225 }
226
generic_phy_init(struct phy * phy)227 int generic_phy_init(struct phy *phy)
228 {
229 struct phy_counts *counts;
230 struct phy_ops const *ops;
231 int ret;
232
233 if (!generic_phy_valid(phy))
234 return 0;
235 counts = phy_get_counts(phy);
236 if (counts->init_count > 0) {
237 counts->init_count++;
238 return 0;
239 }
240
241 ops = phy_dev_ops(phy->dev);
242 if (ops->init) {
243 ret = ops->init(phy);
244 if (ret) {
245 dev_err(phy->dev, "PHY: Failed to init %s: %d.\n",
246 phy->dev->name, ret);
247 return ret;
248 }
249 }
250 counts->init_count = 1;
251
252 return 0;
253 }
254
generic_phy_reset(struct phy * phy)255 int generic_phy_reset(struct phy *phy)
256 {
257 struct phy_ops const *ops;
258 int ret;
259
260 if (!generic_phy_valid(phy))
261 return 0;
262 ops = phy_dev_ops(phy->dev);
263 if (!ops->reset)
264 return 0;
265 ret = ops->reset(phy);
266 if (ret)
267 dev_err(phy->dev, "PHY: Failed to reset %s: %d.\n",
268 phy->dev->name, ret);
269
270 return ret;
271 }
272
generic_phy_exit(struct phy * phy)273 int generic_phy_exit(struct phy *phy)
274 {
275 struct phy_counts *counts;
276 struct phy_ops const *ops;
277 int ret;
278
279 if (!generic_phy_valid(phy))
280 return 0;
281 counts = phy_get_counts(phy);
282 if (counts->init_count == 0)
283 return 0;
284 if (counts->init_count > 1) {
285 counts->init_count--;
286 return 0;
287 }
288
289 ops = phy_dev_ops(phy->dev);
290 if (ops->exit) {
291 ret = ops->exit(phy);
292 if (ret) {
293 dev_err(phy->dev, "PHY: Failed to exit %s: %d.\n",
294 phy->dev->name, ret);
295 return ret;
296 }
297 }
298 counts->init_count = 0;
299
300 return 0;
301 }
302
generic_phy_power_on(struct phy * phy)303 int generic_phy_power_on(struct phy *phy)
304 {
305 struct phy_counts *counts;
306 struct phy_ops const *ops;
307 int ret;
308
309 if (!generic_phy_valid(phy))
310 return 0;
311 counts = phy_get_counts(phy);
312 if (counts->power_on_count > 0) {
313 counts->power_on_count++;
314 return 0;
315 }
316
317 ret = regulator_set_enable_if_allowed(counts->supply, true);
318 if (ret && ret != -ENOSYS) {
319 dev_err(phy->dev, "PHY: Failed to enable regulator %s: %d.\n",
320 counts->supply->name, ret);
321 return ret;
322 }
323
324 ops = phy_dev_ops(phy->dev);
325 if (ops->power_on) {
326 ret = ops->power_on(phy);
327 if (ret) {
328 dev_err(phy->dev, "PHY: Failed to power on %s: %d.\n",
329 phy->dev->name, ret);
330 regulator_set_enable_if_allowed(counts->supply, false);
331 return ret;
332 }
333 }
334 counts->power_on_count = 1;
335
336 return 0;
337 }
338
generic_phy_power_off(struct phy * phy)339 int generic_phy_power_off(struct phy *phy)
340 {
341 struct phy_counts *counts;
342 struct phy_ops const *ops;
343 int ret;
344
345 if (!generic_phy_valid(phy))
346 return 0;
347 counts = phy_get_counts(phy);
348 if (counts->power_on_count == 0)
349 return 0;
350 if (counts->power_on_count > 1) {
351 counts->power_on_count--;
352 return 0;
353 }
354
355 ops = phy_dev_ops(phy->dev);
356 if (ops->power_off) {
357 ret = ops->power_off(phy);
358 if (ret) {
359 dev_err(phy->dev, "PHY: Failed to power off %s: %d.\n",
360 phy->dev->name, ret);
361 return ret;
362 }
363 }
364 counts->power_on_count = 0;
365
366 ret = regulator_set_enable_if_allowed(counts->supply, false);
367 if (ret && ret != -ENOSYS)
368 dev_err(phy->dev, "PHY: Failed to disable regulator %s: %d.\n",
369 counts->supply->name, ret);
370
371 return 0;
372 }
373
generic_phy_configure(struct phy * phy,void * params)374 int generic_phy_configure(struct phy *phy, void *params)
375 {
376 struct phy_ops const *ops;
377
378 if (!generic_phy_valid(phy))
379 return 0;
380 ops = phy_dev_ops(phy->dev);
381
382 return ops->configure ? ops->configure(phy, params) : 0;
383 }
384
generic_phy_set_mode(struct phy * phy,enum phy_mode mode,int submode)385 int generic_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
386 {
387 struct phy_ops const *ops;
388
389 if (!generic_phy_valid(phy))
390 return 0;
391 ops = phy_dev_ops(phy->dev);
392
393 return ops->set_mode ? ops->set_mode(phy, mode, submode) : 0;
394 }
395
generic_phy_set_speed(struct phy * phy,int speed)396 int generic_phy_set_speed(struct phy *phy, int speed)
397 {
398 struct phy_ops const *ops;
399
400 if (!generic_phy_valid(phy))
401 return 0;
402 ops = phy_dev_ops(phy->dev);
403
404 return ops->set_speed ? ops->set_speed(phy, speed) : 0;
405 }
406
generic_phy_get_bulk(struct udevice * dev,struct phy_bulk * bulk)407 int generic_phy_get_bulk(struct udevice *dev, struct phy_bulk *bulk)
408 {
409 int i, ret, count;
410 struct udevice *phydev = dev;
411
412 bulk->count = 0;
413
414 /* Return if no phy declared */
415 if (!dev_read_prop(dev, "phys", NULL)) {
416 phydev = dev->parent;
417 if (!dev_read_prop(phydev, "phys", NULL)) {
418 pr_debug("%s : no phys property\n", __func__);
419 return 0;
420 }
421 }
422
423 count = dev_count_phandle_with_args(phydev, "phys", "#phy-cells", 0);
424 if (count < 1) {
425 pr_err("%s : no phys found %d\n", __func__, count);
426 return count;
427 }
428
429 bulk->phys = devm_kcalloc(phydev, count, sizeof(struct phy), GFP_KERNEL);
430 if (!bulk->phys)
431 return -ENOMEM;
432
433 for (i = 0; i < count; i++) {
434 ret = generic_phy_get_by_index(phydev, i, &bulk->phys[i]);
435 if (ret) {
436 pr_err("Failed to get PHY%d for %s\n", i, dev->name);
437 return ret;
438 }
439 bulk->count++;
440 }
441
442 return 0;
443 }
444
generic_phy_init_bulk(struct phy_bulk * bulk)445 int generic_phy_init_bulk(struct phy_bulk *bulk)
446 {
447 struct phy *phys = bulk->phys;
448 int i, ret;
449
450 for (i = 0; i < bulk->count; i++) {
451 ret = generic_phy_init(&phys[i]);
452 if (ret) {
453 pr_err("Can't init PHY%d\n", i);
454 goto phys_init_err;
455 }
456 }
457
458 return 0;
459
460 phys_init_err:
461 for (; i > 0; i--)
462 generic_phy_exit(&phys[i - 1]);
463
464 return ret;
465 }
466
generic_phy_exit_bulk(struct phy_bulk * bulk)467 int generic_phy_exit_bulk(struct phy_bulk *bulk)
468 {
469 struct phy *phys = bulk->phys;
470 int i, ret = 0;
471
472 for (i = 0; i < bulk->count; i++)
473 ret |= generic_phy_exit(&phys[i]);
474
475 return ret;
476 }
477
generic_phy_power_on_bulk(struct phy_bulk * bulk)478 int generic_phy_power_on_bulk(struct phy_bulk *bulk)
479 {
480 struct phy *phys = bulk->phys;
481 int i, ret;
482
483 for (i = 0; i < bulk->count; i++) {
484 ret = generic_phy_power_on(&phys[i]);
485 if (ret) {
486 pr_err("Can't power on PHY%d\n", i);
487 goto phys_poweron_err;
488 }
489 }
490
491 return 0;
492
493 phys_poweron_err:
494 for (; i > 0; i--)
495 generic_phy_power_off(&phys[i - 1]);
496
497 return ret;
498 }
499
generic_phy_power_off_bulk(struct phy_bulk * bulk)500 int generic_phy_power_off_bulk(struct phy_bulk *bulk)
501 {
502 struct phy *phys = bulk->phys;
503 int i, ret = 0;
504
505 for (i = 0; i < bulk->count; i++)
506 ret |= generic_phy_power_off(&phys[i]);
507
508 return ret;
509 }
510
generic_setup_phy(struct udevice * dev,struct phy * phy,int index,enum phy_mode mode,int submode)511 int generic_setup_phy(struct udevice *dev, struct phy *phy, int index,
512 enum phy_mode mode, int submode)
513 {
514 int ret;
515
516 ret = generic_phy_get_by_index(dev, index, phy);
517 if (ret)
518 return ret == -ENOENT ? 0 : ret;
519
520 ret = generic_phy_init(phy);
521 if (ret)
522 return ret;
523
524 ret = generic_phy_set_mode(phy, mode, submode);
525 if (ret)
526 goto phys_mode_err;
527
528 ret = generic_phy_power_on(phy);
529 if (ret)
530 goto phys_mode_err;
531
532 return 0;
533
534 phys_mode_err:
535 generic_phy_exit(phy);
536 return ret;
537 }
538
generic_shutdown_phy(struct phy * phy)539 int generic_shutdown_phy(struct phy *phy)
540 {
541 int ret;
542
543 if (!generic_phy_valid(phy))
544 return 0;
545
546 ret = generic_phy_power_off(phy);
547 if (ret)
548 return ret;
549
550 return generic_phy_exit(phy);
551 }
552
553 UCLASS_DRIVER(phy) = {
554 .id = UCLASS_PHY,
555 .name = "phy",
556 .pre_probe = phy_uclass_pre_probe,
557 .pre_remove = phy_uclass_pre_remove,
558 .per_device_auto = sizeof(struct list_head),
559 };
560