Commit dd5c5d03 authored by Jon Mason's avatar Jon Mason Committed by David S. Miller

net: ethernet: bgmac: add NS2 support

Add support for the variant of amac hardware present in the Broadcom
Northstar2 based SoCs.  Northstar2 requires an additional register to be
configured with the port speed/duplexity (NICPM).  This can be added to
the link callback to hide it from the instances that do not use this.
Also, clearing of the pending interrupts on init is required due to
observed issues on some platforms.
Signed-off-by: default avatarJon Mason <jon.mason@broadcom.com>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Acked-by: default avatarRafał Miłecki <rafal@milecki.pl>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1676aba5
...@@ -14,12 +14,21 @@ ...@@ -14,12 +14,21 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/bcma/bcma.h> #include <linux/bcma/bcma.h>
#include <linux/brcmphy.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_mdio.h> #include <linux/of_mdio.h>
#include <linux/of_net.h> #include <linux/of_net.h>
#include "bgmac.h" #include "bgmac.h"
#define NICPM_IOMUX_CTRL 0x00000008
#define NICPM_IOMUX_CTRL_INIT_VAL 0x3196e000
#define NICPM_IOMUX_CTRL_SPD_SHIFT 10
#define NICPM_IOMUX_CTRL_SPD_10M 0
#define NICPM_IOMUX_CTRL_SPD_100M 1
#define NICPM_IOMUX_CTRL_SPD_1000M 2
static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset) static u32 platform_bgmac_read(struct bgmac *bgmac, u16 offset)
{ {
return readl(bgmac->plat.base + offset); return readl(bgmac->plat.base + offset);
...@@ -87,11 +96,45 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, ...@@ -87,11 +96,45 @@ static void platform_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset,
WARN_ON(1); WARN_ON(1);
} }
static void bgmac_nicpm_speed_set(struct net_device *net_dev)
{
struct bgmac *bgmac = netdev_priv(net_dev);
u32 val;
if (!bgmac->plat.nicpm_base)
return;
val = NICPM_IOMUX_CTRL_INIT_VAL;
switch (bgmac->net_dev->phydev->speed) {
default:
netdev_err(net_dev, "Unsupported speed. Defaulting to 1000Mb\n");
case SPEED_1000:
val |= NICPM_IOMUX_CTRL_SPD_1000M << NICPM_IOMUX_CTRL_SPD_SHIFT;
break;
case SPEED_100:
val |= NICPM_IOMUX_CTRL_SPD_100M << NICPM_IOMUX_CTRL_SPD_SHIFT;
break;
case SPEED_10:
val |= NICPM_IOMUX_CTRL_SPD_10M << NICPM_IOMUX_CTRL_SPD_SHIFT;
break;
}
writel(val, bgmac->plat.nicpm_base + NICPM_IOMUX_CTRL);
bgmac_adjust_link(bgmac->net_dev);
}
static int platform_phy_connect(struct bgmac *bgmac) static int platform_phy_connect(struct bgmac *bgmac)
{ {
struct phy_device *phy_dev; struct phy_device *phy_dev;
phy_dev = of_phy_get_and_connect(bgmac->net_dev, bgmac->dev->of_node, if (bgmac->plat.nicpm_base)
phy_dev = of_phy_get_and_connect(bgmac->net_dev,
bgmac->dev->of_node,
bgmac_nicpm_speed_set);
else
phy_dev = of_phy_get_and_connect(bgmac->net_dev,
bgmac->dev->of_node,
bgmac_adjust_link); bgmac_adjust_link);
if (!phy_dev) { if (!phy_dev) {
dev_err(bgmac->dev, "PHY connection failed\n"); dev_err(bgmac->dev, "PHY connection failed\n");
...@@ -156,6 +199,14 @@ static int bgmac_probe(struct platform_device *pdev) ...@@ -156,6 +199,14 @@ static int bgmac_probe(struct platform_device *pdev)
if (IS_ERR(bgmac->plat.idm_base)) if (IS_ERR(bgmac->plat.idm_base))
return PTR_ERR(bgmac->plat.idm_base); return PTR_ERR(bgmac->plat.idm_base);
regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base");
if (regs) {
bgmac->plat.nicpm_base = devm_ioremap_resource(&pdev->dev,
regs);
if (IS_ERR(bgmac->plat.nicpm_base))
return PTR_ERR(bgmac->plat.nicpm_base);
}
bgmac->read = platform_bgmac_read; bgmac->read = platform_bgmac_read;
bgmac->write = platform_bgmac_write; bgmac->write = platform_bgmac_write;
bgmac->idm_read = platform_bgmac_idm_read; bgmac->idm_read = platform_bgmac_idm_read;
...@@ -187,6 +238,7 @@ static int bgmac_remove(struct platform_device *pdev) ...@@ -187,6 +238,7 @@ static int bgmac_remove(struct platform_device *pdev)
static const struct of_device_id bgmac_of_enet_match[] = { static const struct of_device_id bgmac_of_enet_match[] = {
{.compatible = "brcm,amac",}, {.compatible = "brcm,amac",},
{.compatible = "brcm,nsp-amac",}, {.compatible = "brcm,nsp-amac",},
{.compatible = "brcm,ns2-amac",},
{}, {},
}; };
......
...@@ -1082,6 +1082,9 @@ static void bgmac_enable(struct bgmac *bgmac) ...@@ -1082,6 +1082,9 @@ static void bgmac_enable(struct bgmac *bgmac)
/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */ /* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipinit */
static void bgmac_chip_init(struct bgmac *bgmac) static void bgmac_chip_init(struct bgmac *bgmac)
{ {
/* Clear any erroneously pending interrupts */
bgmac_write(bgmac, BGMAC_INT_STATUS, ~0);
/* 1 interrupt per received frame */ /* 1 interrupt per received frame */
bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT); bgmac_write(bgmac, BGMAC_INT_RECV_LAZY, 1 << BGMAC_IRL_FC_SHIFT);
......
...@@ -463,6 +463,7 @@ struct bgmac { ...@@ -463,6 +463,7 @@ struct bgmac {
struct { struct {
void *base; void *base;
void *idm_base; void *idm_base;
void *nicpm_base;
} plat; } plat;
struct { struct {
struct bcma_device *core; struct bcma_device *core;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment