Hi Stephen, On Mon, 15 Oct 2012 23:10:35 -0600, Stephen Warren <swar...@wwwdotorg.org> wrote:
> 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 <swar...@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(®s->status); > + if (val & BCM2835_MBOX_STATUS_RD_EMPTY) > + break; > + if (get_timer(0) >= endtime) > + return -1; > + val = readl(®s->read); > + } > + > + /* Send the request */ > + > + /* FIXME: timeout */ Develop this FIXME to indicate what exactly should be fixed. > + for (;;) { > + val = readl(®s->status); > + if (!(val & BCM2835_MBOX_STATUS_WR_FULL)) > + break; > + if (get_timer(0) >= endtime) > + return -1; > + } > + > + writel(BCM2835_MBOX_PACK(chan, send), ®s->write); > + > + /* Wait for the response */ > + > + /* FIXME: timeout */ Ditto. > + for (;;) { > + val = readl(®s->status); > + if (!(val & BCM2835_MBOX_STATUS_RD_EMPTY)) > + break; > + if (get_timer(0) >= endtime) > + return -1; > + } > + > + val = readl(®s->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; Remove __packed here, as all fields are 32 bits and thus no padding would happen anyway. > +#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; Ditto. > +#define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE 0x80000000 > + > +#define BCM2835_MBOX_TAG_GET_ARM_MEMORY 0x00010005 > + > +struct bcm2835_mbox_req_get_arm_mem { > +} __packed; Ditto (for an empty struct). > +struct bcm2835_mbox_resp_get_arm_mem { > + u32 mem_base; > + u32 mem_size; > +} __packed; Ditto. > +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; Ditto. Also, what is the point of bcm2835_mbox_buf_get_arm_mem which is not referenced in the API below? > +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 Amicalement, -- Albert. _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot