public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/2] ARMv7: at91: Enable ICache and DCache for at91 armv7 cpu
@ 2014-05-16  8:15 Josh Wu
  2014-05-16  8:15 ` [U-Boot] [PATCH 1/2] net: macb: enable dcache in macb Josh Wu
  2014-05-16  8:15 ` [U-Boot] [PATCH 2/2] ARMv7: at91: enable ICache and DCache Josh Wu
  0 siblings, 2 replies; 6+ messages in thread
From: Josh Wu @ 2014-05-16  8:15 UTC (permalink / raw)
  To: u-boot

First, before we enable DCache. We need add dcache support for macb driver.
Then enable ICache/DCache.

Tested on SAMA5D3x-EK board and AT91SAM9M10G45EK.

Josh Wu (2):
  net: macb: enable dcache in macb
  ARMv7: at91: enable ICache and DCache.

 arch/arm/cpu/armv7/at91/cpu.c       |    6 +++++
 board/atmel/sama5d3xek/sama5d3xek.c |    6 ++++-
 drivers/net/macb.c                  |   51 +++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 1 deletion(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH 1/2] net: macb: enable dcache in macb
  2014-05-16  8:15 [U-Boot] [PATCH 0/2] ARMv7: at91: Enable ICache and DCache for at91 armv7 cpu Josh Wu
@ 2014-05-16  8:15 ` Josh Wu
  2014-05-16  8:15 ` [U-Boot] [PATCH 2/2] ARMv7: at91: enable ICache and DCache Josh Wu
  1 sibling, 0 replies; 6+ messages in thread
From: Josh Wu @ 2014-05-16  8:15 UTC (permalink / raw)
  To: u-boot

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 <josh.wu@atmel.com>
---
 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;
 
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH 2/2] ARMv7: at91: enable ICache and DCache.
  2014-05-16  8:15 [U-Boot] [PATCH 0/2] ARMv7: at91: Enable ICache and DCache for at91 armv7 cpu Josh Wu
  2014-05-16  8:15 ` [U-Boot] [PATCH 1/2] net: macb: enable dcache in macb Josh Wu
@ 2014-05-16  8:15 ` Josh Wu
  2014-05-16  8:29   ` Bo Shen
  1 sibling, 1 reply; 6+ messages in thread
From: Josh Wu @ 2014-05-16  8:15 UTC (permalink / raw)
  To: u-boot

As SAMA5D3 is a at91 ARMv7 cpu, so we should enable LCD DCache
flush for SAMA5D3X-EK.

Signed-off-by: Josh Wu <josh.wu@atmel.com>
---
 arch/arm/cpu/armv7/at91/cpu.c       |    6 ++++++
 board/atmel/sama5d3xek/sama5d3xek.c |    6 +++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/arch/arm/cpu/armv7/at91/cpu.c b/arch/arm/cpu/armv7/at91/cpu.c
index 2fbf60d..6f2164f 100644
--- a/arch/arm/cpu/armv7/at91/cpu.c
+++ b/arch/arm/cpu/armv7/at91/cpu.c
@@ -61,6 +61,12 @@ int print_cpuinfo(void)
 
 void enable_caches(void)
 {
+#ifndef CONFIG_SYS_ICACHE_OFF
+	icache_enable();
+#endif
+#ifndef CONFIG_SYS_DCACHE_OFF
+	dcache_enable();
+#endif
 }
 
 unsigned int get_chip_id(void)
diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c
index c835c12..1fc91d9 100644
--- a/board/atmel/sama5d3xek/sama5d3xek.c
+++ b/board/atmel/sama5d3xek/sama5d3xek.c
@@ -200,8 +200,12 @@ int board_init(void)
 		at91_gmac_hw_init();
 #endif
 #ifdef CONFIG_LCD
-	if (has_lcdc())
+	if (has_lcdc()) {
 		sama5d3xek_lcd_hw_init();
+
+		/* Enable flushing as we enabled dcache */
+		lcd_set_flush_dcache(1);
+	}
 #endif
 	return 0;
 }
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH 2/2] ARMv7: at91: enable ICache and DCache.
  2014-05-16  8:15 ` [U-Boot] [PATCH 2/2] ARMv7: at91: enable ICache and DCache Josh Wu
@ 2014-05-16  8:29   ` Bo Shen
  2014-05-16  9:17     ` Josh Wu
  0 siblings, 1 reply; 6+ messages in thread
From: Bo Shen @ 2014-05-16  8:29 UTC (permalink / raw)
  To: u-boot

Hi Josh,

On 05/16/2014 04:15 PM, Josh Wu wrote:
> As SAMA5D3 is a at91 ARMv7 cpu, so we should enable LCD DCache
> flush for SAMA5D3X-EK.
>
> Signed-off-by: Josh Wu <josh.wu@atmel.com>
> ---
>   arch/arm/cpu/armv7/at91/cpu.c       |    6 ++++++
>   board/atmel/sama5d3xek/sama5d3xek.c |    6 +++++-
>   2 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm/cpu/armv7/at91/cpu.c b/arch/arm/cpu/armv7/at91/cpu.c
> index 2fbf60d..6f2164f 100644
> --- a/arch/arm/cpu/armv7/at91/cpu.c
> +++ b/arch/arm/cpu/armv7/at91/cpu.c
> @@ -61,6 +61,12 @@ int print_cpuinfo(void)
>
>   void enable_caches(void)
>   {
> +#ifndef CONFIG_SYS_ICACHE_OFF
> +	icache_enable();
> +#endif

No need this one. Ifdef CONFIG_SYS_ICACHE_OFF, it will be disabled.

> +#ifndef CONFIG_SYS_DCACHE_OFF
> +	dcache_enable();
> +#endif
>   }
>
>   unsigned int get_chip_id(void)
> diff --git a/board/atmel/sama5d3xek/sama5d3xek.c b/board/atmel/sama5d3xek/sama5d3xek.c
> index c835c12..1fc91d9 100644
> --- a/board/atmel/sama5d3xek/sama5d3xek.c
> +++ b/board/atmel/sama5d3xek/sama5d3xek.c
> @@ -200,8 +200,12 @@ int board_init(void)
>   		at91_gmac_hw_init();
>   #endif
>   #ifdef CONFIG_LCD
> -	if (has_lcdc())
> +	if (has_lcdc()) {
>   		sama5d3xek_lcd_hw_init();
> +
> +		/* Enable flushing as we enabled dcache */
> +		lcd_set_flush_dcache(1);

Why not implement in driver, or else, each SoC enable dcache will need 
add this.

> +	}
>   #endif
>   	return 0;
>   }
>

Best Regards,
Bo Shen

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH 2/2] ARMv7: at91: enable ICache and DCache.
  2014-05-16  8:29   ` Bo Shen
@ 2014-05-16  9:17     ` Josh Wu
  2014-05-16  9:56       ` Bo Shen
  0 siblings, 1 reply; 6+ messages in thread
From: Josh Wu @ 2014-05-16  9:17 UTC (permalink / raw)
  To: u-boot

Hi, Bo

Thanks for the review  ;-)

On 5/16/2014 4:29 PM, Bo Shen wrote:
> Hi Josh,
>
> On 05/16/2014 04:15 PM, Josh Wu wrote:
>> As SAMA5D3 is a at91 ARMv7 cpu, so we should enable LCD DCache
>> flush for SAMA5D3X-EK.
>>
>> Signed-off-by: Josh Wu <josh.wu@atmel.com>
>> ---
>>   arch/arm/cpu/armv7/at91/cpu.c       |    6 ++++++
>>   board/atmel/sama5d3xek/sama5d3xek.c |    6 +++++-
>>   2 files changed, 11 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/cpu/armv7/at91/cpu.c 
>> b/arch/arm/cpu/armv7/at91/cpu.c
>> index 2fbf60d..6f2164f 100644
>> --- a/arch/arm/cpu/armv7/at91/cpu.c
>> +++ b/arch/arm/cpu/armv7/at91/cpu.c
>> @@ -61,6 +61,12 @@ int print_cpuinfo(void)
>>
>>   void enable_caches(void)
>>   {
>> +#ifndef CONFIG_SYS_ICACHE_OFF
>> +    icache_enable();
>> +#endif
>
> No need this one. Ifdef CONFIG_SYS_ICACHE_OFF, it will be disabled.

ok, good. I will remove this #if.

>
>> +#ifndef CONFIG_SYS_DCACHE_OFF
>> +    dcache_enable();
>> +#endif

This will be removed too.

>>   }
>>
>>   unsigned int get_chip_id(void)
>> diff --git a/board/atmel/sama5d3xek/sama5d3xek.c 
>> b/board/atmel/sama5d3xek/sama5d3xek.c
>> index c835c12..1fc91d9 100644
>> --- a/board/atmel/sama5d3xek/sama5d3xek.c
>> +++ b/board/atmel/sama5d3xek/sama5d3xek.c
>> @@ -200,8 +200,12 @@ int board_init(void)
>>           at91_gmac_hw_init();
>>   #endif
>>   #ifdef CONFIG_LCD
>> -    if (has_lcdc())
>> +    if (has_lcdc()) {
>>           sama5d3xek_lcd_hw_init();
>> +
>> +        /* Enable flushing as we enabled dcache */
>> +        lcd_set_flush_dcache(1);
>
> Why not implement in driver, or else, each SoC enable dcache will need 
> add this.

hmm, the thing is some at91 board, for example at91sam9x5ek board, not 
defined CONFIG_SYS_DCACHE_OFF, that means DCache is enabled. But 
actually it doesn't implement dcache_enable().
In above situation, if we implement it in driver, I can't tell whether 
dcache is really enabled or not.
For this reason, I manually call lcd_set_flush_dcache(1) in the board file.
In the future if all boards (use hlcd driver) enabled dcache I will move 
this function to hlcd driver.

Best Regards,
Josh Wu

>
>> +    }
>>   #endif
>>       return 0;
>>   }
>>
>
> Best Regards,
> Bo Shen
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH 2/2] ARMv7: at91: enable ICache and DCache.
  2014-05-16  9:17     ` Josh Wu
@ 2014-05-16  9:56       ` Bo Shen
  0 siblings, 0 replies; 6+ messages in thread
From: Bo Shen @ 2014-05-16  9:56 UTC (permalink / raw)
  To: u-boot

Hi Josh,

On 05/16/2014 05:17 PM, Josh Wu wrote:
>>> diff --git a/board/atmel/sama5d3xek/sama5d3xek.c
>>> b/board/atmel/sama5d3xek/sama5d3xek.c
>>> index c835c12..1fc91d9 100644
>>> --- a/board/atmel/sama5d3xek/sama5d3xek.c
>>> +++ b/board/atmel/sama5d3xek/sama5d3xek.c
>>> @@ -200,8 +200,12 @@ int board_init(void)
>>>           at91_gmac_hw_init();
>>>   #endif
>>>   #ifdef CONFIG_LCD
>>> -    if (has_lcdc())
>>> +    if (has_lcdc()) {
>>>           sama5d3xek_lcd_hw_init();
>>> +
>>> +        /* Enable flushing as we enabled dcache */
>>> +        lcd_set_flush_dcache(1);
>>
>> Why not implement in driver, or else, each SoC enable dcache will need
>> add this.
>
> hmm, the thing is some at91 board, for example at91sam9x5ek board, not
> defined CONFIG_SYS_DCACHE_OFF, that means DCache is enabled. But
> actually it doesn't implement dcache_enable().
> In above situation, if we implement it in driver, I can't tell whether
> dcache is really enabled or not.
> For this reason, I manually call lcd_set_flush_dcache(1) in the board file.
> In the future if all boards (use hlcd driver) enabled dcache I will move
> this function to hlcd driver.

I don't see any issue to implement this in driver, may be I am wrong? 
Can you figure out what issue you met?

Btw, if there is really have issues, can make this condition with 
CONFIG_SYS_DCACHE_OFF?

> Best Regards,
> Josh Wu

Best Regards,
Bo Shen

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2014-05-16  9:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-16  8:15 [U-Boot] [PATCH 0/2] ARMv7: at91: Enable ICache and DCache for at91 armv7 cpu Josh Wu
2014-05-16  8:15 ` [U-Boot] [PATCH 1/2] net: macb: enable dcache in macb Josh Wu
2014-05-16  8:15 ` [U-Boot] [PATCH 2/2] ARMv7: at91: enable ICache and DCache Josh Wu
2014-05-16  8:29   ` Bo Shen
2014-05-16  9:17     ` Josh Wu
2014-05-16  9:56       ` Bo Shen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox