miiphybb.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. * (C) Copyright 2001
  3. * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
  4. *
  5. * See file CREDITS for list of people who contributed to this
  6. * project.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License as
  10. * published by the Free Software Foundation; either version 2 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21. * MA 02111-1307 USA
  22. */
  23. /*
  24. * This provides a bit-banged interface to the ethernet MII management
  25. * channel.
  26. */
  27. #include <common.h>
  28. #include <ioports.h>
  29. #include <ppc_asm.tmpl>
  30. #ifdef CONFIG_BITBANGMII
  31. /*****************************************************************************
  32. *
  33. * Utility to send the preamble, address, and register (common to read
  34. * and write).
  35. */
  36. static void miiphy_pre (char read, unsigned char addr, unsigned char reg)
  37. {
  38. int j; /* counter */
  39. #if !(defined(CONFIG_EP8248) || defined(CONFIG_EP82XXM))
  40. volatile ioport_t *iop = ioport_addr ((immap_t *) CFG_IMMR, MDIO_PORT);
  41. #endif
  42. /*
  43. * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
  44. * The IEEE spec says this is a PHY optional requirement. The AMD
  45. * 79C874 requires one after power up and one after a MII communications
  46. * error. This means that we are doing more preambles than we need,
  47. * but it is safer and will be much more robust.
  48. */
  49. MDIO_ACTIVE;
  50. MDIO (1);
  51. for (j = 0; j < 32; j++) {
  52. MDC (0);
  53. MIIDELAY;
  54. MDC (1);
  55. MIIDELAY;
  56. }
  57. /* send the start bit (01) and the read opcode (10) or write (10) */
  58. MDC (0);
  59. MDIO (0);
  60. MIIDELAY;
  61. MDC (1);
  62. MIIDELAY;
  63. MDC (0);
  64. MDIO (1);
  65. MIIDELAY;
  66. MDC (1);
  67. MIIDELAY;
  68. MDC (0);
  69. MDIO (read);
  70. MIIDELAY;
  71. MDC (1);
  72. MIIDELAY;
  73. MDC (0);
  74. MDIO (!read);
  75. MIIDELAY;
  76. MDC (1);
  77. MIIDELAY;
  78. /* send the PHY address */
  79. for (j = 0; j < 5; j++) {
  80. MDC (0);
  81. if ((addr & 0x10) == 0) {
  82. MDIO (0);
  83. } else {
  84. MDIO (1);
  85. }
  86. MIIDELAY;
  87. MDC (1);
  88. MIIDELAY;
  89. addr <<= 1;
  90. }
  91. /* send the register address */
  92. for (j = 0; j < 5; j++) {
  93. MDC (0);
  94. if ((reg & 0x10) == 0) {
  95. MDIO (0);
  96. } else {
  97. MDIO (1);
  98. }
  99. MIIDELAY;
  100. MDC (1);
  101. MIIDELAY;
  102. reg <<= 1;
  103. }
  104. }
  105. /*****************************************************************************
  106. *
  107. * Read a MII PHY register.
  108. *
  109. * Returns:
  110. * 0 on success
  111. */
  112. int bb_miiphy_read (char *devname, unsigned char addr,
  113. unsigned char reg, unsigned short *value)
  114. {
  115. short rdreg; /* register working value */
  116. int j; /* counter */
  117. #if !(defined(CONFIG_EP8248) || defined(CONFIG_EP82XXM))
  118. volatile ioport_t *iop = ioport_addr ((immap_t *) CFG_IMMR, MDIO_PORT);
  119. #endif
  120. miiphy_pre (1, addr, reg);
  121. /* tri-state our MDIO I/O pin so we can read */
  122. MDC (0);
  123. MDIO_TRISTATE;
  124. MIIDELAY;
  125. MDC (1);
  126. MIIDELAY;
  127. /* check the turnaround bit: the PHY should be driving it to zero */
  128. if (MDIO_READ != 0) {
  129. /* puts ("PHY didn't drive TA low\n"); */
  130. for (j = 0; j < 32; j++) {
  131. MDC (0);
  132. MIIDELAY;
  133. MDC (1);
  134. MIIDELAY;
  135. }
  136. return (-1);
  137. }
  138. MDC (0);
  139. MIIDELAY;
  140. /* read 16 bits of register data, MSB first */
  141. rdreg = 0;
  142. for (j = 0; j < 16; j++) {
  143. MDC (1);
  144. MIIDELAY;
  145. rdreg <<= 1;
  146. rdreg |= MDIO_READ;
  147. MDC (0);
  148. MIIDELAY;
  149. }
  150. MDC (1);
  151. MIIDELAY;
  152. MDC (0);
  153. MIIDELAY;
  154. MDC (1);
  155. MIIDELAY;
  156. *value = rdreg;
  157. #ifdef DEBUG
  158. printf ("miiphy_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, *value);
  159. #endif
  160. return 0;
  161. }
  162. /*****************************************************************************
  163. *
  164. * Write a MII PHY register.
  165. *
  166. * Returns:
  167. * 0 on success
  168. */
  169. int bb_miiphy_write (char *devname, unsigned char addr,
  170. unsigned char reg, unsigned short value)
  171. {
  172. int j; /* counter */
  173. #if !(defined(CONFIG_EP8248) || defined(CONFIG_EP82XXM))
  174. volatile ioport_t *iop = ioport_addr ((immap_t *) CFG_IMMR, MDIO_PORT);
  175. #endif
  176. miiphy_pre (0, addr, reg);
  177. /* send the turnaround (10) */
  178. MDC (0);
  179. MDIO (1);
  180. MIIDELAY;
  181. MDC (1);
  182. MIIDELAY;
  183. MDC (0);
  184. MDIO (0);
  185. MIIDELAY;
  186. MDC (1);
  187. MIIDELAY;
  188. /* write 16 bits of register data, MSB first */
  189. for (j = 0; j < 16; j++) {
  190. MDC (0);
  191. if ((value & 0x00008000) == 0) {
  192. MDIO (0);
  193. } else {
  194. MDIO (1);
  195. }
  196. MIIDELAY;
  197. MDC (1);
  198. MIIDELAY;
  199. value <<= 1;
  200. }
  201. /*
  202. * Tri-state the MDIO line.
  203. */
  204. MDIO_TRISTATE;
  205. MDC (0);
  206. MIIDELAY;
  207. MDC (1);
  208. MIIDELAY;
  209. return 0;
  210. }
  211. #endif /* CONFIG_BITBANGMII */