Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 521ea952 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'bgmac-stingray-soc'



Abhishek Shah says:

====================
Extend BGMAC driver for Stingray SoC

The patchset extends Broadcom BGMAC driver for Broadcom Stingray SoC.

This patchset is based on Linux-4.12 and tested on NS2 and Stingray.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 10b3bf54 10d79f7d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ Required properties:
 - reg-names:	Names of the registers.
		"amac_base":	Address and length of the GMAC registers
		"idm_base":	Address and length of the GMAC IDM registers
				(required for NSP and Northstar2)
		"nicpm_base":	Address and length of the NIC Port Manager
				registers (required for Northstar2)
 - interrupts:	Interrupt number
+13 −8
Original line number Diff line number Diff line
@@ -50,11 +50,14 @@ static u32 platform_bgmac_idm_read(struct bgmac *bgmac, u16 offset)

static void platform_bgmac_idm_write(struct bgmac *bgmac, u16 offset, u32 value)
{
	return writel(value, bgmac->plat.idm_base + offset);
	writel(value, bgmac->plat.idm_base + offset);
}

static bool platform_bgmac_clk_enabled(struct bgmac *bgmac)
{
	if (!bgmac->plat.idm_base)
		return true;

	if ((bgmac_idm_read(bgmac, BCMA_IOCTL) & BGMAC_CLK_EN) != BGMAC_CLK_EN)
		return false;
	if (bgmac_idm_read(bgmac, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
@@ -66,6 +69,9 @@ static void platform_bgmac_clk_enable(struct bgmac *bgmac, u32 flags)
{
	u32 val;

	if (!bgmac->plat.idm_base)
		return;

	/* The Reset Control register only contains a single bit to show if the
	 * controller is currently in reset.  Do a sanity check here, just in
	 * case the bootloader happened to leave the device in reset.
@@ -180,6 +186,7 @@ static int bgmac_probe(struct platform_device *pdev)
	bgmac->feature_flags |= BGMAC_FEAT_CMDCFG_SR_REV4;
	bgmac->feature_flags |= BGMAC_FEAT_TX_MASK_SETUP;
	bgmac->feature_flags |= BGMAC_FEAT_RX_MASK_SETUP;
	bgmac->feature_flags |= BGMAC_FEAT_IDM_MASK;

	bgmac->dev = &pdev->dev;
	bgmac->dma_dev = &pdev->dev;
@@ -207,14 +214,12 @@ static int bgmac_probe(struct platform_device *pdev)
		return PTR_ERR(bgmac->plat.base);

	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "idm_base");
	if (!regs) {
		dev_err(&pdev->dev, "Unable to obtain idm resource\n");
		return -EINVAL;
	}

	if (regs) {
		bgmac->plat.idm_base = devm_ioremap_resource(&pdev->dev, regs);
		if (IS_ERR(bgmac->plat.idm_base))
			return PTR_ERR(bgmac->plat.idm_base);
		bgmac->feature_flags &= ~BGMAC_FEAT_IDM_MASK;
	}

	regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base");
	if (regs) {
+42 −28
Original line number Diff line number Diff line
@@ -622,10 +622,12 @@ static int bgmac_dma_alloc(struct bgmac *bgmac)
	BUILD_BUG_ON(BGMAC_MAX_TX_RINGS > ARRAY_SIZE(ring_base));
	BUILD_BUG_ON(BGMAC_MAX_RX_RINGS > ARRAY_SIZE(ring_base));

	if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) {
		if (!(bgmac_idm_read(bgmac, BCMA_IOST) & BCMA_IOST_DMA64)) {
			dev_err(bgmac->dev, "Core does not report 64-bit DMA\n");
			return -ENOTSUPP;
		}
	}

	for (i = 0; i < BGMAC_MAX_TX_RINGS; i++) {
		ring = &bgmac->tx_ring[i];
@@ -855,9 +857,11 @@ static void bgmac_mac_speed(struct bgmac *bgmac)
static void bgmac_miiconfig(struct bgmac *bgmac)
{
	if (bgmac->feature_flags & BGMAC_FEAT_FORCE_SPEED_2500) {
		if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) {
			bgmac_idm_write(bgmac, BCMA_IOCTL,
				bgmac_idm_read(bgmac, BCMA_IOCTL) | 0x40 |
				BGMAC_BCMA_IOCTL_SW_CLKEN);
					bgmac_idm_read(bgmac, BCMA_IOCTL) |
					0x40 | BGMAC_BCMA_IOCTL_SW_CLKEN);
		}
		bgmac->mac_speed = SPEED_2500;
		bgmac->mac_duplex = DUPLEX_FULL;
		bgmac_mac_speed(bgmac);
@@ -874,11 +878,36 @@ static void bgmac_miiconfig(struct bgmac *bgmac)
	}
}

static void bgmac_chip_reset_idm_config(struct bgmac *bgmac)
{
	u32 iost;

	iost = bgmac_idm_read(bgmac, BCMA_IOST);
	if (bgmac->feature_flags & BGMAC_FEAT_IOST_ATTACHED)
		iost &= ~BGMAC_BCMA_IOST_ATTACHED;

	/* 3GMAC: for BCM4707 & BCM47094, only do core reset at bgmac_probe() */
	if (!(bgmac->feature_flags & BGMAC_FEAT_NO_RESET)) {
		u32 flags = 0;

		if (iost & BGMAC_BCMA_IOST_ATTACHED) {
			flags = BGMAC_BCMA_IOCTL_SW_CLKEN;
			if (!bgmac->has_robosw)
				flags |= BGMAC_BCMA_IOCTL_SW_RESET;
		}
		bgmac_clk_enable(bgmac, flags);
	}

	if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw)
		bgmac_idm_write(bgmac, BCMA_IOCTL,
				bgmac_idm_read(bgmac, BCMA_IOCTL) &
				~BGMAC_BCMA_IOCTL_SW_RESET);
}

/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipreset */
static void bgmac_chip_reset(struct bgmac *bgmac)
{
	u32 cmdcfg_sr;
	u32 iost;
	int i;

	if (bgmac_clk_enabled(bgmac)) {
@@ -899,20 +928,8 @@ static void bgmac_chip_reset(struct bgmac *bgmac)
		/* TODO: Clear software multicast filter list */
	}

	iost = bgmac_idm_read(bgmac, BCMA_IOST);
	if (bgmac->feature_flags & BGMAC_FEAT_IOST_ATTACHED)
		iost &= ~BGMAC_BCMA_IOST_ATTACHED;

	/* 3GMAC: for BCM4707 & BCM47094, only do core reset at bgmac_probe() */
	if (!(bgmac->feature_flags & BGMAC_FEAT_NO_RESET)) {
		u32 flags = 0;
		if (iost & BGMAC_BCMA_IOST_ATTACHED) {
			flags = BGMAC_BCMA_IOCTL_SW_CLKEN;
			if (!bgmac->has_robosw)
				flags |= BGMAC_BCMA_IOCTL_SW_RESET;
		}
		bgmac_clk_enable(bgmac, flags);
	}
	if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK))
		bgmac_chip_reset_idm_config(bgmac);

	/* Request Misc PLL for corerev > 2 */
	if (bgmac->feature_flags & BGMAC_FEAT_MISC_PLL_REQ) {
@@ -970,11 +987,6 @@ static void bgmac_chip_reset(struct bgmac *bgmac)
				      BGMAC_CHIPCTL_7_IF_TYPE_RGMII);
	}

	if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw)
		bgmac_idm_write(bgmac, BCMA_IOCTL,
				bgmac_idm_read(bgmac, BCMA_IOCTL) &
				~BGMAC_BCMA_IOCTL_SW_RESET);

	/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_reset
	 * Specs don't say about using BGMAC_CMDCFG_SR, but in this routine
	 * BGMAC_CMDCFG is read _after_ putting chip in a reset. So it has to
@@ -1497,8 +1509,10 @@ int bgmac_enet_probe(struct bgmac *bgmac)
	bgmac_clk_enable(bgmac, 0);

	/* This seems to be fixing IRQ by assigning OOB #6 to the core */
	if (!(bgmac->feature_flags & BGMAC_FEAT_IDM_MASK)) {
		if (bgmac->feature_flags & BGMAC_FEAT_IRQ_ID_OOB_6)
			bgmac_idm_write(bgmac, BCMA_OOB_SEL_OUT_A30, 0x86);
	}

	bgmac_chip_reset(bgmac);

+1 −0
Original line number Diff line number Diff line
@@ -425,6 +425,7 @@
#define BGMAC_FEAT_CC4_IF_SW_TYPE	BIT(17)
#define BGMAC_FEAT_CC4_IF_SW_TYPE_RGMII	BIT(18)
#define BGMAC_FEAT_CC7_IF_TYPE_RGMII	BIT(19)
#define BGMAC_FEAT_IDM_MASK		BIT(20)

struct bgmac_slot_info {
	union {