diff mbox

[linux] mach-aspeed: Add Zaius BMC PHY reset

Message ID 1477004194-107484-1-git-send-email-xow@google.com
State Accepted, archived
Headers show

Commit Message

Xo Wang Oct. 20, 2016, 10:56 p.m. UTC
The Broadcom PHY for the Zaius BMC requires a hard reset after RGMII
clocks are enabled. This asserts the reset in case it wasn't performed
in U-Boot.

Signed-off-by: Xo Wang <xow@google.com>
---
 arch/arm/mach-aspeed/aspeed.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Comments

Joel Stanley Oct. 21, 2016, 4:57 a.m. UTC | #1
On Fri, Oct 21, 2016 at 9:26 AM, Xo Wang <xow@google.com> wrote:
> The Broadcom PHY for the Zaius BMC requires a hard reset after RGMII
> clocks are enabled. This asserts the reset in case it wasn't performed
> in U-Boot.

Applied to dev-4.7 as b1842ce03a37af80f638c2f7c679704b5bb5bd56.

I'm not sure how we would handle this properly if we were to submit it
upstream. We can carry it for now though.

Cheers,

Joel

>
> Signed-off-by: Xo Wang <xow@google.com>
> ---
>  arch/arm/mach-aspeed/aspeed.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
>
> diff --git a/arch/arm/mach-aspeed/aspeed.c b/arch/arm/mach-aspeed/aspeed.c
> index 0a1700e..ebb2224 100644
> --- a/arch/arm/mach-aspeed/aspeed.c
> +++ b/arch/arm/mach-aspeed/aspeed.c
> @@ -11,6 +11,7 @@
>  #include <linux/of_irq.h>
>  #include <linux/of_platform.h>
>  #include <linux/io.h>
> +#include <linux/delay.h>
>  #include <asm/mach-types.h>
>  #include <asm/mach/arch.h>
>  #include <asm/mach/map.h>
> @@ -186,6 +187,9 @@ static void __init do_zaius_setup(void)
>
>         /* EVT1 hacks */
>         if (board_rev == 0) {
> +               /* D3 in GPIOA/B/C/D direction and data registers */
> +               unsigned long phy_reset_mask = BIT(27);
> +
>                 /* Set strap[13:12] to 01, Enable SPI master */
>                 /* Set bits in writes to SCU7C are cleared from SCU70 */
>                 writel(BIT(13), AST_IO(AST_BASE_SCU | 0x7C));
> @@ -195,6 +199,18 @@ static void __init do_zaius_setup(void)
>                 /* Disable GPIO I, G/AB pulldowns due to weak driving buffers */
>                 reg = readl(AST_IO(AST_BASE_SCU | 0x8C));
>                 writel(reg | BIT(24) | BIT(22), AST_IO(AST_BASE_SCU | 0x8C));
> +
> +               /* Assert MAC2 PHY hardware reset */
> +               /* Set pin low */
> +               reg = readl(AST_IO(AST_BASE_GPIO | 0x00));
> +               writel(reg & ~phy_reset_mask, AST_IO(AST_BASE_GPIO | 0x00));
> +               /* Enable pin for output */
> +               reg = readl(AST_IO(AST_BASE_GPIO | 0x04));
> +               writel(reg | phy_reset_mask, AST_IO(AST_BASE_GPIO | 0x04));
> +               udelay(3);
> +               /* Set pin high */
> +               reg = readl(AST_IO(AST_BASE_GPIO | 0x00));
> +               writel(reg | phy_reset_mask, AST_IO(AST_BASE_GPIO | 0x00));
>         }
>  }
>
> --
> 2.8.0.rc3.226.g39d4020
>
> _______________________________________________
> openbmc mailing list
> openbmc@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/openbmc
Joel Stanley Oct. 25, 2016, 4:18 a.m. UTC | #2
Hi Xo,

On Fri, Oct 21, 2016 at 3:27 PM, Joel Stanley <joel@jms.id.au> wrote:
> On Fri, Oct 21, 2016 at 9:26 AM, Xo Wang <xow@google.com> wrote:
>> The Broadcom PHY for the Zaius BMC requires a hard reset after RGMII
>> clocks are enabled. This asserts the reset in case it wasn't performed
>> in U-Boot.

> I'm not sure how we would handle this properly if we were to submit it
> upstream. We can carry it for now though.

I came across this thread on lkml: https://patchwork.ozlabs.org/patch/685741/

It has some suggestions for now to do a hard reset of the IP on boot
using GPIOs, which might be an upstreamable solution for your issue.

Cheers,

Joel
Xo Wang Oct. 31, 2016, 10:54 p.m. UTC | #3
Hi Joel,

On Mon, Oct 24, 2016 at 9:18 PM, Joel Stanley <joel@jms.id.au> wrote:
> Hi Xo,
>
> On Fri, Oct 21, 2016 at 3:27 PM, Joel Stanley <joel@jms.id.au> wrote:
>> On Fri, Oct 21, 2016 at 9:26 AM, Xo Wang <xow@google.com> wrote:
>>> The Broadcom PHY for the Zaius BMC requires a hard reset after RGMII
>>> clocks are enabled. This asserts the reset in case it wasn't performed
>>> in U-Boot.
>
>> I'm not sure how we would handle this properly if we were to submit it
>> upstream. We can carry it for now though.
>
> I came across this thread on lkml: https://patchwork.ozlabs.org/patch/685741/
>
> It has some suggestions for now to do a hard reset of the IP on boot
> using GPIOs, which might be an upstreamable solution for your issue.
>
> Cheers,
>
> Joel

I was hoping to wiggle out of needing this PHY reset if it can instead
happen in U-Boot, but now I'm thinking that would be an irritating
(and unexpected) dependency to have.

The discussion and proposed code there make sense to me. The
discussion for the general libphy driver reset looks like it has some
nuances yet to be ironed out:
https://patchwork.ozlabs.org/patch/623651/

Do you think the path of least controversy would be to port the
Freescale MAC patch to the Broadcom PHY driver?

cheers
xo
diff mbox

Patch

diff --git a/arch/arm/mach-aspeed/aspeed.c b/arch/arm/mach-aspeed/aspeed.c
index 0a1700e..ebb2224 100644
--- a/arch/arm/mach-aspeed/aspeed.c
+++ b/arch/arm/mach-aspeed/aspeed.c
@@ -11,6 +11,7 @@ 
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/io.h>
+#include <linux/delay.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -186,6 +187,9 @@  static void __init do_zaius_setup(void)
 
 	/* EVT1 hacks */
 	if (board_rev == 0) {
+		/* D3 in GPIOA/B/C/D direction and data registers */
+		unsigned long phy_reset_mask = BIT(27);
+
 		/* Set strap[13:12] to 01, Enable SPI master */
 		/* Set bits in writes to SCU7C are cleared from SCU70 */
 		writel(BIT(13), AST_IO(AST_BASE_SCU | 0x7C));
@@ -195,6 +199,18 @@  static void __init do_zaius_setup(void)
 		/* Disable GPIO I, G/AB pulldowns due to weak driving buffers */
 		reg = readl(AST_IO(AST_BASE_SCU | 0x8C));
 		writel(reg | BIT(24) | BIT(22), AST_IO(AST_BASE_SCU | 0x8C));
+
+		/* Assert MAC2 PHY hardware reset */
+		/* Set pin low */
+		reg = readl(AST_IO(AST_BASE_GPIO | 0x00));
+		writel(reg & ~phy_reset_mask, AST_IO(AST_BASE_GPIO | 0x00));
+		/* Enable pin for output */
+		reg = readl(AST_IO(AST_BASE_GPIO | 0x04));
+		writel(reg | phy_reset_mask, AST_IO(AST_BASE_GPIO | 0x04));
+		udelay(3);
+		/* Set pin high */
+		reg = readl(AST_IO(AST_BASE_GPIO | 0x00));
+		writel(reg | phy_reset_mask, AST_IO(AST_BASE_GPIO | 0x00));
 	}
 }