summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2013-11-07 08:31:47 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2013-11-07 08:31:47 +0100
commitded25480d8c5e56d9dcbf53a88d05f023b9740c4 (patch)
tree8691bdf7f0fc801b08b114204c83d25007eb8fba /arch
parentb3055b0f6b1687089b914eb8cde5bbb73cfca7a1 (diff)
parent97607e85cdc44824e9617c74325bc9bc6405c383 (diff)
downloadbarebox-ded25480d8c5e56d9dcbf53a88d05f023b9740c4.tar.gz
barebox-ded25480d8c5e56d9dcbf53a88d05f023b9740c4.tar.xz
Merge branch 'for-next/rpi'
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/boards/at91sam9x5ek/hw_version.c4
-rw-r--r--arch/arm/boards/highbank/init.c4
-rw-r--r--arch/arm/boards/raspberry-pi/env/init/bootargs-base2
-rw-r--r--arch/arm/boards/raspberry-pi/rpi.c110
-rw-r--r--arch/arm/configs/rpi_defconfig45
-rw-r--r--arch/arm/cpu/cache.c18
-rw-r--r--arch/arm/cpu/start.c4
-rw-r--r--arch/arm/mach-bcm2835/Makefile2
-rw-r--r--arch/arm/mach-bcm2835/core.c33
-rw-r--r--arch/arm/mach-bcm2835/include/mach/core.h13
-rw-r--r--arch/arm/mach-bcm2835/include/mach/mbox.h421
-rw-r--r--arch/arm/mach-bcm2835/mbox.c152
-rw-r--r--arch/ppc/mach-mpc5xxx/cpu.c4
-rw-r--r--arch/ppc/mach-mpc85xx/fdt.c4
14 files changed, 760 insertions, 56 deletions
diff --git a/arch/arm/boards/at91sam9x5ek/hw_version.c b/arch/arm/boards/at91sam9x5ek/hw_version.c
index 1207a3e49d..2da4e5ed8c 100644
--- a/arch/arm/boards/at91sam9x5ek/hw_version.c
+++ b/arch/arm/boards/at91sam9x5ek/hw_version.c
@@ -229,7 +229,7 @@ static void at91sam9x5ek_devices_detect_one(const char *name)
#define NODE_NAME_LEN 128
-static int cm_cogent_fixup(struct device_node *root)
+static int cm_cogent_fixup(struct device_node *root, void *unused)
{
int ret;
struct device_node *node;
@@ -260,5 +260,5 @@ void at91sam9x5ek_devices_detect_hw(void)
armlinux_set_serial(sn);
if (at91sam9x5ek_cm_is_vendor(VENDOR_COGENT))
- of_register_fixup(cm_cogent_fixup);
+ of_register_fixup(cm_cogent_fixup, NULL);
}
diff --git a/arch/arm/boards/highbank/init.c b/arch/arm/boards/highbank/init.c
index 7b1be046a5..8a24b21a73 100644
--- a/arch/arm/boards/highbank/init.c
+++ b/arch/arm/boards/highbank/init.c
@@ -24,7 +24,7 @@
struct fdt_header *fdt = NULL;
-static int hb_fixup(struct device_node *root)
+static int hb_fixup(struct device_node *root, void *unused)
{
struct device_node *node;
u32 reg = readl(sregs_base + HB_SREG_A9_PWRDOM_DATA);
@@ -108,7 +108,7 @@ mem_initcall(highbank_mem_init);
static int highbank_devices_init(void)
{
- of_register_fixup(hb_fixup);
+ of_register_fixup(hb_fixup, NULL);
if (!fdt) {
highbank_register_gpio(0);
highbank_register_gpio(1);
diff --git a/arch/arm/boards/raspberry-pi/env/init/bootargs-base b/arch/arm/boards/raspberry-pi/env/init/bootargs-base
index d86975406e..4dda5501e3 100644
--- a/arch/arm/boards/raspberry-pi/env/init/bootargs-base
+++ b/arch/arm/boards/raspberry-pi/env/init/bootargs-base
@@ -5,4 +5,4 @@ if [ "$1" = menu ]; then
exit
fi
-global.linux.bootargs.base="console=ttymxc0,115200"
+global.linux.bootargs.base="console=ttyAMA0,115200"
diff --git a/arch/arm/boards/raspberry-pi/rpi.c b/arch/arm/boards/raspberry-pi/rpi.c
index d4912ccdc7..96025ba9b1 100644
--- a/arch/arm/boards/raspberry-pi/rpi.c
+++ b/arch/arm/boards/raspberry-pi/rpi.c
@@ -15,16 +15,83 @@
#include <common.h>
#include <init.h>
+#include <fs.h>
+#include <linux/stat.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <envfs.h>
#include <asm/armlinux.h>
#include <generated/mach-types.h>
#include <mach/core.h>
+#include <mach/mbox.h>
-static int rpi_mem_init(void)
+struct msg_get_arm_mem {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_get_arm_mem get_arm_mem;
+ u32 end_tag;
+};
+
+struct msg_get_clock_rate {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_get_clock_rate get_clock_rate;
+ u32 end_tag;
+};
+
+static int rpi_get_arm_mem(u32 *size)
{
- bcm2835_add_device_sdram(0);
+ BCM2835_MBOX_STACK_ALIGN(struct msg_get_arm_mem, msg);
+ int ret;
+
+ BCM2835_MBOX_INIT_HDR(msg);
+ BCM2835_MBOX_INIT_TAG(&msg->get_arm_mem, GET_ARM_MEMORY);
+
+ ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
+ if (ret)
+ return ret;
+
+ *size = msg->get_arm_mem.body.resp.mem_size;
+
return 0;
}
+
+static int rpi_register_clkdev(u32 clock_id, const char *name)
+{
+ BCM2835_MBOX_STACK_ALIGN(struct msg_get_clock_rate, msg);
+ struct clk *clk;
+ int ret;
+
+ BCM2835_MBOX_INIT_HDR(msg);
+ BCM2835_MBOX_INIT_TAG(&msg->get_clock_rate, GET_CLOCK_RATE);
+ msg->get_clock_rate.body.req.clock_id = clock_id;
+
+ ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr);
+ if (ret)
+ return ret;
+
+ clk = clk_fixed(name, msg->get_clock_rate.body.resp.rate_hz);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ if (!clk_register_clkdev(clk, NULL, name))
+ return -ENODEV;
+
+ return 0;
+}
+
+static int rpi_mem_init(void)
+{
+ u32 size = 0;
+ int ret;
+
+ ret = rpi_get_arm_mem(&size);
+ if (ret)
+ printf("could not query ARM memory size\n");
+
+ bcm2835_add_device_sdram(size);
+
+ return ret;
+}
mem_initcall(rpi_mem_init);
static int rpi_console_init(void)
@@ -37,11 +104,46 @@ static int rpi_console_init(void)
}
console_initcall(rpi_console_init);
+static int rpi_clock_init(void)
+{
+ rpi_register_clkdev(BCM2835_MBOX_CLOCK_ID_EMMC, "bcm2835_mci0");
+ return 0;
+}
+postconsole_initcall(rpi_clock_init);
+
+static int rpi_env_init(void)
+{
+ struct stat s;
+ const char *diskdev = "/dev/disk0.0";
+ int ret;
+
+ device_detect_by_name("mci0");
+
+ ret = stat(diskdev, &s);
+ if (ret) {
+ printf("no %s. using default env\n", diskdev);
+ return 0;
+ }
+
+ mkdir("/boot", 0666);
+ ret = mount(diskdev, "fat", "/boot");
+ if (ret) {
+ printf("failed to mount %s\n", diskdev);
+ return 0;
+ }
+
+ default_environment_path = "/boot/barebox.env";
+
+ return 0;
+}
+
static int rpi_devices_init(void)
{
+ bcm2835_register_mci();
+ bcm2835_register_fb();
armlinux_set_architecture(MACH_TYPE_BCM2708);
armlinux_set_bootparams((void *)(0x00000100));
+ rpi_env_init();
return 0;
}
-
-device_initcall(rpi_devices_init);
+late_initcall(rpi_devices_init);
diff --git a/arch/arm/configs/rpi_defconfig b/arch/arm/configs/rpi_defconfig
index 014e28c73d..76029d025f 100644
--- a/arch/arm/configs/rpi_defconfig
+++ b/arch/arm/configs/rpi_defconfig
@@ -1,41 +1,66 @@
CONFIG_ARCH_BCM2835=y
-CONFIG_GPIO_BCM2835=y
+CONFIG_AEABI=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_ARM_UNWIND=y
+CONFIG_MMU=y
+CONFIG_MALLOC_TLSF=y
+CONFIG_KALLSYMS=y
CONFIG_PROMPT="R-Pi> "
CONFIG_LONGHELP=y
-CONFIG_GLOB=y
CONFIG_HUSH_FANCY_PROMPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
-CONFIG_PARTITION=y
+CONFIG_BLSPEC=y
CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/raspberry-pi/env"
CONFIG_CMD_EDIT=y
CONFIG_CMD_SLEEP=y
+CONFIG_CMD_MSLEEP=y
CONFIG_CMD_SAVEENV=y
-CONFIG_CMD_LOADENV=y
CONFIG_CMD_EXPORT=y
CONFIG_CMD_PRINTENV=y
CONFIG_CMD_READLINE=y
+CONFIG_CMD_LET=y
CONFIG_CMD_MENU=y
CONFIG_CMD_MENU_MANAGEMENT=y
CONFIG_CMD_PASSWD=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_LN=y
+CONFIG_CMD_FILETYPE=y
CONFIG_CMD_ECHO_E=y
CONFIG_CMD_LOADB=y
CONFIG_CMD_MEMINFO=y
-CONFIG_CMD_MTEST=y
-CONFIG_CMD_MTEST_ALTERNATIVE=y
-CONFIG_CMD_BOOTM_ZLIB=y
-CONFIG_CMD_BOOTM_BZLIB=y
+CONFIG_CMD_IOMEM=y
+CONFIG_CMD_MM=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
+CONFIG_CMD_MD5SUM=y
CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_BOOTM_VERBOSE=y
+CONFIG_CMD_BOOTM_INITRD=y
+CONFIG_CMD_BOOTM_OFTREE=y
+CONFIG_CMD_UIMAGE=y
CONFIG_CMD_RESET=y
-CONFIG_CMD_CLK=y
CONFIG_CMD_GO=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OF_NODE=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
-CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_MAGICVAR=y
+CONFIG_CMD_MAGICVAR_HELP=y
CONFIG_CMD_GPIO=y
+CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_DETECT=y
CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_MCI=y
+CONFIG_MCI_BCM2835=y
+CONFIG_GPIO_BCM2835=y
+CONFIG_FS_EXT4=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FAT_WRITE=y
+CONFIG_FS_FAT_LFN=y
CONFIG_SHA1=y
CONFIG_SHA256=y
diff --git a/arch/arm/cpu/cache.c b/arch/arm/cpu/cache.c
index 7aab55b6bc..223e3089b2 100644
--- a/arch/arm/cpu/cache.c
+++ b/arch/arm/cpu/cache.c
@@ -41,32 +41,38 @@ DEFINE_CPU_FNS(v7)
void __dma_clean_range(unsigned long start, unsigned long end)
{
- cache_fns->dma_clean_range(start, end);
+ if (cache_fns)
+ cache_fns->dma_clean_range(start, end);
}
void __dma_flush_range(unsigned long start, unsigned long end)
{
- cache_fns->dma_flush_range(start, end);
+ if (cache_fns)
+ cache_fns->dma_flush_range(start, end);
}
void __dma_inv_range(unsigned long start, unsigned long end)
{
- cache_fns->dma_inv_range(start, end);
+ if (cache_fns)
+ cache_fns->dma_inv_range(start, end);
}
void __mmu_cache_on(void)
{
- cache_fns->mmu_cache_on();
+ if (cache_fns)
+ cache_fns->mmu_cache_on();
}
void __mmu_cache_off(void)
{
- cache_fns->mmu_cache_off();
+ if (cache_fns)
+ cache_fns->mmu_cache_off();
}
void __mmu_cache_flush(void)
{
- cache_fns->mmu_cache_flush();
+ if (cache_fns)
+ cache_fns->mmu_cache_flush();
}
int arm_set_cache_functions(void)
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index f8d343f4ec..f0a7df37bd 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -70,7 +70,9 @@ static noinline __noreturn void __start(uint32_t membase, uint32_t memsize,
endmem &= ~0x3fff;
endmem -= SZ_16K; /* ttb */
- if (!IS_ENABLED(CONFIG_PBL_IMAGE)) {
+ if (IS_ENABLED(CONFIG_PBL_IMAGE)) {
+ arm_set_cache_functions();
+ } else {
arm_early_mmu_cache_invalidate();
mmu_early_enable(membase, memsize, endmem);
}
diff --git a/arch/arm/mach-bcm2835/Makefile b/arch/arm/mach-bcm2835/Makefile
index 820eb10ac2..940f98cbce 100644
--- a/arch/arm/mach-bcm2835/Makefile
+++ b/arch/arm/mach-bcm2835/Makefile
@@ -1 +1 @@
-obj-y += core.o
+obj-y += core.o mbox.o
diff --git a/arch/arm/mach-bcm2835/core.c b/arch/arm/mach-bcm2835/core.c
index 906e4344dd..04bc89751d 100644
--- a/arch/arm/mach-bcm2835/core.c
+++ b/arch/arm/mach-bcm2835/core.c
@@ -32,45 +32,28 @@
#include <mach/core.h>
#include <linux/amba/bus.h>
-enum brcm_clks {
- dummy, clk_ref_3, clk_ref_1, clks_max
-};
-
-static struct clk *clks[clks_max];
-
static int bcm2835_clk_init(void)
{
- int ret;
+ struct clk *clk;
- clks[dummy] = clk_fixed("dummy", 0);
- clks[clk_ref_3] = clk_fixed("ref3", 3 * 1000 * 1000);
- clks[clk_ref_1] = clk_fixed("ref1", 1 * 1000 * 1000);
+ clk = clk_fixed("apb_pclk", 0);
+ clk_register_clkdev(clk, "apb_pclk", NULL);
- ret = clk_register_clkdev(clks[dummy], "apb_pclk", NULL);
- if (ret)
- goto clk_err;
+ clk = clk_fixed("uart0-pl0110", 3 * 1000 * 1000);
+ clk_register_clkdev(clk, NULL, "uart0-pl0110");
- ret = clk_register_clkdev(clks[clk_ref_3], NULL, "uart0-pl0110");
- if (ret)
- goto clk_err;
+ clk = clk_fixed("bcm2835-cs", 1 * 1000 * 1000);
+ clk_register_clkdev(clk, NULL, "bcm2835-cs");
- ret = clk_register_clkdev(clks[clk_ref_1], NULL, "bcm2835-cs");
- if (ret)
- goto clk_err;
+ add_generic_device("bcm2835-cs", DEVICE_ID_SINGLE, NULL, BCM2835_ST_BASE, 0x1C, IORESOURCE_MEM, NULL);
return 0;
-
-clk_err:
- return ret;
-
}
postcore_initcall(bcm2835_clk_init);
static int bcm2835_dev_init(void)
{
add_generic_device("bcm2835-gpio", 0, NULL, BCM2835_GPIO_BASE, 0xB0, IORESOURCE_MEM, NULL);
- add_generic_device("bcm2835-cs", DEVICE_ID_SINGLE, NULL, BCM2835_ST_BASE, 0x1C, IORESOURCE_MEM, NULL);
- add_generic_device("bcm2835_mci", 0, NULL, BCM2835_EMMC_BASE, 0xFC, IORESOURCE_MEM, NULL);
return 0;
}
coredevice_initcall(bcm2835_dev_init);
diff --git a/arch/arm/mach-bcm2835/include/mach/core.h b/arch/arm/mach-bcm2835/include/mach/core.h
index 9379af209b..477ecb977c 100644
--- a/arch/arm/mach-bcm2835/include/mach/core.h
+++ b/arch/arm/mach-bcm2835/include/mach/core.h
@@ -16,7 +16,20 @@
#ifndef __BCM2835_CORE_H__
#define __BCM2835_CORE_H__
+#include <mach/platform.h>
+
void bcm2835_register_uart(void);
void bcm2835_add_device_sdram(u32 size);
+static void inline bcm2835_register_mci(void)
+{
+ add_generic_device("bcm2835_mci", 0, NULL, BCM2835_EMMC_BASE, 0xFC,
+ IORESOURCE_MEM, NULL);
+}
+
+static void inline bcm2835_register_fb(void)
+{
+ add_generic_device("bcm2835_fb", 0, NULL, 0, 0, 0, NULL);
+}
+
#endif
diff --git a/arch/arm/mach-bcm2835/include/mach/mbox.h b/arch/arm/mach-bcm2835/include/mach/mbox.h
new file mode 100644
index 0000000000..fb8a9bf029
--- /dev/null
+++ b/arch/arm/mach-bcm2835/include/mach/mbox.h
@@ -0,0 +1,421 @@
+/*
+ * based on U-Boot code
+ *
+ * (C) Copyright 2012 Stephen Warren
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _BCM2835_MBOX_H
+#define _BCM2835_MBOX_H
+
+#include <common.h>
+
+/*
+ * 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 hardware supports passing 32-bit values back and forth.
+ * Presumably by software convention of the firmware, the bottom 4 bits of the
+ * value are used to indicate a logical channel, and the upper 28 bits are the
+ * actual payload. Various channels exist using these simple raw messages. See
+ * https://github.com/raspberrypi/firmware/wiki/Mailboxes for a list. As an
+ * example, the messages on the power management channel are a bitmask of
+ * devices whose power should be enabled.
+ *
+ * The property mailbox channel passes messages that contain the (16-byte
+ * aligned) ARM physical address of a memory buffer. This buffer is passed to
+ * the VC for processing, is modified in-place by the VC, and the address then
+ * passed back to the ARM CPU as the response mailbox message to indicate
+ * request completion. The buffers have a generic and extensible format; each
+ * buffer contains a standard header, a list of "tags", and a terminating zero
+ * entry. Each tag contains an ID indicating its type, and length fields for
+ * generic parsing. With some limitations, an arbitrary set of tags may be
+ * combined together into a single message buffer. This file defines structs
+ * representing the header and many individual tag layouts and IDs.
+ */
+
+/* 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
+
+/* Lower 4-bits are channel ID */
+#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
+
+/* All message buffers must start with this header */
+struct bcm2835_mbox_hdr {
+ u32 buf_size;
+ u32 code;
+};
+
+#define BCM2835_MBOX_REQ_CODE 0
+#define BCM2835_MBOX_RESP_CODE_SUCCESS 0x80000000
+
+#define BCM2835_MBOX_STACK_ALIGN(type, name) \
+ STACK_ALIGN_ARRAY(type, name, 1, BCM2835_CHAN_MASK + 1)
+
+#define BCM2835_MBOX_INIT_HDR(_m_) { \
+ memset((_m_), 0, sizeof(*(_m_))); \
+ (_m_)->hdr.buf_size = sizeof(*(_m_)); \
+ (_m_)->hdr.code = 0; \
+ (_m_)->end_tag = 0; \
+ }
+
+/*
+ * A message buffer contains a list of tags. Each tag must also start with
+ * a standardized header.
+ */
+struct bcm2835_mbox_tag_hdr {
+ u32 tag;
+ u32 val_buf_size;
+ u32 val_len;
+};
+
+#define BCM2835_MBOX_INIT_TAG(_t_, _id_) { \
+ (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \
+ (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \
+ (_t_)->tag_hdr.val_len = sizeof((_t_)->body.req); \
+ }
+
+#define BCM2835_MBOX_INIT_TAG_NO_REQ(_t_, _id_) { \
+ (_t_)->tag_hdr.tag = BCM2835_MBOX_TAG_##_id_; \
+ (_t_)->tag_hdr.val_buf_size = sizeof((_t_)->body); \
+ (_t_)->tag_hdr.val_len = 0; \
+ }
+
+/* When responding, the VC sets this bit in val_len to indicate a response */
+#define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE 0x80000000
+
+/*
+ * Below we define the ID and struct for many possible tags. This header only
+ * defines individual tag structs, not entire message structs, since in
+ * general an arbitrary set of tags may be combined into a single message.
+ * Clients of the mbox API are expected to define their own overall message
+ * structures by combining the header, a set of tags, and a terminating
+ * entry. For example,
+ *
+ * struct msg {
+ * struct bcm2835_mbox_hdr hdr;
+ * struct bcm2835_mbox_tag_get_arm_mem get_arm_mem;
+ * ... perhaps other tags here ...
+ * u32 end_tag;
+ * };
+ */
+
+#define BCM2835_MBOX_TAG_GET_ARM_MEMORY 0x00010005
+
+struct bcm2835_mbox_tag_get_arm_mem {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ } req;
+ struct {
+ u32 mem_base;
+ u32 mem_size;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_CLOCK_RATE 0x00030002
+
+#define BCM2835_MBOX_CLOCK_ID_EMMC 1
+#define BCM2835_MBOX_CLOCK_ID_UART 2
+#define BCM2835_MBOX_CLOCK_ID_ARM 3
+#define BCM2835_MBOX_CLOCK_ID_CORE 4
+#define BCM2835_MBOX_CLOCK_ID_V3D 5
+#define BCM2835_MBOX_CLOCK_ID_H264 6
+#define BCM2835_MBOX_CLOCK_ID_ISP 7
+#define BCM2835_MBOX_CLOCK_ID_SDRAM 8
+#define BCM2835_MBOX_CLOCK_ID_PIXEL 9
+#define BCM2835_MBOX_CLOCK_ID_PWM 10
+
+struct bcm2835_mbox_tag_get_clock_rate {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ u32 clock_id;
+ } req;
+ struct {
+ u32 clock_id;
+ u32 rate_hz;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_ALLOCATE_BUFFER 0x00040001
+
+struct bcm2835_mbox_tag_allocate_buffer {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ u32 alignment;
+ } req;
+ struct {
+ u32 fb_address;
+ u32 fb_size;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_RELEASE_BUFFER 0x00048001
+
+struct bcm2835_mbox_tag_release_buffer {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ } req;
+ struct {
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_BLANK_SCREEN 0x00040002
+
+struct bcm2835_mbox_tag_blank_screen {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ /* bit 0 means on, other bits reserved */
+ u32 state;
+ } req;
+ struct {
+ u32 state;
+ } resp;
+ } body;
+};
+
+/* Physical means output signal */
+#define BCM2835_MBOX_TAG_GET_PHYSICAL_W_H 0x00040003
+#define BCM2835_MBOX_TAG_TEST_PHYSICAL_W_H 0x00044003
+#define BCM2835_MBOX_TAG_SET_PHYSICAL_W_H 0x00048003
+
+struct bcm2835_mbox_tag_physical_w_h {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ /* req not used for get */
+ struct {
+ u32 width;
+ u32 height;
+ } req;
+ struct {
+ u32 width;
+ u32 height;
+ } resp;
+ } body;
+};
+
+/* Virtual means display buffer */
+#define BCM2835_MBOX_TAG_GET_VIRTUAL_W_H 0x00040004
+#define BCM2835_MBOX_TAG_TEST_VIRTUAL_W_H 0x00044004
+#define BCM2835_MBOX_TAG_SET_VIRTUAL_W_H 0x00048004
+
+struct bcm2835_mbox_tag_virtual_w_h {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ /* req not used for get */
+ struct {
+ u32 width;
+ u32 height;
+ } req;
+ struct {
+ u32 width;
+ u32 height;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_DEPTH 0x00040005
+#define BCM2835_MBOX_TAG_TEST_DEPTH 0x00044005
+#define BCM2835_MBOX_TAG_SET_DEPTH 0x00048005
+
+struct bcm2835_mbox_tag_depth {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ /* req not used for get */
+ struct {
+ u32 bpp;
+ } req;
+ struct {
+ u32 bpp;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_PIXEL_ORDER 0x00040006
+#define BCM2835_MBOX_TAG_TEST_PIXEL_ORDER 0x00044005
+#define BCM2835_MBOX_TAG_SET_PIXEL_ORDER 0x00048006
+
+#define BCM2835_MBOX_PIXEL_ORDER_BGR 0
+#define BCM2835_MBOX_PIXEL_ORDER_RGB 1
+
+struct bcm2835_mbox_tag_pixel_order {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ /* req not used for get */
+ struct {
+ u32 order;
+ } req;
+ struct {
+ u32 order;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_ALPHA_MODE 0x00040007
+#define BCM2835_MBOX_TAG_TEST_ALPHA_MODE 0x00044007
+#define BCM2835_MBOX_TAG_SET_ALPHA_MODE 0x00048007
+
+#define BCM2835_MBOX_ALPHA_MODE_0_OPAQUE 0
+#define BCM2835_MBOX_ALPHA_MODE_0_TRANSPARENT 1
+#define BCM2835_MBOX_ALPHA_MODE_IGNORED 2
+
+struct bcm2835_mbox_tag_alpha_mode {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ /* req not used for get */
+ struct {
+ u32 alpha;
+ } req;
+ struct {
+ u32 alpha;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_PITCH 0x00040008
+
+struct bcm2835_mbox_tag_pitch {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ } req;
+ struct {
+ u32 pitch;
+ } resp;
+ } body;
+};
+
+/* Offset of display window within buffer */
+#define BCM2835_MBOX_TAG_GET_VIRTUAL_OFFSET 0x00040009
+#define BCM2835_MBOX_TAG_TEST_VIRTUAL_OFFSET 0x00044009
+#define BCM2835_MBOX_TAG_SET_VIRTUAL_OFFSET 0x00048009
+
+struct bcm2835_mbox_tag_virtual_offset {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ /* req not used for get */
+ struct {
+ u32 x;
+ u32 y;
+ } req;
+ struct {
+ u32 x;
+ u32 y;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_OVERSCAN 0x0004000a
+#define BCM2835_MBOX_TAG_TEST_OVERSCAN 0x0004400a
+#define BCM2835_MBOX_TAG_SET_OVERSCAN 0x0004800a
+
+struct bcm2835_mbox_tag_overscan {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ /* req not used for get */
+ struct {
+ u32 top;
+ u32 bottom;
+ u32 left;
+ u32 right;
+ } req;
+ struct {
+ u32 top;
+ u32 bottom;
+ u32 left;
+ u32 right;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_GET_PALETTE 0x0004000b
+
+struct bcm2835_mbox_tag_get_palette {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ } req;
+ struct {
+ u32 data[1024];
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_TEST_PALETTE 0x0004400b
+
+struct bcm2835_mbox_tag_test_palette {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ u32 offset;
+ u32 num_entries;
+ u32 data[256];
+ } req;
+ struct {
+ u32 is_invalid;
+ } resp;
+ } body;
+};
+
+#define BCM2835_MBOX_TAG_SET_PALETTE 0x0004800b
+
+struct bcm2835_mbox_tag_set_palette {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ u32 offset;
+ u32 num_entries;
+ u32 data[256];
+ } req;
+ struct {
+ u32 is_invalid;
+ } resp;
+ } body;
+};
+
+/*
+ * Pass a complete property-style buffer to the VC, and wait until it has
+ * been processed.
+ *
+ * This function expects a pointer to the mbox_hdr structure in an attempt
+ * to ensure some degree of type safety. However, some number of tags and
+ * a termination value are expected to immediately follow the header in
+ * memory, as required by the property protocol.
+ *
+ * Returns 0 for success, any other value for error.
+ */
+int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer);
+
+#endif
diff --git a/arch/arm/mach-bcm2835/mbox.c b/arch/arm/mach-bcm2835/mbox.c
new file mode 100644
index 0000000000..2bca567f39
--- /dev/null
+++ b/arch/arm/mach-bcm2835/mbox.c
@@ -0,0 +1,152 @@
+/*
+ * based on U-Boot code
+ *
+ * (C) Copyright 2012 Stephen Warren
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/io.h>
+#include <asm/mmu.h>
+#include <common.h>
+#include <clock.h>
+
+#include <mach/mbox.h>
+
+#define TIMEOUT (MSECOND * 100) /* 100mS */
+
+static int bcm2835_mbox_call_raw(u32 chan, struct bcm2835_mbox_hdr *buffer,
+ u32 *recv)
+{
+ struct bcm2835_mbox_regs __iomem *regs =
+ (struct bcm2835_mbox_regs *)BCM2835_MBOX_PHYSADDR;
+ uint64_t starttime = get_time_ns();
+ u32 send = virt_to_phys(buffer);
+ u32 val;
+
+ if (send & BCM2835_CHAN_MASK) {
+ printf("mbox: Illegal mbox data 0x%08x\n", send);
+ return -EINVAL;
+ }
+
+ /* Drain any stale responses */
+ for (;;) {
+ val = readl(&regs->status);
+ if (val & BCM2835_MBOX_STATUS_RD_EMPTY)
+ break;
+ if (is_timeout(starttime, TIMEOUT)) {
+ printf("mbox: Timeout draining stale responses\n");
+ return -ETIMEDOUT;
+ }
+ val = readl(&regs->read);
+ }
+
+ /* Wait for space to send */
+ for (;;) {
+ val = readl(&regs->status);
+ if (!(val & BCM2835_MBOX_STATUS_WR_FULL))
+ break;
+ if (is_timeout(starttime, TIMEOUT)) {
+ printf("mbox: Timeout waiting for send space\n");
+ return -ETIMEDOUT;
+ }
+ }
+
+ /* Send the request */
+ val = BCM2835_MBOX_PACK(chan, send);
+ debug("mbox: TX raw: 0x%08x\n", val);
+ dma_flush_range(send, send + buffer->buf_size);
+ writel(val, &regs->write);
+
+ /* Wait for the response */
+ for (;;) {
+ val = readl(&regs->status);
+ if (!(val & BCM2835_MBOX_STATUS_RD_EMPTY))
+ break;
+ if (is_timeout(starttime, TIMEOUT)) {
+ printf("mbox: Timeout waiting for response\n");
+ return -ETIMEDOUT;
+ }
+ }
+
+ /* Read the response */
+ val = readl(&regs->read);
+ debug("mbox: RX raw: 0x%08x\n", val);
+ dma_inv_range(send, send + buffer->buf_size);
+
+ /* Validate the response */
+ if (BCM2835_MBOX_UNPACK_CHAN(val) != chan) {
+ printf("mbox: Response channel mismatch\n");
+ return -EIO;
+ }
+
+ *recv = BCM2835_MBOX_UNPACK_DATA(val);
+
+ return 0;
+}
+
+#ifdef DEBUG
+void dump_buf(struct bcm2835_mbox_hdr *buffer)
+{
+ u32 *p;
+ u32 words;
+ int i;
+
+ p = (u32 *)buffer;
+ words = buffer->buf_size / 4;
+ for (i = 0; i < words; i++)
+ printf(" 0x%04x: 0x%08x\n", i * 4, p[i]);
+}
+#endif
+
+int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer)
+{
+ int ret;
+ u32 rbuffer;
+ struct bcm2835_mbox_tag_hdr *tag;
+ int tag_index;
+
+#ifdef DEBUG
+ printf("mbox: TX buffer\n");
+ dump_buf(buffer);
+#endif
+
+ ret = bcm2835_mbox_call_raw(chan, buffer, &rbuffer);
+ if (ret)
+ return ret;
+ if (rbuffer != (u32)buffer) {
+ printf("mbox: Response buffer mismatch\n");
+ return -EIO;
+ }
+
+#ifdef DEBUG
+ printf("mbox: RX buffer\n");
+ dump_buf(buffer);
+#endif
+
+ /* Validate overall response status */
+ if (buffer->code != BCM2835_MBOX_RESP_CODE_SUCCESS) {
+ printf("mbox: Header response code invalid\n");
+ return -EIO;
+ }
+
+ /* Validate each tag's response status */
+ tag = (void *)(buffer + 1);
+ tag_index = 0;
+ while (tag->tag) {
+ if (!(tag->val_len & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE)) {
+ printf("mbox: Tag %d missing val_len response bit\n",
+ tag_index);
+ return -EIO;
+ }
+ /*
+ * Clear the reponse bit so clients can just look right at the
+ * length field without extra processing
+ */
+ tag->val_len &= ~BCM2835_MBOX_TAG_VAL_LEN_RESPONSE;
+ tag = (void *)(((u8 *)tag) + sizeof(*tag) + tag->val_buf_size);
+ tag_index++;
+ }
+
+ return 0;
+}
diff --git a/arch/ppc/mach-mpc5xxx/cpu.c b/arch/ppc/mach-mpc5xxx/cpu.c
index 0ece4a9ed9..c860e709f2 100644
--- a/arch/ppc/mach-mpc5xxx/cpu.c
+++ b/arch/ppc/mach-mpc5xxx/cpu.c
@@ -77,7 +77,7 @@ void __noreturn reset_cpu (unsigned long addr)
/* ------------------------------------------------------------------------- */
#ifdef CONFIG_OFTREE
-static int of_mpc5200_fixup(struct device_node *root)
+static int of_mpc5200_fixup(struct device_node *root, void *unused)
{
struct device_node *node;
@@ -103,7 +103,7 @@ static int of_mpc5200_fixup(struct device_node *root)
static int of_register_mpc5200_fixup(void)
{
- return of_register_fixup(of_mpc5200_fixup);
+ return of_register_fixup(of_mpc5200_fixup, NULL);
}
late_initcall(of_register_mpc5200_fixup);
#endif
diff --git a/arch/ppc/mach-mpc85xx/fdt.c b/arch/ppc/mach-mpc85xx/fdt.c
index 65de6f1104..fd919a56e7 100644
--- a/arch/ppc/mach-mpc85xx/fdt.c
+++ b/arch/ppc/mach-mpc85xx/fdt.c
@@ -89,7 +89,7 @@ error:
return -ENODEV;
}
-static int fdt_cpu_setup(struct device_node *blob)
+static int fdt_cpu_setup(struct device_node *blob, void *unused)
{
struct device_node *node;
struct sys_info sysinfo;
@@ -139,6 +139,6 @@ static int fdt_cpu_setup(struct device_node *blob)
static int of_register_mpc85xx_fixup(void)
{
- return of_register_fixup(fdt_cpu_setup);
+ return of_register_fixup(fdt_cpu_setup, NULL);
}
late_initcall(of_register_mpc85xx_fixup);