From 1c848a258600490f6964597b92b69a107af141d6 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 8 May 2014 22:26:32 +0100 Subject: net/designware: ensure device private data is DMA aligned. struct dw_eth_dev contains fields which are accessed via DMA, so make sure it is aligned to a dma boundary. Without this I see: ERROR: v7_dcache_inval_range - start address is not aligned - 0x7fb677e0 Signed-off-by: Ian Campbell Reviewed-by: Alexey Brodkin Acked-by: Marek Vasut --- drivers/net/designware.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net/designware.c') diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 78751b2..41ab3ac 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -414,7 +414,8 @@ int designware_initialize(ulong base_addr, u32 interface) * Since the priv structure contains the descriptors which need a strict * buswidth alignment, memalign is used to allocate memory */ - priv = (struct dw_eth_dev *) memalign(16, sizeof(struct dw_eth_dev)); + priv = (struct dw_eth_dev *) memalign(ARCH_DMA_MINALIGN, + sizeof(struct dw_eth_dev)); if (!priv) { free(dev); return -ENOMEM; -- cgit v1.1 From 964ea7c1cea6228aa414f4aee5acf25bcd87ca21 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 8 May 2014 22:26:33 +0100 Subject: net/designware: ensure cache invalidations are aligned to ARCH_DMA_MINALIGN This is required at least on ARM. When sending instead of simply invalidating the entire descriptor, flush as little as possible while still respecting ARCH_DMA_MINALIGN, as requested by Alexey. Signed-off-by: Ian Campbell Cc: Alexey Brodkin --- drivers/net/designware.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers/net/designware.c') diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 41ab3ac..fa816bf 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -280,10 +280,18 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length) u32 desc_num = priv->tx_currdescnum; struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num]; - /* Invalidate only "status" field for the following check */ - invalidate_dcache_range((unsigned long)&desc_p->txrx_status, - (unsigned long)&desc_p->txrx_status + - sizeof(desc_p->txrx_status)); + /* + * Strictly we only need to invalidate the "txrx_status" field + * for the following check, but on some platforms we cannot + * invalidate only 4 bytes, so roundup to + * ARCH_DMA_MINALIGN. This is safe because the individual + * descriptors in the array are each aligned to + * ARCH_DMA_MINALIGN. + */ + invalidate_dcache_range( + (unsigned long)desc_p, + (unsigned long)desc_p + + roundup(sizeof(desc_p->txrx_status), ARCH_DMA_MINALIGN)); /* Check if the descriptor is owned by CPU */ if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) { @@ -351,7 +359,7 @@ static int dw_eth_recv(struct eth_device *dev) /* Invalidate received data */ invalidate_dcache_range((unsigned long)desc_p->dmamac_addr, (unsigned long)desc_p->dmamac_addr + - length); + roundup(length, ARCH_DMA_MINALIGN)); NetReceive(desc_p->dmamac_addr, length); -- cgit v1.1 From 49692c5f517d8e44ed9db0de778728fe7d2a300c Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 8 May 2014 22:26:35 +0100 Subject: net/designware: Make DMA burst length configurable and reduce by default The correct value for this setting can vary across SoCs and boards, so make it configurable. Also reduce the default value to 8, which is the same default as used in the Linux driver. Signed-off-by: Ian Campbell Cc: Alexey Brodkin --- drivers/net/designware.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/designware.c') diff --git a/drivers/net/designware.c b/drivers/net/designware.c index fa816bf..7186e3b 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -249,7 +249,7 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis) rx_descs_init(dev); tx_descs_init(dev); - writel(FIXEDBURST | PRIORXTX_41 | BURST_16, &dma_p->busmode); + writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode); writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD, &dma_p->opmode); -- cgit v1.1