xilinx_phy.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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 <phy.h>
  10. #include <dm.h>
  11. DECLARE_GLOBAL_DATA_PTR;
  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. debug("%s\n", __func__);
  86. phytype = fdtdec_get_int(gd->fdt_blob, dev_of_offset(phydev->dev),
  87. "xlnx,phy-type", -1);
  88. if (phytype == XAE_PHY_TYPE_1000BASE_X)
  89. phydev->flags |= XAE_PHY_TYPE_1000BASE_X;
  90. return 0;
  91. }
  92. static int xilinxphy_config(struct phy_device *phydev)
  93. {
  94. int temp;
  95. debug("%s\n", __func__);
  96. xilinxphy_of_init(phydev);
  97. temp = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
  98. temp &= XPCSPMA_PHY_CTRL_ISOLATE_DISABLE;
  99. phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, temp);
  100. return 0;
  101. }
  102. static struct phy_driver xilinxphy_driver = {
  103. .uid = XILINX_PHY_ID,
  104. .mask = XILINX_PHY_ID_MASK,
  105. .name = "Xilinx PCS/PMA PHY",
  106. .features = PHY_GBIT_FEATURES,
  107. .config = &xilinxphy_config,
  108. .startup = &xilinxphy_startup,
  109. .shutdown = &genphy_shutdown,
  110. };
  111. int phy_xilinx_init(void)
  112. {
  113. debug("%s\n", __func__);
  114. phy_register(&xilinxphy_driver);
  115. return 0;
  116. }