"Das U-Boot" Source Tree
at master 559 lines 12 kB view raw
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 */ 35struct 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 43static inline struct phy_ops *phy_dev_ops(struct udevice *dev) 44{ 45 return (struct phy_ops *)dev->driver->ops; 46} 47 48static 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 64static 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 88static 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 97static 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 108static 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 126int 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 197err: 198 phy->dev = NULL; 199 return ret; 200} 201 202int 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 208int 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 227int 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 255int 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 273int 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 303int 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 339int 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 374int 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 385int 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 396int 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 407int 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 445int 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 460phys_init_err: 461 for (; i > 0; i--) 462 generic_phy_exit(&phys[i - 1]); 463 464 return ret; 465} 466 467int 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 478int 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 493phys_poweron_err: 494 for (; i > 0; i--) 495 generic_phy_power_off(&phys[i - 1]); 496 497 return ret; 498} 499 500int 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 511int 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 534phys_mode_err: 535 generic_phy_exit(phy); 536 return ret; 537} 538 539int 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 553UCLASS_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};