miiphybb.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  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. /*****************************************************************************
  31. *
  32. * Utility to send the preamble, address, and register (common to read
  33. * and write).
  34. */
  35. static void miiphy_pre (char read, unsigned char addr, unsigned char reg)
  36. {
  37. int j; /* counter */
  38. #if !(defined(CONFIG_EP8248) || defined(CONFIG_EP82XXM))
  39. volatile ioport_t *iop = ioport_addr ((immap_t *) CONFIG_SYS_IMMR, MDIO_PORT);
  40. #endif
  41. /*
  42. * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
  43. * The IEEE spec says this is a PHY optional requirement. The AMD
  44. * 79C874 requires one after power up and one after a MII communications
  45. * error. This means that we are doing more preambles than we need,
  46. * but it is safer and will be much more robust.
  47. */
  48. MDIO_ACTIVE;
  49. MDIO (1);
  50. for (j = 0; j < 32; j++) {
  51. MDC (0);
  52. MIIDELAY;
  53. MDC (1);
  54. MIIDELAY;
  55. }
  56. /* send the start bit (01) and the read opcode (10) or write (10) */
  57. MDC (0);
  58. MDIO (0);
  59. MIIDELAY;
  60. MDC (1);
  61. MIIDELAY;
  62. MDC (0);
  63. MDIO (1);
  64. MIIDELAY;
  65. MDC (1);
  66. MIIDELAY;
  67. MDC (0);
  68. MDIO (read);
  69. MIIDELAY;
  70. MDC (1);
  71. MIIDELAY;
  72. MDC (0);
  73. MDIO (!read);
  74. MIIDELAY;
  75. MDC (1);
  76. MIIDELAY;
  77. /* send the PHY address */
  78. for (j = 0; j < 5; j++) {
  79. MDC (0);
  80. if ((addr & 0x10) == 0) {
  81. MDIO (0);
  82. } else {
  83. MDIO (1);
  84. }
  85. MIIDELAY;
  86. MDC (1);
  87. MIIDELAY;
  88. addr <<= 1;
  89. }
  90. /* send the register address */
  91. for (j = 0; j < 5; j++) {
  92. MDC (0);
  93. if ((reg & 0x10) == 0) {
  94. MDIO (0);
  95. } else {
  96. MDIO (1);
  97. }
  98. MIIDELAY;
  99. MDC (1);
  100. MIIDELAY;
  101. reg <<= 1;
  102. }
  103. }
  104. /*****************************************************************************
  105. *
  106. * Read a MII PHY register.
  107. *
  108. * Returns:
  109. * 0 on success
  110. */
  111. int bb_miiphy_read (char *devname, unsigned char addr,
  112. unsigned char reg, unsigned short *value)
  113. {
  114. short rdreg; /* register working value */
  115. int j; /* counter */
  116. #if !(defined(CONFIG_EP8248) || defined(CONFIG_EP82XXM))
  117. volatile ioport_t *iop = ioport_addr ((immap_t *) CONFIG_SYS_IMMR, MDIO_PORT);
  118. #endif
  119. miiphy_pre (1, addr, reg);
  120. /* tri-state our MDIO I/O pin so we can read */
  121. MDC (0);
  122. MDIO_TRISTATE;
  123. MIIDELAY;
  124. MDC (1);
  125. MIIDELAY;
  126. /* check the turnaround bit: the PHY should be driving it to zero */
  127. if (MDIO_READ != 0) {
  128. /* puts ("PHY didn't drive TA low\n"); */
  129. for (j = 0; j < 32; j++) {
  130. MDC (0);
  131. MIIDELAY;
  132. MDC (1);
  133. MIIDELAY;
  134. }
  135. return (-1);
  136. }
  137. MDC (0);
  138. MIIDELAY;
  139. /* read 16 bits of register data, MSB first */
  140. rdreg = 0;
  141. for (j = 0; j < 16; j++) {
  142. MDC (1);
  143. MIIDELAY;
  144. rdreg <<= 1;
  145. rdreg |= MDIO_READ;
  146. MDC (0);
  147. MIIDELAY;
  148. }
  149. MDC (1);
  150. MIIDELAY;
  151. MDC (0);
  152. MIIDELAY;
  153. MDC (1);
  154. MIIDELAY;
  155. *value = rdreg;
  156. #ifdef DEBUG
  157. printf ("miiphy_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, *value);
  158. #endif
  159. return 0;
  160. }
  161. /*****************************************************************************
  162. *
  163. * Write a MII PHY register.
  164. *
  165. * Returns:
  166. * 0 on success
  167. */
  168. int bb_miiphy_write (char *devname, unsigned char addr,
  169. unsigned char reg, unsigned short value)
  170. {
  171. int j; /* counter */
  172. #if !(defined(CONFIG_EP8248) || defined(CONFIG_EP82XXM))
  173. volatile ioport_t *iop = ioport_addr ((immap_t *) CONFIG_SYS_IMMR, MDIO_PORT);
  174. #endif
  175. miiphy_pre (0, addr, reg);
  176. /* send the turnaround (10) */
  177. MDC (0);
  178. MDIO (1);
  179. MIIDELAY;
  180. MDC (1);
  181. MIIDELAY;
  182. MDC (0);
  183. MDIO (0);
  184. MIIDELAY;
  185. MDC (1);
  186. MIIDELAY;
  187. /* write 16 bits of register data, MSB first */
  188. for (j = 0; j < 16; j++) {
  189. MDC (0);
  190. if ((value & 0x00008000) == 0) {
  191. MDIO (0);
  192. } else {
  193. MDIO (1);
  194. }
  195. MIIDELAY;
  196. MDC (1);
  197. MIIDELAY;
  198. value <<= 1;
  199. }
  200. /*
  201. * Tri-state the MDIO line.
  202. */
  203. MDIO_TRISTATE;
  204. MDC (0);
  205. MIIDELAY;
  206. MDC (1);
  207. MIIDELAY;
  208. return 0;
  209. }