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