xilinx_phy.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Xilinx PCS/PMA Core phy driver
  4. *
  5. * Copyright (C) 2015 - 2016 Xilinx, Inc.
  6. */
  7. #include <config.h>
  8. #include <common.h>
  9. #include <log.h>
  10. #include <phy.h>
  11. #include <dm.h>
  12. #define MII_PHY_STATUS_SPD_MASK 0x0C00
  13. #define MII_PHY_STATUS_FULLDUPLEX 0x1000
  14. #define MII_PHY_STATUS_1000 0x0800
  15. #define MII_PHY_STATUS_100 0x0400
  16. #define XPCSPMA_PHY_CTRL_ISOLATE_DISABLE 0xFBFF
  17. /* Mask used for ID comparisons */
  18. #define XILINX_PHY_ID_MASK 0xfffffff0
  19. /* Known PHY IDs */
  20. #define XILINX_PHY_ID 0x01740c00
  21. /* struct phy_device dev_flags definitions */
  22. #define XAE_PHY_TYPE_MII 0
  23. #define XAE_PHY_TYPE_GMII 1
  24. #define XAE_PHY_TYPE_RGMII_1_3 2
  25. #define XAE_PHY_TYPE_RGMII_2_0 3
  26. #define XAE_PHY_TYPE_SGMII 4
  27. #define XAE_PHY_TYPE_1000BASE_X 5
  28. static int xilinxphy_startup(struct phy_device *phydev)
  29. {
  30. int err;
  31. int status = 0;
  32. debug("%s\n", __func__);
  33. /* Update the link, but return if there
  34. * was an error
  35. */
  36. err = genphy_update_link(phydev);
  37. if (err)
  38. return err;
  39. if (AUTONEG_ENABLE == phydev->autoneg) {
  40. status = phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
  41. status = status & MII_PHY_STATUS_SPD_MASK;
  42. if (status & MII_PHY_STATUS_FULLDUPLEX)
  43. phydev->duplex = DUPLEX_FULL;
  44. else
  45. phydev->duplex = DUPLEX_HALF;
  46. switch (status) {
  47. case MII_PHY_STATUS_1000:
  48. phydev->speed = SPEED_1000;
  49. break;
  50. case MII_PHY_STATUS_100:
  51. phydev->speed = SPEED_100;
  52. break;
  53. default:
  54. phydev->speed = SPEED_10;
  55. break;
  56. }
  57. } else {
  58. int bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
  59. if (bmcr < 0)
  60. return bmcr;
  61. if (bmcr & BMCR_FULLDPLX)
  62. phydev->duplex = DUPLEX_FULL;
  63. else
  64. phydev->duplex = DUPLEX_HALF;
  65. if (bmcr & BMCR_SPEED1000)
  66. phydev->speed = SPEED_1000;
  67. else if (bmcr & BMCR_SPEED100)
  68. phydev->speed = SPEED_100;
  69. else
  70. phydev->speed = SPEED_10;
  71. }
  72. /*
  73. * For 1000BASE-X Phy Mode the speed/duplex will always be
  74. * 1000Mbps/fullduplex
  75. */
  76. if (phydev->flags == XAE_PHY_TYPE_1000BASE_X) {
  77. phydev->duplex = DUPLEX_FULL;
  78. phydev->speed = SPEED_1000;
  79. }
  80. return 0;
  81. }
  82. static int xilinxphy_of_init(struct phy_device *phydev)
  83. {
  84. u32 phytype;
  85. ofnode node;
  86. debug("%s\n", __func__);
  87. node = phy_get_ofnode(phydev);
  88. if (!ofnode_valid(node))
  89. return -EINVAL;
  90. phytype = ofnode_read_u32_default(node, "xlnx,phy-type", -1);
  91. if (phytype == XAE_PHY_TYPE_1000BASE_X)
  92. phydev->flags |= XAE_PHY_TYPE_1000BASE_X;
  93. return 0;
  94. }
  95. static int xilinxphy_config(struct phy_device *phydev)
  96. {
  97. int temp;
  98. debug("%s\n", __func__);
  99. xilinxphy_of_init(phydev);
  100. temp = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
  101. temp &= XPCSPMA_PHY_CTRL_ISOLATE_DISABLE;
  102. phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, temp);
  103. return 0;
  104. }
  105. static struct phy_driver xilinxphy_driver = {
  106. .uid = XILINX_PHY_ID,
  107. .mask = XILINX_PHY_ID_MASK,
  108. .name = "Xilinx PCS/PMA PHY",
  109. .features = PHY_GBIT_FEATURES,
  110. .config = &xilinxphy_config,
  111. .startup = &xilinxphy_startup,
  112. .shutdown = &genphy_shutdown,
  113. };
  114. int phy_xilinx_init(void)
  115. {
  116. debug("%s\n", __func__);
  117. phy_register(&xilinxphy_driver);
  118. return 0;
  119. }