fsl_enetc_mdio.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * ENETC ethernet controller driver
  4. * Copyright 2019 NXP
  5. */
  6. #include <common.h>
  7. #include <dm.h>
  8. #include <errno.h>
  9. #include <pci.h>
  10. #include <miiphy.h>
  11. #include <asm/io.h>
  12. #include <asm/processor.h>
  13. #include <miiphy.h>
  14. #include "fsl_enetc.h"
  15. static void enetc_mdio_wait_bsy(struct enetc_mdio_priv *priv)
  16. {
  17. int to = 10000;
  18. while ((enetc_read(priv, ENETC_MDIO_CFG) & ENETC_EMDIO_CFG_BSY) &&
  19. --to)
  20. cpu_relax();
  21. if (!to)
  22. printf("T");
  23. }
  24. int enetc_mdio_read_priv(struct enetc_mdio_priv *priv, int addr, int devad,
  25. int reg)
  26. {
  27. if (devad == MDIO_DEVAD_NONE)
  28. enetc_write(priv, ENETC_MDIO_CFG, ENETC_EMDIO_CFG_C22);
  29. else
  30. enetc_write(priv, ENETC_MDIO_CFG, ENETC_EMDIO_CFG_C45);
  31. enetc_mdio_wait_bsy(priv);
  32. if (devad == MDIO_DEVAD_NONE) {
  33. enetc_write(priv, ENETC_MDIO_CTL, ENETC_MDIO_CTL_READ |
  34. (addr << 5) | reg);
  35. } else {
  36. enetc_write(priv, ENETC_MDIO_CTL, (addr << 5) + devad);
  37. enetc_mdio_wait_bsy(priv);
  38. enetc_write(priv, ENETC_MDIO_STAT, reg);
  39. enetc_mdio_wait_bsy(priv);
  40. enetc_write(priv, ENETC_MDIO_CTL, ENETC_MDIO_CTL_READ |
  41. (addr << 5) | devad);
  42. }
  43. enetc_mdio_wait_bsy(priv);
  44. if (enetc_read(priv, ENETC_MDIO_CFG) & ENETC_EMDIO_CFG_RD_ER)
  45. return ENETC_MDIO_READ_ERR;
  46. return enetc_read(priv, ENETC_MDIO_DATA);
  47. }
  48. int enetc_mdio_write_priv(struct enetc_mdio_priv *priv, int addr, int devad,
  49. int reg, u16 val)
  50. {
  51. if (devad == MDIO_DEVAD_NONE)
  52. enetc_write(priv, ENETC_MDIO_CFG, ENETC_EMDIO_CFG_C22);
  53. else
  54. enetc_write(priv, ENETC_MDIO_CFG, ENETC_EMDIO_CFG_C45);
  55. enetc_mdio_wait_bsy(priv);
  56. if (devad != MDIO_DEVAD_NONE) {
  57. enetc_write(priv, ENETC_MDIO_CTL, (addr << 5) + devad);
  58. enetc_write(priv, ENETC_MDIO_STAT, reg);
  59. } else {
  60. enetc_write(priv, ENETC_MDIO_CTL, (addr << 5) + reg);
  61. }
  62. enetc_mdio_wait_bsy(priv);
  63. enetc_write(priv, ENETC_MDIO_DATA, val);
  64. enetc_mdio_wait_bsy(priv);
  65. return 0;
  66. }
  67. /* DM wrappers */
  68. static int dm_enetc_mdio_read(struct udevice *dev, int addr, int devad, int reg)
  69. {
  70. struct enetc_mdio_priv *priv = dev_get_priv(dev);
  71. return enetc_mdio_read_priv(priv, addr, devad, reg);
  72. }
  73. static int dm_enetc_mdio_write(struct udevice *dev, int addr, int devad,
  74. int reg, u16 val)
  75. {
  76. struct enetc_mdio_priv *priv = dev_get_priv(dev);
  77. return enetc_mdio_write_priv(priv, addr, devad, reg, val);
  78. }
  79. static const struct mdio_ops enetc_mdio_ops = {
  80. .read = dm_enetc_mdio_read,
  81. .write = dm_enetc_mdio_write,
  82. };
  83. static int enetc_mdio_bind(struct udevice *dev)
  84. {
  85. char name[16];
  86. static int eth_num_devices;
  87. /*
  88. * prefer using PCI function numbers to number interfaces, but these
  89. * are only available if dts nodes are present. For PCI they are
  90. * optional, handle that case too. Just in case some nodes are present
  91. * and some are not, use different naming scheme - enetc-N based on
  92. * PCI function # and enetc#N based on interface count
  93. */
  94. if (ofnode_valid(dev_ofnode(dev)))
  95. sprintf(name, "emdio-%u", PCI_FUNC(pci_get_devfn(dev)));
  96. else
  97. sprintf(name, "emdio#%u", eth_num_devices++);
  98. device_set_name(dev, name);
  99. return 0;
  100. }
  101. static int enetc_mdio_probe(struct udevice *dev)
  102. {
  103. struct enetc_mdio_priv *priv = dev_get_priv(dev);
  104. priv->regs_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0);
  105. if (!priv->regs_base) {
  106. enetc_dbg(dev, "failed to map BAR0\n");
  107. return -EINVAL;
  108. }
  109. priv->regs_base += ENETC_MDIO_BASE;
  110. dm_pci_clrset_config16(dev, PCI_COMMAND, 0, PCI_COMMAND_MEMORY);
  111. return 0;
  112. }
  113. U_BOOT_DRIVER(enetc_mdio) = {
  114. .name = "enetc_mdio",
  115. .id = UCLASS_MDIO,
  116. .bind = enetc_mdio_bind,
  117. .probe = enetc_mdio_probe,
  118. .ops = &enetc_mdio_ops,
  119. .priv_auto = sizeof(struct enetc_mdio_priv),
  120. };
  121. static struct pci_device_id enetc_mdio_ids[] = {
  122. { PCI_DEVICE(PCI_VENDOR_ID_FREESCALE, PCI_DEVICE_ID_ENETC_MDIO) },
  123. { }
  124. };
  125. U_BOOT_PCI_DEVICE(enetc_mdio, enetc_mdio_ids);