* [PATCH] net: stmmac: add fix_mac_speed support for socfpga
@ 2014-08-20 6:33 Ley Foon Tan
2014-08-20 6:57 ` LF.Tan
2014-08-22 19:35 ` David Miller
0 siblings, 2 replies; 3+ messages in thread
From: Ley Foon Tan @ 2014-08-20 6:33 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: Ley Foon Tan, lftan.linux, Giuseppe Cavallaro, Vince Bridgers
This patch adds fix_mac_speed() support for
Altera socfpga Ethernet controller. Emac splitter is a
soft IP core in FPGA system that converts GMII interface from
Synopsys mac to RGMII/SGMII interface. This splitter core is
an optional IP if user would like to use RGMII/SGMII
interface in their system. Software needs to update a register
in splitter core when there is speed change.
Signed-off-by: Ley Foon Tan <lftan@altera.com>
---
.../devicetree/bindings/net/socfpga-dwmac.txt | 4 ++
.../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 63 ++++++++++++++++++++++
2 files changed, 67 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/socfpga-dwmac.txt b/Documentation/devicetree/bindings/net/socfpga-dwmac.txt
index 2a60cd3..3a9d679 100644
--- a/Documentation/devicetree/bindings/net/socfpga-dwmac.txt
+++ b/Documentation/devicetree/bindings/net/socfpga-dwmac.txt
@@ -12,6 +12,10 @@ Required properties:
- altr,sysmgr-syscon : Should be the phandle to the system manager node that
encompasses the glue register, the register offset, and the register shift.
+Optional properties:
+altr,emac-splitter: Should be the phandle to the emac splitter soft IP node if
+ DWMAC controller is connected emac splitter.
+
Example:
gmac0: ethernet@ff700000 {
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index ec632e6..cd613d7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -17,6 +17,7 @@
#include <linux/mfd/syscon.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_net.h>
#include <linux/phy.h>
#include <linux/regmap.h>
@@ -30,6 +31,12 @@
#define SYSMGR_EMACGRP_CTRL_PHYSEL_WIDTH 2
#define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x00000003
+#define EMAC_SPLITTER_CTRL_REG 0x0
+#define EMAC_SPLITTER_CTRL_SPEED_MASK 0x3
+#define EMAC_SPLITTER_CTRL_SPEED_10 0x2
+#define EMAC_SPLITTER_CTRL_SPEED_100 0x3
+#define EMAC_SPLITTER_CTRL_SPEED_1000 0x0
+
struct socfpga_dwmac {
int interface;
u32 reg_offset;
@@ -37,14 +44,46 @@ struct socfpga_dwmac {
struct device *dev;
struct regmap *sys_mgr_base_addr;
struct reset_control *stmmac_rst;
+ void __iomem *splitter_base;
};
+static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed)
+{
+ struct socfpga_dwmac *dwmac = (struct socfpga_dwmac *)priv;
+ void __iomem *splitter_base = dwmac->splitter_base;
+ u32 val;
+
+ if (!splitter_base)
+ return;
+
+ val = readl(splitter_base + EMAC_SPLITTER_CTRL_REG);
+ val &= ~EMAC_SPLITTER_CTRL_SPEED_MASK;
+
+ switch (speed) {
+ case 1000:
+ val |= EMAC_SPLITTER_CTRL_SPEED_1000;
+ break;
+ case 100:
+ val |= EMAC_SPLITTER_CTRL_SPEED_100;
+ break;
+ case 10:
+ val |= EMAC_SPLITTER_CTRL_SPEED_10;
+ break;
+ default:
+ return;
+ }
+
+ writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG);
+}
+
static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev)
{
struct device_node *np = dev->of_node;
struct regmap *sys_mgr_base_addr;
u32 reg_offset, reg_shift;
int ret;
+ struct device_node *np_splitter;
+ struct resource res_splitter;
dwmac->stmmac_rst = devm_reset_control_get(dev,
STMMAC_RESOURCE_NAME);
@@ -73,6 +112,21 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *
return -EINVAL;
}
+ np_splitter = of_parse_phandle(np, "altr,emac-splitter", 0);
+ if (np_splitter) {
+ if (of_address_to_resource(np_splitter, 0, &res_splitter)) {
+ dev_info(dev, "Missing emac splitter address\n");
+ return -EINVAL;
+ }
+
+ dwmac->splitter_base = (void *)devm_ioremap_resource(dev,
+ &res_splitter);
+ if (!dwmac->splitter_base) {
+ dev_info(dev, "Failed to mapping emac splitter\n");
+ return -EINVAL;
+ }
+ }
+
dwmac->reg_offset = reg_offset;
dwmac->reg_shift = reg_shift;
dwmac->sys_mgr_base_addr = sys_mgr_base_addr;
@@ -91,6 +145,7 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac)
switch (phymode) {
case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
break;
case PHY_INTERFACE_MODE_MII:
@@ -102,6 +157,13 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac)
return -EINVAL;
}
+ /* Overwrite val to GMII if splitter core is enabled. The phymode here
+ * is the actual phy mode on phy hardware, but phy interface from
+ * EMAC core is GMII.
+ */
+ if (dwmac->splitter_base)
+ val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
+
regmap_read(sys_mgr_base_addr, reg_offset, &ctrl);
ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift);
ctrl |= val << reg_shift;
@@ -196,4 +258,5 @@ const struct stmmac_of_data socfpga_gmac_data = {
.setup = socfpga_dwmac_probe,
.init = socfpga_dwmac_init,
.exit = socfpga_dwmac_exit,
+ .fix_mac_speed = socfpga_dwmac_fix_mac_speed,
};
--
1.8.2.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] net: stmmac: add fix_mac_speed support for socfpga
2014-08-20 6:33 [PATCH] net: stmmac: add fix_mac_speed support for socfpga Ley Foon Tan
@ 2014-08-20 6:57 ` LF.Tan
2014-08-22 19:35 ` David Miller
1 sibling, 0 replies; 3+ messages in thread
From: LF.Tan @ 2014-08-20 6:57 UTC (permalink / raw)
To: netdev, linux-kernel
Cc: Ley Foon Tan, LeyFoon Tan, Giuseppe Cavallaro, Vince Bridgers, davem
On Wed, Aug 20, 2014 at 2:33 PM, Ley Foon Tan <lftan@altera.com> wrote:
> This patch adds fix_mac_speed() support for
> Altera socfpga Ethernet controller. Emac splitter is a
> soft IP core in FPGA system that converts GMII interface from
> Synopsys mac to RGMII/SGMII interface. This splitter core is
> an optional IP if user would like to use RGMII/SGMII
> interface in their system. Software needs to update a register
> in splitter core when there is speed change.
>
> Signed-off-by: Ley Foon Tan <lftan@altera.com>
> ---
> .../devicetree/bindings/net/socfpga-dwmac.txt | 4 ++
> .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 63 ++++++++++++++++++++++
> 2 files changed, 67 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/net/socfpga-dwmac.txt b/Documentation/devicetree/bindings/net/socfpga-dwmac.txt
> index 2a60cd3..3a9d679 100644
> --- a/Documentation/devicetree/bindings/net/socfpga-dwmac.txt
> +++ b/Documentation/devicetree/bindings/net/socfpga-dwmac.txt
> @@ -12,6 +12,10 @@ Required properties:
> - altr,sysmgr-syscon : Should be the phandle to the system manager node that
> encompasses the glue register, the register offset, and the register shift.
>
> +Optional properties:
> +altr,emac-splitter: Should be the phandle to the emac splitter soft IP node if
> + DWMAC controller is connected emac splitter.
> +
> Example:
>
> gmac0: ethernet@ff700000 {
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
> index ec632e6..cd613d7 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
> @@ -17,6 +17,7 @@
>
> #include <linux/mfd/syscon.h>
> #include <linux/of.h>
> +#include <linux/of_address.h>
> #include <linux/of_net.h>
> #include <linux/phy.h>
> #include <linux/regmap.h>
> @@ -30,6 +31,12 @@
> #define SYSMGR_EMACGRP_CTRL_PHYSEL_WIDTH 2
> #define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x00000003
>
> +#define EMAC_SPLITTER_CTRL_REG 0x0
> +#define EMAC_SPLITTER_CTRL_SPEED_MASK 0x3
> +#define EMAC_SPLITTER_CTRL_SPEED_10 0x2
> +#define EMAC_SPLITTER_CTRL_SPEED_100 0x3
> +#define EMAC_SPLITTER_CTRL_SPEED_1000 0x0
> +
> struct socfpga_dwmac {
> int interface;
> u32 reg_offset;
> @@ -37,14 +44,46 @@ struct socfpga_dwmac {
> struct device *dev;
> struct regmap *sys_mgr_base_addr;
> struct reset_control *stmmac_rst;
> + void __iomem *splitter_base;
> };
>
> +static void socfpga_dwmac_fix_mac_speed(void *priv, unsigned int speed)
> +{
> + struct socfpga_dwmac *dwmac = (struct socfpga_dwmac *)priv;
> + void __iomem *splitter_base = dwmac->splitter_base;
> + u32 val;
> +
> + if (!splitter_base)
> + return;
> +
> + val = readl(splitter_base + EMAC_SPLITTER_CTRL_REG);
> + val &= ~EMAC_SPLITTER_CTRL_SPEED_MASK;
> +
> + switch (speed) {
> + case 1000:
> + val |= EMAC_SPLITTER_CTRL_SPEED_1000;
> + break;
> + case 100:
> + val |= EMAC_SPLITTER_CTRL_SPEED_100;
> + break;
> + case 10:
> + val |= EMAC_SPLITTER_CTRL_SPEED_10;
> + break;
> + default:
> + return;
> + }
> +
> + writel(val, splitter_base + EMAC_SPLITTER_CTRL_REG);
> +}
> +
> static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev)
> {
> struct device_node *np = dev->of_node;
> struct regmap *sys_mgr_base_addr;
> u32 reg_offset, reg_shift;
> int ret;
> + struct device_node *np_splitter;
> + struct resource res_splitter;
>
> dwmac->stmmac_rst = devm_reset_control_get(dev,
> STMMAC_RESOURCE_NAME);
> @@ -73,6 +112,21 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *
> return -EINVAL;
> }
>
> + np_splitter = of_parse_phandle(np, "altr,emac-splitter", 0);
> + if (np_splitter) {
> + if (of_address_to_resource(np_splitter, 0, &res_splitter)) {
> + dev_info(dev, "Missing emac splitter address\n");
> + return -EINVAL;
> + }
> +
> + dwmac->splitter_base = (void *)devm_ioremap_resource(dev,
> + &res_splitter);
> + if (!dwmac->splitter_base) {
> + dev_info(dev, "Failed to mapping emac splitter\n");
> + return -EINVAL;
> + }
> + }
> +
> dwmac->reg_offset = reg_offset;
> dwmac->reg_shift = reg_shift;
> dwmac->sys_mgr_base_addr = sys_mgr_base_addr;
> @@ -91,6 +145,7 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac)
>
> switch (phymode) {
> case PHY_INTERFACE_MODE_RGMII:
> + case PHY_INTERFACE_MODE_RGMII_ID:
> val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
> break;
> case PHY_INTERFACE_MODE_MII:
> @@ -102,6 +157,13 @@ static int socfpga_dwmac_setup(struct socfpga_dwmac *dwmac)
> return -EINVAL;
> }
>
> + /* Overwrite val to GMII if splitter core is enabled. The phymode here
> + * is the actual phy mode on phy hardware, but phy interface from
> + * EMAC core is GMII.
> + */
> + if (dwmac->splitter_base)
> + val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
> +
> regmap_read(sys_mgr_base_addr, reg_offset, &ctrl);
> ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << reg_shift);
> ctrl |= val << reg_shift;
> @@ -196,4 +258,5 @@ const struct stmmac_of_data socfpga_gmac_data = {
> .setup = socfpga_dwmac_probe,
> .init = socfpga_dwmac_init,
> .exit = socfpga_dwmac_exit,
> + .fix_mac_speed = socfpga_dwmac_fix_mac_speed,
> };
> --
> 1.8.2.1
>
Adding David S. Miller to CC list.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] net: stmmac: add fix_mac_speed support for socfpga
2014-08-20 6:33 [PATCH] net: stmmac: add fix_mac_speed support for socfpga Ley Foon Tan
2014-08-20 6:57 ` LF.Tan
@ 2014-08-22 19:35 ` David Miller
1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2014-08-22 19:35 UTC (permalink / raw)
To: lftan; +Cc: netdev, linux-kernel, lftan.linux, peppe.cavallaro, vbridger
From: Ley Foon Tan <lftan@altera.com>
Date: Wed, 20 Aug 2014 14:33:33 +0800
> This patch adds fix_mac_speed() support for
> Altera socfpga Ethernet controller. Emac splitter is a
> soft IP core in FPGA system that converts GMII interface from
> Synopsys mac to RGMII/SGMII interface. This splitter core is
> an optional IP if user would like to use RGMII/SGMII
> interface in their system. Software needs to update a register
> in splitter core when there is speed change.
>
> Signed-off-by: Ley Foon Tan <lftan@altera.com>
Applied.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-08-22 19:35 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-20 6:33 [PATCH] net: stmmac: add fix_mac_speed support for socfpga Ley Foon Tan
2014-08-20 6:57 ` LF.Tan
2014-08-22 19:35 ` David Miller
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.