diff options
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c | 111 |
1 files changed, 67 insertions, 44 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index 0e8937c1184a..da32d6037e3e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -30,37 +30,76 @@ #include "dwmac1000.h" #include "dwmac_dma.h" -static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb, - int burst_len, u32 dma_tx, u32 dma_rx, int atds) +static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi) { - u32 value = readl(ioaddr + DMA_BUS_MODE); - int limit; + u32 value = readl(ioaddr + DMA_AXI_BUS_MODE); + int i; - /* DMA SW reset */ - value |= DMA_BUS_MODE_SFT_RESET; - writel(value, ioaddr + DMA_BUS_MODE); - limit = 10; - while (limit--) { - if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET)) + pr_info("dwmac1000: Master AXI performs %s burst length\n", + !(value & DMA_AXI_UNDEF) ? "fixed" : "any"); + + if (axi->axi_lpi_en) + value |= DMA_AXI_EN_LPI; + if (axi->axi_xit_frm) + value |= DMA_AXI_LPI_XIT_FRM; + + value |= (axi->axi_wr_osr_lmt & DMA_AXI_WR_OSR_LMT_MASK) << + DMA_AXI_WR_OSR_LMT_SHIFT; + + value |= (axi->axi_rd_osr_lmt & DMA_AXI_RD_OSR_LMT_MASK) << + DMA_AXI_RD_OSR_LMT_SHIFT; + + /* Depending on the UNDEF bit the Master AXI will perform any burst + * length according to the BLEN programmed (by default all BLEN are + * set). + */ + for (i = 0; i < AXI_BLEN; i++) { + switch (axi->axi_blen[i]) { + case 256: + value |= DMA_AXI_BLEN256; break; - mdelay(10); + case 128: + value |= DMA_AXI_BLEN128; + break; + case 64: + value |= DMA_AXI_BLEN64; + break; + case 32: + value |= DMA_AXI_BLEN32; + break; + case 16: + value |= DMA_AXI_BLEN16; + break; + case 8: + value |= DMA_AXI_BLEN8; + break; + case 4: + value |= DMA_AXI_BLEN4; + break; + } } - if (limit < 0) - return -EBUSY; + + writel(value, ioaddr + DMA_AXI_BUS_MODE); +} + +static void dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb, + int aal, u32 dma_tx, u32 dma_rx, int atds) +{ + u32 value = readl(ioaddr + DMA_BUS_MODE); /* - * Set the DMA PBL (Programmable Burst Length) mode - * Before stmmac core 3.50 this mode bit was 4xPBL, and + * Set the DMA PBL (Programmable Burst Length) mode. + * + * Note: before stmmac core 3.50 this mode bit was 4xPBL, and * post 3.5 mode bit acts as 8*PBL. - * For core rev < 3.5, when the core is set for 4xPBL mode, the - * DMA transfers the data in 4, 8, 16, 32, 64 & 128 beats - * depending on pbl value. - * For core rev > 3.5, when the core is set for 8xPBL mode, the - * DMA transfers the data in 8, 16, 32, 64, 128 & 256 beats - * depending on pbl value. + * + * This configuration doesn't take care about the Separate PBL + * so only the bits: 13-8 are programmed with the PBL passed from the + * platform. */ - value = DMA_BUS_MODE_PBL | ((pbl << DMA_BUS_MODE_PBL_SHIFT) | - (pbl << DMA_BUS_MODE_RPBL_SHIFT)); + value |= DMA_BUS_MODE_MAXPBL; + value &= ~DMA_BUS_MODE_PBL_MASK; + value |= (pbl << DMA_BUS_MODE_PBL_SHIFT); /* Set the Fixed burst mode */ if (fb) @@ -73,26 +112,10 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb, if (atds) value |= DMA_BUS_MODE_ATDS; - writel(value, ioaddr + DMA_BUS_MODE); + if (aal) + value |= DMA_BUS_MODE_AAL; - /* In case of GMAC AXI configuration, program the DMA_AXI_BUS_MODE - * for supported bursts. - * - * Note: This is applicable only for revision GMACv3.61a. For - * older version this register is reserved and shall have no - * effect. - * - * Note: - * For Fixed Burst Mode: if we directly write 0xFF to this - * register using the configurations pass from platform code, - * this would ensure that all bursts supported by core are set - * and those which are not supported would remain ineffective. - * - * For Non Fixed Burst Mode: provide the maximum value of the - * burst length. Any burst equal or below the provided burst - * length would be allowed to perform. - */ - writel(burst_len, ioaddr + DMA_AXI_BUS_MODE); + writel(value, ioaddr + DMA_BUS_MODE); /* Mask interrupts by writing to CSR7 */ writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA); @@ -102,8 +125,6 @@ static int dwmac1000_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb, */ writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR); writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR); - - return 0; } static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz) @@ -205,7 +226,9 @@ static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt) } const struct stmmac_dma_ops dwmac1000_dma_ops = { + .reset = dwmac_dma_reset, .init = dwmac1000_dma_init, + .axi = dwmac1000_dma_axi, .dump_regs = dwmac1000_dump_dma_regs, .dma_mode = dwmac1000_dma_operation_mode, .enable_dma_transmission = dwmac_enable_dma_transmission, |