xref: /rk3399_rockchip-uboot/arch/arm/mach-at91/phy.c (revision 20680b560a17fb29c862de77930cfbf76b24f83c)
1*62011840SMasahiro Yamada /*
2*62011840SMasahiro Yamada  * (C) Copyright 2007-2008
3*62011840SMasahiro Yamada  * Stelian Pop <stelian@popies.net>
4*62011840SMasahiro Yamada  * Lead Tech Design <www.leadtechdesign.com>
5*62011840SMasahiro Yamada  *
6*62011840SMasahiro Yamada  * (C) Copyright 2012
7*62011840SMasahiro Yamada  * Markus Hubig <mhubig@imko.de>
8*62011840SMasahiro Yamada  * IMKO GmbH <www.imko.de>
9*62011840SMasahiro Yamada  *
10*62011840SMasahiro Yamada  * Copyright (C) 2013 DENX Software Engineering, hs@denx.de
11*62011840SMasahiro Yamada  *
12*62011840SMasahiro Yamada  * SPDX-License-Identifier:	GPL-2.0+
13*62011840SMasahiro Yamada  */
14*62011840SMasahiro Yamada 
15*62011840SMasahiro Yamada #include <common.h>
16*62011840SMasahiro Yamada #include <asm/io.h>
17*62011840SMasahiro Yamada #include <linux/sizes.h>
18*62011840SMasahiro Yamada #include <asm/arch/at91_rstc.h>
19*62011840SMasahiro Yamada #include <watchdog.h>
20*62011840SMasahiro Yamada 
at91_phy_reset(void)21*62011840SMasahiro Yamada void at91_phy_reset(void)
22*62011840SMasahiro Yamada {
23*62011840SMasahiro Yamada 	unsigned long erstl;
24*62011840SMasahiro Yamada 	unsigned long start = get_timer(0);
25*62011840SMasahiro Yamada 	unsigned long const timeout = 1000; /* 1000ms */
26*62011840SMasahiro Yamada 	at91_rstc_t *rstc = (at91_rstc_t *)ATMEL_BASE_RSTC;
27*62011840SMasahiro Yamada 
28*62011840SMasahiro Yamada 	erstl = readl(&rstc->mr) & AT91_RSTC_MR_ERSTL_MASK;
29*62011840SMasahiro Yamada 
30*62011840SMasahiro Yamada 	/*
31*62011840SMasahiro Yamada 	 * Need to reset PHY -> 500ms reset
32*62011840SMasahiro Yamada 	 * Reset PHY by pulling the NRST line for 500ms to low. To do so
33*62011840SMasahiro Yamada 	 * disable user reset for low level on NRST pin and poll the NRST
34*62011840SMasahiro Yamada 	 * level in reset status register.
35*62011840SMasahiro Yamada 	 */
36*62011840SMasahiro Yamada 	writel(AT91_RSTC_KEY | AT91_RSTC_MR_ERSTL(0x0D) |
37*62011840SMasahiro Yamada 		AT91_RSTC_MR_URSTEN, &rstc->mr);
38*62011840SMasahiro Yamada 
39*62011840SMasahiro Yamada 	writel(AT91_RSTC_KEY | AT91_RSTC_CR_EXTRST, &rstc->cr);
40*62011840SMasahiro Yamada 
41*62011840SMasahiro Yamada 	/* Wait for end of hardware reset */
42*62011840SMasahiro Yamada 	while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL)) {
43*62011840SMasahiro Yamada 		/* avoid shutdown by watchdog */
44*62011840SMasahiro Yamada 		WATCHDOG_RESET();
45*62011840SMasahiro Yamada 		mdelay(10);
46*62011840SMasahiro Yamada 
47*62011840SMasahiro Yamada 		/* timeout for not getting stuck in an endless loop */
48*62011840SMasahiro Yamada 		if (get_timer(start) >= timeout) {
49*62011840SMasahiro Yamada 			puts("*** ERROR: Timeout waiting for PHY reset!\n");
50*62011840SMasahiro Yamada 			break;
51*62011840SMasahiro Yamada 		}
52*62011840SMasahiro Yamada 	};
53*62011840SMasahiro Yamada 
54*62011840SMasahiro Yamada 	/* Restore NRST value */
55*62011840SMasahiro Yamada 	writel(AT91_RSTC_KEY | erstl | AT91_RSTC_MR_URSTEN, &rstc->mr);
56*62011840SMasahiro Yamada }
57