ihs_mdio.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /*
  2. * (C) Copyright 2014
  3. * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <common.h>
  8. #include <gdsys_fpga.h>
  9. #include <miiphy.h>
  10. #include "ihs_mdio.h"
  11. static int ihs_mdio_idle(struct mii_dev *bus)
  12. {
  13. struct ihs_mdio_info *info = bus->priv;
  14. u16 val;
  15. unsigned int ctr = 0;
  16. do {
  17. FPGA_GET_REG(info->fpga, mdio.control, &val);
  18. udelay(100);
  19. if (ctr++ > 10)
  20. return -1;
  21. } while (!(val & (1 << 12)));
  22. return 0;
  23. }
  24. static int ihs_mdio_reset(struct mii_dev *bus)
  25. {
  26. ihs_mdio_idle(bus);
  27. return 0;
  28. }
  29. static int ihs_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
  30. int regnum)
  31. {
  32. struct ihs_mdio_info *info = bus->priv;
  33. u16 val;
  34. ihs_mdio_idle(bus);
  35. FPGA_SET_REG(info->fpga, mdio.control,
  36. ((addr & 0x1f) << 5) | (regnum & 0x1f) | (2 << 10));
  37. /* wait for rx data available */
  38. udelay(100);
  39. FPGA_GET_REG(info->fpga, mdio.rx_data, &val);
  40. return val;
  41. }
  42. static int ihs_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
  43. int regnum, u16 value)
  44. {
  45. struct ihs_mdio_info *info = bus->priv;
  46. ihs_mdio_idle(bus);
  47. FPGA_SET_REG(info->fpga, mdio.address_data, value);
  48. FPGA_SET_REG(info->fpga, mdio.control,
  49. ((addr & 0x1f) << 5) | (regnum & 0x1f) | (1 << 10));
  50. return 0;
  51. }
  52. int ihs_mdio_init(struct ihs_mdio_info *info)
  53. {
  54. struct mii_dev *bus = mdio_alloc();
  55. if (!bus) {
  56. printf("Failed to allocate FSL MDIO bus\n");
  57. return -1;
  58. }
  59. bus->read = ihs_mdio_read;
  60. bus->write = ihs_mdio_write;
  61. bus->reset = ihs_mdio_reset;
  62. strcpy(bus->name, info->name);
  63. bus->priv = info;
  64. return mdio_register(bus);
  65. }