From patchwork Fri May 16 08:15:29 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Josh Wu X-Patchwork-Id: 349495 X-Patchwork-Delegate: andreas.biessmann@googlemail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 8301F140084 for ; Fri, 16 May 2014 18:24:20 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id C2DE64B8D7; Fri, 16 May 2014 10:24:17 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id prmBUpZVnKbK; Fri, 16 May 2014 10:24:17 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 4A9AD4B9C9; Fri, 16 May 2014 10:24:14 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id CC4A04B9D7 for ; Fri, 16 May 2014 10:24:10 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id jQz0HHq6CYRN for ; Fri, 16 May 2014 10:24:08 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from eusmtp01.atmel.com (eusmtp01.atmel.com [212.144.249.242]) by theia.denx.de (Postfix) with ESMTPS id 409044B9C9 for ; Fri, 16 May 2014 10:23:58 +0200 (CEST) Received: from apsmtp01.atmel.com (10.168.254.31) by eusmtp01.atmel.com (10.161.101.30) with Microsoft SMTP Server id 14.2.347.0; Fri, 16 May 2014 10:23:51 +0200 Received: from shaarm01.corp.atmel.com (10.168.254.13) by apsmtp01.atmel.com (10.168.254.31) with Microsoft SMTP Server id 14.2.347.0; Fri, 16 May 2014 16:24:39 +0800 From: Josh Wu To: , Date: Fri, 16 May 2014 16:15:29 +0800 Message-ID: <1400228130-18113-2-git-send-email-josh.wu@atmel.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1400228130-18113-1-git-send-email-josh.wu@atmel.com> References: <1400228130-18113-1-git-send-email-josh.wu@atmel.com> MIME-Version: 1.0 Cc: u-boot@lists.denx.de Subject: [U-Boot] [PATCH 1/2] net: macb: enable dcache in macb X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Add to code to flush the dcache after we writing in DMA buffer. Also we need invalidate the dcache before we check the status in the DMA buffer. Tested in SAMA5D3x-EK with gmac0. Tftp download speed shows in below: Disable DCache: 1.1 MiB/s Enable DCache: 1.6 MiB/s Increase speed with about 40%. The code should have no impact with the boards which are not enable_dcache(). Tested in AT91SAM9M10G45EK. Signed-off-by: Josh Wu --- drivers/net/macb.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 781a272..b18f07b 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -194,6 +194,39 @@ int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value) } #endif +#define IS_RX 1 +#define IS_TX 0 +static inline void macb_invalidate_ring_desc(struct macb_device *macb, bool is_rx) +{ + if (is_rx) + invalidate_dcache_range(macb->rx_ring_dma, macb->rx_ring_dma + + CONFIG_SYS_MACB_RX_RING_SIZE * sizeof(struct macb_dma_desc)); + else + invalidate_dcache_range(macb->tx_ring_dma, macb->tx_ring_dma + + CONFIG_SYS_MACB_TX_RING_SIZE * sizeof(struct macb_dma_desc)); +} + +static inline void macb_flush_ring_desc(struct macb_device *macb, bool is_rx) +{ + if (is_rx) + flush_dcache_range(macb->rx_ring_dma, macb->rx_ring_dma + + CONFIG_SYS_MACB_RX_RING_SIZE * sizeof(struct macb_dma_desc)); + else + flush_dcache_range(macb->tx_ring_dma, macb->tx_ring_dma + + CONFIG_SYS_MACB_TX_RING_SIZE * sizeof(struct macb_dma_desc)); +} + +static inline void macb_flush_rx_buffer(struct macb_device *macb) +{ + flush_dcache_range(macb->rx_buffer_dma, + macb->rx_buffer_dma + CONFIG_SYS_MACB_RX_BUFFER_SIZE); +} + +static inline void macb_invalidate_rx_buffer(struct macb_device *macb) +{ + invalidate_dcache_range(macb->rx_buffer_dma, + macb->rx_buffer_dma + CONFIG_SYS_MACB_RX_BUFFER_SIZE); +} #if defined(CONFIG_CMD_NET) @@ -217,6 +250,9 @@ static int macb_send(struct eth_device *netdev, void *packet, int length) macb->tx_ring[tx_head].ctrl = ctrl; macb->tx_ring[tx_head].addr = paddr; barrier(); + macb_flush_ring_desc(macb, IS_TX); + /* Do we need check paddr and length is dcache line aligned? */ + flush_dcache_range(paddr, paddr + length); macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART)); /* @@ -225,6 +261,7 @@ static int macb_send(struct eth_device *netdev, void *packet, int length) */ for (i = 0; i <= CONFIG_SYS_MACB_TX_TIMEOUT; i++) { barrier(); + macb_invalidate_ring_desc(macb, IS_TX); ctrl = macb->tx_ring[tx_head].ctrl; if (ctrl & TXBUF_USED) break; @@ -253,6 +290,8 @@ static void reclaim_rx_buffers(struct macb_device *macb, unsigned int i; i = macb->rx_tail; + + macb_invalidate_ring_desc(macb, IS_RX); while (i > new_tail) { macb->rx_ring[i].addr &= ~RXADDR_USED; i++; @@ -266,6 +305,7 @@ static void reclaim_rx_buffers(struct macb_device *macb, } barrier(); + macb_flush_ring_desc(macb, IS_RX); macb->rx_tail = new_tail; } @@ -279,6 +319,8 @@ static int macb_recv(struct eth_device *netdev) u32 status; for (;;) { + macb_invalidate_ring_desc(macb, IS_RX); + if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED)) return -1; @@ -292,6 +334,8 @@ static int macb_recv(struct eth_device *netdev) if (status & RXBUF_FRAME_END) { buffer = macb->rx_buffer + 128 * macb->rx_tail; length = status & RXBUF_FRMLEN_MASK; + + macb_invalidate_rx_buffer(macb); if (wrapped) { unsigned int headlen, taillen; @@ -506,6 +550,9 @@ static int macb_init(struct eth_device *netdev, bd_t *bd) macb->rx_ring[i].ctrl = 0; paddr += 128; } + macb_flush_ring_desc(macb, IS_RX); + macb_flush_rx_buffer(macb); + for (i = 0; i < CONFIG_SYS_MACB_TX_RING_SIZE; i++) { macb->tx_ring[i].addr = 0; if (i == (CONFIG_SYS_MACB_TX_RING_SIZE - 1)) @@ -513,6 +560,8 @@ static int macb_init(struct eth_device *netdev, bd_t *bd) else macb->tx_ring[i].ctrl = TXBUF_USED; } + macb_flush_ring_desc(macb, IS_TX); + macb->rx_tail = macb->tx_head = macb->tx_tail = 0; macb_writel(macb, RBQP, macb->rx_ring_dma); @@ -663,6 +712,8 @@ int macb_eth_initialize(int id, void *regs, unsigned int phy_addr) * sizeof(struct macb_dma_desc), &macb->tx_ring_dma); + /* TODO: we need check the rx/tx_ring_dma is dcache line aligned */ + macb->regs = regs; macb->phy_addr = phy_addr;