public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 1/2] ARM: bcm2835: add mailbox driver
@ 2012-10-16  5:10 Stephen Warren
  2012-10-16  5:10 ` [U-Boot] [PATCH 2/2] ARM: rpi_b: use bcm2835 mbox driver to get memory size Stephen Warren
  2012-10-18 20:23 ` [U-Boot] [PATCH 1/2] ARM: bcm2835: add mailbox driver Albert ARIBAUD
  0 siblings, 2 replies; 7+ messages in thread
From: Stephen Warren @ 2012-10-16  5:10 UTC (permalink / raw)
  To: u-boot

The BCM2835 SoC contains (at least) two CPUs; the VideoCore (a/k/a "GPU")
and the ARM CPU. The ARM CPU is often thought of as the main CPU.
However, the VideoCore actually controls the initial SoC boot, and hides
much of the hardware behind a protocol. This protocol is transported
using the SoC's mailbox hardware module. The mailbox supports two forms
of communication: Raw 28-bit values, and a so-called "property"
interface, where the 28-bit value is a physical pointer to a memory
buffer that contains various "tags".

Here, we add a very simplistic driver for the mailbox module, and define
a few structures for the property messages.

Signed-off-by: Stephen Warren <swarren@wwwdotorg.org>
---
 arch/arm/cpu/arm1176/bcm2835/Makefile    |    2 +-
 arch/arm/cpu/arm1176/bcm2835/mbox.c      |   92 ++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-bcm2835/mbox.h |   87 ++++++++++++++++++++++++++++
 3 files changed, 180 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/cpu/arm1176/bcm2835/mbox.c
 create mode 100644 arch/arm/include/asm/arch-bcm2835/mbox.h

diff --git a/arch/arm/cpu/arm1176/bcm2835/Makefile b/arch/arm/cpu/arm1176/bcm2835/Makefile
index 95da6a8..135de42 100644
--- a/arch/arm/cpu/arm1176/bcm2835/Makefile
+++ b/arch/arm/cpu/arm1176/bcm2835/Makefile
@@ -17,7 +17,7 @@ include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(SOC).o
 
 SOBJS	:= lowlevel_init.o
-COBJS	:= init.o reset.o timer.o
+COBJS	:= init.o reset.o timer.o mbox.o
 
 SRCS	:= $(SOBJS:.o=.c) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
diff --git a/arch/arm/cpu/arm1176/bcm2835/mbox.c b/arch/arm/cpu/arm1176/bcm2835/mbox.c
new file mode 100644
index 0000000..f5c060b
--- /dev/null
+++ b/arch/arm/cpu/arm1176/bcm2835/mbox.c
@@ -0,0 +1,92 @@
+/*
+ * (C) Copyright 2012 Stephen Warren
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/mbox.h>
+
+#define TIMEOUT (100 * 1000) /* 100mS in uS */
+
+int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv)
+{
+	struct bcm2835_mbox_regs *regs =
+		(struct bcm2835_mbox_regs *)BCM2835_MBOX_PHYSADDR;
+	ulong endtime = get_timer(0) + TIMEOUT;
+	u32 val;
+
+	if (send & BCM2835_CHAN_MASK)
+		return -1;
+
+	/* Drain any stale responses */
+
+	for (;;) {
+		val = readl(&regs->status);
+		if (val & BCM2835_MBOX_STATUS_RD_EMPTY)
+			break;
+		if (get_timer(0) >= endtime)
+			return -1;
+		val = readl(&regs->read);
+	}
+
+	/* Send the request */
+
+	/* FIXME: timeout */
+	for (;;) {
+		val = readl(&regs->status);
+		if (!(val & BCM2835_MBOX_STATUS_WR_FULL))
+			break;
+		if (get_timer(0) >= endtime)
+			return -1;
+	}
+
+	writel(BCM2835_MBOX_PACK(chan, send), &regs->write);
+
+	/* Wait for the response */
+
+	/* FIXME: timeout */
+	for (;;) {
+		val = readl(&regs->status);
+		if (!(val & BCM2835_MBOX_STATUS_RD_EMPTY))
+			break;
+		if (get_timer(0) >= endtime)
+			return -1;
+	}
+
+	val = readl(&regs->read);
+
+	/* Validate the response */
+
+	if (BCM2835_MBOX_UNPACK_CHAN(val) != chan)
+		return -1;
+
+	*recv = BCM2835_MBOX_UNPACK_DATA(val);
+
+	return 0;
+}
+
+int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_prop_hdr *buffer)
+{
+	int ret;
+	u32 rbuffer;
+
+	ret = bcm2835_mbox_call_raw(chan, (u32)buffer, &rbuffer);
+	if (ret)
+		return ret;
+	if (rbuffer != (u32)buffer)
+		return -1;
+
+	return 0;
+}
diff --git a/arch/arm/include/asm/arch-bcm2835/mbox.h b/arch/arm/include/asm/arch-bcm2835/mbox.h
new file mode 100644
index 0000000..907fabd
--- /dev/null
+++ b/arch/arm/include/asm/arch-bcm2835/mbox.h
@@ -0,0 +1,87 @@
+/*
+ * (C) Copyright 2012 Stephen Warren
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _BCM2835_MBOX_H
+#define _BCM2835_MBOX_H
+
+#include <linux/compiler.h>
+
+/* Raw mailbox HW */
+
+#define BCM2835_MBOX_PHYSADDR	0x2000b880
+
+struct bcm2835_mbox_regs {
+	u32 read;
+	u32 rsvd0[5];
+	u32 status;
+	u32 config;
+	u32 write;
+};
+
+#define BCM2835_MBOX_STATUS_WR_FULL	0x80000000
+#define BCM2835_MBOX_STATUS_RD_EMPTY	0x40000000
+
+#define BCM2835_CHAN_MASK		0xf
+
+#define BCM2835_MBOX_PACK(chan, data)	(((data) & (~BCM2835_CHAN_MASK)) | \
+					 (chan & BCM2835_CHAN_MASK))
+#define BCM2835_MBOX_UNPACK_CHAN(val)	((val) & BCM2835_CHAN_MASK)
+#define BCM2835_MBOX_UNPACK_DATA(val)	((val) & (~BCM2835_CHAN_MASK))
+
+/* Property mailbox buffer structures */
+
+#define BCM2835_MBOX_PROP_CHAN		8
+
+struct bcm2835_mbox_prop_hdr {
+	u32 buf_size;
+	u32 code;
+} __packed;
+
+#define BCM2835_MBOX_REQ_CODE		0
+#define BCM2835_MBOX_RESP_CODE_SUCCESS	0x80000000
+
+struct bcm2835_mbox_tag_hdr {
+	u32 tag;
+	u32 val_buf_size;
+	u32 val_len;
+} __packed;
+
+#define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE	0x80000000
+
+#define BCM2835_MBOX_TAG_GET_ARM_MEMORY		0x00010005
+
+struct bcm2835_mbox_req_get_arm_mem {
+} __packed;
+
+struct bcm2835_mbox_resp_get_arm_mem {
+	u32 mem_base;
+	u32 mem_size;
+} __packed;
+
+struct bcm2835_mbox_buf_get_arm_mem {
+	struct bcm2835_mbox_prop_hdr hdr;
+	struct bcm2835_mbox_tag_hdr tag_hdr;
+	union {
+		struct bcm2835_mbox_req_get_arm_mem req;
+		struct bcm2835_mbox_resp_get_arm_mem resp;
+	} body;
+	u32 end_tag;
+} __packed;
+
+int bcm2835_mbox_call_raw(u32 chan, u32 send, u32 *recv);
+int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_prop_hdr *buffer);
+
+#endif
-- 
1.7.9.5

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

end of thread, other threads:[~2012-10-18 23:21 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-16  5:10 [U-Boot] [PATCH 1/2] ARM: bcm2835: add mailbox driver Stephen Warren
2012-10-16  5:10 ` [U-Boot] [PATCH 2/2] ARM: rpi_b: use bcm2835 mbox driver to get memory size Stephen Warren
2012-10-18 20:28   ` Albert ARIBAUD
2012-10-18 21:51     ` Stephen Warren
2012-10-18 20:23 ` [U-Boot] [PATCH 1/2] ARM: bcm2835: add mailbox driver Albert ARIBAUD
2012-10-18 20:34   ` Stephen Warren
2012-10-18 23:21     ` Albert ARIBAUD

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