summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2020-01-15 07:58:30 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2020-01-15 07:58:30 +0100
commit56c313fe1751756ba978824798f61b4abe6ac49c (patch)
tree9e98f6bee10468f8b58667e41d2f3dc3e842477a /arch
parent38188906dce22189462cea0b23e67fd122e22dea (diff)
parent184050d9972b37557cdff40805ee04582c8e54e6 (diff)
downloadbarebox-56c313fe1751756ba978824798f61b4abe6ac49c.tar.gz
barebox-56c313fe1751756ba978824798f61b4abe6ac49c.tar.xz
Merge branch 'for-next/rpi'
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/boards/raspberry-pi/lowlevel.c9
-rw-r--r--arch/arm/boards/raspberry-pi/rpi-common.c21
-rw-r--r--arch/arm/configs/rpi_defconfig26
-rw-r--r--arch/arm/cpu/mmu-common.c33
-rw-r--r--arch/arm/cpu/mmu.c4
-rw-r--r--arch/arm/cpu/mmu_64.c4
-rw-r--r--arch/arm/mach-bcm283x/include/mach/mbox.h4
-rw-r--r--arch/arm/mach-bcm283x/mbox.c47
8 files changed, 114 insertions, 34 deletions
diff --git a/arch/arm/boards/raspberry-pi/lowlevel.c b/arch/arm/boards/raspberry-pi/lowlevel.c
index 70f1936522..d58beb6052 100644
--- a/arch/arm/boards/raspberry-pi/lowlevel.c
+++ b/arch/arm/boards/raspberry-pi/lowlevel.c
@@ -11,8 +11,15 @@ static void copy_vc_fdt(void *dest, void *src, unsigned long max_size)
{
struct fdt_header *oftree_src = src;
struct fdt_header *oftree_dest = dest;
+ unsigned long size;
- unsigned long size = be32_to_cpu(oftree_src->totalsize);
+ if (!src) {
+ oftree_dest->magic = cpu_to_be32(VIDEOCORE_FDT_ERROR);
+ oftree_dest->totalsize = cpu_to_be32(0);
+ return;
+ }
+
+ size = be32_to_cpu(oftree_src->totalsize);
if (size > max_size) {
oftree_dest->magic = cpu_to_be32(VIDEOCORE_FDT_ERROR);
/* Save an error code after the magic value for easier
diff --git a/arch/arm/boards/raspberry-pi/rpi-common.c b/arch/arm/boards/raspberry-pi/rpi-common.c
index dd6bbd5bdd..45961b52ee 100644
--- a/arch/arm/boards/raspberry-pi/rpi-common.c
+++ b/arch/arm/boards/raspberry-pi/rpi-common.c
@@ -21,6 +21,7 @@
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <envfs.h>
+#include <regulator.h>
#include <malloc.h>
#include <libfile.h>
#include <gpio.h>
@@ -433,13 +434,16 @@ static void rpi_vc_fdt(void)
oftree = saved_vc_fdt;
magic = be32_to_cpu(oftree->magic);
- if (magic != FDT_MAGIC) {
- pr_err("videocore fdt saved in pbl has invalid magic\n");
- if (magic == VIDEOCORE_FDT_ERROR) {
+ if (magic == VIDEOCORE_FDT_ERROR) {
+ if (oftree->totalsize)
pr_err("there was an error copying fdt in pbl: %d\n",
be32_to_cpu(oftree->totalsize));
- }
+ return;
+ }
+
+ if (magic != FDT_MAGIC) {
+ pr_err("videocore fdt saved in pbl has invalid magic\n");
return;
}
@@ -459,11 +463,20 @@ static void rpi_vc_fdt(void)
static int rpi_devices_init(void)
{
+ struct regulator *reg;
+
rpi_model_init();
bcm2835_register_fb();
armlinux_set_architecture(MACH_TYPE_BCM2708);
rpi_env_init();
rpi_vc_fdt();
+
+ reg = regulator_get_name("bcm2835_usb");
+ if (IS_ERR(reg))
+ return PTR_ERR(reg);
+
+ regulator_enable(reg);
+
return 0;
}
late_initcall(rpi_devices_init);
diff --git a/arch/arm/configs/rpi_defconfig b/arch/arm/configs/rpi_defconfig
index 0ae0c42b12..dd5ca7585a 100644
--- a/arch/arm/configs/rpi_defconfig
+++ b/arch/arm/configs/rpi_defconfig
@@ -2,6 +2,7 @@ CONFIG_ARCH_BCM283X=y
CONFIG_MACH_RPI=y
CONFIG_MACH_RPI2=y
CONFIG_MACH_RPI3=y
+CONFIG_MACH_RPI_CM3=y
CONFIG_AEABI=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
CONFIG_ARM_UNWIND=y
@@ -20,11 +21,15 @@ CONFIG_BOOTM_VERBOSE=y
CONFIG_BOOTM_INITRD=y
CONFIG_BOOTM_OFTREE=y
CONFIG_BLSPEC=y
+CONFIG_CONSOLE_ALLOW_COLOR=y
CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/raspberry-pi/env"
+CONFIG_CMD_DMESG=y
CONFIG_LONGHELP=y
CONFIG_CMD_IOMEM=y
+CONFIG_CMD_IMD=y
CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_REGULATOR=y
CONFIG_CMD_GO=y
CONFIG_CMD_LOADB=y
CONFIG_CMD_LOADY=y
@@ -32,17 +37,25 @@ CONFIG_CMD_RESET=y
CONFIG_CMD_UIMAGE=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_EXPORT=y
+CONFIG_CMD_DEFAULTENV=y
+CONFIG_CMD_LOADENV=y
CONFIG_CMD_PRINTENV=y
CONFIG_CMD_MAGICVAR=y
CONFIG_CMD_MAGICVAR_HELP=y
CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_CMP=y
CONFIG_CMD_FILETYPE=y
CONFIG_CMD_LN=y
CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_SHA1SUM=y
+CONFIG_CMD_SHA256SUM=y
CONFIG_CMD_UNCOMPRESS=y
CONFIG_CMD_LET=y
CONFIG_CMD_MSLEEP=y
CONFIG_CMD_SLEEP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_PING=y
CONFIG_CMD_ECHO_E=y
CONFIG_CMD_EDIT=y
CONFIG_CMD_LOGIN=y
@@ -57,26 +70,35 @@ CONFIG_CMD_MM=y
CONFIG_CMD_CLK=y
CONFIG_CMD_DETECT=y
CONFIG_CMD_GPIO=y
+CONFIG_CMD_LED=y
+CONFIG_CMD_LED_TRIGGER=y
CONFIG_CMD_WD=y
CONFIG_CMD_OF_NODE=y
CONFIG_CMD_OF_PROPERTY=y
CONFIG_CMD_OFTREE=y
CONFIG_CMD_TIME=y
+CONFIG_NET=y
CONFIG_SERIAL_AMBA_PL011=y
CONFIG_DRIVER_SERIAL_NS16550=y
+CONFIG_NET_USB=y
+CONFIG_NET_USB_SMSC95XX=y
+CONFIG_USB_HOST=y
+CONFIG_USB_DWC2_HOST=y
CONFIG_MCI=y
CONFIG_MCI_BCM283X=y
CONFIG_MCI_BCM283X_SDHOST=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
+CONFIG_LED_GPIO_OF=y
CONFIG_LED_TRIGGERS=y
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_BCM2835=y
+CONFIG_GPIO_RASPBERRYPI_EXP=y
CONFIG_PINCTRL_BCM283X=y
CONFIG_REGULATOR=y
CONFIG_FS_EXT4=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_NFS=y
CONFIG_FS_FAT=y
CONFIG_FS_FAT_WRITE=y
CONFIG_FS_FAT_LFN=y
-CONFIG_DIGEST_SHA1_GENERIC=y
-CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/cpu/mmu-common.c b/arch/arm/cpu/mmu-common.c
index aeefbb2daa..287622b203 100644
--- a/arch/arm/cpu/mmu-common.c
+++ b/arch/arm/cpu/mmu-common.c
@@ -11,9 +11,32 @@
#include "mmu.h"
+static inline dma_addr_t cpu_to_dma(struct device_d *dev, unsigned long cpu_addr)
+{
+ dma_addr_t dma_addr = cpu_addr;
+
+ if (dev)
+ dma_addr -= dev->dma_offset;
+
+ return dma_addr;
+}
+
+static inline unsigned long dma_to_cpu(struct device_d *dev, dma_addr_t addr)
+{
+ unsigned long cpu_addr = addr;
+
+ if (dev)
+ cpu_addr += dev->dma_offset;
+
+ return cpu_addr;
+}
+
void dma_sync_single_for_cpu(dma_addr_t address, size_t size,
enum dma_data_direction dir)
{
+ /*
+ * FIXME: This function needs a device argument to support non 1:1 mappings
+ */
if (dir != DMA_TO_DEVICE)
dma_inv_range((void *)address, size);
}
@@ -25,12 +48,14 @@ dma_addr_t dma_map_single(struct device_d *dev, void *ptr, size_t size,
dma_sync_single_for_device(addr, size, dir);
- return addr;
+ return cpu_to_dma(dev, addr);
}
-void dma_unmap_single(struct device_d *dev, dma_addr_t addr, size_t size,
+void dma_unmap_single(struct device_d *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction dir)
{
+ unsigned long addr = dma_to_cpu(dev, dma_addr);
+
dma_sync_single_for_cpu(addr, size, dir);
}
@@ -53,6 +78,10 @@ void *dma_alloc_map(size_t size, dma_addr_t *dma_handle, unsigned flags)
void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
{
+ /*
+ * FIXME: This function needs a device argument to support non 1:1 mappings
+ */
+
return dma_alloc_map(size, dma_handle, MAP_UNCACHED);
}
diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c
index 158b130b57..1f97c28ec6 100644
--- a/arch/arm/cpu/mmu.c
+++ b/arch/arm/cpu/mmu.c
@@ -491,6 +491,10 @@ void *dma_alloc_writecombine(size_t size, dma_addr_t *dma_handle)
void dma_sync_single_for_device(dma_addr_t address, size_t size,
enum dma_data_direction dir)
{
+ /*
+ * FIXME: This function needs a device argument to support non 1:1 mappings
+ */
+
if (dir == DMA_FROM_DEVICE) {
__dma_inv_range(address, address + size);
if (outer_cache.inv_range)
diff --git a/arch/arm/cpu/mmu_64.c b/arch/arm/cpu/mmu_64.c
index f7a13014af..98cd4c754e 100644
--- a/arch/arm/cpu/mmu_64.c
+++ b/arch/arm/cpu/mmu_64.c
@@ -245,6 +245,10 @@ void dma_flush_range(void *ptr, size_t size)
void dma_sync_single_for_device(dma_addr_t address, size_t size,
enum dma_data_direction dir)
{
+ /*
+ * FIXME: This function needs a device argument to support non 1:1 mappings
+ */
+
if (dir == DMA_FROM_DEVICE)
v8_inv_dcache_range(address, address + size - 1);
else
diff --git a/arch/arm/mach-bcm283x/include/mach/mbox.h b/arch/arm/mach-bcm283x/include/mach/mbox.h
index 6db961b807..f10f5bc148 100644
--- a/arch/arm/mach-bcm283x/include/mach/mbox.h
+++ b/arch/arm/mach-bcm283x/include/mach/mbox.h
@@ -126,6 +126,10 @@ struct bcm2835_mbox_tag_hdr {
*/
#define BCM2835_MBOX_TAG_GET_BOARD_REV 0x00010002
+#define BCM2835_MBOX_TAG_GET_GPIO_STATE 0x00030041
+#define BCM2835_MBOX_TAG_SET_GPIO_STATE 0x00038041
+#define BCM2835_MBOX_TAG_GET_GPIO_CONFIG 0x00030043
+#define BCM2835_MBOX_TAG_SET_GPIO_CONFIG 0x00038043
/*
* ids
diff --git a/arch/arm/mach-bcm283x/mbox.c b/arch/arm/mach-bcm283x/mbox.c
index b295993359..22abbb0ca5 100644
--- a/arch/arm/mach-bcm283x/mbox.c
+++ b/arch/arm/mach-bcm283x/mbox.c
@@ -6,6 +6,8 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#define pr_fmt(fmt) "rpi-mbox: " fmt
+
#include <clock.h>
#include <common.h>
#include <dma.h>
@@ -26,7 +28,7 @@ static int bcm2835_mbox_call_raw(u32 chan, struct bcm2835_mbox_hdr *buffer,
u32 val;
if (send & BCM2835_CHAN_MASK) {
- printf("mbox: Illegal mbox data 0x%08x\n", send);
+ pr_err("mbox: Illegal mbox data 0x%08x\n", send);
return -EINVAL;
}
@@ -35,8 +37,8 @@ static int bcm2835_mbox_call_raw(u32 chan, struct bcm2835_mbox_hdr *buffer,
val = readl(mbox_base + MAIL0_STA);
if (val & BCM2835_MBOX_STATUS_RD_EMPTY)
break;
- if (is_timeout(starttime, TIMEOUT)) {
- printf("mbox: Timeout draining stale responses\n");
+ if (is_timeout_non_interruptible(starttime, TIMEOUT)) {
+ pr_err("mbox: Timeout draining stale responses\n");
return -ETIMEDOUT;
}
val = readl(mbox_base + MAIL0_RD);
@@ -47,15 +49,15 @@ static int bcm2835_mbox_call_raw(u32 chan, struct bcm2835_mbox_hdr *buffer,
val = readl(mbox_base + MAIL0_STA);
if (!(val & BCM2835_MBOX_STATUS_WR_FULL))
break;
- if (is_timeout(starttime, TIMEOUT)) {
- printf("mbox: Timeout waiting for send space\n");
+ if (is_timeout_non_interruptible(starttime, TIMEOUT)) {
+ pr_err("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);
+ pr_debug("mbox: TX raw: 0x%08x\n", val);
dma_sync_single_for_device((unsigned long)send, buffer->buf_size,
DMA_BIDIRECTIONAL);
writel(val, mbox_base + MAIL1_WRT);
@@ -65,21 +67,21 @@ static int bcm2835_mbox_call_raw(u32 chan, struct bcm2835_mbox_hdr *buffer,
val = readl(mbox_base + MAIL0_STA);
if (!(val & BCM2835_MBOX_STATUS_RD_EMPTY))
break;
- if (is_timeout(starttime, TIMEOUT)) {
- printf("mbox: Timeout waiting for response\n");
+ if (is_timeout_non_interruptible(starttime, TIMEOUT)) {
+ pr_err("mbox: Timeout waiting for response\n");
return -ETIMEDOUT;
}
}
/* Read the response */
val = readl(mbox_base + MAIL0_RD);
- debug("mbox: RX raw: 0x%08x\n", val);
+ pr_debug("mbox: RX raw: 0x%08x\n", val);
dma_sync_single_for_cpu((unsigned long)send, buffer->buf_size,
DMA_BIDIRECTIONAL);
/* Validate the response */
if (BCM2835_MBOX_UNPACK_CHAN(val) != chan) {
- printf("mbox: Response channel mismatch\n");
+ pr_err("mbox: Response channel mismatch\n");
return -EIO;
}
@@ -89,7 +91,7 @@ static int bcm2835_mbox_call_raw(u32 chan, struct bcm2835_mbox_hdr *buffer,
}
#ifdef DEBUG
-void dump_buf(struct bcm2835_mbox_hdr *buffer)
+static void dump_buf(struct bcm2835_mbox_hdr *buffer)
{
u32 *p;
u32 words;
@@ -98,7 +100,11 @@ void dump_buf(struct bcm2835_mbox_hdr *buffer)
p = (u32 *)buffer;
words = buffer->buf_size / 4;
for (i = 0; i < words; i++)
- printf(" 0x%04x: 0x%08x\n", i * 4, p[i]);
+ pr_debug(" 0x%04x: 0x%08x\n", i * 4, p[i]);
+}
+#else
+static void dump_buf(struct bcm2835_mbox_hdr *buffer)
+{
}
#endif
@@ -109,27 +115,23 @@ int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer)
struct bcm2835_mbox_tag_hdr *tag;
int tag_index;
-#ifdef DEBUG
- printf("mbox: TX buffer\n");
+ pr_debug("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");
+ pr_err("mbox: Response buffer mismatch\n");
return -EIO;
}
-#ifdef DEBUG
- printf("mbox: RX buffer\n");
+ pr_debug("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");
+ pr_err("mbox: Header response code invalid\n");
return -EIO;
}
@@ -137,11 +139,6 @@ int bcm2835_mbox_call_prop(u32 chan, struct bcm2835_mbox_hdr *buffer)
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