From: wdenk Date: Mon, 8 Oct 2001 19:18:17 +0000 (+0000) Subject: * Patch by Jerry Van Baren, 19 Sep 2001: X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=e39a1ed523ad83805b05d5202dc8609bf6a217ba;p=users%2Frw%2Fppcboot.git * Patch by Jerry Van Baren, 19 Sep 2001: - tweaks to SBC8260 configuration - added "mii" command to read and write MII PHY registers; it will also do a simple "info" where it finds all MII PHYs and prints some info from their registers. --- diff --git a/CHANGELOG b/CHANGELOG index 414ebaa..259f235 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -56,6 +56,12 @@ To do: Modifications for 1.0.6: ====================================================================== +* Patch by Jerry Van Baren, 19 Sep 2001: +- tweaks to SBC8260 configuration +- added "mii" command to read and write MII PHY registers; it will + also do a simple "info" where it finds all MII PHYs and prints some + info from their registers. + * Patch by David Updegraff, 05 Oct 2001: - Added "reginfo" command for 405GP - Added DHCP vendor extensions diff --git a/common/Makefile b/common/Makefile index 81ff6ea..e0b8f10 100644 --- a/common/Makefile +++ b/common/Makefile @@ -35,7 +35,8 @@ COBJS = board.o main.o command.o \ cmd_nvedit.o cmd_pcmcia.o cmd_reginfo.o \ cmd_fdc.o cmd_scsi.o cmd_autoscript.o \ cmd_bedbug.o bedbug.o s_record.o dlmalloc.o \ - kgdb.o console.o lists.o devices.o flash.o cmd_i2c.o cmd_immap.o + kgdb.o console.o lists.o devices.o flash.o cmd_i2c.o \ + cmd_immap.o miiphyutil.o miiphybb.o cmd_mii.o OBJS = $(AOBJS) $(COBJS) diff --git a/common/cmd_mii.c b/common/cmd_mii.c new file mode 100644 index 0000000..c7108bf --- /dev/null +++ b/common/cmd_mii.c @@ -0,0 +1,126 @@ +/* + * (C) Copyright 2001 + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * MII Utilities + */ + +#include +#include +#include +#include + +#if (CONFIG_COMMANDS & CFG_CMD_MII) + +/* + * Display values from last command. + */ +uint last_op; +uint last_addr; +uint last_data; +uint last_reg; + +/* + * MII read/write + * + * Syntax: + * mii read {addr} {reg} + * mii write {addr} {reg} {data} + */ + +void do_mii (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]) +{ + char op; + unsigned char addr, reg; + unsigned short data; + + /* + * We use the last specified parameters, unless new ones are + * entered. + */ + op = last_op; + addr = last_addr; + data = last_data; + reg = last_reg; + + if ((flag & CMD_FLAG_REPEAT) == 0) + { + op = argv[1][0]; + if (argc >= 3) + addr = simple_strtoul(argv[2], NULL, 16); + if (argc >= 4) + reg = simple_strtoul(argv[3], NULL, 16); + if (argc >= 5) + data = simple_strtoul(argv[4], NULL, 16); + } + + /* + * check info/read/write. + */ + if(op == 'i') + { + int j; + unsigned int oui; + unsigned char model; + unsigned char rev; + + /* + * Look for any and all PHYs. Valid addresses are 0..31. + */ + for(j = 0; j < 32; j++) + { + if(miiphy_info(j, &oui, &model, &rev) == 0) + { + printf("PHY 0x%02X: OUI = 0x%04X, Model = 0x%02X, Rev = 0x%02X, %3dbaseT, %s\n", + j, oui, model, rev, + miiphy_speed(j) == _100BASET ? 100 : 10, + miiphy_duplex(j) == FULL ? "FDX" : "HDX"); + } + } + } + else if(op == 'r') + { + if(miiphy_read(addr, reg, &data) != 0) + printf("Error reading from the PHY\n"); + printf("%04X\n", data & 0x0000FFFF); + } + else if(op == 'w') + { + if(miiphy_write(addr, reg, data) != 0) + printf("Error writing to the PHY\n"); + } + else + { + printf("Usage:\n%s\n", cmdtp->usage); + return; + } + + /* + * Save the parameters for repeats. + */ + last_op = op; + last_addr = addr; + last_data = data; +} + +#endif /* CFG_CMD_MII */ diff --git a/common/command.c b/common/command.c index 9e8b61d..69fa07d 100644 --- a/common/command.c +++ b/common/command.c @@ -51,6 +51,7 @@ #include /* board special functions */ #include /* Floppy support */ #include +#include #include @@ -271,6 +272,7 @@ cmd_tbl_t cmd_tbl[] = { CMD_TBL_STEP CMD_TBL_NEXT CMD_TBL_RDUMP + CMD_TBL_MII /* the following entry terminates this table */ MK_CMD_TBL_ENTRY( NULL, 0, 0, 0, NULL, NULL, NULL ) }; diff --git a/common/miiphybb.c b/common/miiphybb.c new file mode 100644 index 0000000..7985be2 --- /dev/null +++ b/common/miiphybb.c @@ -0,0 +1,207 @@ +/* + * (C) Copyright 2001 + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * This provides a bit-banged interface to the ethernet MII management + * channel. + */ + +#include +#include +#include + +#ifdef CONFIG_BITBANGMII + + +/***************************************************************************** + * + * Utility to send the preamble, address, and register (common to read + * and write). + */ +static void miiphy_pre(char read, + unsigned char addr, + unsigned char reg) +{ + int j; /* counter */ + volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, MDIO_PORT); + + /* + * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure. + * The IEEE spec says this is a PHY optional requirement. The AMD + * 79C874 requires one after power up and one after a MII communications + * error. This means that we are doing more preambles than we need, + * but it is safer and will be much more robust. + */ + MDIO_ACTIVE; + MDIO(1); + for(j = 0; j < 32; j++) + { + MDC(0); + MIIDELAY; + MDC(1); + MIIDELAY; + } + + /* send the start bit (01) and the read opcode (10) or write (10) */ + MDC(0); MDIO(0); MIIDELAY; MDC(1); MIIDELAY; + MDC(0); MDIO(1); MIIDELAY; MDC(1); MIIDELAY; + MDC(0); MDIO(read); MIIDELAY; MDC(1); MIIDELAY; + MDC(0); MDIO(!read); MIIDELAY; MDC(1); MIIDELAY; + + /* send the PHY address */ + for(j = 0; j < 5; j++) + { + MDC(0); + if((addr & 0x10) == 0) + { + MDIO(0); + } + else + { + MDIO(1); + } + MIIDELAY; + MDC(1); + MIIDELAY; + addr <<= 1; + } + + /* send the register address */ + for(j = 0; j < 5; j++) + { + MDC(0); + if((reg & 0x10) == 0) + { + MDIO(0); + } + else + { + MDIO(1); + } + MIIDELAY; + MDC(1); + MIIDELAY; + reg <<= 1; + } +} + + +/***************************************************************************** + * + * Read a MII PHY register. + * + * Returns: + * 0 on success + */ +int miiphy_read(unsigned char addr, + unsigned char reg, + unsigned short *value) +{ + short rdreg; /* register working value */ + int j; /* counter */ + volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, MDIO_PORT); + + miiphy_pre(1, addr, reg); + + /* tri-state our MDIO I/O pin so we can read */ + MDC(0); + MDIO_TRISTATE; + MIIDELAY; + MDC(1); + MIIDELAY; + + /* check the turnaround bit: the PHY should be driving it to zero */ + if(MDIO_READ != 0) + { + /* printf("PHY didn't drive TA low\n"); */ + return(-1); + } + + MDC(0); + MIIDELAY; + + /* read 16 bits of register data, MSB first */ + rdreg = 0; + for(j = 0; j < 16; j++) + { + MDC(1); + MIIDELAY; + rdreg <<= 1; + rdreg |= MDIO_READ; + MDC(0); + MIIDELAY; + } + + *value = rdreg; + return 0; +} + + +/***************************************************************************** + * + * Write a MII PHY register. + * + * Returns: + * 0 on success + */ +int miiphy_write(unsigned char addr, + unsigned char reg, + unsigned short value) +{ + int j; /* counter */ + volatile ioport_t *iop = ioport_addr((immap_t *)CFG_IMMR, MDIO_PORT); + + miiphy_pre(0, addr, reg); + + /* send the turnaround (10) */ + MDC(0); MDIO(1); MIIDELAY; MDC(1); MIIDELAY; + MDC(0); MDIO(0); MIIDELAY; MDC(1); MIIDELAY; + + /* write 16 bits of register data, MSB first */ + for(j = 0; j < 16; j++) + { + MDC(0); + if((value & 0x00008000) == 0) + { + MDIO(0); + } + else + { + MDIO(1); + } + MIIDELAY; + MDC(1); + MIIDELAY; + value <<= 1; + } + + /* + * Tri-state the MDIO line. + */ + MDIO_TRISTATE; + + return 0; +} + +#endif /* CONFIG_BITBANGMII */ + diff --git a/common/miiphyutil.c b/common/miiphyutil.c new file mode 100644 index 0000000..a3f4666 --- /dev/null +++ b/common/miiphyutil.c @@ -0,0 +1,181 @@ +/* + * (C) Copyright 2001 + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * This provides a bit-banged interface to the ethernet MII management + * channel. + */ + +#include +#include + +#ifdef CONFIG_MII + +#undef DEBUG /* define for more debug messages */ + + +/***************************************************************************** + * + * Read the OUI, manufacture's model number, and revision number. + * + * OUI: 22 bits (unsigned int) + * Model: 6 bits (unsigned char) + * Revision: 4 bits (unsigned char) + * + * Returns: + * 0 on success + */ +int miiphy_info(unsigned char addr, + unsigned int *oui, + unsigned char *model, + unsigned char *rev) +{ + unsigned int reg; + + /* + * Trick: we are reading two 16 registers into a 32 bit variable + * so we do a 16 read into the high order bits of the variable (big + * endian, you know), shift it down 16 bits, and the read the rest. + */ + if(miiphy_read(addr, PHY_PHYIDR2, (unsigned short *)®) != 0) + { +# ifdef DEBUG + printf("PHY ID register 2 read failed\n"); +# endif + return(-1); + } + reg >>= 16; + if(miiphy_read(addr, PHY_PHYIDR1, (unsigned short *)®) != 0) + { +# ifdef DEBUG + printf("PHY ID register 1 read failed\n"); +# endif + return(-1); + } + *oui = (reg >> 10); + *model = (unsigned char)((reg >> 4) & 0x0000003F); + *rev = (unsigned char)( reg & 0x0000000F); + return(0); +} + + +/***************************************************************************** + * + * Reset the PHY. + * Returns: + * 0 on success + */ +int miiphy_reset(unsigned char addr) +{ + unsigned short reg; + int loop_cnt; + + if(miiphy_write(addr, PHY_BMCR, 0x8000) != 0) + { +# ifdef DEBUG + printf("PHY reset failed\n"); +# endif + return(-1); + } + + /* + * Poll the control register for the reset bit to go to 0 (it is + * auto-clearing). This should happen within 0.5 seconds per the + * IEEE spec. + */ + loop_cnt = 0; + reg = 0x8000; + while(((reg & 0x8000) != 0) && (loop_cnt++ < 1000000)) + { + if(miiphy_read(addr, PHY_BMCR, ®) != 0) + { +# ifdef DEBUG + printf("PHY status read failed\n"); +# endif + return(-1); + } + } + if((reg & 0x8000) == 0) + { + return(0); + } + else + { + printf("PHY reset timed out\n"); + return(-1); + } + return(0); +} + + +/***************************************************************************** + * + * Determine the ethernet speed (10/100). + */ +int miiphy_speed(unsigned char addr) +{ + unsigned short reg; + + if(miiphy_read(addr, PHY_ANLPAR, ®)) + { + printf("PHY speed1 read failed, assuming 10bT\n"); + return(_10BASET); + } + + if((reg & PHY_ANLPAR_100) != 0) + { + return(_100BASET); + } + else + { + return(_10BASET); + } +} + + +/***************************************************************************** + * + * Determine full/half duplex. + */ +int miiphy_duplex(unsigned char addr) +{ + unsigned short reg; + + if(miiphy_read(addr, PHY_ANLPAR, ®)) + { + printf("PHY duplex read failed, assuming half duplex\n"); + return(HALF); + } + + if((reg & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) != 0) + { + return(FULL); + } + else + { + return(HALF); + } +} + +#endif /* CONFIG_MII */ + diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c index 610c781..232c91b 100644 --- a/cpu/ppc4xx/miiphy.c +++ b/cpu/ppc4xx/miiphy.c @@ -63,7 +63,7 @@ void miiphy_dump(void) for(i=0; i<0x1A; i++) { - if(miiphy_read(i, &data)) + if(miiphy_read(0, i, &data)) { printf("read error for reg %lx\n",i); return; @@ -83,7 +83,7 @@ void miiphy_dump(void) /* read a phy reg and return the value with a rc */ /***********************************************************/ -int miiphy_read(unsigned char reg, unsigned short * value) +int miiphy_read(unsigned char addr, unsigned char reg, unsigned short * value) { unsigned long sta_reg; /* STA scratch area */ unsigned long i; @@ -140,7 +140,7 @@ int miiphy_read(unsigned char reg, unsigned short * value) /* write a phy reg and return the value with a rc */ /***********************************************************/ -int miiphy_write(unsigned char reg, unsigned short value) +int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value) { unsigned long sta_reg; /* STA scratch area */ unsigned long i; @@ -190,7 +190,7 @@ int miiphy_speed() int speed = _10BASET; /* Assume 10Mbs */ unsigned short bmcr = 0x0; - if (miiphy_read(PHY_ANLPAR,&bmcr)) { + if (miiphy_read(0,PHY_ANLPAR,&bmcr)) { printf("phy speed1 read failed \n"); miiphy_dump(); } @@ -209,7 +209,7 @@ int miiphy_duplex() int speed = HALF; /* Assume HALF */ unsigned short bmcr = 0x0; - if (miiphy_read(PHY_ANLPAR,&bmcr)) + if (miiphy_read(0,PHY_ANLPAR,&bmcr)) { printf("phy duplex read failed \n"); miiphy_dump(); diff --git a/include/cmd_confdefs.h b/include/cmd_confdefs.h index 162e08f..5d7e290 100644 --- a/include/cmd_confdefs.h +++ b/include/cmd_confdefs.h @@ -60,7 +60,8 @@ #define CFG_CMD_FDC 0x04000000 /* Floppy Disk Support */ #define CFG_CMD_SCSI 0x08000000 /* SCSI Support */ #define CFG_CMD_AUTOSCRIPT 0x10000000 /* Autoscript Support */ -#define CFG_CMD_BSP 0x80000000 /* Board SPecific functions */ +#define CFG_CMD_MII 0x20000000 /* MII support */ +#define CFG_CMD_BSP 0x80000000 /* Board Specific functions */ #define CFG_CMD_ALL 0xFFFFFFFF /* ALL commands */ diff --git a/include/cmd_mii.h b/include/cmd_mii.h new file mode 100644 index 0000000..8bef609 --- /dev/null +++ b/include/cmd_mii.h @@ -0,0 +1,46 @@ +/* + * (C) Copyright 2001 + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * MII Functions + */ +#ifndef _CMD_MII_H +#define _CMD_MII_H + +#if (CONFIG_COMMANDS & CFG_CMD_MII) +#define CMD_TBL_MII MK_CMD_TBL_ENTRY( \ + "mii", 3, 5, 1, do_mii, \ + "mii - MII utility commands\n", \ + "\ +info - display MII PHY info\n\ +mii read - read MII PHY register \n\ +mii write - write MII PHY register \n" \ +), + +void do_mii (cmd_tbl_t *cmdtp, bd_t *bd, int flag, int argc, char *argv[]); + +#else +#define CMD_TBL_MII +#endif /* CFG_CMD_MII */ + +#endif /* _CMD_MII_H */ diff --git a/include/config_sbc8260.h b/include/config_sbc8260.h index caa13e5..3c21f2f 100644 --- a/include/config_sbc8260.h +++ b/include/config_sbc8260.h @@ -46,7 +46,7 @@ *****************************************************************************/ /* What is the oscillator's (UX2) frequency in Hz? */ -#define CONFIG_8260_CLKIN (33 * 1000 * 1000) +#define CONFIG_8260_CLKIN (66 * 1000 * 1000) /*----------------------------------------------------------------------- * MODCK_H & MODCLK[1-3] - Ref: Section 9.2 in MPC8206 User Manual @@ -70,7 +70,7 @@ * 0x6 0x1 66 133 266 Close Close Open * 0x6 0x2 66 133 300 Close Open Close */ -#define CFG_SBC_MODCK_H 0x02 +#define CFG_SBC_MODCK_H 0x05 /* Define this if you want to boot from 0x00000100. If you don't define * this, you will need to program the bootloader to 0xfff00000, and @@ -197,6 +197,23 @@ #define CONFIG_ETHER_ON_FCC /* define if ethernet on FCC */ #undef CONFIG_ETHER_NONE /* define if ethernet on neither */ #define CONFIG_ETHER_INDEX 2 /* which SCC/FCC channel for ethernet */ +#define CONFIG_MII /* MII PHY management */ +#define CONFIG_BITBANGMII /* bit-bang MII PHY management */ +/* + * Port pins used for bit-banged MII communictions (if applicable). + */ +#define MDIO_PORT 2 /* Port C */ +#define MDIO_ACTIVE (iop->pdir |= 0x00400000) +#define MDIO_TRISTATE (iop->pdir &= ~0x00400000) +#define MDIO_READ ((iop->pdat & 0x00400000) != 0) + +#define MDIO(bit) if(bit) iop->pdat |= 0x00400000; \ + else iop->pdat &= ~0x00400000 + +#define MDC(bit) if(bit) iop->pdat |= 0x00200000; \ + else iop->pdat &= ~0x00200000 + +#define MIIDELAY udelay(1) #endif /* CONFIG_ETHER_USE_FCC2 */ /* Define this to reserve an entire FLASH sector (256 KB) for @@ -268,7 +285,16 @@ #define CFG_PROMPT "=> " /* What ppcboot subsytems do you want enabled? */ -#define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | CFG_CMD_BEDBUG) +#define CONFIG_COMMANDS (((CONFIG_CMD_DFL & ~(CFG_CMD_KGDB))) | \ + CFG_CMD_BEDBUG | \ + CFG_CMD_ASKENV | \ + CFG_CMD_ECHO | \ + CFG_CMD_I2C | \ + CFG_CMD_REGINFO | \ + CFG_CMD_IMMAP | \ + CFG_CMD_MII | \ + CFG_CMD_BSP) + /* Where do the internal registers live? */ #define CFG_IMMR 0xf0000000 diff --git a/include/miiphy.h b/include/miiphy.h index 47441ca..f1840ae 100644 --- a/include/miiphy.h +++ b/include/miiphy.h @@ -20,9 +20,9 @@ +----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------+ | -| File Name: dp83843.h +| File Name: miiphy.h | -| Function: Include file for NS DP83843 PHY. +| Function: Include file defining PHY registers. | | Author: Mark Wisner | @@ -32,17 +32,20 @@ | --------- --------------------- --- | 04-May-99 Created MKW | 07-Jul-99 Added full duplex support MKW +| 08-Sep-01 Tweaks gvb | +----------------------------------------------------------------------------*/ #ifndef _miiphy_h_ #define _miiphy_h_ -int miiphy_read(unsigned char reg, unsigned short * value); -int miiphy_write(unsigned char reg, unsigned short value); -void miiphy_dump(void); -int miiphy_speed(void); -int miiphy_duplex(void); +int miiphy_read(unsigned char addr, unsigned char reg, unsigned short * value); +int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value); +int miiphy_info(unsigned char addr, unsigned int *oui, unsigned char *model, + unsigned char *rev); +int miiphy_reset(unsigned char addr); +int miiphy_speed(unsigned char addr); +int miiphy_duplex(unsigned char addr); /* phy seed setup */ @@ -55,7 +58,7 @@ int miiphy_duplex(void); /* phy register offsets */ #define PHY_BMCR 0x00 #define PHY_BMSR 0x01 -#define PHY_PHY1DR1 0x02 +#define PHY_PHYIDR1 0x02 #define PHY_PHYIDR2 0x03 #define PHY_ANAR 0x04 #define PHY_ANLPAR 0x05