Re: [PATCH v2 1/2] net: stmmac: Add Adaptrum Anarion GMAC glue layer

2017-08-06 Thread David Miller
From: Alexandru Gagniuc 
Date: Fri,  4 Aug 2017 13:08:51 -0700

> Before the GMAC on the Anarion chip can be used, the PHY interface
> selection must be configured with the DWMAC block in reset.
> 
> This layer covers a block containing only two registers. Although it
> is possible to model this as a reset controller and use the "resets"
> property of stmmac, it's much more intuitive to include this in the
> glue layer instead.
> 
> At this time only RGMII is supported, because it is the only mode
> which has been validated hardware-wise.
> 
> Signed-off-by: Alexandru Gagniuc 

Applied.


[PATCH v2 1/2] net: stmmac: Add Adaptrum Anarion GMAC glue layer

2017-08-04 Thread Alexandru Gagniuc
Before the GMAC on the Anarion chip can be used, the PHY interface
selection must be configured with the DWMAC block in reset.

This layer covers a block containing only two registers. Although it
is possible to model this as a reset controller and use the "resets"
property of stmmac, it's much more intuitive to include this in the
glue layer instead.

At this time only RGMII is supported, because it is the only mode
which has been validated hardware-wise.

Signed-off-by: Alexandru Gagniuc 
---
Changes since v1:
 * Moved documentation for bindings to separate patch

 drivers/net/ethernet/stmicro/stmmac/Kconfig|   9 ++
 drivers/net/ethernet/stmicro/stmmac/Makefile   |   1 +
 .../net/ethernet/stmicro/stmmac/dwmac-anarion.c| 152 +
 3 files changed, 162 insertions(+)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig 
b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 85c0e41..9703576 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -45,6 +45,15 @@ config DWMAC_GENERIC
  platform specific code to function or is using platform
  data for setup.
 
+config DWMAC_ANARION
+   tristate "Adaptrum Anarion GMAC support"
+   default ARC
+   depends on OF && (ARC || COMPILE_TEST)
+   help
+ Support for Adaptrum Anarion GMAC Ethernet controller.
+
+ This selects the Anarion SoC glue layer support for the stmmac driver.
+
 config DWMAC_IPQ806X
tristate "QCA IPQ806x DWMAC support"
default ARCH_QCOM
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile 
b/drivers/net/ethernet/stmicro/stmmac/Makefile
index fd4937a..238307f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -7,6 +7,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o 
ring_mode.o  \
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)  += stmmac-platform.o
+obj-$(CONFIG_DWMAC_ANARION)+= dwmac-anarion.o
 obj-$(CONFIG_DWMAC_IPQ806X)+= dwmac-ipq806x.o
 obj-$(CONFIG_DWMAC_LPC18XX)+= dwmac-lpc18xx.o
 obj-$(CONFIG_DWMAC_MESON)  += dwmac-meson.o dwmac-meson8b.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c 
b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
new file mode 100644
index 000..85ce80c
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-anarion.c
@@ -0,0 +1,152 @@
+/*
+ * Adaptrum Anarion DWMAC glue layer
+ *
+ * Copyright (C) 2017, Adaptrum, Inc.
+ * (Written by Alexandru Gagniuc  for Adaptrum, Inc.)
+ * Licensed under the GPLv2 or (at your option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "stmmac.h"
+#include "stmmac_platform.h"
+
+#define GMAC_RESET_CONTROL_REG 0
+#define GMAC_SW_CONFIG_REG 4
+#define  GMAC_CONFIG_INTF_SEL_MASK (0x7 << 0)
+#define  GMAC_CONFIG_INTF_RGMII(0x1 << 0)
+
+struct anarion_gmac {
+   uintptr_t ctl_block;
+   uint32_t phy_intf_sel;
+};
+
+static uint32_t gmac_read_reg(struct anarion_gmac *gmac, uint8_t reg)
+{
+   return readl((void *)(gmac->ctl_block + reg));
+};
+
+static void gmac_write_reg(struct anarion_gmac *gmac, uint8_t reg, uint32_t 
val)
+{
+   writel(val, (void *)(gmac->ctl_block + reg));
+}
+
+static int anarion_gmac_init(struct platform_device *pdev, void *priv)
+{
+   uint32_t sw_config;
+   struct anarion_gmac *gmac = priv;
+
+   /* Reset logic, configure interface mode, then release reset. SIMPLE! */
+   gmac_write_reg(gmac, GMAC_RESET_CONTROL_REG, 1);
+
+   sw_config = gmac_read_reg(gmac, GMAC_SW_CONFIG_REG);
+   sw_config &= ~GMAC_CONFIG_INTF_SEL_MASK;
+   sw_config |= (gmac->phy_intf_sel & GMAC_CONFIG_INTF_SEL_MASK);
+   gmac_write_reg(gmac, GMAC_SW_CONFIG_REG, sw_config);
+
+   gmac_write_reg(gmac, GMAC_RESET_CONTROL_REG, 0);
+
+   return 0;
+}
+
+static void anarion_gmac_exit(struct platform_device *pdev, void *priv)
+{
+   struct anarion_gmac *gmac = priv;
+
+   gmac_write_reg(gmac, GMAC_RESET_CONTROL_REG, 1);
+}
+
+static struct anarion_gmac *anarion_config_dt(struct platform_device *pdev)
+{
+   int phy_mode;
+   struct resource *res;
+   void __iomem *ctl_block;
+   struct anarion_gmac *gmac;
+
+   res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+   ctl_block = devm_ioremap_resource(>dev, res);
+   if (IS_ERR(ctl_block)) {
+   dev_err(>dev, "Cannot get reset region (%ld)!\n",
+   PTR_ERR(ctl_block));
+   return ctl_block;
+   }
+
+   gmac = devm_kzalloc(>dev, sizeof(*gmac), GFP_KERNEL);
+   if (!gmac)
+   return ERR_PTR(-ENOMEM);
+
+   gmac->ctl_block = (uintptr_t)ctl_block;
+
+   phy_mode = of_get_phy_mode(pdev->dev.of_node);
+   switch