Exemple #1
0
//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);
			reg |= (1 << 7); /* set phy RMII 50MHz clk;*/
			miiphy_write(devname, phyaddr, 0x1F, reg);

			miiphy_read(devname, phyaddr, 0x16, &reg);
			reg |= (1 << 1); /* set phy RMII override; */
			miiphy_write(devname, phyaddr, 0x16, reg);
		}
	}
	return 0;
}
Exemple #2
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);
	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);
}
Exemple #4
0
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);
	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);
	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);
}
Exemple #5
0
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;
}
Exemple #6
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;
}
Exemple #7
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;
}
Exemple #8
0
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;
}
Exemple #9
0
/* 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);
	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);
}
Exemple #10
0
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;
}
Exemple #11
0
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;
}
Exemple #12
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, &reg_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, &reg_short);
		if (reg_short != 0x6000) {
			printf
			    ("\nEMAC2 error set LOOPBACK mode error,reg2[0]=%x\n",
			     reg_short);
		}
	}

	miiphy_read(devemac3, 0x3, 1, &reg_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, &reg_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 */
}
Exemple #13
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;
	}
}
Exemple #14
0
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);
}
Exemple #15
0
int fecmxc_mii_postcall(int phy)
{
	/* change PHY RMII clock to 50MHz */
	miiphy_write("FEC", 0, MII_PHY_CTRL2, 0x8180);

	return 0;
}
Exemple #16
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;
}
Exemple #17
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;
}
Exemple #18
0
/* 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");
	}
}
Exemple #19
0
void lxt971_no_sleep(void)
{
	unsigned short reg;

	miiphy_read("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, &reg);
	reg &= ~0x0040;                  /* disable sleep mode */
	miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, reg);
}
Exemple #20
0
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;
}
Exemple #21
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));
}
Exemple #22
0
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;
}
Exemple #23
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;
}
Exemple #25
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);

}
Exemple #26
0
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;
}
Exemple #27
0
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);
	reg |= 0x0001;
	miiphy_write("ppc_4xx_eth2", CONFIG_PHY2_ADDR, 0x18, reg);
	miiphy_read("ppc_4xx_eth3", CONFIG_PHY3_ADDR, 0x18, &reg);
	reg |= 0x0001;
	miiphy_write("ppc_4xx_eth3", CONFIG_PHY3_ADDR, 0x18, reg);

	return 0;
}
Exemple #29
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, &reg_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, &reg_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, &reg_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, &reg_short);
	reg_short &= ~(0x40);
	miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0x17, reg_short);

	miiphy_write(devemac3, CONFIG_PHY3_ADDR, 0x1c, 0x74f0);
}
Exemple #30
0
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;

}