コード例 #1
0
static void cpu9260_macb_hw_init(void)
{
	unsigned long rstc;

	/* Enable clock */
	at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_EMAC);

	/*
	 * Disable pull-up on:
	 *	RXDV (PA17) => PHY normal mode (not Test mode)
	 *	ERX0 (PA14) => PHY ADDR0
	 *	ERX1 (PA15) => PHY ADDR1
	 *	ERX2 (PA25) => PHY ADDR2
	 *	ERX3 (PA26) => PHY ADDR3
	 *	ECRS (PA28) => PHY ADDR4  => PHYADDR = 0x0
	 *
	 * PHY has internal pull-down
	 */
	writel(pin_to_mask(AT91_PIN_PA14) |
	       pin_to_mask(AT91_PIN_PA15) |
	       pin_to_mask(AT91_PIN_PA17) |
	       pin_to_mask(AT91_PIN_PA25) |
	       pin_to_mask(AT91_PIN_PA26) |
	       pin_to_mask(AT91_PIN_PA28),
	       pin_to_controller(AT91_PIN_PA0) + PIO_PUDR);

	rstc = at91_sys_read(AT91_RSTC_MR) & AT91_RSTC_ERSTL;

	/* Need to reset PHY -> 500ms reset */
	at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
		       (AT91_RSTC_ERSTL & (0x0D << 8)) |
		       AT91_RSTC_URSTEN);

	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_EXTRST);

	/* Wait for end hardware reset */
	while (!(at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_NRSTL))
		;

	/* Restore NRST value */
	at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
		       (rstc) |
		       AT91_RSTC_URSTEN);

	/* Re-enable pull-up */
	writel(pin_to_mask(AT91_PIN_PA14) |
	       pin_to_mask(AT91_PIN_PA15) |
	       pin_to_mask(AT91_PIN_PA17) |
	       pin_to_mask(AT91_PIN_PA25) |
	       pin_to_mask(AT91_PIN_PA26) |
	       pin_to_mask(AT91_PIN_PA28),
	       pin_to_controller(AT91_PIN_PA0) + PIO_PUER);

	at91_macb_hw_init();
}
コード例 #2
0
static int at91_gpio_show(struct seq_file *s, void *unused)
{
	int bank, j;

	/* print heading */
	seq_printf(s, "Pin\t");
	for (bank = 0; bank < gpio_banks; bank++) {
		seq_printf(s, "PIO%c\t", 'A' + bank);
	};
	seq_printf(s, "\n\n");

	/* print pin status */
	for (j = 0; j < 32; j++) {
		seq_printf(s, "%i:\t", j);

		for (bank = 0; bank < gpio_banks; bank++) {
			unsigned	pin  = PIN_BASE + (32 * bank) + j;
			void __iomem	*pio = pin_to_controller(pin);
			unsigned	mask = pin_to_mask(pin);

			if (__raw_readl(pio + PIO_PSR) & mask)
				seq_printf(s, "GPIO:%s", __raw_readl(pio + PIO_PDSR) & mask ? "1" : "0");
			else
				seq_printf(s, "%s", __raw_readl(pio + PIO_ABSR) & mask ? "B" : "A");

			seq_printf(s, "\t");
		}

		seq_printf(s, "\n");
	}

	return 0;
}
コード例 #3
0
ファイル: gpio.c プロジェクト: 01org/KVMGT-kernel
static int at91_gpio_show(struct seq_file *s, void *unused)
{
	int bank, j;

	/* print heading */
	seq_printf(s, "Pin\t");
	for (bank = 0; bank < gpio_banks; bank++) {
		seq_printf(s, "PIO%c\t\t", 'A' + bank);
	};
	seq_printf(s, "\n\n");

	/* print pin status */
	for (j = 0; j < 32; j++) {
		seq_printf(s, "%i:\t", j);

		for (bank = 0; bank < gpio_banks; bank++) {
			unsigned	pin  = (32 * bank) + j;
			void __iomem	*pio = pin_to_controller(pin);
			unsigned	mask = pin_to_mask(pin);

			if (__raw_readl(pio + PIO_PSR) & mask)
				gpio_printf(s, pio, mask);
			else
				seq_printf(s, "%c\t\t",
						peripheral_function(pio, mask));
		}

		seq_printf(s, "\n");
	}

	return 0;
}
コード例 #4
0
static void at91_gpiolib_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{
	int i;

	for (i = 0; i < chip->ngpio; i++) {
		unsigned pin = chip->base + i;
		void __iomem *pio = pin_to_controller(pin);
		unsigned mask = pin_to_mask(pin);
		const char *gpio_label;

		gpio_label = gpiochip_is_requested(chip, i);
		if (gpio_label) {
			seq_printf(s, "[%s] GPIO%s%d: ",
				   gpio_label, chip->label, i);
			if (__raw_readl(pio + PIO_PSR) & mask)
				seq_printf(s, "[gpio] %s\n",
					   at91_get_gpio_value(pin) ?
					   "set" : "clear");
			else
				seq_printf(s, "[periph %s]\n",
					   __raw_readl(pio + PIO_ABSR) &
					   mask ? "B" : "A");
		}
	}
}
コード例 #5
0
ファイル: gpio.c プロジェクト: ivucica/linux
static void gpio_irq_unmask(unsigned pin)
{
	void __iomem	*pio = pin_to_controller(pin);
	unsigned	mask = pin_to_mask(pin);

	if (pio)
		__raw_writel(mask, pio + PIO_IER);
}
コード例 #6
0
ファイル: gpio.c プロジェクト: sisilet/linux-imx21
static void gpio_irq_unmask(unsigned pin)
{
	struct pio_controller __iomem	*pio = pin_to_controller(pin);
	unsigned			mask = pin_to_mask(pin);

	if (pio)
		__raw_writel(mask, &pio->ier);
}
コード例 #7
0
static void gpio_irq_unmask(struct irq_data *d)
{
	void __iomem	*pio = pin_to_controller(d->irq);
	unsigned	mask = pin_to_mask(d->irq);

	if (pio)
		__raw_writel(mask, pio + PIO_IER);
}
コード例 #8
0
ファイル: gpio.c プロジェクト: sisilet/linux-imx21
/*
 * assuming the pin is muxed as a gpio output, set its value.
 */
int at91_set_gpio_value(unsigned pin, int value)
{
	struct pio_controller __iomem	*pio = pin_to_controller(pin);
	unsigned			mask = pin_to_mask(pin);

	if (!pio)
		return -EINVAL;
	__raw_writel(mask, value ? &pio->sodr : &pio->codr);
	return 0;
}
コード例 #9
0
ファイル: gpio.c プロジェクト: ivucica/linux
/*
 * enable/disable the glitch filter; mostly used with IRQ handling.
 */
int __init_or_module at91_set_deglitch(unsigned pin, int is_on)
{
	void __iomem	*pio = pin_to_controller(pin);
	unsigned	mask = pin_to_mask(pin);

	if (!pio)
		return -EINVAL;
	__raw_writel(mask, pio + (is_on ? PIO_IFER : PIO_IFDR));
	return 0;
}
コード例 #10
0
ファイル: gpio.c プロジェクト: sisilet/linux-imx21
/*
 * enable/disable the glitch filter; mostly used with IRQ handling.
 */
int __init_or_module at91_set_deglitch(unsigned pin, int is_on)
{
	struct pio_controller __iomem	*pio = pin_to_controller(pin);
	unsigned			mask = pin_to_mask(pin);

	if (!pio)
		return -EINVAL;
	__raw_writel(mask, is_on ? &pio->ifer : &pio->ifdr);
	return 0;
}
コード例 #11
0
ファイル: smc_driverL.c プロジェクト: ESLab/rtdl
int at91_set_gpio_value(unsigned pin, int value)
{
	void __iomem	*pio = pin_to_controller(pin);
	unsigned	mask = pin_to_mask(pin);

	if (!pio)
		return -EINVAL;
	__raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
	return 0;
}
コード例 #12
0
ファイル: gpio.c プロジェクト: ForayJones/iods
int gpio_direction_input(unsigned pin)
{
	void __iomem	*pio = pin_to_controller(pin);
	unsigned	mask = pin_to_mask(pin);

	if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
		return -EINVAL;
	__raw_writel(mask, pio + PIO_ODR);
	return 0;
}
コード例 #13
0
ファイル: gpio.c プロジェクト: sisilet/linux-imx21
/*
 * read the pin's value (works even if it's not muxed as a gpio).
 */
int at91_get_gpio_value(unsigned pin)
{
	struct pio_controller __iomem	*pio = pin_to_controller(pin);
	unsigned			mask = pin_to_mask(pin);
	u32				pdsr;

	if (!pio)
		return -EINVAL;
	pdsr = __raw_readl(&pio->pdsr);
	return (pdsr & mask) != 0;
}
コード例 #14
0
ファイル: gpio.c プロジェクト: ivucica/linux
/*
 * read the pin's value (works even if it's not muxed as a gpio).
 */
int at91_get_gpio_value(unsigned pin)
{
	void __iomem	*pio = pin_to_controller(pin);
	unsigned	mask = pin_to_mask(pin);
	u32		pdsr;

	if (!pio)
		return -EINVAL;
	pdsr = __raw_readl(pio + PIO_PDSR);
	return (pdsr & mask) != 0;
}
コード例 #15
0
ファイル: gpio.c プロジェクト: ForayJones/iods
int gpio_direction_output(unsigned pin, int value)
{
	void __iomem	*pio = pin_to_controller(pin);
	unsigned	mask = pin_to_mask(pin);

	if (!pio || !(__raw_readl(pio + PIO_PSR) & mask))
		return -EINVAL;
	__raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
	__raw_writel(mask, pio + PIO_OER);
	return 0;
}
コード例 #16
0
ファイル: gpio.c プロジェクト: 01org/KVMGT-kernel
/*
 * disable Schmitt trigger
 */
int __init_or_module at91_disable_schmitt_trig(unsigned pin)
{
	void __iomem	*pio = pin_to_controller(pin);
	unsigned	mask = pin_to_mask(pin);

	if (!pio || !has_pio3())
		return -EINVAL;

	__raw_writel(__raw_readl(pio + PIO_SCHMITT) | mask, pio + PIO_SCHMITT);
	return 0;
}
コード例 #17
0
/*
 * mux the pin to the "GPIO" peripheral role.
 */
int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup)
{
	void __iomem	*pio = pin_to_controller(pin);
	unsigned	mask = pin_to_mask(pin);

	if (!pio)
		return -EINVAL;
	__raw_writel(mask, pio + PIO_IDR);
	__raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
	__raw_writel(mask, pio + PIO_PER);
	return 0;
}
コード例 #18
0
ファイル: gpio.c プロジェクト: 01org/KVMGT-kernel
/*
 * enable/disable the pull-down.
 * If pull-up already enabled while calling the function, we disable it.
 */
int __init_or_module at91_set_pulldown(unsigned pin, int is_on)
{
	void __iomem	*pio = pin_to_controller(pin);
	unsigned	mask = pin_to_mask(pin);

	if (!pio || !has_pio3())
		return -EINVAL;

	/* Disable pull-up anyway */
	__raw_writel(mask, pio + PIO_PUDR);
	__raw_writel(mask, pio + (is_on ? PIO_PPDER : PIO_PPDDR));
	return 0;
}
コード例 #19
0
ファイル: gpio.c プロジェクト: sisilet/linux-imx21
/*
 * mux the pin to the "B" internal peripheral role.
 */
int __init_or_module at91_set_B_periph(unsigned pin, int use_pullup)
{
	struct pio_controller __iomem	*pio = pin_to_controller(pin);
	unsigned			mask = pin_to_mask(pin);

	if (!pio)
		return -EINVAL;

	__raw_writel(mask, &pio->idr);
	__raw_writel(mask, use_pullup ? &pio->puer : &pio->pudr);
	__raw_writel(mask, &pio->bsr);
	__raw_writel(mask, &pio->pdr);
	return 0;
}
コード例 #20
0
ファイル: gpio.c プロジェクト: 01org/KVMGT-kernel
/*
 * mux the pin to the "D" internal peripheral role.
 */
int __init_or_module at91_set_D_periph(unsigned pin, int use_pullup)
{
	void __iomem	*pio = pin_to_controller(pin);
	unsigned	mask = pin_to_mask(pin);

	if (!pio || !has_pio3())
		return -EINVAL;

	__raw_writel(mask, pio + PIO_IDR);
	__raw_writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
	__raw_writel(__raw_readl(pio + PIO_ABCDSR1) | mask, pio + PIO_ABCDSR1);
	__raw_writel(__raw_readl(pio + PIO_ABCDSR2) | mask, pio + PIO_ABCDSR2);
	__raw_writel(mask, pio + PIO_PDR);
	return 0;
}
コード例 #21
0
ファイル: smc_driverL.c プロジェクト: ESLab/rtdl
int __init_or_module at91_set_gpio_output(unsigned pin, int value)
{
	void __iomem	*pio = pin_to_controller(pin);
	unsigned	mask = pin_to_mask(pin);

	if (!pio)
		return -EINVAL;

	__raw_writel(mask, pio + PIO_IDR);
	__raw_writel(mask, pio + PIO_PUDR);
	__raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));
	__raw_writel(mask, pio + PIO_OER);
	__raw_writel(mask, pio + PIO_PER);
	return 0;
}
コード例 #22
0
ファイル: smc_driverL.c プロジェクト: ESLab/rtdl
int at91_set_A_periph(unsigned pin, int use_pullup)
{
	//void __iomem	*pio = pin_to_controller(pin);
	void *pio = pin_to_controller(pin);
	unsigned	mask = pin_to_mask(pin);

	if (!pio)
		//return -EINVAL;
	  return 1;

	writel(mask, pio + PIO_IDR);
	writel(mask, pio + (use_pullup ? PIO_PUER : PIO_PUDR));
	writel(mask, pio + PIO_ASR);
	writel(mask, pio + PIO_PDR);
	return 0;
}
コード例 #23
0
ファイル: gpio.c プロジェクト: 01org/KVMGT-kernel
/*
 * enable/disable the debounce filter;
 */
int __init_or_module at91_set_debounce(unsigned pin, int is_on, int div)
{
	void __iomem	*pio = pin_to_controller(pin);
	unsigned	mask = pin_to_mask(pin);

	if (!pio || !has_pio3())
		return -EINVAL;

	if (is_on) {
		__raw_writel(mask, pio + PIO_IFSCER);
		__raw_writel(div & PIO_SCDR_DIV, pio + PIO_SCDR);
		__raw_writel(mask, pio + PIO_IFER);
	} else {
		__raw_writel(mask, pio + PIO_IFDR);
	}
	return 0;
}
コード例 #24
0
ファイル: gpio.c プロジェクト: sisilet/linux-imx21
/*
 * mux the pin to the gpio controller (instead of "A" or "B" peripheral).
 *  for input, mode == use_pullup
 *  for output, mode == initial value
 */
int __init_or_module at91_set_gpio_direction(unsigned pin, int is_input, int mode)
{
	struct pio_controller __iomem	*pio = pin_to_controller(pin);
	unsigned			mask = pin_to_mask(pin);

	if (!pio)
		return -EINVAL;

	__raw_writel(mask, &pio->idr);
	if (is_input) {
		__raw_writel(mask, mode ? &pio->puer : &pio->pudr);
		__raw_writel(mask, &pio->odr);
	} else {
		__raw_writel(mask, &pio->pudr);
		__raw_writel(mask, mode ? &pio->sodr : &pio->codr);
		__raw_writel(mask, &pio->oer);
	}
	__raw_writel(mask, &pio->per);
	return 0;
}
コード例 #25
0
ファイル: som-9g20.c プロジェクト: sensysnetworks/u-boot-at91
static void at91sam9g20ek_macb_hw_init(void)
{
	/* Enable clock */
	at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_EMAC);

	/*
	 * Disable pull-up on:
	 *	RXDV (PA17) => PHY normal mode (not Test mode)
	 *	ERX0 (PA14) => PHY ADDR0
	 *	ERX1 (PA15) => PHY ADDR1
	 *	ERX2 (PA25) => PHY ADDR2
	 *	ERX3 (PA26) => PHY ADDR3
	 *	ECRS (PA28) => PHY ADDR4  => PHYADDR = 0x0
	 *
	 * PHY has internal pull-down
	 */
	writel(pin_to_mask(AT91_PIN_PA14) |
	       pin_to_mask(AT91_PIN_PA15) |
	       pin_to_mask(AT91_PIN_PA17) |
	       pin_to_mask(AT91_PIN_PA25) |
	       pin_to_mask(AT91_PIN_PA26) |
	       pin_to_mask(AT91_PIN_PA28),
	       pin_to_controller(AT91_PIN_PA0) + PIO_PUDR);

//	/* Need to reset PHY -> 500ms reset */
//	at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
//				     (AT91_RSTC_ERSTL & (0x0D << 8)) |
//				     AT91_RSTC_URSTEN);
//
//	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_EXTRST);
//
//	/* Wait for end hardware reset */
//	while (!(at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_NRSTL));
//
	/* Restore NRST value */
	at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
				     (AT91_RSTC_ERSTL & (0x0 << 8)) |
				     AT91_RSTC_URSTEN);

	/* Re-enable pull-up */
	writel(pin_to_mask(AT91_PIN_PA14) |
	       pin_to_mask(AT91_PIN_PA15) |
	       pin_to_mask(AT91_PIN_PA17) |
	       pin_to_mask(AT91_PIN_PA25) |
	       pin_to_mask(AT91_PIN_PA26) |
	       pin_to_mask(AT91_PIN_PA28),
	       pin_to_controller(AT91_PIN_PA0) + PIO_PUER);

	at91_set_A_periph(AT91_PIN_PA19, 0);	/* ETXCK_EREFCK */
	at91_set_A_periph(AT91_PIN_PA17, 0);	/* ERXDV */
	at91_set_A_periph(AT91_PIN_PA14, 0);	/* ERX0 */
	at91_set_A_periph(AT91_PIN_PA15, 0);	/* ERX1 */
	at91_set_A_periph(AT91_PIN_PA18, 0);	/* ERXER */
	at91_set_A_periph(AT91_PIN_PA16, 0);	/* ETXEN */
	at91_set_A_periph(AT91_PIN_PA12, 0);	/* ETX0 */
	at91_set_A_periph(AT91_PIN_PA13, 0);	/* ETX1 */
	at91_set_A_periph(AT91_PIN_PA21, 0);	/* EMDIO */
	at91_set_A_periph(AT91_PIN_PA20, 0);	/* EMDC */

#ifndef CONFIG_RMII
	at91_set_B_periph(AT91_PIN_PA28, 0);	/* ECRS */
	at91_set_B_periph(AT91_PIN_PA29, 0);	/* ECOL */
	at91_set_B_periph(AT91_PIN_PA25, 0);	/* ERX2 */
	at91_set_B_periph(AT91_PIN_PA26, 0);	/* ERX3 */
	at91_set_B_periph(AT91_PIN_PA27, 0);	/* ERXCK */
#if defined(CONFIG_AT91SAM9G20EK)
	/*
	 * use PA10, PA11 for ETX2, ETX3.
	 * PA23 and PA24 are for TWI EEPROM
	 */
	at91_set_B_periph(AT91_PIN_PA10, 0);    /* ETX2 */
	at91_set_B_periph(AT91_PIN_PA11, 0);    /* ETX3 */
#else
	at91_set_B_periph(AT91_PIN_PA23, 0);    /* ETX2 */
	at91_set_B_periph(AT91_PIN_PA24, 0);    /* ETX3 */
#endif
	at91_set_B_periph(AT91_PIN_PA22, 0);	/* ETXER */
#endif

}
コード例 #26
0
static void at91sam9263ek_macb_hw_init(void)
{
	/* Enable clock */
	at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9263_ID_EMAC);

	/*
	 * Disable pull-up on:
	 *	RXDV (PC25) => PHY normal mode (not Test mode)
	 * 	ERX0 (PE25) => PHY ADDR0
	 *	ERX1 (PE26) => PHY ADDR1 => PHYADDR = 0x0
	 *
	 * PHY has internal pull-down
	 */
	writel(pin_to_mask(AT91_PIN_PC25),
	       pin_to_controller(AT91_PIN_PC0) + PIO_PUDR);
	writel(pin_to_mask(AT91_PIN_PE25) |
	       pin_to_mask(AT91_PIN_PE26),
	       pin_to_controller(AT91_PIN_PE0) + PIO_PUDR);

	/* Need to reset PHY -> 500ms reset */
	at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
				     (AT91_RSTC_ERSTL & (0x0D << 8)) |
				     AT91_RSTC_URSTEN);

	at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_EXTRST);

	/* Wait for end hardware reset */
	while (!(at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_NRSTL));

	/* Restore NRST value */
	at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
				     (AT91_RSTC_ERSTL & (0x0 << 8)) |
				     AT91_RSTC_URSTEN);

	/* Re-enable pull-up */
	writel(pin_to_mask(AT91_PIN_PC25),
	       pin_to_controller(AT91_PIN_PC0) + PIO_PUER);
	writel(pin_to_mask(AT91_PIN_PE25) |
	       pin_to_mask(AT91_PIN_PE26),
	       pin_to_controller(AT91_PIN_PE0) + PIO_PUER);

	at91_set_A_periph(AT91_PIN_PE21, 0);	/* ETXCK_EREFCK */
	at91_set_B_periph(AT91_PIN_PC25, 0);	/* ERXDV */
	at91_set_A_periph(AT91_PIN_PE25, 0);	/* ERX0 */
	at91_set_A_periph(AT91_PIN_PE26, 0);	/* ERX1 */
	at91_set_A_periph(AT91_PIN_PE27, 0);	/* ERXER */
	at91_set_A_periph(AT91_PIN_PE28, 0);	/* ETXEN */
	at91_set_A_periph(AT91_PIN_PE23, 0);	/* ETX0 */
	at91_set_A_periph(AT91_PIN_PE24, 0);	/* ETX1 */
	at91_set_A_periph(AT91_PIN_PE30, 0);	/* EMDIO */
	at91_set_A_periph(AT91_PIN_PE29, 0);	/* EMDC */

#ifndef CONFIG_RMII
	at91_set_A_periph(AT91_PIN_PE22, 0);	/* ECRS */
	at91_set_B_periph(AT91_PIN_PC26, 0);	/* ECOL */
	at91_set_B_periph(AT91_PIN_PC22, 0);	/* ERX2 */
	at91_set_B_periph(AT91_PIN_PC23, 0);	/* ERX3 */
	at91_set_B_periph(AT91_PIN_PC27, 0);	/* ERXCK */
	at91_set_B_periph(AT91_PIN_PC20, 0);	/* ETX2 */
	at91_set_B_periph(AT91_PIN_PC21, 0);	/* ETX3 */
	at91_set_B_periph(AT91_PIN_PC24, 0);	/* ETXER */
#endif

}
コード例 #27
0
ファイル: at91cap9adk.c プロジェクト: mrtos/Logitech-Revue
static void at91cap9_macb_hw_init(void)
{
    /* Enable clock */
    at91_sys_write(AT91_PMC_PCER, 1 << AT91CAP9_ID_EMAC);

    /*
     * Disable pull-up on:
     *	RXDV (PB22) => PHY normal mode (not Test mode)
     *	ERX0 (PB25) => PHY ADDR0
     *	ERX1 (PB26) => PHY ADDR1 => PHYADDR = 0x0
     *
     * PHY has internal pull-down
     */
    writel(pin_to_mask(AT91_PIN_PB22) |
           pin_to_mask(AT91_PIN_PB25) |
           pin_to_mask(AT91_PIN_PB26),
           pin_to_controller(AT91_PIN_PA0) + PIO_PUDR);

    /* Need to reset PHY -> 500ms reset */
    at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
                   (AT91_RSTC_ERSTL & (0x0D << 8)) |
                   AT91_RSTC_URSTEN);

    at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_EXTRST);

    /* Wait for end hardware reset */
    while (!(at91_sys_read(AT91_RSTC_SR) & AT91_RSTC_NRSTL));

    /* Restore NRST value */
    at91_sys_write(AT91_RSTC_MR, AT91_RSTC_KEY |
                   (AT91_RSTC_ERSTL & (0x0 << 8)) |
                   AT91_RSTC_URSTEN);

    /* Re-enable pull-up */
    writel(pin_to_mask(AT91_PIN_PB22) |
           pin_to_mask(AT91_PIN_PB25) |
           pin_to_mask(AT91_PIN_PB26),
           pin_to_controller(AT91_PIN_PA0) + PIO_PUER);

    at91_set_A_periph(AT91_PIN_PB21, 0);	/* ETXCK_EREFCK */
    at91_set_A_periph(AT91_PIN_PB22, 0);	/* ERXDV */
    at91_set_A_periph(AT91_PIN_PB25, 0);	/* ERX0 */
    at91_set_A_periph(AT91_PIN_PB26, 0);	/* ERX1 */
    at91_set_A_periph(AT91_PIN_PB27, 0);	/* ERXER */
    at91_set_A_periph(AT91_PIN_PB28, 0);	/* ETXEN */
    at91_set_A_periph(AT91_PIN_PB23, 0);	/* ETX0 */
    at91_set_A_periph(AT91_PIN_PB24, 0);	/* ETX1 */
    at91_set_A_periph(AT91_PIN_PB30, 0);	/* EMDIO */
    at91_set_A_periph(AT91_PIN_PB29, 0);	/* EMDC */

#ifndef CONFIG_RMII
    at91_set_B_periph(AT91_PIN_PC25, 0);	/* ECRS */
    at91_set_B_periph(AT91_PIN_PC26, 0);	/* ECOL */
    at91_set_B_periph(AT91_PIN_PC22, 0);	/* ERX2 */
    at91_set_B_periph(AT91_PIN_PC23, 0);	/* ERX3 */
    at91_set_B_periph(AT91_PIN_PC27, 0);	/* ERXCK */
    at91_set_B_periph(AT91_PIN_PC20, 0);	/* ETX2 */
    at91_set_B_periph(AT91_PIN_PC21, 0);	/* ETX3 */
    at91_set_B_periph(AT91_PIN_PC24, 0);	/* ETXER */
#endif
    /* Unlock EMAC, 3 0 2 1 sequence */
#define MP_MAC_KEY0	0x5969cb2a
#define MP_MAC_KEY1	0xb4a1872e
#define MP_MAC_KEY2	0x05683fbc
#define MP_MAC_KEY3	0x3634fba4
#define UNLOCK_MAC	0x00000008
    writel(MP_MAC_KEY3, MP_BLOCK_3_BASE + 0x3c);
    writel(MP_MAC_KEY0, MP_BLOCK_3_BASE + 0x30);
    writel(MP_MAC_KEY2, MP_BLOCK_3_BASE + 0x38);
    writel(MP_MAC_KEY1, MP_BLOCK_3_BASE + 0x34);
    writel(UNLOCK_MAC, MP_BLOCK_3_BASE + 0x40);
}