Skip to contentSkip to conversation

Enable ICache and DCache for at91 armv7 Soc

PATCH New Josh Wu 4 participants 12 messages May 19, 2014 – Jun 14, 2014

Subsystems (4)
lore
Share & tools
lore

Josh Wu

author
#0 lore raw

v2 cover Enable ICache and DCache for at91 armv7 Soc

This patch series add DCache support for macb and atmel_hlcdfb driver. Then enabled ICache and DCache support for at91 armv7 SoC.

Tested on SAMA5D3x-EK board and AT91SAM9M10G45EK and AT91SAM9X5EK.

Change log:
v1 -> v2:
1. move the lcd_set_flush_dcache() to atmel hlcdfb driver.
2. split the atmel hlcdfb driver part alone.
3. fix bug that lcd cannot work after power up as we miss flush the lcd dma descriptor.
4. remove the redundant ifndef CONFIG_SYS_I/DCACHE_OFF.

Josh Wu (3):
net: macb: enable dcache in macb
video: atmel_hlcdfb: enable dcache support
ARMv7: at91: enable ICache and DCache.

 arch/arm/cpu/armv7/at91/cpu.c |    2 ++
 drivers/net/macb.c            |   51 +++++++++++++++++++++++++++++++++++++++++
 drivers/video/atmel_hlcdfb.c  |    6 +++++
 3 files changed, 59 insertions(+)
Signature · 1 line
1.7.9.5
author
#1 lore raw

PATCH v2 1/3 net: macb: enable dcache in macb

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.

---
v1 -> v2:
no change.

 drivers/net/macb.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
drivers/net/macb.c +51 -0
index 781a272..b18f07b 100644
@@ -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;
 
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH v2 1/3 net: macb: enable dcache in macb

Hi Josh,

Quoted 9 lines · Josh Wu

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%.

Quoted 5 lines

The code should have no impact with the boards which are not enable_dcache().
Tested in AT91SAM9M10G45EK.

For this patch set, tested ok on sama5d3xek board.

Best Regards,
Bo Shen

Quoted 133 lines

---
v1 -> v2:
no change.

  drivers/net/macb.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
  1 file changed, 51 insertions(+)
drivers/net/macb.c +51 -0
index 781a272..b18f07b 100644
@@ -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;
 
#3 lore raw

PATCH v2 1/3 net: macb: enable dcache in macb

In reply to Josh Wu

Hi Josh,

Quoted 26 lines · Josh Wu

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.

---
v1 -> v2:
no change.

 drivers/net/macb.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
drivers/net/macb.c +0 -0
index 781a272..b18f07b 100644

drivers/net/macb.c int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value) · line 203

Quoted 10 lines
drivers/net/macb.c +7 -0
@@ -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));

these lines produce checkpatch 'line over 80 chars' warnings. Could you please check my macb cleanup patch [1] and adopt yours to that one? Could you please also do a formal review of that patch?

Also it could make sens to introduce some MACB_RX_RING_BYTE_SIZE or something like this to prevent writing always the multiply by sizeof(macb_dma_desc).
If you could a new version of this patch it could go in as the first version was in merge window phase AFAIR. The other two patches in this series are ok.

Best regards

Andreas Bie?mann

[1] http://patchwork.ozlabs.org/patch/352624/

author
#4 lore raw

PATCH v2 1/3 net: macb: enable dcache in macb

Hi, Andreas

Quoted 32 lines · Andreas Bie?mann

Hi Josh,

Quoted 29 lines · Josh Wu

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.

---
v1 -> v2:
no change.

  drivers/net/macb.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
  1 file changed, 51 insertions(+)
drivers/net/macb.c +0 -0
index 781a272..b18f07b 100644
@@ -194,6 +194,39 @@ int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value)
  }
  #endif
 
Quoted 9 lines

drivers/net/macb.c int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value) · line 203

Quoted 7 lines
drivers/net/macb.c +7 -0
+#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));

these lines produce checkpatch 'line over 80 chars' warnings. Could you please check my macb cleanup patch [1] and adopt yours to that one?

No problem.

Quoted 1 line

Could you please also do a formal review of that patch?

Thanks for the clean up patch. I already add my Reviewed-by in that patch.

Quoted 7 lines

Also it could make sens to introduce some MACB_RX_RING_BYTE_SIZE or something like this to prevent writing always the multiply by sizeof(macb_dma_desc).
If you could a new version of this patch it could go in as the first version was in merge window phase AFAIR. The other two patches in this series are ok.

So I will resend a new version of this patch which will rebase on your clean up macb patch.
Thanks.

Best Regards,
Josh Wu

Quoted 6 lines

Best regards

Andreas Bie?mann

[1] http://patchwork.ozlabs.org/patch/352624/

author
#5 lore raw

PATCH RESEND v2 1/3 net: macb: enable dcache in macb

In reply to Andreas Bießmann

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.

---
v2 resend:
1. rebase Andreas' macb clean up patch: http://patchwork.ozlabs.org/patch/352624/
2. add definitions: MACB_TX/RX_DMA_DESC_SIZE for the TX/RX dma descriptor buffer size.
3. replace the IS_RX/IS_TX with RX/TX, which is more readable.
4. fix checkpatch warnings.

v1 -> v2: none

 drivers/net/macb.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 57 insertions(+), 4 deletions(-)
drivers/net/macb.c +57 -4
index 750331d..01a94a4 100644
@@ -51,6 +51,10 @@ struct macb_dma_desc {
 	u32	ctrl;
 };
 
+#define DMA_DESC_BYTES(n)	(n * sizeof(struct macb_dma_desc))
+#define MACB_TX_DMA_DESC_SIZE	(DMA_DESC_BYTES(MACB_TX_RING_SIZE))
+#define MACB_RX_DMA_DESC_SIZE	(DMA_DESC_BYTES(MACB_RX_RING_SIZE))
+
 #define RXADDR_USED		0x00000001
 #define RXADDR_WRAP		0x00000002
 
@@ -194,6 +198,39 @@ int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value)
 }
 #endif
 
+#define RX	1
+#define TX	0
+static inline void macb_invalidate_ring_desc(struct macb_device *macb, bool rx)
+{
+	if (rx)
+		invalidate_dcache_range(macb->rx_ring_dma, macb->rx_ring_dma +
+			MACB_RX_DMA_DESC_SIZE);
+	else
+		invalidate_dcache_range(macb->tx_ring_dma, macb->tx_ring_dma +
+			MACB_TX_DMA_DESC_SIZE);
+}
+
+static inline void macb_flush_ring_desc(struct macb_device *macb, bool rx)
+{
+	if (rx)
+		flush_dcache_range(macb->rx_ring_dma, macb->rx_ring_dma +
+			MACB_RX_DMA_DESC_SIZE);
+	else
+		flush_dcache_range(macb->tx_ring_dma, macb->tx_ring_dma +
+			MACB_TX_DMA_DESC_SIZE);
+}
+
+static inline void macb_flush_rx_buffer(struct macb_device *macb)
+{
+	flush_dcache_range(macb->rx_buffer_dma, macb->rx_buffer_dma +
+				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 +
+				MACB_RX_BUFFER_SIZE);
+}
 
 #if defined(CONFIG_CMD_NET)
 
@@ -218,6 +255,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, 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));
 
 	/*
@@ -226,6 +266,7 @@ static int macb_send(struct eth_device *netdev, void *packet, int length)
 	 */
 	for (i = 0; i <= MACB_TX_TIMEOUT; i++) {
 		barrier();
+		macb_invalidate_ring_desc(macb, TX);
 		ctrl = macb->tx_ring[tx_head].ctrl;
 		if (ctrl & TXBUF_USED)
 			break;
@@ -254,6 +295,8 @@ static void reclaim_rx_buffers(struct macb_device *macb,
 	unsigned int i;
 
 	i = macb->rx_tail;
+
+	macb_invalidate_ring_desc(macb, RX);
 	while (i > new_tail) {
 		macb->rx_ring[i].addr &= ~RXADDR_USED;
 		i++;
@@ -267,6 +310,7 @@ static void reclaim_rx_buffers(struct macb_device *macb,
 	}
 
 	barrier();
+	macb_flush_ring_desc(macb, RX);
 	macb->rx_tail = new_tail;
 }
 
@@ -280,6 +324,8 @@ static int macb_recv(struct eth_device *netdev)
 	u32 status;
 
 	for (;;) {
+		macb_invalidate_ring_desc(macb, RX);
+
 		if (!(macb->rx_ring[rx_tail].addr & RXADDR_USED))
 			return -1;
 
@@ -293,6 +339,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 +554,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, RX);
+	macb_flush_rx_buffer(macb);
+
 	for (i = 0; i < MACB_TX_RING_SIZE; i++) {
 		macb->tx_ring[i].addr = 0;
 		if (i == (MACB_TX_RING_SIZE - 1))
@@ -513,6 +564,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, TX);
+
 	macb->rx_tail = 0;
 	macb->tx_head = 0;
 	macb->tx_tail = 0;
@@ -658,13 +711,13 @@ int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
 
 	macb->rx_buffer = dma_alloc_coherent(MACB_RX_BUFFER_SIZE,
 					     &macb->rx_buffer_dma);
-	macb->rx_ring = dma_alloc_coherent(MACB_RX_RING_SIZE
-					   * sizeof(struct macb_dma_desc),
+	macb->rx_ring = dma_alloc_coherent(MACB_RX_DMA_DESC_SIZE,
 					   &macb->rx_ring_dma);
-	macb->tx_ring = dma_alloc_coherent(MACB_TX_RING_SIZE
-					   * sizeof(struct macb_dma_desc),
+	macb->tx_ring = dma_alloc_coherent(MACB_TX_DMA_DESC_SIZE,
 					   &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;
 
Signature · 1 line
1.7.9.5
#6 lore raw

PATCH RESEND v2 1/3 net: macb: enable dcache in macb

Dear Josh Wu,

Quoted 22 lines · Josh Wu

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.

---
v2 resend:
1. rebase Andreas' macb clean up patch: http://patchwork.ozlabs.org/patch/352624/
2. add definitions: MACB_TX/RX_DMA_DESC_SIZE for the TX/RX dma descriptor buffer size.
3. replace the IS_RX/IS_TX with RX/TX, which is more readable.
4. fix checkpatch warnings.

Quoted 4 lines

v1 -> v2: none

drivers/net/macb.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++----

1 file changed, 57 insertions(+), 4 deletions(-)

applied to u-boot-atmel/master, thanks!

Best regards,
Andreas Bie?mann

author
#7 lore raw

PATCH v2 2/3 video: atmel_hlcdfb: enable dcache support

In reply to Josh Wu

To support dcache, we need flush DMA descriptor buffer before enable lcd DMA.

Also we need call lcd_set_flush_dcache(1) to make lcd driver flush the lcd buffer if there is any change.

Cc Anatolij Gustschin <[email protected]>
---
 drivers/video/atmel_hlcdfb.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/video/atmel_hlcdfb.c +6 -0
index bb4d7d8..935ae42 100644
@@ -171,6 +171,9 @@ void lcd_ctrl_init(void *lcdbase)
 			| LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH;
 	desc->next = (u32)desc;
 
+	/* Flush the DMA descriptor if we enabled dcache */
+	flush_dcache_range((u32)desc, (u32)desc + sizeof(*desc));
+
 	lcdc_writel(&regs->lcdc_baseaddr, desc->address);
 	lcdc_writel(&regs->lcdc_basectrl, desc->control);
 	lcdc_writel(&regs->lcdc_basenext, desc->next);
@@ -194,4 +197,7 @@ void lcd_ctrl_init(void *lcdbase)
 	lcdc_writel(&regs->lcdc_lcden, value | LCDC_LCDEN_PWMEN);
 	while (!(lcdc_readl(&regs->lcdc_lcdsr) & LCDC_LCDSR_PWMSTS))
 		udelay(1);
+
+	/* Enable flushing if we enabled dcache */
+	lcd_set_flush_dcache(1);
 }
Signature · 1 line
1.7.9.5
#8 lore raw

PATCH v2 2/3 video: atmel_hlcdfb: enable dcache support

Quoted 11 lines · On Mon, 19 May 2014 19:51:27 +0800 Josh Wu <[email protected]> wrote:

To support dcache, we need flush DMA descriptor buffer before enable lcd DMA.

Also we need call lcd_set_flush_dcache(1) to make lcd driver flush the lcd buffer if there is any change.

Cc Anatolij Gustschin <[email protected]>
---
 drivers/video/atmel_hlcdfb.c |    6 ++++++
 1 file changed, 6 insertions(+)
#9 lore raw

PATCH v2 2/3 video: atmel_hlcdfb: enable dcache support

In reply to Josh Wu

Dear Josh Wu,

Quoted 6 lines · Josh Wu

To support dcache, we need flush DMA descriptor buffer before enable lcd DMA.

Also we need call lcd_set_flush_dcache(1) to make lcd driver flush the lcd buffer if there is any change.

Quoted 7 lines

---
drivers/video/atmel_hlcdfb.c | 6 ++++++

1 file changed, 6 insertions(+)

applied to u-boot-atmel/master, thanks!

Best regards,
Andreas Bie?mann

author
#10 lore raw

PATCH v2 3/3 ARMv7: at91: enable ICache and DCache.

In reply to Josh Wu

For at91 armv7 SoC (SAMA5D3x), only LCD and macb used DMA. Now as the lcd and macb driver already support dcache. So we can enable dcache now.

Also we can enable icache without any problem.

---
v1 -> v2:
remove the redundant #ifndef(s).

 arch/arm/cpu/armv7/at91/cpu.c |    2 ++
 1 file changed, 2 insertions(+)
arch/arm/cpu/armv7/at91/cpu.c +2 -0
index 2fbf60d..8d86f97 100644
@@ -61,6 +61,8 @@ int print_cpuinfo(void)
 
 void enable_caches(void)
 {
+	icache_enable();
+	dcache_enable();
 }
 
 unsigned int get_chip_id(void)
Signature · 1 line
1.7.9.5
#11 lore raw

PATCH v2 3/3 ARMv7: at91: enable ICache and DCache.

Dear Josh Wu,

Quoted 6 lines · Josh Wu

For at91 armv7 SoC (SAMA5D3x), only LCD and macb used DMA. Now as the lcd and macb driver already support dcache. So we can enable dcache now.

Also we can enable icache without any problem.

Quoted 8 lines

---
v1 -> v2:
remove the redundant #ifndef(s).

arch/arm/cpu/armv7/at91/cpu.c | 2 ++

1 file changed, 2 insertions(+)

applied to u-boot-atmel/master, thanks!

Best regards,
Andreas Bie?mann