diff mbox

[U-Boot,4/5] arm/mach-bcm283x/mbox: Flush and invalidate dcache when using fw mailbox

Message ID 1436003324-8769-5-git-send-email-alexanders83@web.de
State Superseded
Delegated to: Tom Rini
Headers show

Commit Message

Alexander Stein July 4, 2015, 9:48 a.m. UTC
When using dcache the setup data for the mailbox must be actually written
into memory before calling into firmware. Thus flush and invalidate the
memory.

Signed-off-by: Alexander Stein <alexanders83@web.de>
---
 arch/arm/mach-bcm283x/mbox.c | 6 ++++++
 1 file changed, 6 insertions(+)

Comments

Stephen Warren July 11, 2015, 5:24 a.m. UTC | #1
On 07/04/2015 03:48 AM, Alexander Stein wrote:
> When using dcache the setup data for the mailbox must be actually written
> into memory before calling into firmware. Thus flush and invalidate the
> memory.

> diff --git a/arch/arm/mach-bcm283x/mbox.c b/arch/arm/mach-bcm283x/mbox.c

> +	flush_dcache_range((unsigned long)buffer,
> +			   (unsigned long)((void *)buffer +
> +			   buffer->buf_size));
> +	invalidate_dcache_range((unsigned long)buffer,
> +				(unsigned long)((void *)buffer +
> +				buffer->buf_size));
>  	ret = bcm2835_mbox_call_raw(chan, phys_to_bus((u32)buffer), &rbuffer);
>  	if (ret)
>  		return ret;

I'm not sure of the details of ARMv6 memory pre-fetching, so perhaps
this doesn't matter. However, I think it'd be best if this code did:

flush cache
execute mailbox operation
invalidate cache
use results

... rather than doing the invalidate before executing the mailbox
operation. This change would guarantee that the invalidate happens after
the VideoCore has written the response into RAM, and hence guarantees
that the invalidate will cause the response to be picked up.
diff mbox

Patch

diff --git a/arch/arm/mach-bcm283x/mbox.c b/arch/arm/mach-bcm283x/mbox.c
index 1af9be7..237c76c 100644
--- a/arch/arm/mach-bcm283x/mbox.c
+++ b/arch/arm/mach-bcm283x/mbox.c
@@ -111,6 +111,12 @@  int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer)
 	dump_buf(buffer);
 #endif
 
+	flush_dcache_range((unsigned long)buffer,
+			   (unsigned long)((void *)buffer +
+			   buffer->buf_size));
+	invalidate_dcache_range((unsigned long)buffer,
+				(unsigned long)((void *)buffer +
+				buffer->buf_size));
 	ret = bcm2835_mbox_call_raw(chan, phys_to_bus((u32)buffer), &rbuffer);
 	if (ret)
 		return ret;