//added by wzh 2009-4-15 unsigned int get_phy_device(char *devname, unsigned char phyaddr) { u32 phy_id; u16 id1, id2; miiphy_read (devname, phyaddr, PHY_PHYIDR1, &id1); miiphy_read (devname, phyaddr, PHY_PHYIDR2, &id2); phy_id = (id1 & 0xffff) << 16; phy_id |= (id2 & 0xffff); /* If the phy_id is all Fs, there is no device there */ if (0xffffffff == phy_id || 0 == phy_id || phy_id == 0xFFFF || phy_id == 0xFFFF0000) { return -1; } /* run this at RMII mode */ if (HIETH_MII_RMII_MODE_U == 1) { /* PHY-KSZ8051RNL */ if ((phy_id & 0xFFFFFFF0) == 0x221550) { unsigned short reg; miiphy_read(devname, phyaddr, 0x1F, ®); reg |= (1 << 7); /* set phy RMII 50MHz clk;*/ miiphy_write(devname, phyaddr, 0x1F, reg); miiphy_read(devname, phyaddr, 0x16, ®); reg |= (1 << 1); /* set phy RMII override; */ miiphy_write(devname, phyaddr, 0x16, reg); } } return 0; }
int configure_gbit_phy(unsigned char addr) { unsigned short value; /* select page 2 */ if (miiphy_write(CONFIG_SYS_GBIT_MII_BUSNAME, addr, PHYREG_PAGE_ADDRESS, 0x0002)) goto err_out; /* disable SGMII autonegotiation */ if (miiphy_write(CONFIG_SYS_GBIT_MII_BUSNAME, addr, PHYREG_PG2_COPPER_SPECIFIC_CONTROL_2, 0x800a)) goto err_out; /* select page 0 */ if (miiphy_write(CONFIG_SYS_GBIT_MII_BUSNAME, addr, PHYREG_PAGE_ADDRESS, 0x0000)) goto err_out; /* switch from powerdown to normal operation */ if (miiphy_read(CONFIG_SYS_GBIT_MII_BUSNAME, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1, &value)) goto err_out; if (miiphy_write(CONFIG_SYS_GBIT_MII_BUSNAME, addr, PHYREG_PG0_COPPER_SPECIFIC_CONTROL_1, value & ~0x0004)) goto err_out; /* reset phy so settings take effect */ if (miiphy_write(CONFIG_SYS_GBIT_MII_BUSNAME, addr, PHYREG_CONTROL, 0x9140)) goto err_out; return 0; err_out: printf("Error writing to the PHY addr=%02x\n", addr); return -1; }
void mv_phy_88e1121_init(char *name) { u16 reg; u16 devadr; if (miiphy_set_current_dev(name)) return; /* command to read PHY dev address */ if (miiphy_read(name, 0xEE, 0xEE, (u16 *) &devadr)) { printf("Err..%s could not read PHY dev address\n", __FUNCTION__); return; } /* * Enable RGMII delay on Tx and Rx for CPU port * Ref: sec 4.7.2 of chip datasheet */ miiphy_write(name, devadr, MV88E1121_PGADR_REG, 2); miiphy_read(name, devadr, MV88E1121_MAC_CTRL2_REG, ®); reg |= (MV88E1121_RGMII_RXTM_CTRL | MV88E1121_RGMII_TXTM_CTRL); miiphy_write(name, devadr, MV88E1121_MAC_CTRL2_REG, reg); miiphy_write(name, devadr, MV88E1121_PGADR_REG, 0); /* reset the phy */ miiphy_reset(name, devadr); printf("88E1121 Initialized on %s\n", name); }
void mv_phy_88e1318_init(const char *name, u16 phyaddr) { u16 reg; if (miiphy_set_current_dev(name)) return; /* * Set control mode 4 for LED[0]. */ miiphy_write(name, phyaddr, MII_MARVELL_PHY_PAGE, 3); miiphy_read(name, phyaddr, 16, ®); reg |= 0xf; miiphy_write(name, phyaddr, 16, reg); /* * Enable RGMII delay on Tx and Rx for CPU port * Ref: sec 4.7.2 of chip datasheet */ miiphy_write(name, phyaddr, MII_MARVELL_PHY_PAGE, 2); miiphy_read(name, phyaddr, MV88E1116_MAC_CTRL_REG, ®); reg |= (MV88E1116_RGMII_TXTM_CTRL | MV88E1116_RGMII_RXTM_CTRL); miiphy_write(name, phyaddr, MV88E1116_MAC_CTRL_REG, reg); miiphy_write(name, phyaddr, MII_MARVELL_PHY_PAGE, 0); if (miiphy_reset(name, phyaddr) == 0) printf("88E1318 Initialized on %s\n", name); }
int last_stage_init(void) { unsigned short temp; /* Change the resistors for the PHY */ /* This is needed to get the RGMII working for the 1.3+ * CDS cards */ if (get_board_version() == 0x13) { miiphy_write(CONFIG_TSEC1_NAME, TSEC1_PHY_ADDR, 29, 18); miiphy_read(CONFIG_TSEC1_NAME, TSEC1_PHY_ADDR, 30, &temp); temp = (temp & 0xf03f); temp |= 2 << 9; /* 36 ohm */ temp |= 2 << 6; /* 39 ohm */ miiphy_write(CONFIG_TSEC1_NAME, TSEC1_PHY_ADDR, 30, temp); miiphy_write(CONFIG_TSEC1_NAME, TSEC1_PHY_ADDR, 29, 3); miiphy_write(CONFIG_TSEC1_NAME, TSEC1_PHY_ADDR, 30, 0x8000); } return 0; }
static int sw_reg_write(const char *devname, u8 phy_addr, u8 port, u8 reg, u16 data) { int ret; u16 value; ret = sw_wait_rdy(devname, phy_addr); if (ret) return ret; debug("%s: write to data: %#x\n", __func__, data); ret = miiphy_write(devname, phy_addr, DATA_REG, data); if (ret) return ret; value = SMI_HDR | SMIWR_OP | ((port & SMI_MASK) << PORT_SHIFT) | (reg & SMI_MASK); debug("%s: write to command: %#x\n", __func__, value); ret = miiphy_write(devname, phy_addr, COMMAND_REG, value); if (ret) return ret; ret = sw_wait_rdy(devname, phy_addr); if (ret) return ret; return 0; }
void configure_rgmii(void) { unsigned short temp; /* Change the resistors for the PHY */ /* This is needed to get the RGMII working for the 1.3+ * CDS cards */ if (get_board_version() == 0x13) { miiphy_write(DEFAULT_MII_NAME, TSEC1_PHY_ADDR, 29, 18); miiphy_read(DEFAULT_MII_NAME, TSEC1_PHY_ADDR, 30, &temp); temp = (temp & 0xf03f); temp |= 2 << 9; /* 36 ohm */ temp |= 2 << 6; /* 39 ohm */ miiphy_write(DEFAULT_MII_NAME, TSEC1_PHY_ADDR, 30, temp); miiphy_write(DEFAULT_MII_NAME, TSEC1_PHY_ADDR, 29, 3); miiphy_write(DEFAULT_MII_NAME, TSEC1_PHY_ADDR, 30, 0x8000); } return; }
static int miiphy_restart_aneg(struct eth_device *dev) { struct fec_priv *fec = (struct fec_priv *)dev->priv; int ret = 0; /* * Wake up from sleep if necessary * Reset PHY, then delay 300ns */ #ifdef CONFIG_MX27 miiphy_write(dev->name, fec->phy_id, MII_DCOUNTER, 0x00FF); #endif miiphy_write(dev->name, fec->phy_id, MII_BMCR, BMCR_RESET); udelay(1000); /* * Set the auto-negotiation advertisement register bits */ miiphy_write(dev->name, fec->phy_id, MII_ADVERTISE, LPA_100FULL | LPA_100HALF | LPA_10FULL | LPA_10HALF | PHY_ANLPAR_PSB_802_3); miiphy_write(dev->name, fec->phy_id, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); if (fec->mii_postcall) ret = fec->mii_postcall(fec->phy_id); return ret; }
/* Configure and initialize PHY */ void reset_phy(void) { u16 reg; u16 devadr; char *name = "egiga0"; if (miiphy_set_current_dev(name)) return; /* command to read PHY dev address */ if (miiphy_read(name, 0xEE, 0xEE, (u16 *) &devadr)) { printf("Err..(%s) could not read PHY dev address\n", __func__); return; } /* * Enable RGMII delay on Tx and Rx for CPU port * Ref: sec 4.7.2 of chip datasheet */ miiphy_write(name, devadr, MV88E1116_PGADR_REG, 2); miiphy_read(name, devadr, MV88E1116_MAC_CTRL_REG, ®); reg |= (MV88E1116_RGMII_RXTM_CTRL | MV88E1116_RGMII_TXTM_CTRL); miiphy_write(name, devadr, MV88E1116_MAC_CTRL_REG, reg); miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0); /* reset the phy */ miiphy_reset(name, devadr); debug("88E1116 Initialized on %s\n", name); }
int board_eth_init(bd_t *bis) { int rv, n = 0; const char *devname; struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE; rv = handle_mac_address(); if (rv) printf("No MAC address found!\n"); writel(RGMII_MODE_ENABLE | RGMII_INT_DELAY, &cdev->miisel); board_phy_init(); rv = cpsw_register(&cpsw_data); if (rv < 0) printf("Error %d registering CPSW switch\n", rv); else n += rv; /* * CPSW RGMII Internal Delay Mode is not supported in all PVT * operating points. So we must set the TX clock delay feature * in the AR8051 PHY. Since we only support a single ethernet * device, we only do this for the first instance. */ devname = miiphy_get_current_dev(); miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_ADDR_REG, AR8051_DEBUG_RGMII_CLK_DLY_REG); miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_DATA_REG, AR8051_RGMII_TX_CLK_DLY); return n; }
int fecmxc_mii_postcall(int phy) { miiphy_write("FEC1", phy, MII_BMCR, 0x9000); miiphy_write("FEC1", phy, MII_OPMODE_STRAP_OVERRIDE, 0x0202); if (phy == 3) miiphy_write("FEC1", 3, MII_PHY_CTRL2, 0x8180); return 0; }
/* * (C) Copyright 2007 * Stefan Roese, DENX Software Engineering, [email protected]. * * 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 */ #include <config.h> #include <common.h> #include <command.h> #include <i2c.h> #include <miiphy.h> #ifdef CONFIG_TAISHAN #define LCD_DELAY_NORMAL_US 100 #define LCD_DELAY_NORMAL_MS 2 #define LCD_CMD_ADDR ((volatile char *)(CONFIG_SYS_EBC2_LCM_BASE)) #define LCD_DATA_ADDR ((volatile char *)(CONFIG_SYS_EBC2_LCM_BASE+1)) #define LCD_BLK_CTRL ((volatile char *)(CONFIG_SYS_EBC1_FPGA_BASE+0x2)) static int g_lcd_init_b = 0; static char *amcc_logo = " AMCC TAISHAN 440GX EvalBoard"; static char addr_flag = 0x80; static void lcd_bl_ctrl(char val) { char cpld_val; cpld_val = *LCD_BLK_CTRL; *LCD_BLK_CTRL = val | cpld_val; } static void lcd_putc(char val) { int i = 100; char addr; while (i--) { if ((*LCD_CMD_ADDR & 0x80) != 0x80) { /*BF = 1 ? */ udelay(LCD_DELAY_NORMAL_US); break; } udelay(LCD_DELAY_NORMAL_US); } if (*LCD_CMD_ADDR & 0x80) { printf("LCD is busy\n"); return; } addr = *LCD_CMD_ADDR; udelay(LCD_DELAY_NORMAL_US); if ((addr != 0) && (addr % 0x10 == 0)) { addr_flag ^= 0x40; *LCD_CMD_ADDR = addr_flag; } udelay(LCD_DELAY_NORMAL_US); *LCD_DATA_ADDR = val; udelay(LCD_DELAY_NORMAL_US); } static void lcd_puts(char *s) { char *p = s; int i = 100; while (i--) { if ((*LCD_CMD_ADDR & 0x80) != 0x80) { /*BF = 1 ? */ udelay(LCD_DELAY_NORMAL_US); break; } udelay(LCD_DELAY_NORMAL_US); } if (*LCD_CMD_ADDR & 0x80) { printf("LCD is busy\n"); return; } while (*p) lcd_putc(*p++); } static void lcd_put_logo(void) { int i = 100; char *p = amcc_logo; while (i--) { if ((*LCD_CMD_ADDR & 0x80) != 0x80) { /*BF = 1 ? */ udelay(LCD_DELAY_NORMAL_US); break; } udelay(LCD_DELAY_NORMAL_US); } if (*LCD_CMD_ADDR & 0x80) { printf("LCD is busy\n"); return; } *LCD_CMD_ADDR = 0x80; while (*p) lcd_putc(*p++); } int lcd_init(void) { if (g_lcd_init_b == 0) { puts("LCD: "); mdelay(100); /* Waiting for the LCD initialize */ *LCD_CMD_ADDR = 0x38; /*set function:8-bit,2-line,5x7 font type */ udelay(LCD_DELAY_NORMAL_US); *LCD_CMD_ADDR = 0x0f; /*set display on,cursor on,blink on */ udelay(LCD_DELAY_NORMAL_US); *LCD_CMD_ADDR = 0x01; /*display clear */ mdelay(LCD_DELAY_NORMAL_MS); *LCD_CMD_ADDR = 0x06; /*set entry */ udelay(LCD_DELAY_NORMAL_US); lcd_bl_ctrl(0x02); lcd_put_logo(); puts(" ready\n"); g_lcd_init_b = 1; } return 0; } static int do_lcd_test(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { lcd_init(); return 0; } static int do_lcd_clear(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { *LCD_CMD_ADDR = 0x01; mdelay(LCD_DELAY_NORMAL_MS); return 0; } static int do_lcd_puts(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { if (argc < 2) return cmd_usage(cmdtp); lcd_puts(argv[1]); return 0; } static int do_lcd_putc(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { if (argc < 2) return cmd_usage(cmdtp); lcd_putc((char)argv[1][0]); return 0; } static int do_lcd_cur(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { ulong count; ulong dir; char cur_addr; if (argc < 3) return cmd_usage(cmdtp); count = simple_strtoul(argv[1], NULL, 16); if (count > 31) { printf("unable to shift > 0x20\n"); count = 0; } dir = simple_strtoul(argv[2], NULL, 16); cur_addr = *LCD_CMD_ADDR; udelay(LCD_DELAY_NORMAL_US); if (dir == 0x0) { if (addr_flag == 0x80) { if (count >= (cur_addr & 0xf)) { *LCD_CMD_ADDR = 0x80; udelay(LCD_DELAY_NORMAL_US); count = 0; } } else { if (count >= ((cur_addr & 0x0f) + 0x0f)) { *LCD_CMD_ADDR = 0x80; addr_flag = 0x80; udelay(LCD_DELAY_NORMAL_US); count = 0x0; } else if (count >= (cur_addr & 0xf)) { count -= cur_addr & 0xf; *LCD_CMD_ADDR = 0x80 | 0xf; addr_flag = 0x80; udelay(LCD_DELAY_NORMAL_US); } } } else { if (addr_flag == 0x80) { if (count >= (0x1f - (cur_addr & 0xf))) { count = 0x0; addr_flag = 0xc0; *LCD_CMD_ADDR = 0xc0 | 0xf; udelay(LCD_DELAY_NORMAL_US); } else if ((count + (cur_addr & 0xf)) >= 0x0f) { count = count + (cur_addr & 0xf) - 0x0f; addr_flag = 0xc0; *LCD_CMD_ADDR = 0xc0; udelay(LCD_DELAY_NORMAL_US); } } else if ((count + (cur_addr & 0xf)) >= 0x0f) { count = 0x0; *LCD_CMD_ADDR = 0xc0 | 0xf; udelay(LCD_DELAY_NORMAL_US); } } while (count--) { if (dir == 0) { *LCD_CMD_ADDR = 0x10; } else { *LCD_CMD_ADDR = 0x14; } udelay(LCD_DELAY_NORMAL_US); } return 0; } U_BOOT_CMD(lcd_test, 1, 1, do_lcd_test, "lcd test display", ""); U_BOOT_CMD(lcd_cls, 1, 1, do_lcd_clear, "lcd clear display", ""); U_BOOT_CMD(lcd_puts, 2, 1, do_lcd_puts, "display string on lcd", "<string> - <string> to be displayed"); U_BOOT_CMD(lcd_putc, 2, 1, do_lcd_putc, "display char on lcd", "<char> - <char> to be displayed"); U_BOOT_CMD(lcd_cur, 3, 1, do_lcd_cur, "shift cursor on lcd", "<count> <dir>- shift cursor on lcd <count> times, direction is <dir> \n" " <count> - 0~31\n" " <dir> - 0,backward; 1, forward"); #if 0 /* test-only */ void set_phy_loopback_mode(void) { char devemac2[32]; char devemac3[32]; sprintf(devemac2, "%s2", CONFIG_EMAC_DEV_NAME); sprintf(devemac3, "%s3", CONFIG_EMAC_DEV_NAME); #if 0 unsigned short reg_short; miiphy_read(devemac2, 0x1, 1, ®_short); if (reg_short & 0x04) { /* * printf("EMAC2 link up,do nothing\n"); */ } else { udelay(1000); miiphy_write(devemac2, 0x1, 0, 0x6000); udelay(1000); miiphy_read(devemac2, 0x1, 0, ®_short); if (reg_short != 0x6000) { printf ("\nEMAC2 error set LOOPBACK mode error,reg2[0]=%x\n", reg_short); } } miiphy_read(devemac3, 0x3, 1, ®_short); if (reg_short & 0x04) { /* * printf("EMAC3 link up,do nothing\n"); */ } else { udelay(1000); miiphy_write(devemac3, 0x3, 0, 0x6000); udelay(1000); miiphy_read(devemac3, 0x3, 0, ®_short); if (reg_short != 0x6000) { printf ("\nEMAC3 error set LOOPBACK mode error,reg2[0]=%x\n", reg_short); } } #else /* Set PHY as LOOPBACK MODE, for Linux emac initializing */ miiphy_write(devemac2, CONFIG_PHY2_ADDR, 0, 0x6000); udelay(1000); miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0, 0x6000); udelay(1000); #endif /* 0 */ }
static void enbw_cmc_switch(int port, int on) { const char *devname; unsigned char phyaddr = 3; unsigned char reg = 0; unsigned short data; if (port == 1) phyaddr = 2; devname = miiphy_get_current_dev(); if (!devname) { printf("Error: no mii device\n"); return; } if (miiphy_read(devname, phyaddr, reg, &data) != 0) { printf("Error reading from the PHY addr=%02x reg=%02x\n", phyaddr, reg); return; } if (on) data &= ~PHY_POWER; else data |= PHY_POWER; if (miiphy_write(devname, phyaddr, reg, data) != 0) { printf("Error writing to the PHY addr=%02x reg=%02x\n", phyaddr, reg); return; } }
void reset_phy (void) { u16 id1, id2; /* initialize the PHY */ miiphy_reset ("NPE0", CONFIG_PHY_ADDR); miiphy_read ("NPE0", CONFIG_PHY_ADDR, MII_PHYSID1, &id1); miiphy_read ("NPE0", CONFIG_PHY_ADDR, MII_PHYSID2, &id2); id2 &= 0xFFF0; /* mask out revision bits */ if (id1 == 0x13 && id2 == 0x78e0) { /* * LXT971/LXT972 PHY: set LED outputs: * LED1(green) = Link/ACT, * LED2 (unused) = LINK, * LED3(red) = Coll */ miiphy_write ("NPE0", CONFIG_PHY_ADDR, 20, 0xD432); } else if (id1 == 0x143 && id2 == 0xbc30) { /* BCM5241: default values are OK */ } else printf ("unknown ethernet PHY ID: %x %x\n", id1, id2); }
int fecmxc_mii_postcall(int phy) { /* change PHY RMII clock to 50MHz */ miiphy_write("FEC", 0, MII_PHY_CTRL2, 0x8180); return 0; }
int fecmxc_mii_postcall(int phy) { #if defined(CONFIG_DENX_M28_V11) || defined(CONFIG_DENX_M28_V10) /* KZ8031 PHY on old boards. */ const uint32_t freq = 0x0080; #else /* KZ8021 PHY on new boards. */ const uint32_t freq = 0x0000; #endif miiphy_write("FEC1", phy, MII_BMCR, 0x9000); miiphy_write("FEC1", phy, MII_OPMODE_STRAP_OVERRIDE, 0x0202); if (phy == 3) miiphy_write("FEC1", 3, MII_PHY_CTRL2, 0x8100 | freq); return 0; }
static int sw_reg_read(const char *devname, u8 phy_addr, u8 port, u8 reg, u16 *data) { int ret; u16 command; ret = sw_wait_rdy(devname, phy_addr); if (ret) return ret; command = SMI_HDR | SMIRD_OP | ((port&SMI_MASK) << PORT_SHIFT) | (reg & SMI_MASK); debug("%s: write to command: %#x\n", __func__, command); ret = miiphy_write(devname, phy_addr, COMMAND_REG, command); if (ret) return ret; ret = sw_wait_rdy(devname, phy_addr); if (ret) return ret; ret = miiphy_read(devname, phy_addr, DATA_REG, data); return ret; }
/* Configure and enable MV88E1118 PHY on the piggy*/ void reset_phy(void) { unsigned int oui; unsigned char model, rev; char *name = "egiga0"; if (miiphy_set_current_dev(name)) return; /* reset the phy */ miiphy_reset(name, CONFIG_PHY_BASE_ADR); /* get PHY model */ if (miiphy_info(name, CONFIG_PHY_BASE_ADR, &oui, &model, &rev)) return; /* check for Marvell 88E1118R Gigabit PHY (PIGGY3) */ if ((oui == PHY_MARVELL_OUI) && (model == PHY_MARVELL_88E1118R_MODEL)) { /* set page register to 3 */ if (miiphy_write(name, CONFIG_PHY_BASE_ADR, PHY_MARVELL_PAGE_REG, PHY_MARVELL_88E1118R_LED_CTRL_PAGE)) printf("Error writing PHY page reg\n"); /* * leds setup as printed on PCB: * LED2 (Link): 0x0 (On Link, Off No Link) * LED1 (Activity): 0x3 (On Activity, Off No Activity) * LED0 (Speed): 0x7 (On 1000 MBits, Off Else) */ if (miiphy_write(name, CONFIG_PHY_BASE_ADR, PHY_MARVELL_88E1118R_LED_CTRL_REG, PHY_MARVELL_88E1118R_LED_CTRL_RESERVED | PHY_MARVELL_88E1118R_LED_CTRL_LED0_1000MB | PHY_MARVELL_88E1118R_LED_CTRL_LED1_ACT | PHY_MARVELL_88E1118R_LED_CTRL_LED2_LINK)) printf("Error writing PHY LED reg\n"); /* set page register back to 0 */ if (miiphy_write(name, CONFIG_PHY_BASE_ADR, PHY_MARVELL_PAGE_REG, PHY_MARVELL_DEFAULT_PAGE)) printf("Error writing PHY page reg\n"); } }
void lxt971_no_sleep(void) { unsigned short reg; miiphy_read("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, ®); reg &= ~0x0040; /* disable sleep mode */ miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, reg); }
int fecmxc_mii_postcall(int phy) { unsigned short val; /* * Due to the i.MX6Q Armadillo2 board HW design,there is * no 125Mhz clock input from SOC. In order to use RGMII, * We need enable AR8031 ouput a 125MHz clk from CLK_25M */ miiphy_write("FEC", phy, MII_MMD_ACCESS_CTRL_REG, 0x7); miiphy_write("FEC", phy, MII_MMD_ACCESS_ADDR_DATA_REG, 0x8016); miiphy_write("FEC", phy, MII_MMD_ACCESS_CTRL_REG, 0x4007); miiphy_read("FEC", phy, MII_MMD_ACCESS_ADDR_DATA_REG, &val); val &= 0xffe3; val |= 0x18; miiphy_write("FEC", phy, MII_MMD_ACCESS_ADDR_DATA_REG, val); /* For the RGMII phy, we need enable tx clock delay */ miiphy_write("FEC", phy, MII_DBG_PORT_REG, 0x5); miiphy_read("FEC", phy, MII_DBG_PORT2_REG, &val); val |= 0x0100; miiphy_write("FEC", phy, MII_DBG_PORT2_REG, val); miiphy_write("FEC", phy, MII_BMCR, 0xa100); return 0; }
static void mv88e61xx_switch_write(char *name, u32 phy_adr, u32 reg_ofs, u16 data) { u16 mii_dev_addr; /* command to read PHY dev address */ if (miiphy_read(name, 0xEE, 0xEE, &mii_dev_addr)) { printf("Error..could not read PHY dev address\n"); return; } mv88e61xx_busychk_multic(name, mii_dev_addr); /* Write data to Switch indirect data register */ miiphy_write(name, mii_dev_addr, 0x1, data); /* Write command to Switch indirect command register (write) */ miiphy_write(name, mii_dev_addr, 0x0, reg_ofs | (phy_adr << 5) | (1 << 10) | (1 << 12) | (1 << 15)); }
int phy_setup_aneg (char *devname, unsigned char addr) { unsigned short ctl, adv; /* Setup standard advertise */ miiphy_read (devname, addr, MII_ADVERTISE, &adv); adv |= (LPA_LPACK | LPA_RFAULT | LPA_100BASE4 | LPA_100FULL | LPA_100HALF | LPA_10FULL | LPA_10HALF); miiphy_write (devname, addr, MII_ADVERTISE, adv); /* Start/Restart aneg */ miiphy_read (devname, addr, MII_BMCR, &ctl); ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); miiphy_write (devname, addr, MII_BMCR, ctl); return 0; }
/* * Additional PHY intialization. After being reset in mpc5xxx_fec_init_phy(), * PHY goes into FX mode. To take it out of the FX mode and switch into * desired TX operation, one needs to clear the FX_SEL bit of Mode Control * Register. */ void reset_phy(void) { unsigned short mode_control; miiphy_read("FEC", CONFIG_PHY_ADDR, 0x15, &mode_control); miiphy_write("FEC", CONFIG_PHY_ADDR, 0x15, mode_control & 0xfffe); return; }
int phy_setup_aneg (unsigned char addr) { unsigned short ctl, adv; /* Setup standard advertise */ miiphy_read (addr, PHY_ANAR, &adv); adv |= (PHY_ANLPAR_ACK | PHY_ANLPAR_RF | PHY_ANLPAR_T4 | PHY_ANLPAR_TXFD | PHY_ANLPAR_TX | PHY_ANLPAR_10FD | PHY_ANLPAR_10); miiphy_write (addr, PHY_ANAR, adv); /* Start/Restart aneg */ miiphy_read (addr, PHY_BMCR, &ctl); ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); miiphy_write (addr, PHY_BMCR, ctl); return 0; }
void reset_phy (void) { int i; /* initialize the PHY */ miiphy_reset ("NPE0", CONFIG_PHY_ADDR); /* all LED outputs = Link/Act */ miiphy_write ("NPE0", CONFIG_PHY_ADDR, 0x16, 0x0AAA); /* * The Marvell 88E6060 switch comes up with all ports disabled. * set all ethernet switch ports to forwarding state */ for (i = 1; i <= 5; i++) miiphy_write ("NPE0", CONFIG_PHY_ADDR + 8 + i, 0x04, 0x03); }
static int process_setupcmd(const char *bus, unsigned char addr, struct mii_setupcmd *setupcmd) { int res; u8 reg = setupcmd->reg; u16 data = setupcmd->data; u16 mask = setupcmd->mask; u32 timeout = setupcmd->timeout; u16 orig_data; unsigned long start; debug("mii %s:%u reg %2u ", bus, addr, reg); switch (setupcmd->token) { case MIICMD_MODIFY: res = miiphy_read(bus, addr, reg, &orig_data); if (res) break; debug("is %04x. (value %04x mask %04x) ", orig_data, data, mask); data = (orig_data & ~mask) | (data & mask); /* fallthrough */ case MIICMD_SET: debug("=> %04x\n", data); res = miiphy_write(bus, addr, reg, data); break; case MIICMD_VERIFY_VALUE: res = miiphy_read(bus, addr, reg, &orig_data); if (res) break; if ((orig_data & mask) != (data & mask)) res = -1; debug("(value %04x mask %04x) == %04x? %s\n", data, mask, orig_data, res ? "FAIL" : "PASS"); break; case MIICMD_WAIT_FOR_VALUE: res = -1; start = get_timer(0); while ((res != 0) && (get_timer(start) < timeout)) { res = miiphy_read(bus, addr, reg, &orig_data); if (res) continue; if ((orig_data & mask) != (data & mask)) res = -1; } debug("(value %04x mask %04x) == %04x? %s after %lu ms\n", data, mask, orig_data, res ? "FAIL" : "PASS", get_timer(start)); break; default: res = -1; break; } return res; }
void reset_phys(void) { int phyno; unsigned short v; udelay(10000); /* reset the damn phys */ mii_init(); for (phyno = 0; phyno < 32; ++phyno) { miiphy_read("FEC ETHERNET", phyno, PHY_PHYIDR1, &v); if (v == 0xFFFF) continue; miiphy_write("FEC ETHERNET", phyno, PHY_BMCR, PHY_BMCR_POWD); udelay(10000); miiphy_write("FEC ETHERNET", phyno, PHY_BMCR, PHY_BMCR_RESET | PHY_BMCR_AUTON); udelay(10000); } }
int last_stage_init(void) { unsigned short reg; /* * Configure LED's of both Marvell 88E1111 PHY's * * This has to be done after the 4xx ethernet driver is loaded, * so "last_stage_init()" is the right place. */ miiphy_read("ppc_4xx_eth2", CONFIG_PHY2_ADDR, 0x18, ®); reg |= 0x0001; miiphy_write("ppc_4xx_eth2", CONFIG_PHY2_ADDR, 0x18, reg); miiphy_read("ppc_4xx_eth3", CONFIG_PHY3_ADDR, 0x18, ®); reg |= 0x0001; miiphy_write("ppc_4xx_eth3", CONFIG_PHY3_ADDR, 0x18, reg); return 0; }
void set_phy_normal_mode(void) { char devemac2[32]; char devemac3[32]; unsigned short reg_short; sprintf(devemac2, "%s2", CONFIG_EMAC_DEV_NAME); sprintf(devemac3, "%s3", CONFIG_EMAC_DEV_NAME); /* Set phy of EMAC2 */ miiphy_read(devemac2, CONFIG_PHY2_ADDR, 0x16, ®_short); reg_short &= ~(0x7); reg_short |= 0x6; /* RGMII DLL Delay */ miiphy_write(devemac2, CONFIG_PHY2_ADDR, 0x16, reg_short); miiphy_read(devemac2, CONFIG_PHY2_ADDR, 0x17, ®_short); reg_short &= ~(0x40); miiphy_write(devemac2, CONFIG_PHY2_ADDR, 0x17, reg_short); miiphy_write(devemac2, CONFIG_PHY2_ADDR, 0x1c, 0x74f0); /* Set phy of EMAC3 */ miiphy_read(devemac3, CONFIG_PHY3_ADDR, 0x16, ®_short); reg_short &= ~(0x7); reg_short |= 0x6; /* RGMII DLL Delay */ miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0x16, reg_short); miiphy_read(devemac3, CONFIG_PHY3_ADDR, 0x17, ®_short); reg_short &= ~(0x40); miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0x17, reg_short); miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0x1c, 0x74f0); }
int brcm_miiphy_read(unsigned char page, unsigned char reg, unsigned int *value) { int cmd; int max_retry = 0; unsigned short temp; cmd = (page << REG_PPM_REG16_SWITCH_PAGE_NUMBER_SHIFT) | REG_PPM_REG16_MDIO_ENABLE; miiphy_write(devname, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG16, cmd); cmd = (reg << REG_PPM_REG17_REG_NUMBER_SHIFT) | REG_PPM_REG17_OP_READ; miiphy_write(devname, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17, cmd); do { miiphy_read(devname, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG17, &temp); udelay(10); } while ((max_retry++ < 5) && ((temp & (REG_PPM_REG17_OP_WRITE | REG_PPM_REG17_OP_READ)) != REG_PPM_REG17_OP_DONE)); if (max_retry == 5) { printf("%s: Read timed out, page=%u, reg=%u, temp=0x%x\n", __func__, page, reg, temp); } miiphy_read(devname, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG24, &temp); *value = temp; miiphy_read(devname, PSEUDO_PHY_ADDR, REG_PSEUDO_PHY_MII_REG25, &temp); *value |= (temp << 16); return 0; }