add common phy reset code into a common function.
Signed-off-by: Heiko Schocher <hs@denx.de>
Cc: Andreas Bießmann <andreas.devel@googlemail.com>
Cc: Bo Shen <voice.shen@atmel.com>
Cc: Jens Scharsig <esw@bus-elektronik.de>
Cc: Sergey Lapin <slapin@ossfans.org>
Cc: Stelian Pop <stelian@popies.net>
Cc: Albin Tonnerre <albin.tonnerre@free-electrons.com>
Cc: Eric Benard <eric@eukrea.com>
Cc: Markus Hubig <mhubig@imko.de>
Acked-by: Jens Scharsig (BuS Elektronik) <esw@bus-elektronik.de>
Tested-by: Jens Scharsig (BuS Elektronik) <esw@bus-elektronik.de>
Tested-by: Bo Shen <voice.shen@atmel.com>
Acked-by: Bo Shen <voice.shen@atmel.com>
Signed-off-by: Andreas Bießmann <andreas.devel@googlemail.com>
 # SPDX-License-Identifier:     GPL-2.0+
 #
 
+obj-$(CONFIG_AT91_WANTS_COMMON_PHY) += phy.o
 obj-$(CONFIG_SPL_BUILD) += mpddrc.o spl.o
 
--- /dev/null
+/*
+ * (C) Copyright 2007-2008
+ * Stelian Pop <stelian@popies.net>
+ * Lead Tech Design <www.leadtechdesign.com>
+ *
+ * (C) Copyright 2012
+ * Markus Hubig <mhubig@imko.de>
+ * IMKO GmbH <www.imko.de>
+ *
+ * Copyright (C) 2013 DENX Software Engineering, hs@denx.de
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/sizes.h>
+#include <asm/arch/at91_pmc.h>
+#include <asm/arch/at91_rstc.h>
+#include <watchdog.h>
+
+void at91_phy_reset(void)
+{
+       unsigned long erstl;
+       unsigned long start = get_timer(0);
+       unsigned long const timeout = 1000; /* 1000ms */
+       at91_rstc_t *rstc = (at91_rstc_t *)ATMEL_BASE_RSTC;
+
+       erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK;
+
+       /*
+        * Need to reset PHY -> 500ms reset
+        * Reset PHY by pulling the NRST line for 500ms to low. To do so
+        * disable user reset for low level on NRST pin and poll the NRST
+        * level in reset status register.
+        */
+       writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(0x0D) |
+               AT91_RSTC_MR_URSTEN, &rstc->mr);
+
+       writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr);
+
+       /* Wait for end of hardware reset */
+       while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL)) {
+               /* avoid shutdown by watchdog */
+               WATCHDOG_RESET();
+               mdelay(10);
+
+               /* timeout for not getting stuck in an endless loop */
+               if (get_timer(start) >= timeout) {
+                       puts("*** ERROR: Timeout waiting for PHY reset!\n");
+                       break;
+               }
+       };
+
+       /* Restore NRST value */
+       writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN, &rstc->mr);
+}
 
 void at91_mck_init(u32 mckr);
 void at91_pmc_init(void);
 void mem_init(void);
+void at91_phy_reset(void);
 
 #endif /* AT91_COMMON_H */
 
 #include <asm/arch/at91sam9_smc.h>
 #include <asm/arch/at91_pmc.h>
 #include <asm/arch/at91_pio.h>
-#include <asm/arch/at91_rstc.h>
 #include <asm/arch/at91sam9263.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/at91_common.h>
 #ifdef CONFIG_MACB
 static void vl_ma2sc_macb_hw_init(void)
 {
-       unsigned long   erstl;
        at91_pmc_t      *pmc    = (at91_pmc_t *) ATMEL_BASE_PMC;
-       at91_rstc_t     *rstc   = (at91_rstc_t *) ATMEL_BASE_RSTC;
+
        /* Enable clock */
        writel(1 << ATMEL_ID_EMAC, &pmc->pcer);
 
-       erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK;
-
-       /* Need to reset PHY -> 500ms reset */
-       writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(0x0D) |
-               AT91_RSTC_MR_URSTEN, &rstc->mr);
-
-       writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr);
-       /* Wait for end hardware reset */
-       while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL))
-               ;
-
-       /* Restore NRST value */
-       writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN, &rstc->mr);
+       at91_phy_reset();
 
        at91_macb_hw_init();
 }
 
 #include <asm/arch/at91sam9_smc.h>
 #include <asm/arch/at91_common.h>
 #include <asm/arch/at91_pmc.h>
-#include <asm/arch/at91_rstc.h>
 #include <asm/arch/gpio.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 {
        struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
        struct at91_port *pioa = (struct at91_port *)ATMEL_BASE_PIOA;
-       struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC;
-       unsigned long erstl;
 
 
        /* Enable EMAC clock */
               pin_to_mask(AT91_PIN_PA28),
               &pioa->pudr);
 
-       erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK;
-
-       /* Need to reset PHY -> 500ms reset */
-       writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(13) |
-               AT91_RSTC_MR_URSTEN, &rstc->mr);
-       writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr);
-
-       /* Wait for end hardware reset */
-       while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL))
-               ;
-       /* Restore NRST value */
-       writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN,
-               &rstc->mr);
-
+       at91_phy_reset();
 
        /* Re-enable pull-up */
        writel(pin_to_mask(AT91_PIN_PA14) |
 
 #include <asm/arch/at91sam9_smc.h>
 #include <asm/arch/at91_common.h>
 #include <asm/arch/at91_pmc.h>
-#include <asm/arch/at91_rstc.h>
 #include <asm/arch/gpio.h>
 #include <atmel_mci.h>
 
 {
        struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
        struct at91_port *pioa = (struct at91_port *)ATMEL_BASE_PIOA;
-       struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC;
-       unsigned long erstl;
 
        /* Enable EMAC clock */
        writel(1 << ATMEL_ID_EMAC0, &pmc->pcer);
                pin_to_mask(AT91_PIN_PA28),
                &pioa->pudr);
 
-       erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK;
-
-       /* Need to reset PHY -> 500ms reset */
-       writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(13) |
-               AT91_RSTC_MR_URSTEN, &rstc->mr);
-
-       writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr);
-
-       /* Wait for end hardware reset */
-       while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL))
-               ;
-
-       /* Restore NRST value */
-       writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN,
-               &rstc->mr);
+       at91_phy_reset();
 
        /* Re-enable pull-up */
        writel(pin_to_mask(AT91_PIN_PA14) |
 
 #include <asm/arch/at91sam9_smc.h>
 #include <asm/arch/at91_common.h>
 #include <asm/arch/at91_pmc.h>
-#include <asm/arch/at91_rstc.h>
 #include <asm/arch/at91_matrix.h>
 #include <asm/arch/at91_pio.h>
 #include <asm/arch/clk.h>
 #ifdef CONFIG_MACB
 static void at91sam9263ek_macb_hw_init(void)
 {
-       unsigned long   erstl;
        at91_pmc_t      *pmc    = (at91_pmc_t *) ATMEL_BASE_PMC;
        at91_pio_t      *pio    = (at91_pio_t *) ATMEL_BASE_PIO;
-       at91_rstc_t     *rstc   = (at91_rstc_t *) ATMEL_BASE_RSTC;
+
        /* Enable clock */
        writel(1 << ATMEL_ID_EMAC, &pmc->pcer);
 
         *
         * PHY has internal pull-down
         */
-
        writel(1 << 25, &pio->pioc.pudr);
        writel((1 << 25) | (1 <<26), &pio->pioe.pudr);
 
-       erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK;
-
-       /* Need to reset PHY -> 500ms reset */
-       writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(0x0D) |
-               AT91_RSTC_MR_URSTEN, &rstc->mr);
-
-       writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr);
-       /* Wait for end hardware reset */
-       while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL))
-               ;
-
-       /* Restore NRST value */
-       writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN, &rstc->mr);
+       at91_phy_reset();
 
        /* Re-enable pull-up */
        writel(1 << 25, &pio->pioc.puer);
 
 #include <asm/arch/at91sam9_smc.h>
 #include <asm/arch/at91_common.h>
 #include <asm/arch/at91_pmc.h>
-#include <asm/arch/at91_rstc.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/clk.h>
 #include <lcd.h>
 {
        struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
        struct at91_port *pioa = (struct at91_port *)ATMEL_BASE_PIOA;
-       struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC;
-       unsigned long erstl;
 
        /* Enable clock */
        writel(1 << ATMEL_ID_EMAC, &pmc->pcer);
               pin_to_mask(AT91_PIN_PA13),
               &pioa->pudr);
 
-       erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK;
-
-       /* Need to reset PHY -> 500ms reset */
-       writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(13) |
-               AT91_RSTC_MR_URSTEN, &rstc->mr);
-
-       writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr);
-
-       /* Wait for end hardware reset */
-       while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL))
-               ;
-
-       /* Restore NRST value */
-       writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN,
-               &rstc->mr);
+       at91_phy_reset();
 
        /* Re-enable pull-up */
        writel(pin_to_mask(AT91_PIN_PA15) |
 
 #include <asm/arch/at91sam9_smc.h>
 #include <asm/arch/at91_common.h>
 #include <asm/arch/at91_pmc.h>
-#include <asm/arch/at91_rstc.h>
 #include <asm/arch/gpio.h>
 #include <net.h>
 #include <netdev.h>
 {
        struct at91_pmc *pmc   = (struct at91_pmc  *)ATMEL_BASE_PMC;
        struct at91_port *pioa = (struct at91_port *)ATMEL_BASE_PIOA;
-       struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC;
-       unsigned long erstl;
 
        /* Enable clock */
        writel(1 << ATMEL_ID_EMAC0, &pmc->pcer);
        /* Enable ethernet power */
        pca953x_set_val(0x28, IO_EXP_ETH_POWER, 0);
 
-       /* Need to reset PHY -> 500ms reset */
-       erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK;
-       writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(13) |
-              AT91_RSTC_MR_URSTEN, &rstc->mr);
-       writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr);
-
-       /* Wait for end hardware reset */
-       while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL))
-               ;
-
-       /* Restore NRST value */
-       writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN, &rstc->mr);
+       at91_phy_reset();
 
        /* Bring the ethernet out of reset */
        pca953x_set_val(0x28, IO_EXP_ETH_RESET, 1);
 
 #include <asm/arch/at91sam9_smc.h>
 #include <asm/arch/at91_common.h>
 #include <asm/arch/at91_pmc.h>
-#include <asm/arch/at91_rstc.h>
 #include <asm/arch/gpio.h>
 
 #if defined(CONFIG_RESET_PHY_R) && defined(CONFIG_MACB)
 {
        struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
        struct at91_port *pioa = (struct at91_port *)ATMEL_BASE_PIOA;
-       struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC;
-       unsigned long erstl;
 
        /* Enable EMAC clock */
        writel(1 << ATMEL_ID_EMAC0, &pmc->pcer);
               pin_to_mask(AT91_PIN_PA28),
               &pioa->pudr);
 
-       erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK;
-
-       /* Need to reset PHY -> 500ms reset */
-       writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(13) |
-               AT91_RSTC_MR_URSTEN, &rstc->mr);
-
-       writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr);
-
-       /* Wait for end hardware reset */
-       while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL))
-               ;
-
-       /* Restore NRST value */
-       writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN,
-               &rstc->mr);
+       at91_phy_reset();
 
        /* Re-enable pull-up */
        writel(pin_to_mask(AT91_PIN_PA14) |
 
 #include <asm/arch/at91_common.h>
 #include <asm/arch/at91_matrix.h>
 #include <asm/arch/at91_pmc.h>
-#include <asm/arch/at91_rstc.h>
 #include <asm/arch/at91_pio.h>
 #include <asm/arch/clk.h>
 #include <asm/arch/hardware.h>
 #ifdef CONFIG_MACB
 static void cpu9260_macb_hw_init(void)
 {
-       unsigned long rstcmr;
        at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC;
-       at91_rstc_t *rstc = (at91_rstc_t *) ATMEL_BASE_RSTC;
 
        /* Enable clock */
        writel(1 << ATMEL_ID_EMAC0, &pmc->pcer);
 
        at91_set_pio_pullup(AT91_PIO_PORTA, 17, 1);
 
-       rstcmr = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK;
-
-       /* Need to reset PHY -> 500ms reset */
-       writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(0xD) |
-                               AT91_RSTC_MR_URSTEN, &rstc->mr);
-
-       writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr);
-
-       /* Wait for end hardware reset */
-       while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL))
-               ;
-
-       /* Restore NRST value */
-       writel(AT91_RSTC_KEY | rstcmr | AT91_RSTC_MR_URSTEN, &rstc->mr);
+       at91_phy_reset();
 
        at91_macb_hw_init();
 }
 
 #include <asm/arch/at91sam9_smc.h>
 #include <asm/arch/at91_common.h>
 #include <asm/arch/at91_pmc.h>
-#include <asm/arch/at91_rstc.h>
 #include <asm/arch/gpio.h>
 #include <watchdog.h>
 
 static void stamp9G20_macb_hw_init(void)
 {
        struct at91_port *pioa = (struct at91_port *)ATMEL_BASE_PIOA;
-       struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC;
-       unsigned long erstl;
 
        /* Enable the PHY Chip via PA26 on the Stamp 2 Adaptor */
        at91_set_gpio_output(AT91_PIN_PA26, 0);
                pin_to_mask(AT91_PIN_PA28),
                &pioa->pudr);
 
-       erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK;
-
-       /* Need to reset PHY -> 500ms reset */
-       writel(AT91_RSTC_KEY | (AT91_RSTC_MR_ERSTL(13) &
-                               ~AT91_RSTC_MR_URSTEN), &rstc->mr);
-       writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr);
-
-       /* Wait for end of hardware reset */
-       unsigned long start = get_timer(0);
-       unsigned long timeout = 1000; /* 1000ms */
-
-       while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL)) {
-
-               /* avoid shutdown by watchdog */
-               WATCHDOG_RESET();
-               mdelay(10);
-
-               /* timeout for not getting stuck in an endless loop */
-               if (get_timer(start) >= timeout) {
-                       puts("*** ERROR: Timeout waiting for PHY reset!\n");
-                       break;
-               };
-       };
-
-       /* Restore NRST value */
-       writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN,
-               &rstc->mr);
+       at91_phy_reset();
 
        /* Re-enable pull-up */
        writel(pin_to_mask(AT91_PIN_PA14) |
 
 /* Ethernet */
 #define CONFIG_MACB
 #define CONFIG_RESET_PHY_R
-
+#define CONFIG_AT91_WANTS_COMMON_PHY
 #define CONFIG_NET_RETRY_COUNT         20
 
 /* USB */
 
 #define CONFIG_RMII                    1
 #define CONFIG_NET_RETRY_COUNT         20
 #define CONFIG_RESET_PHY_R             1
+#define CONFIG_AT91_WANTS_COMMON_PHY
 
 /* USB */
 #define CONFIG_USB_ATMEL
 
 #define CONFIG_RMII                    1
 #define CONFIG_NET_RETRY_COUNT         20
 #define CONFIG_RESET_PHY_R             1
+#define CONFIG_AT91_WANTS_COMMON_PHY
 
 /* USB */
 #define CONFIG_USB_ATMEL
 
 #define CONFIG_RMII
 #define CONFIG_NET_RETRY_COUNT         20
 #define CONFIG_RESET_PHY_R
+#define CONFIG_AT91_WANTS_COMMON_PHY
 
 /* USB */
 #define CONFIG_USB_EHCI
 
 #define CONFIG_RMII
 #define CONFIG_NET_RETRY_COUNT                 20
 #define CONFIG_MACB_SEARCH_PHY
+#define CONFIG_AT91_WANTS_COMMON_PHY
 
 /* LEDS */
 /* Status LED */
 
 #define CONFIG_NET_RETRY_COUNT         20
 #define CONFIG_RESET_PHY_R
 #define CONFIG_MACB_SEARCH_PHY
+#define CONFIG_AT91_WANTS_COMMON_PHY
 
 /* USB */
 #define CONFIG_USB_ATMEL
 
 #define CONFIG_RMII
 #define CONFIG_NET_RETRY_COUNT         20
 #define CONFIG_RESET_PHY_R
+#define CONFIG_AT91_WANTS_COMMON_PHY
 #define CONFIG_TFTP_PORT
 #define CONFIG_TFTP_TSIZE
 
 
 #ifdef CONFIG_MACB
 # define CONFIG_RMII                   /* use reduced MII inteface */
 # define CONFIG_NET_RETRY_COUNT        20      /* # of DHCP/BOOTP retries */
+#define CONFIG_AT91_WANTS_COMMON_PHY
 
 /* BOOTP and DHCP options */
 # define CONFIG_BOOTP_BOOTFILESIZE
 
 #define CONFIG_RMII
 #define CONFIG_NET_MULTI
 #define CONFIG_NET_RETRY_COUNT         5
+#define CONFIG_AT91_WANTS_COMMON_PHY
 
 #define CONFIG_OVERWRITE_ETHADDR_ONCE