Merge branch 'stmmac-DMA-burst'
Niklas Cassel says: ==================== net: stmmac: make DMA programmable burst length more configurable Make DMA programmable burst length more configurable in the stmmac driver. This is done by adding support for independent pbl for tx/rx through DT. More fine grained tuning of pbl is possible thanks to a DT property saying that we should NOT multiply pbl values by x8/x4 in hardware. All new DT properties are optional, and created in a way that it will not affect any existing DT configurations. Changes since V1: Created cover-letter. Rebased patch set against next-20161205, since conflicting patches to stmmac_platform.c has been merged since V1. Changes since V2: Moved default value initialization of pbl to stmmac_platform.c and added a check for pbl != 0 in stmmac_main.c, to catch a possble pbl == 0 from pci glue. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
797149d034
|
@ -34,7 +34,13 @@ Optional properties:
|
|||
platforms.
|
||||
- tx-fifo-depth: See ethernet.txt file in the same directory
|
||||
- rx-fifo-depth: See ethernet.txt file in the same directory
|
||||
- snps,pbl Programmable Burst Length
|
||||
- snps,pbl Programmable Burst Length (tx and rx)
|
||||
- snps,txpbl Tx Programmable Burst Length. Only for GMAC and newer.
|
||||
If set, DMA tx will use this value rather than snps,pbl.
|
||||
- snps,rxpbl Rx Programmable Burst Length. Only for GMAC and newer.
|
||||
If set, DMA rx will use this value rather than snps,pbl.
|
||||
- snps,no-pbl-x8 Don't multiply the pbl/txpbl/rxpbl values by 8.
|
||||
For core rev < 3.50, don't multiply the values by 4.
|
||||
- snps,aal Address-Aligned Beats
|
||||
- snps,fixed-burst Program the DMA to use the fixed burst mode
|
||||
- snps,mixed-burst Program the DMA to use the mixed burst mode
|
||||
|
|
|
@ -152,8 +152,10 @@ Where:
|
|||
o dma_cfg: internal DMA parameters
|
||||
o pbl: the Programmable Burst Length is maximum number of beats to
|
||||
be transferred in one DMA transaction.
|
||||
GMAC also enables the 4xPBL by default.
|
||||
o fixed_burst/mixed_burst/burst_len
|
||||
GMAC also enables the 4xPBL by default. (8xPBL for GMAC 3.50 and newer)
|
||||
o txpbl/rxpbl: GMAC and newer supports independent DMA pbl for tx/rx.
|
||||
o pblx8: Enable 8xPBL (4xPBL for core rev < 3.50). Enabled by default.
|
||||
o fixed_burst/mixed_burst/aal
|
||||
o clk_csr: fixed CSR Clock range selection.
|
||||
o has_gmac: uses the GMAC core.
|
||||
o enh_desc: if sets the MAC will use the enhanced descriptor structure.
|
||||
|
@ -205,16 +207,24 @@ tuned according to the HW capabilities.
|
|||
|
||||
struct stmmac_dma_cfg {
|
||||
int pbl;
|
||||
int txpbl;
|
||||
int rxpbl;
|
||||
bool pblx8;
|
||||
int fixed_burst;
|
||||
int burst_len_supported;
|
||||
int mixed_burst;
|
||||
bool aal;
|
||||
};
|
||||
|
||||
Where:
|
||||
o pbl: Programmable Burst Length
|
||||
o pbl: Programmable Burst Length (tx and rx)
|
||||
o txpbl: Transmit Programmable Burst Length. Only for GMAC and newer.
|
||||
If set, DMA tx will use this value rather than pbl.
|
||||
o rxpbl: Receive Programmable Burst Length. Only for GMAC and newer.
|
||||
If set, DMA rx will use this value rather than pbl.
|
||||
o pblx8: Enable 8xPBL (4xPBL for core rev < 3.50). Enabled by default.
|
||||
o fixed_burst: program the DMA to use the fixed burst mode
|
||||
o burst_len: this is the value we put in the register
|
||||
supported values are provided as macros in
|
||||
linux/stmmac.h header file.
|
||||
o mixed_burst: program the DMA to use the mixed burst mode
|
||||
o aal: Address-Aligned Beats
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -412,8 +412,8 @@ extern const struct stmmac_desc_ops ndesc_ops;
|
|||
struct stmmac_dma_ops {
|
||||
/* DMA core initialization */
|
||||
int (*reset)(void __iomem *ioaddr);
|
||||
void (*init)(void __iomem *ioaddr, int pbl, int fb, int mb,
|
||||
int aal, u32 dma_tx, u32 dma_rx, int atds);
|
||||
void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg,
|
||||
u32 dma_tx, u32 dma_rx, int atds);
|
||||
/* Configure the AXI Bus Mode Register */
|
||||
void (*axi)(void __iomem *ioaddr, struct stmmac_axi *axi);
|
||||
/* Dump DMA registers */
|
||||
|
|
|
@ -225,7 +225,7 @@ enum rx_tx_priority_ratio {
|
|||
|
||||
#define DMA_BUS_MODE_FB 0x00010000 /* Fixed burst */
|
||||
#define DMA_BUS_MODE_MB 0x04000000 /* Mixed burst */
|
||||
#define DMA_BUS_MODE_RPBL_MASK 0x003e0000 /* Rx-Programmable Burst Len */
|
||||
#define DMA_BUS_MODE_RPBL_MASK 0x007e0000 /* Rx-Programmable Burst Len */
|
||||
#define DMA_BUS_MODE_RPBL_SHIFT 17
|
||||
#define DMA_BUS_MODE_USP 0x00800000
|
||||
#define DMA_BUS_MODE_MAXPBL 0x01000000
|
||||
|
|
|
@ -84,37 +84,39 @@ static void dwmac1000_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
|
|||
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)
|
||||
static void dwmac1000_dma_init(void __iomem *ioaddr,
|
||||
struct stmmac_dma_cfg *dma_cfg,
|
||||
u32 dma_tx, u32 dma_rx, int atds)
|
||||
{
|
||||
u32 value = readl(ioaddr + DMA_BUS_MODE);
|
||||
int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
|
||||
int rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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_MAXPBL;
|
||||
value &= ~DMA_BUS_MODE_PBL_MASK;
|
||||
value |= (pbl << DMA_BUS_MODE_PBL_SHIFT);
|
||||
if (dma_cfg->pblx8)
|
||||
value |= DMA_BUS_MODE_MAXPBL;
|
||||
value |= DMA_BUS_MODE_USP;
|
||||
value &= ~(DMA_BUS_MODE_PBL_MASK | DMA_BUS_MODE_RPBL_MASK);
|
||||
value |= (txpbl << DMA_BUS_MODE_PBL_SHIFT);
|
||||
value |= (rxpbl << DMA_BUS_MODE_RPBL_SHIFT);
|
||||
|
||||
/* Set the Fixed burst mode */
|
||||
if (fb)
|
||||
if (dma_cfg->fixed_burst)
|
||||
value |= DMA_BUS_MODE_FB;
|
||||
|
||||
/* Mixed Burst has no effect when fb is set */
|
||||
if (mb)
|
||||
if (dma_cfg->mixed_burst)
|
||||
value |= DMA_BUS_MODE_MB;
|
||||
|
||||
if (atds)
|
||||
value |= DMA_BUS_MODE_ATDS;
|
||||
|
||||
if (aal)
|
||||
if (dma_cfg->aal)
|
||||
value |= DMA_BUS_MODE_AAL;
|
||||
|
||||
writel(value, ioaddr + DMA_BUS_MODE);
|
||||
|
|
|
@ -32,11 +32,12 @@
|
|||
#include "dwmac100.h"
|
||||
#include "dwmac_dma.h"
|
||||
|
||||
static void dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
|
||||
int aal, u32 dma_tx, u32 dma_rx, int atds)
|
||||
static void dwmac100_dma_init(void __iomem *ioaddr,
|
||||
struct stmmac_dma_cfg *dma_cfg,
|
||||
u32 dma_tx, u32 dma_rx, int atds)
|
||||
{
|
||||
/* Enable Application Access by writing to DMA CSR0 */
|
||||
writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
|
||||
writel(DMA_BUS_MODE_DEFAULT | (dma_cfg->pbl << DMA_BUS_MODE_PBL_SHIFT),
|
||||
ioaddr + DMA_BUS_MODE);
|
||||
|
||||
/* Mask interrupts by writing to CSR7 */
|
||||
|
|
|
@ -71,25 +71,29 @@ static void dwmac4_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
|
|||
writel(value, ioaddr + DMA_SYS_BUS_MODE);
|
||||
}
|
||||
|
||||
static void dwmac4_dma_init_channel(void __iomem *ioaddr, int pbl,
|
||||
static void dwmac4_dma_init_channel(void __iomem *ioaddr,
|
||||
struct stmmac_dma_cfg *dma_cfg,
|
||||
u32 dma_tx_phy, u32 dma_rx_phy,
|
||||
u32 channel)
|
||||
{
|
||||
u32 value;
|
||||
int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
|
||||
int rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
|
||||
|
||||
/* set PBL for each channels. Currently we affect same configuration
|
||||
* on each channel
|
||||
*/
|
||||
value = readl(ioaddr + DMA_CHAN_CONTROL(channel));
|
||||
value = value | DMA_BUS_MODE_PBL;
|
||||
if (dma_cfg->pblx8)
|
||||
value = value | DMA_BUS_MODE_PBL;
|
||||
writel(value, ioaddr + DMA_CHAN_CONTROL(channel));
|
||||
|
||||
value = readl(ioaddr + DMA_CHAN_TX_CONTROL(channel));
|
||||
value = value | (pbl << DMA_BUS_MODE_PBL_SHIFT);
|
||||
value = value | (txpbl << DMA_BUS_MODE_PBL_SHIFT);
|
||||
writel(value, ioaddr + DMA_CHAN_TX_CONTROL(channel));
|
||||
|
||||
value = readl(ioaddr + DMA_CHAN_RX_CONTROL(channel));
|
||||
value = value | (pbl << DMA_BUS_MODE_RPBL_SHIFT);
|
||||
value = value | (rxpbl << DMA_BUS_MODE_RPBL_SHIFT);
|
||||
writel(value, ioaddr + DMA_CHAN_RX_CONTROL(channel));
|
||||
|
||||
/* Mask interrupts by writing to CSR7 */
|
||||
|
@ -99,27 +103,28 @@ static void dwmac4_dma_init_channel(void __iomem *ioaddr, int pbl,
|
|||
writel(dma_rx_phy, ioaddr + DMA_CHAN_RX_BASE_ADDR(channel));
|
||||
}
|
||||
|
||||
static void dwmac4_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
|
||||
int aal, u32 dma_tx, u32 dma_rx, int atds)
|
||||
static void dwmac4_dma_init(void __iomem *ioaddr,
|
||||
struct stmmac_dma_cfg *dma_cfg,
|
||||
u32 dma_tx, u32 dma_rx, int atds)
|
||||
{
|
||||
u32 value = readl(ioaddr + DMA_SYS_BUS_MODE);
|
||||
int i;
|
||||
|
||||
/* Set the Fixed burst mode */
|
||||
if (fb)
|
||||
if (dma_cfg->fixed_burst)
|
||||
value |= DMA_SYS_BUS_FB;
|
||||
|
||||
/* Mixed Burst has no effect when fb is set */
|
||||
if (mb)
|
||||
if (dma_cfg->mixed_burst)
|
||||
value |= DMA_SYS_BUS_MB;
|
||||
|
||||
if (aal)
|
||||
if (dma_cfg->aal)
|
||||
value |= DMA_SYS_BUS_AAL;
|
||||
|
||||
writel(value, ioaddr + DMA_SYS_BUS_MODE);
|
||||
|
||||
for (i = 0; i < DMA_CHANNEL_NB_MAX; i++)
|
||||
dwmac4_dma_init_channel(ioaddr, pbl, dma_tx, dma_rx, i);
|
||||
dwmac4_dma_init_channel(ioaddr, dma_cfg, dma_tx, dma_rx, i);
|
||||
}
|
||||
|
||||
static void _dwmac4_dump_dma_regs(void __iomem *ioaddr, u32 channel)
|
||||
|
|
|
@ -1578,16 +1578,12 @@ static void stmmac_check_ether_addr(struct stmmac_priv *priv)
|
|||
*/
|
||||
static int stmmac_init_dma_engine(struct stmmac_priv *priv)
|
||||
{
|
||||
int pbl = DEFAULT_DMA_PBL, fixed_burst = 0, aal = 0;
|
||||
int mixed_burst = 0;
|
||||
int atds = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (priv->plat->dma_cfg) {
|
||||
pbl = priv->plat->dma_cfg->pbl;
|
||||
fixed_burst = priv->plat->dma_cfg->fixed_burst;
|
||||
mixed_burst = priv->plat->dma_cfg->mixed_burst;
|
||||
aal = priv->plat->dma_cfg->aal;
|
||||
if (!priv->plat->dma_cfg || !priv->plat->dma_cfg->pbl) {
|
||||
dev_err(priv->device, "Invalid DMA configuration\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (priv->extend_desc && (priv->mode == STMMAC_RING_MODE))
|
||||
|
@ -1599,8 +1595,8 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
|
|||
return ret;
|
||||
}
|
||||
|
||||
priv->hw->dma->init(priv->ioaddr, pbl, fixed_burst, mixed_burst,
|
||||
aal, priv->dma_tx_phy, priv->dma_rx_phy, atds);
|
||||
priv->hw->dma->init(priv->ioaddr, priv->plat->dma_cfg,
|
||||
priv->dma_tx_phy, priv->dma_rx_phy, atds);
|
||||
|
||||
if (priv->synopsys_id >= DWMAC_CORE_4_00) {
|
||||
priv->rx_tail_addr = priv->dma_rx_phy +
|
||||
|
|
|
@ -81,6 +81,7 @@ static void stmmac_default_data(struct plat_stmmacenet_data *plat)
|
|||
plat->mdio_bus_data->phy_mask = 0;
|
||||
|
||||
plat->dma_cfg->pbl = 32;
|
||||
plat->dma_cfg->pblx8 = true;
|
||||
/* TODO: AXI */
|
||||
|
||||
/* Set default value for multicast hash bins */
|
||||
|
@ -115,6 +116,7 @@ static int quark_default_data(struct plat_stmmacenet_data *plat,
|
|||
plat->mdio_bus_data->phy_mask = 0;
|
||||
|
||||
plat->dma_cfg->pbl = 16;
|
||||
plat->dma_cfg->pblx8 = true;
|
||||
plat->dma_cfg->fixed_burst = 1;
|
||||
/* AXI (TODO) */
|
||||
|
||||
|
|
|
@ -304,21 +304,25 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
|
|||
plat->force_sf_dma_mode = 1;
|
||||
}
|
||||
|
||||
if (of_find_property(np, "snps,pbl", NULL)) {
|
||||
dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
|
||||
GFP_KERNEL);
|
||||
if (!dma_cfg) {
|
||||
stmmac_remove_config_dt(pdev, plat);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
plat->dma_cfg = dma_cfg;
|
||||
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
|
||||
dma_cfg->aal = of_property_read_bool(np, "snps,aal");
|
||||
dma_cfg->fixed_burst =
|
||||
of_property_read_bool(np, "snps,fixed-burst");
|
||||
dma_cfg->mixed_burst =
|
||||
of_property_read_bool(np, "snps,mixed-burst");
|
||||
dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
|
||||
GFP_KERNEL);
|
||||
if (!dma_cfg) {
|
||||
stmmac_remove_config_dt(pdev, plat);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
plat->dma_cfg = dma_cfg;
|
||||
|
||||
of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
|
||||
if (!dma_cfg->pbl)
|
||||
dma_cfg->pbl = DEFAULT_DMA_PBL;
|
||||
of_property_read_u32(np, "snps,txpbl", &dma_cfg->txpbl);
|
||||
of_property_read_u32(np, "snps,rxpbl", &dma_cfg->rxpbl);
|
||||
dma_cfg->pblx8 = !of_property_read_bool(np, "snps,no-pbl-x8");
|
||||
|
||||
dma_cfg->aal = of_property_read_bool(np, "snps,aal");
|
||||
dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst");
|
||||
dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst");
|
||||
|
||||
plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode");
|
||||
if (plat->force_thresh_dma_mode) {
|
||||
plat->force_sf_dma_mode = 0;
|
||||
|
|
|
@ -88,6 +88,9 @@ struct stmmac_mdio_bus_data {
|
|||
|
||||
struct stmmac_dma_cfg {
|
||||
int pbl;
|
||||
int txpbl;
|
||||
int rxpbl;
|
||||
bool pblx8;
|
||||
int fixed_burst;
|
||||
int mixed_burst;
|
||||
bool aal;
|
||||
|
|
Loading…
Reference in a new issue