diff options
author | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-10-05 10:12:53 +0000 |
---|---|---|
committer | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-10-05 10:12:53 +0000 |
commit | 5c105d9f3fd086aff195d3849dcf847d6b0bd927 (patch) | |
tree | 1229a11f725bfa58aa7c57a76898553bb5f6654a /target/linux/brcm63xx/patches-3.3/414-bcm63xx_enet-split-dma-registers-access.patch | |
download | openwrt-5c105d9f3fd086aff195d3849dcf847d6b0bd927.tar.gz openwrt-5c105d9f3fd086aff195d3849dcf847d6b0bd927.zip |
branch Attitude Adjustment
git-svn-id: svn://svn.openwrt.org/openwrt/branches/attitude_adjustment@33625 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/brcm63xx/patches-3.3/414-bcm63xx_enet-split-dma-registers-access.patch')
-rw-r--r-- | target/linux/brcm63xx/patches-3.3/414-bcm63xx_enet-split-dma-registers-access.patch | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/target/linux/brcm63xx/patches-3.3/414-bcm63xx_enet-split-dma-registers-access.patch b/target/linux/brcm63xx/patches-3.3/414-bcm63xx_enet-split-dma-registers-access.patch new file mode 100644 index 000000000..90999fa95 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/414-bcm63xx_enet-split-dma-registers-access.patch @@ -0,0 +1,381 @@ +From 305579c1f946ed1aa6c125252ace21c53d47c11d Mon Sep 17 00:00:00 2001 +From: Maxime Bizon <mbizon@freebox.fr> +Date: Thu, 21 Jan 2010 17:50:54 +0100 +Subject: [PATCH 30/63] bcm63xx_enet: split dma registers access. + +--- + arch/mips/bcm63xx/dev-enet.c | 23 +++- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 4 +- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 179 ++++++++++++++-------- + 3 files changed, 138 insertions(+), 68 deletions(-) + +--- a/arch/mips/bcm63xx/dev-enet.c ++++ b/arch/mips/bcm63xx/dev-enet.c +@@ -19,6 +19,16 @@ static struct resource shared_res[] = { + .end = -1, /* filled at runtime */ + .flags = IORESOURCE_MEM, + }, ++ { ++ .start = -1, /* filled at runtime */ ++ .end = -1, /* filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = -1, /* filled at runtime */ ++ .end = -1, /* filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ }, + }; + + static struct platform_device bcm63xx_enet_shared_device = { +@@ -110,10 +120,15 @@ int __init bcm63xx_enet_register(int uni + if (!shared_device_registered) { + shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA); + shared_res[0].end = shared_res[0].start; +- if (BCMCPU_IS_6338()) +- shared_res[0].end += (RSET_ENETDMA_SIZE / 2) - 1; +- else +- shared_res[0].end += (RSET_ENETDMA_SIZE) - 1; ++ shared_res[0].end += (RSET_ENETDMA_SIZE) - 1; ++ ++ shared_res[1].start = bcm63xx_regset_address(RSET_ENETDMAC); ++ shared_res[1].end = shared_res[1].start; ++ shared_res[1].end += RSET_ENETDMAC_SIZE(16) - 1; ++ ++ shared_res[2].start = bcm63xx_regset_address(RSET_ENETDMAS); ++ shared_res[2].end = shared_res[2].start; ++ shared_res[2].end += RSET_ENETDMAS_SIZE(16) - 1; + + ret = platform_device_register(&bcm63xx_enet_shared_device); + if (ret) +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -172,7 +172,9 @@ enum bcm63xx_regs_set { + #define BCM_6358_RSET_SPI_SIZE 1804 + #define BCM_6368_RSET_SPI_SIZE 1804 + #define RSET_ENET_SIZE 2048 +-#define RSET_ENETDMA_SIZE 2048 ++#define RSET_ENETDMA_SIZE 256 ++#define RSET_ENETDMAC_SIZE(chans) (16 * (chans)) ++#define RSET_ENETDMAS_SIZE(chans) (16 * (chans)) + #define RSET_ENETSW_SIZE 65536 + #define RSET_UART_SIZE 24 + #define RSET_HSSPI_SIZE 1536 +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -41,8 +41,8 @@ static int copybreak __read_mostly = 128 + module_param(copybreak, int, 0); + MODULE_PARM_DESC(copybreak, "Receive copy threshold"); + +-/* io memory shared between all devices */ +-static void __iomem *bcm_enet_shared_base; ++/* io registers memory shared between all devices */ ++static void __iomem *bcm_enet_shared_base[3]; + + /* + * io helpers to access mac registers +@@ -63,13 +63,35 @@ static inline void enet_writel(struct bc + */ + static inline u32 enet_dma_readl(struct bcm_enet_priv *priv, u32 off) + { +- return bcm_readl(bcm_enet_shared_base + off); ++ return bcm_readl(bcm_enet_shared_base[0] + off); + } + + static inline void enet_dma_writel(struct bcm_enet_priv *priv, + u32 val, u32 off) + { +- bcm_writel(val, bcm_enet_shared_base + off); ++ bcm_writel(val, bcm_enet_shared_base[0] + off); ++} ++ ++static inline u32 enet_dmac_readl(struct bcm_enet_priv *priv, u32 off) ++{ ++ return bcm_readl(bcm_enet_shared_base[1] + off); ++} ++ ++static inline void enet_dmac_writel(struct bcm_enet_priv *priv, ++ u32 val, u32 off) ++{ ++ bcm_writel(val, bcm_enet_shared_base[1] + off); ++} ++ ++static inline u32 enet_dmas_readl(struct bcm_enet_priv *priv, u32 off) ++{ ++ return bcm_readl(bcm_enet_shared_base[2] + off); ++} ++ ++static inline void enet_dmas_writel(struct bcm_enet_priv *priv, ++ u32 val, u32 off) ++{ ++ bcm_writel(val, bcm_enet_shared_base[2] + off); + } + + /* +@@ -353,8 +375,8 @@ static int bcm_enet_receive_queue(struct + bcm_enet_refill_rx(dev); + + /* kick rx dma */ +- enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK, +- ENETDMA_CHANCFG_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK, ++ ENETDMAC_CHANCFG_REG(priv->rx_chan)); + } + + return processed; +@@ -429,10 +451,10 @@ static int bcm_enet_poll(struct napi_str + dev = priv->net_dev; + + /* ack interrupts */ +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IR_REG(priv->rx_chan)); +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IR_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IR_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IR_REG(priv->tx_chan)); + + /* reclaim sent skb */ + tx_work_done = bcm_enet_tx_reclaim(dev, 0); +@@ -451,10 +473,10 @@ static int bcm_enet_poll(struct napi_str + napi_complete(napi); + + /* restore rx/tx interrupt */ +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IRMASK_REG(priv->rx_chan)); +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IRMASK_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IRMASK_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IRMASK_REG(priv->tx_chan)); + + return rx_work_done; + } +@@ -497,8 +519,8 @@ static irqreturn_t bcm_enet_isr_dma(int + priv = netdev_priv(dev); + + /* mask rx/tx interrupts */ +- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan)); + + napi_schedule(&priv->napi); + +@@ -557,8 +579,8 @@ static int bcm_enet_start_xmit(struct sk + wmb(); + + /* kick tx dma */ +- enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK, +- ENETDMA_CHANCFG_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK, ++ ENETDMAC_CHANCFG_REG(priv->tx_chan)); + + /* stop queue if no more desc available */ + if (!priv->tx_desc_count) +@@ -801,8 +823,8 @@ static int bcm_enet_open(struct net_devi + + /* mask all interrupts and request them */ + enet_writel(priv, 0, ENET_IRMASK_REG); +- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan)); + + ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev); + if (ret) +@@ -891,28 +913,28 @@ static int bcm_enet_open(struct net_devi + } + + /* write rx & tx ring addresses */ +- enet_dma_writel(priv, priv->rx_desc_dma, +- ENETDMA_RSTART_REG(priv->rx_chan)); +- enet_dma_writel(priv, priv->tx_desc_dma, +- ENETDMA_RSTART_REG(priv->tx_chan)); ++ enet_dmas_writel(priv, priv->rx_desc_dma, ++ ENETDMAS_RSTART_REG(priv->rx_chan)); ++ enet_dmas_writel(priv, priv->tx_desc_dma, ++ ENETDMAS_RSTART_REG(priv->tx_chan)); + + /* clear remaining state ram for rx & tx channel */ +- enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->rx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->tx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->rx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->tx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->rx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->tx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG(priv->rx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG(priv->tx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG(priv->rx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG(priv->tx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG(priv->rx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG(priv->tx_chan)); + + /* set max rx/tx length */ + enet_writel(priv, priv->hw_mtu, ENET_RXMAXLEN_REG); + enet_writel(priv, priv->hw_mtu, ENET_TXMAXLEN_REG); + + /* set dma maximum burst len */ +- enet_dma_writel(priv, BCMENET_DMA_MAXBURST, +- ENETDMA_MAXBURST_REG(priv->rx_chan)); +- enet_dma_writel(priv, BCMENET_DMA_MAXBURST, +- ENETDMA_MAXBURST_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ ENETDMAC_MAXBURST_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ ENETDMAC_MAXBURST_REG(priv->tx_chan)); + + /* set correct transmit fifo watermark */ + enet_writel(priv, BCMENET_TX_FIFO_TRESH, ENET_TXWMARK_REG); +@@ -930,26 +952,26 @@ static int bcm_enet_open(struct net_devi + val |= ENET_CTL_ENABLE_MASK; + enet_writel(priv, val, ENET_CTL_REG); + enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG); +- enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK, +- ENETDMA_CHANCFG_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK, ++ ENETDMAC_CHANCFG_REG(priv->rx_chan)); + + /* watch "mib counters about to overflow" interrupt */ + enet_writel(priv, ENET_IR_MIB, ENET_IR_REG); + enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG); + + /* watch "packet transferred" interrupt in rx and tx */ +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IR_REG(priv->rx_chan)); +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IR_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IR_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IR_REG(priv->tx_chan)); + + /* make sure we enable napi before rx interrupt */ + napi_enable(&priv->napi); + +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IRMASK_REG(priv->rx_chan)); +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IRMASK_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IRMASK_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IRMASK_REG(priv->tx_chan)); + + if (priv->has_phy) + phy_start(priv->phydev); +@@ -1026,14 +1048,14 @@ static void bcm_enet_disable_dma(struct + { + int limit; + +- enet_dma_writel(priv, 0, ENETDMA_CHANCFG_REG(chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_CHANCFG_REG(chan)); + + limit = 1000; + do { + u32 val; + +- val = enet_dma_readl(priv, ENETDMA_CHANCFG_REG(chan)); +- if (!(val & ENETDMA_CHANCFG_EN_MASK)) ++ val = enet_dmac_readl(priv, ENETDMAC_CHANCFG_REG(chan)); ++ if (!(val & ENETDMAC_CHANCFG_EN_MASK)) + break; + udelay(1); + } while (limit--); +@@ -1059,8 +1081,8 @@ static int bcm_enet_stop(struct net_devi + + /* mask all interrupts */ + enet_writel(priv, 0, ENET_IRMASK_REG); +- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan)); + + /* make sure no mib update is scheduled */ + cancel_work_sync(&priv->mib_update_task); +@@ -1598,7 +1620,7 @@ static int __devinit bcm_enet_probe(stru + + /* stop if shared driver failed, assume driver->probe will be + * called in the same order we register devices (correct ?) */ +- if (!bcm_enet_shared_base) ++ if (!bcm_enet_shared_base[0]) + return -ENODEV; + + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +@@ -1904,30 +1926,61 @@ struct platform_driver bcm63xx_enet_driv + static int __devinit bcm_enet_shared_probe(struct platform_device *pdev) + { + struct resource *res; ++ int ret, i, requested[3]; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!res) +- return -ENODEV; ++ memset(bcm_enet_shared_base, 0, sizeof (bcm_enet_shared_base)); ++ memset(requested, 0, sizeof (requested)); + +- if (!request_mem_region(res->start, resource_size(res), +- "bcm63xx_enet_dma")) +- return -EBUSY; ++ for (i = 0; i < 3; i++) { ++ void __iomem *p; + +- bcm_enet_shared_base = ioremap(res->start, resource_size(res)); +- if (!bcm_enet_shared_base) { +- release_mem_region(res->start, resource_size(res)); +- return -ENOMEM; ++ res = platform_get_resource(pdev, IORESOURCE_MEM, i); ++ if (!res) { ++ ret = -EINVAL; ++ goto fail; ++ } ++ ++ if (!request_mem_region(res->start, resource_size(res), ++ "bcm63xx_enet_dma")) { ++ ret = -EBUSY; ++ goto fail; ++ } ++ requested[i] = 0; ++ ++ p = ioremap(res->start, resource_size(res)); ++ if (!p) { ++ ret = -ENOMEM; ++ goto fail; ++ } ++ ++ bcm_enet_shared_base[i] = p; + } ++ + return 0; ++ ++fail: ++ for (i = 0; i < 3; i++) { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, i); ++ if (!res) ++ continue; ++ if (bcm_enet_shared_base[i]) ++ iounmap(bcm_enet_shared_base[i]); ++ if (requested[i]) ++ release_mem_region(res->start, resource_size(res)); ++ } ++ return ret; + } + + static int __devexit bcm_enet_shared_remove(struct platform_device *pdev) + { + struct resource *res; ++ int i; + +- iounmap(bcm_enet_shared_base); +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- release_mem_region(res->start, resource_size(res)); ++ for (i = 0; i < 3; i++) { ++ iounmap(bcm_enet_shared_base[i]); ++ res = platform_get_resource(pdev, IORESOURCE_MEM, i); ++ release_mem_region(res->start, resource_size(res)); ++ } + return 0; + } + |