summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/boards/bcm2835.rst10
-rw-r--r--arch/arm/boards/raspberry-pi/lowlevel.c66
-rw-r--r--arch/arm/boards/raspberry-pi/lowlevel.h9
-rw-r--r--arch/arm/boards/raspberry-pi/rpi-common.c86
-rw-r--r--arch/arm/configs/rpi_defconfig4
-rw-r--r--arch/arm/cpu/start.c8
-rw-r--r--arch/arm/dts/Makefile1
-rw-r--r--arch/arm/dts/bcm2837-rpi-3.dts9
-rw-r--r--arch/arm/dts/bcm2837-rpi-cm3.dts18
-rw-r--r--arch/arm/include/asm/barebox-arm.h1
-rw-r--r--arch/arm/mach-bcm283x/Kconfig26
-rw-r--r--arch/arm/mach-bcm283x/include/mach/debug_ll.h51
-rw-r--r--arch/arm/mach-bcm283x/include/mach/platform.h4
-rw-r--r--arch/arm/mach-highbank/include/mach/debug_ll.h2
-rw-r--r--arch/arm/mach-qemu/include/mach/debug_ll.h2
-rw-r--r--arch/arm/mach-versatile/include/mach/debug_ll.h2
-rw-r--r--arch/arm/mach-vexpress/include/mach/debug_ll.h2
-rw-r--r--common/Kconfig19
-rw-r--r--drivers/gpio/Kconfig4
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/mci/mci-bcm2835.c5
-rw-r--r--drivers/pinctrl/Kconfig10
-rw-r--r--drivers/pinctrl/Makefile1
-rw-r--r--drivers/pinctrl/pinctrl-bcm2835.c (renamed from drivers/gpio/gpio-bcm2835.c)52
-rw-r--r--drivers/watchdog/bcm2835_wdt.c5
-rw-r--r--images/Makefile.bcm283x6
-rw-r--r--include/debug_ll/ns16550.h56
-rw-r--r--include/debug_ll/pl011.h (renamed from arch/arm/include/asm/debug_ll_pl011.h)0
28 files changed, 404 insertions, 56 deletions
diff --git a/Documentation/boards/bcm2835.rst b/Documentation/boards/bcm2835.rst
index ea80d58348..e9ad1d4d57 100644
--- a/Documentation/boards/bcm2835.rst
+++ b/Documentation/boards/bcm2835.rst
@@ -30,5 +30,15 @@ Raspberry Pi
6. Turn board's power on.
+VideoCore firmware creates a device tree based on the entries in ``config.txt``. This file is available to the Barebox environment in the file ``/vc.dtb``. For example, to boot a kernel shipped with Raspbian::
+
+ bootm -o /vc.dtb /boot/kernel7.img
+
+VideoCore device tree also contains the kernel command-line that is constructed from ``cmdline.txt`` and other parameters internally determined by the VideoCore firmware. Normally in Barebox this command-line gets overwritten on boot by the Linux bootargs (see :ref:`booting_linux`).
+
+The original command-line from VideoCore device tree is available to the Barebox environment in the ``vc.bootargs`` global variable. For example, to append it to the Linux bootargs::
+
+ global linux.bootargs.vc="$global.vc.bootargs"
+
.. _Raspberry Pi firmware: https://codeload.github.com/raspberrypi/firmware/zip/80e1fbeb78f9df06701d28c0ed3a3060a3f557ef
.. _documentation for config.txt: https://www.raspberrypi.org/documentation/configuration/config-txt/
diff --git a/arch/arm/boards/raspberry-pi/lowlevel.c b/arch/arm/boards/raspberry-pi/lowlevel.c
index 34c9350920..4b64f5d1d7 100644
--- a/arch/arm/boards/raspberry-pi/lowlevel.c
+++ b/arch/arm/boards/raspberry-pi/lowlevel.c
@@ -3,33 +3,73 @@
#include <common.h>
#include <linux/sizes.h>
#include <mach/platform.h>
+#include <of.h>
-extern char __dtb_bcm2835_rpi_start[];
-ENTRY_FUNCTION(start_raspberry_pi1, r0, r1, r2)
+#include "lowlevel.h"
+
+static void copy_vc_fdt(void *dest, void *src, unsigned long max_size)
{
- void *fdt = __dtb_bcm2835_rpi_start + get_runtime_offset();
+ struct fdt_header *oftree_src = src;
+ struct fdt_header *oftree_dest = dest;
- arm_cpu_lowlevel_init();
+ unsigned long 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
+ * debugging. We can't print out anything this early */
+ oftree_dest->totalsize = cpu_to_be32(ENOMEM);
+ return;
+ }
- barebox_arm_entry(BCM2835_SDRAM_BASE, SZ_128M, fdt);
+ memmove(dest, src, size);
}
-extern char __dtb_bcm2836_rpi_2_start[];
-ENTRY_FUNCTION(start_raspberry_pi2, r0, r1, r2)
+/* Must be inline since stack isn't setup yet. */
+static inline void start_raspberry_pi(unsigned long memsize, void *fdt,
+ void *vc_fdt)
{
- void *fdt = __dtb_bcm2836_rpi_2_start + get_runtime_offset();
+ void *saved_vc_fdt;
+ unsigned long membase = BCM2835_SDRAM_BASE;
+
+ /* A pointer to the FDT created by VideoCore was passed to us in r2. We
+ * reserve some memory just above the region used for Basebox and copy
+ * this FDT there. We fetch it from there later in rpi_devices_init().*/
+ memsize -= VIDEOCORE_FDT_SZ;
arm_cpu_lowlevel_init();
- barebox_arm_entry(BCM2835_SDRAM_BASE, SZ_512M, fdt);
+ /* Copied from barebox_arm_entry(). We need stack here early
+ * for normal function calls to work. */
+ arm_setup_stack(arm_mem_stack_top(membase, membase + memsize) - 16);
+
+ fdt += get_runtime_offset();
+
+ saved_vc_fdt = (void *)(membase + memsize);
+ copy_vc_fdt(saved_vc_fdt, vc_fdt, VIDEOCORE_FDT_SZ);
+
+ barebox_arm_entry(membase, memsize, fdt);
+}
+
+extern char __dtb_bcm2835_rpi_start[];
+ENTRY_FUNCTION(start_raspberry_pi1, r0, r1, r2)
+{
+ start_raspberry_pi(SZ_128M, __dtb_bcm2835_rpi_start, (void *)r2);
+}
+
+extern char __dtb_bcm2836_rpi_2_start[];
+ENTRY_FUNCTION(start_raspberry_pi2, r0, r1, r2)
+{
+ start_raspberry_pi(SZ_512M, __dtb_bcm2836_rpi_2_start, (void *)r2);
}
extern char __dtb_bcm2837_rpi_3_start[];
ENTRY_FUNCTION(start_raspberry_pi3, r0, r1, r2)
{
- void *fdt = __dtb_bcm2837_rpi_3_start + get_runtime_offset();
-
- arm_cpu_lowlevel_init();
+ start_raspberry_pi(SZ_512M, __dtb_bcm2837_rpi_3_start, (void *)r2);
+}
- barebox_arm_entry(BCM2835_SDRAM_BASE, SZ_512M, fdt);
+extern char __dtb_bcm2837_rpi_cm3_start[];
+ENTRY_FUNCTION(start_raspberry_pi_cm3, r0, r1, r2)
+{
+ start_raspberry_pi(SZ_512M, __dtb_bcm2837_rpi_cm3_start, (void *)r2);
}
diff --git a/arch/arm/boards/raspberry-pi/lowlevel.h b/arch/arm/boards/raspberry-pi/lowlevel.h
new file mode 100644
index 0000000000..9ef9135b2d
--- /dev/null
+++ b/arch/arm/boards/raspberry-pi/lowlevel.h
@@ -0,0 +1,9 @@
+#ifndef __ARCH_ARM_BOARDS_LOWLEVEL_H__
+#define __ARCH_ARM_BOARDS_LOWLEVEL_H__
+
+#include <linux/sizes.h>
+
+#define VIDEOCORE_FDT_SZ SZ_1M
+#define VIDEOCORE_FDT_ERROR 0xdeadfeed
+
+#endif /* __ARCH_ARM_BOARDS_LOWLEVEL_H__ */
diff --git a/arch/arm/boards/raspberry-pi/rpi-common.c b/arch/arm/boards/raspberry-pi/rpi-common.c
index b5d16a15ca..60cea7f8e9 100644
--- a/arch/arm/boards/raspberry-pi/rpi-common.c
+++ b/arch/arm/boards/raspberry-pi/rpi-common.c
@@ -16,21 +16,28 @@
#include <common.h>
#include <init.h>
#include <fs.h>
+#include <of.h>
#include <linux/stat.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <envfs.h>
#include <malloc.h>
+#include <libfile.h>
#include <gpio.h>
#include <net.h>
#include <led.h>
#include <asm/armlinux.h>
+#include <asm/barebox-arm.h>
#include <generated/mach-types.h>
+#include <linux/sizes.h>
+#include <globalvar.h>
#include <mach/core.h>
#include <mach/mbox.h>
+#include <mach/platform.h>
#include "rpi.h"
+#include "lowlevel.h"
struct msg_get_arm_mem {
struct bcm2835_mbox_hdr hdr;
@@ -314,10 +321,6 @@ static int rpi_clock_init(void)
}
postconsole_initcall(rpi_clock_init);
-#define BCM2835_PL011_BASE 0x20201000
-#define BCM2836_PL011_BASE 0x3f201000
-#define BCM2836_MINIUART_BASE 0x3f215040
-
static int rpi_console_clock_init(void)
{
struct clk *clk;
@@ -370,12 +373,87 @@ static int rpi_env_init(void)
return 0;
}
+/* Extract /chosen/bootargs from the VideoCore FDT into vc.bootargs
+ * global variable. */
+static int rpi_vc_fdt_bootargs(void *fdt)
+{
+ int ret = 0;
+ struct device_node *root = NULL, *node;
+ const char *cmdline;
+
+ root = of_unflatten_dtb(fdt);
+ if (IS_ERR(root)) {
+ ret = PTR_ERR(root);
+ root = NULL;
+ goto out;
+ }
+
+ node = of_find_node_by_path_from(root, "/chosen");
+ if (!node) {
+ pr_err("no /chosen node\n");
+ ret = -ENOENT;
+ goto out;
+ }
+
+ cmdline = of_get_property(node, "bootargs", NULL);
+ if (!cmdline) {
+ pr_err("no bootargs property in the /chosen node\n");
+ ret = -ENOENT;
+ goto out;
+ }
+
+ globalvar_add_simple("vc.bootargs", cmdline);
+
+out:
+ if (root)
+ of_delete_node(root);
+
+ return ret;
+}
+
+static void rpi_vc_fdt(void)
+{
+ void *saved_vc_fdt;
+ struct fdt_header *oftree;
+ unsigned long magic, size;
+ int ret;
+
+ /* VideoCore FDT was copied in PBL just above Barebox memory */
+ saved_vc_fdt = (void *)(arm_mem_endmem_get());
+
+ 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) {
+ pr_err("there was an error copying fdt in pbl: %d\n",
+ be32_to_cpu(oftree->totalsize));
+ }
+ return;
+ }
+
+ size = be32_to_cpu(oftree->totalsize);
+ if (write_file("/vc.dtb", saved_vc_fdt, size)) {
+ pr_err("failed to save videocore fdt to a file\n");
+ return;
+ }
+
+ ret = rpi_vc_fdt_bootargs(saved_vc_fdt);
+ if (ret) {
+ pr_err("failed to extract bootargs from videocore fdt: %d\n",
+ ret);
+ return;
+ }
+}
+
static int rpi_devices_init(void)
{
rpi_model_init();
bcm2835_register_fb();
armlinux_set_architecture(MACH_TYPE_BCM2708);
rpi_env_init();
+ rpi_vc_fdt();
return 0;
}
late_initcall(rpi_devices_init);
diff --git a/arch/arm/configs/rpi_defconfig b/arch/arm/configs/rpi_defconfig
index dc5ab1fe17..f167625c96 100644
--- a/arch/arm/configs/rpi_defconfig
+++ b/arch/arm/configs/rpi_defconfig
@@ -71,8 +71,8 @@ CONFIG_LED_GPIO=y
CONFIG_LED_TRIGGERS=y
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_BCM2835=y
-CONFIG_GPIO_BCM283X=y
-# CONFIG_PINCTRL is not set
+CONFIG_PINCTRL=y
+CONFIG_PINCTRL_BCM283X=y
CONFIG_REGULATOR=y
CONFIG_FS_EXT4=y
CONFIG_FS_FAT=y
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 768fa9e1b2..6573c2ef74 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -38,6 +38,7 @@
unsigned long arm_stack_top;
static unsigned long arm_barebox_size;
+static unsigned long arm_endmem;
static void *barebox_boarddata;
static unsigned long barebox_boarddata_size;
@@ -131,6 +132,12 @@ unsigned long arm_mem_ramoops_get(void)
}
EXPORT_SYMBOL_GPL(arm_mem_ramoops_get);
+unsigned long arm_mem_endmem_get(void)
+{
+ return arm_endmem;
+}
+EXPORT_SYMBOL_GPL(arm_mem_endmem_get);
+
static int barebox_memory_areas_init(void)
{
if(barebox_boarddata)
@@ -163,6 +170,7 @@ __noreturn void barebox_non_pbl_start(unsigned long membase,
pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
+ arm_endmem = endmem;
arm_stack_top = arm_mem_stack_top(membase, endmem);
arm_barebox_size = barebox_size;
malloc_end = barebox_base;
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 917a1eb0b7..f989df6b0c 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -76,6 +76,7 @@ pbl-dtb-$(CONFIG_MACH_REALQ7) += imx6q-dmo-edmqmx6.dtb.o
pbl-dtb-$(CONFIG_MACH_RPI) += bcm2835-rpi.dtb.o
pbl-dtb-$(CONFIG_MACH_RPI2) += bcm2836-rpi-2.dtb.o
pbl-dtb-$(CONFIG_MACH_RPI3) += bcm2837-rpi-3.dtb.o
+pbl-dtb-$(CONFIG_MACH_RPI_CM3) += bcm2837-rpi-cm3.dtb.o
pbl-dtb-$(CONFIG_MACH_SABRELITE) += imx6q-sabrelite.dtb.o imx6dl-sabrelite.dtb.o
pbl-dtb-$(CONFIG_MACH_SABRESD) += imx6q-sabresd.dtb.o
pbl-dtb-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB) += imx6sx-sdb.dtb.o
diff --git a/arch/arm/dts/bcm2837-rpi-3.dts b/arch/arm/dts/bcm2837-rpi-3.dts
index 194b41c23b..51883613ce 100644
--- a/arch/arm/dts/bcm2837-rpi-3.dts
+++ b/arch/arm/dts/bcm2837-rpi-3.dts
@@ -9,3 +9,12 @@
reg = <0x0 0x0>;
};
};
+
+&sdhci {
+ pinctrl-0 = <&emmc_gpio48>;
+ /delete-node/ wifi@1;
+};
+
+&sdhost {
+ status = "disabled";
+};
diff --git a/arch/arm/dts/bcm2837-rpi-cm3.dts b/arch/arm/dts/bcm2837-rpi-cm3.dts
new file mode 100644
index 0000000000..cfbffe175f
--- /dev/null
+++ b/arch/arm/dts/bcm2837-rpi-cm3.dts
@@ -0,0 +1,18 @@
+#include <arm/bcm2837-rpi-cm3-io3.dts>
+
+/ {
+ chosen {
+ stdout-path = &uart0;
+ };
+
+ memory {
+ reg = <0x0 0x0>;
+ };
+};
+
+&sdhci {
+ pinctrl-0 = <&emmc_gpio48>;
+ no-sd;
+ non-removable;
+ status = "okay";
+};
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h
index e065b479e3..a11d34923d 100644
--- a/arch/arm/include/asm/barebox-arm.h
+++ b/arch/arm/include/asm/barebox-arm.h
@@ -86,6 +86,7 @@ static inline void boarddata_create(void *adr, u32 machine)
u32 barebox_arm_machine(void);
unsigned long arm_mem_ramoops_get(void);
+unsigned long arm_mem_endmem_get(void);
struct barebox_arm_boarddata_compressed_dtb {
#define BAREBOX_ARM_BOARDDATA_COMPRESSED_DTB_MAGIC 0x7b66bcbd
diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig
index af2f88c47a..9d6a7b2ec2 100644
--- a/arch/arm/mach-bcm283x/Kconfig
+++ b/arch/arm/mach-bcm283x/Kconfig
@@ -25,26 +25,12 @@ config MACH_RPI3
select MACH_RPI_COMMON
select ARM_SECURE_MONITOR
-endmenu
-
-config MACH_RPI_DEBUG_UART_BASE
- hex
- default 0x20201000 if MACH_RPI_DEBUG_UART_RPI
- default 0x3f201000 if MACH_RPI_DEBUG_UART_RPI2
-
-if DEBUG_LL
-
-choice
- prompt "Lowlevel debug UART"
-
-config MACH_RPI_DEBUG_UART_RPI
- bool "use RaspberryPi 1 compatible base"
-
-config MACH_RPI_DEBUG_UART_RPI2
- bool "use RaspberryPi 2 and 3 compatible base"
-
-endchoice
+config MACH_RPI_CM3
+ bool "RaspberryPi Compute Module 3 (BCM2837/CORTEX-A53)"
+ select CPU_V7
+ select MACH_RPI_COMMON
+ select ARM_SECURE_MONITOR
-endif
+endmenu
endif
diff --git a/arch/arm/mach-bcm283x/include/mach/debug_ll.h b/arch/arm/mach-bcm283x/include/mach/debug_ll.h
index a625a8bdb7..99c59d011b 100644
--- a/arch/arm/mach-bcm283x/include/mach/debug_ll.h
+++ b/arch/arm/mach-bcm283x/include/mach/debug_ll.h
@@ -20,12 +20,53 @@
#include <mach/platform.h>
-#ifndef CONFIG_MACH_RPI_DEBUG_UART_BASE
-#define CONFIG_MACH_RPI_DEBUG_UART_BASE 0
-#endif
+#ifdef CONFIG_DEBUG_RPI1_UART
+
+static inline void debug_ll_init(void)
+{
+ /* Configured by ROM */
+}
+
+#define DEBUG_LL_UART_ADDR BCM2835_PL011_BASE
+#include <debug_ll/pl011.h>
+
+#elif defined CONFIG_DEBUG_RPI2_3_UART
+
+static inline void debug_ll_init(void)
+{
+ /* Configured by ROM */
+}
+
+#define DEBUG_LL_UART_ADDR BCM2836_PL011_BASE
+#include <debug_ll/pl011.h>
+
+#elif defined CONFIG_DEBUG_RPI3_MINI_UART
-#define DEBUG_LL_UART_ADDR CONFIG_MACH_RPI_DEBUG_UART_BASE
+static inline uint8_t debug_ll_read_reg(int reg)
+{
+ return readb(BCM2836_MINIUART_BASE + (reg << 2));
+}
-#include <asm/debug_ll_pl011.h>
+static inline void debug_ll_write_reg(int reg, uint8_t val)
+{
+ writeb(val, BCM2836_MINIUART_BASE + (reg << 2));
+}
+
+#define BCM2836_AUX_CLOCK_ENB 0x3f215004 /* BCM2835 AUX Clock enable register */
+#define BCM2836_AUX_CLOCK_EN_UART BIT(0) /* Bit 0 enables the Miniuart */
+
+#include <debug_ll/ns16550.h>
+
+static inline void debug_ll_init(void)
+{
+ uint16_t divisor;
+
+ writeb(BCM2836_AUX_CLOCK_EN_UART, BCM2836_AUX_CLOCK_ENB);
+
+ divisor = debug_ll_ns16550_calc_divisor(250000000 * 2);
+ debug_ll_ns16550_init(divisor);
+}
+
+#endif
#endif /* __MACH_BCM2835_DEBUG_LL_H__ */
diff --git a/arch/arm/mach-bcm283x/include/mach/platform.h b/arch/arm/mach-bcm283x/include/mach/platform.h
index 80b529a46f..d8561c1610 100644
--- a/arch/arm/mach-bcm283x/include/mach/platform.h
+++ b/arch/arm/mach-bcm283x/include/mach/platform.h
@@ -30,6 +30,10 @@
#define BCM2835_CACHELINE_SIZE 64
+#define BCM2835_PL011_BASE 0x20201000
+#define BCM2836_PL011_BASE 0x3f201000
+#define BCM2836_MINIUART_BASE 0x3f215040
+
#endif
/* END */
diff --git a/arch/arm/mach-highbank/include/mach/debug_ll.h b/arch/arm/mach-highbank/include/mach/debug_ll.h
index 1820eb1d13..5d0fae80e7 100644
--- a/arch/arm/mach-highbank/include/mach/debug_ll.h
+++ b/arch/arm/mach-highbank/include/mach/debug_ll.h
@@ -9,6 +9,6 @@
#define DEBUG_LL_UART_ADDR 0xfff36000
-#include <asm/debug_ll_pl011.h>
+#include <debug_ll/pl011.h>
#endif
diff --git a/arch/arm/mach-qemu/include/mach/debug_ll.h b/arch/arm/mach-qemu/include/mach/debug_ll.h
index 89b06923ad..d59f68ea19 100644
--- a/arch/arm/mach-qemu/include/mach/debug_ll.h
+++ b/arch/arm/mach-qemu/include/mach/debug_ll.h
@@ -19,6 +19,6 @@
#define DEBUG_LL_UART_ADDR DEBUG_LL_PHYS_BASE_RS1
#endif
-#include <asm/debug_ll_pl011.h>
+#include <debug_ll/pl011.h>
#endif
diff --git a/arch/arm/mach-versatile/include/mach/debug_ll.h b/arch/arm/mach-versatile/include/mach/debug_ll.h
index e6ee877a54..073402c51a 100644
--- a/arch/arm/mach-versatile/include/mach/debug_ll.h
+++ b/arch/arm/mach-versatile/include/mach/debug_ll.h
@@ -18,6 +18,6 @@
#define DEBUG_LL_UART_ADDR 0x101F1000
-#include <asm/debug_ll_pl011.h>
+#include <debug_ll/pl011.h>
#endif
diff --git a/arch/arm/mach-vexpress/include/mach/debug_ll.h b/arch/arm/mach-vexpress/include/mach/debug_ll.h
index 89b06923ad..d59f68ea19 100644
--- a/arch/arm/mach-vexpress/include/mach/debug_ll.h
+++ b/arch/arm/mach-vexpress/include/mach/debug_ll.h
@@ -19,6 +19,6 @@
#define DEBUG_LL_UART_ADDR DEBUG_LL_PHYS_BASE_RS1
#endif
-#include <asm/debug_ll_pl011.h>
+#include <debug_ll/pl011.h>
#endif
diff --git a/common/Kconfig b/common/Kconfig
index 53052c9cc1..5abe488db4 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -1159,7 +1159,26 @@ config DEBUG_SOCFPGA_UART1
Say Y here if you want kernel low-level debugging support
on SOCFPGA(Arria 10) based platforms.
+config DEBUG_RPI1_UART
+ bool "RaspberryPi 1 PL011 UART"
+ depends on ARCH_BCM283X
+ help
+ Say Y here if you want low-level debugging support on
+ RaspberryPi 1 boards.
+
+config DEBUG_RPI2_3_UART
+ bool "RaspberryPi 2/3 PL011 UART"
+ depends on ARCH_BCM283X
+ help
+ Say Y here if you want low-level debugging support on
+ RaspberryPi 2 and 3 boards.
+config DEBUG_RPI3_MINI_UART
+ bool "RaspberryPi 3 mini UART"
+ depends on ARCH_BCM283X
+ help
+ Say Y here if you want low-level debugging support on
+ RaspberryPi 3 board mini UART.
endchoice
config DEBUG_IMX_UART_PORT
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index ed93e868ae..c535904ed0 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -21,10 +21,6 @@ config GPIO_74164
shift registers. This driver can be used to provide access
to more gpio outputs.
-config GPIO_BCM283X
- bool "GPIO support for BCM283X"
- depends on ARCH_BCM283X
-
config GPIO_CLPS711X
bool "GPIO support for CLPS711X"
depends on ARCH_CLPS711X
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index f5ed876d5e..52280f0bb4 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -2,7 +2,6 @@ obj-$(CONFIG_GPIOLIB) += gpiolib.o
obj-$(CONFIG_GPIO_74164) += gpio-74164.o
obj-$(CONFIG_MACH_MIPS_ATH79) += gpio-ath79.o
-obj-$(CONFIG_GPIO_BCM283X) += gpio-bcm2835.o
obj-$(CONFIG_GPIO_DAVINCI) += gpio-davinci.o
obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o
obj-$(CONFIG_GPIO_DIGIC) += gpio-digic.o
diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c
index 9438e66af0..2ed1251672 100644
--- a/drivers/mci/mci-bcm2835.c
+++ b/drivers/mci/mci-bcm2835.c
@@ -506,6 +506,9 @@ static int bcm2835_mci_probe(struct device_d *hw_dev)
host->mci.hw_dev = hw_dev;
host->hw_dev = hw_dev;
host->max_clock = clk_get_rate(clk);
+
+ mci_of_parse(&host->mci);
+
iores = dev_request_mem_resource(hw_dev, 0);
if (IS_ERR(iores)) {
dev_err(host->hw_dev, "Failed request mem region, aborting...\n");
@@ -561,4 +564,4 @@ static int bcm2835_mci_add(void)
{
return platform_driver_register(&bcm2835_mci_driver);
}
-coredevice_initcall(bcm2835_mci_add);
+device_initcall(bcm2835_mci_add);
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 12fff4f010..45c3b351d6 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -1,3 +1,5 @@
+menu "Pin controllers"
+
config PINCTRL
bool "Pin controller core support"
default y if OFDEVICE
@@ -15,6 +17,12 @@ config PINCTRL_AT91
help
The pinmux controller found on AT91 SoCs.
+config PINCTRL_BCM283X
+ bool "GPIO and pinmux support for BCM283X"
+ depends on ARCH_BCM283X
+ help
+ The pinmux controller on BCM2835
+
config PINCTRL_IMX_IOMUX_V1
bool
help
@@ -83,3 +91,5 @@ config PINCTRL_VF610
help
Pinmux controller found on Vybrid VF610 family of SoCs
endif
+
+endmenu
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 9450dbbdf5..35b2d4707c 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_PINCTRL) += pinctrl.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
+obj-$(CONFIG_PINCTRL_BCM283X) += pinctrl-bcm2835.o
obj-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o
obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o
obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o
diff --git a/drivers/gpio/gpio-bcm2835.c b/drivers/pinctrl/pinctrl-bcm2835.c
index 1802ab7ccb..5fd5740e81 100644
--- a/drivers/gpio/gpio-bcm2835.c
+++ b/drivers/pinctrl/pinctrl-bcm2835.c
@@ -1,7 +1,9 @@
/*
* Author: Carlo Caione <carlo@carlocaione.org>
*
- * Based on linux/arch/arm/mach-bcm2708/bcm2708_gpio.c
+ * GPIO code based on linux/arch/arm/mach-bcm2708/bcm2708_gpio.c
+ *
+ * pinctrl part added by Tomaz Solc <tomaz.solc@tablix.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -21,6 +23,7 @@
#include <io.h>
#include <gpio.h>
#include <init.h>
+#include <pinctrl.h>
#define GPIOFSEL(x) (0x00+(x)*4)
#define GPIOSET(x) (0x1c+(x)*4)
@@ -46,6 +49,7 @@ enum {
struct bcm2835_gpio_chip {
void __iomem *base;
struct gpio_chip chip;
+ struct pinctrl_device pctl;
};
static int bcm2835_set_function(struct gpio_chip *chip, unsigned gpio, int function)
@@ -110,6 +114,39 @@ static struct gpio_ops bcm2835_gpio_ops = {
.set = bcm2835_gpio_set_value,
};
+static int bcm2835_pinctrl_set_state(struct pinctrl_device *pdev, struct device_node *np)
+{
+ const __be32 *list;
+ u32 function;
+ int i, size;
+
+ list = of_get_property(np, "brcm,pins", &size);
+ if (!list) {
+ return -EINVAL;
+ }
+
+ size /= sizeof(*list);
+
+ if (of_property_read_u32(np, "brcm,function", &function)) {
+ return -EINVAL;
+ }
+
+ for (i = 0; i < size; i++) {
+ int pin = be32_to_cpu(list[i]);
+ struct bcm2835_gpio_chip *bcmgpio = container_of(pdev, struct bcm2835_gpio_chip, pctl);
+
+ dev_dbg(pdev->dev, "set_state pin %d to function %d\n", pin, function);
+
+ bcm2835_set_function(&bcmgpio->chip, pin, function);
+ }
+
+ return 0;
+}
+
+static struct pinctrl_ops bcm2835_pinctrl_ops = {
+ .set_state = bcm2835_pinctrl_set_state,
+};
+
static int bcm2835_gpio_probe(struct device_d *dev)
{
struct resource *iores;
@@ -125,14 +162,27 @@ static int bcm2835_gpio_probe(struct device_d *dev)
bcmgpio->chip.base = 0;
bcmgpio->chip.ngpio = 54;
bcmgpio->chip.dev = dev;
+ bcmgpio->pctl.ops = &bcm2835_pinctrl_ops;
+ bcmgpio->pctl.dev = dev;
ret = gpiochip_add(&bcmgpio->chip);
if (ret) {
dev_err(dev, "couldn't add gpiochip, ret = %d\n", ret);
goto err;
}
+
dev_info(dev, "probed gpiochip%d with base %d\n", dev->id, bcmgpio->chip.base);
+ if (IS_ENABLED(CONFIG_PINCTRL)) {
+ ret = pinctrl_register(&bcmgpio->pctl);
+ if (ret) {
+ dev_err(dev, "couldn't add pinctrl, ret = %d\n", ret);
+ // don't free bcmgpio, since it's already used by gpiochip.
+ } else {
+ dev_dbg(dev, "bcm283x pinctrl registered\n");
+ }
+ }
+
return 0;
err:
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c
index d0c51ed9e9..781626fa0f 100644
--- a/drivers/watchdog/bcm2835_wdt.c
+++ b/drivers/watchdog/bcm2835_wdt.c
@@ -45,6 +45,10 @@
#define SECS_TO_WDOG_TICKS(x) ((x) << 16)
+/* Largest value where SECS_TO_WDOG_TICKS doesn't overflow 20 bits
+ * (PM_WDOG_TIME_SET) */
+#define WDOG_SECS_MAX 15
+
struct bcm2835_wd {
struct watchdog wd;
void __iomem *base;
@@ -101,6 +105,7 @@ static int bcm2835_wd_probe(struct device_d *dev)
}
priv->base = IOMEM(iores->start);
priv->wd.set_timeout = bcm2835_wd_set_timeout;
+ priv->wd.timeout_max = WDOG_SECS_MAX;
priv->wd.hwdev = dev;
priv->dev = dev;
diff --git a/images/Makefile.bcm283x b/images/Makefile.bcm283x
index 9199f153dc..3fd2c3d06a 100644
--- a/images/Makefile.bcm283x
+++ b/images/Makefile.bcm283x
@@ -12,4 +12,8 @@ image-$(CONFIG_MACH_RPI2) += barebox-raspberry-pi-2.img
pblb-$(CONFIG_MACH_RPI3) += start_raspberry_pi3
FILE_barebox-raspberry-pi-3.img = start_raspberry_pi3.pblb
-image-$(CONFIG_MACH_RPI3) += barebox-raspberry-pi-3.img \ No newline at end of file
+image-$(CONFIG_MACH_RPI3) += barebox-raspberry-pi-3.img
+
+pblb-$(CONFIG_MACH_RPI_CM3) += start_raspberry_pi_cm3
+FILE_barebox-raspberry-pi-cm3.img = start_raspberry_pi_cm3.pblb
+image-$(CONFIG_MACH_RPI_CM3) += barebox-raspberry-pi-cm3.img \ No newline at end of file
diff --git a/include/debug_ll/ns16550.h b/include/debug_ll/ns16550.h
new file mode 100644
index 0000000000..7e4dbeb453
--- /dev/null
+++ b/include/debug_ll/ns16550.h
@@ -0,0 +1,56 @@
+#ifndef __DEBUG_LL_NS16550_H
+#define __DEBUG_LL_NS16550_H
+
+/*
+ * Early debugging functions for the NS16550
+ * This file needs register access functions declared as:
+ *
+ * uint8_t debug_ll_read_reg(int reg);
+ * void debug_ll_write_reg(int reg, uint8_t val);
+ */
+#define NS16550_THR 0x0
+#define NS16550_RBR 0x0
+#define NS16550_DLL 0x0
+#define NS16550_IER 0x1
+#define NS16550_DLM 0x1
+#define NS16550_FCR 0x2
+#define NS16550_LCR 0x3
+#define NS16550_MCR 0x4
+#define NS16550_LSR 0x5
+
+#define NS16550_LCR_VAL 0x3 /* 8 data, 1 stop, no parity */
+#define NS16550_MCR_VAL 0x3 /* RTS/DTR */
+#define NS16550_FCR_VAL 0x7 /* Clear & enable FIFOs */
+
+#define NS16550_LSR_DR 0x01 /* UART received data present */
+#define NS16550_LSR_THRE 0x20 /* Xmit holding register empty */
+
+#define NS16550_LCR_BKSE 0x80 /* Bank select enable */
+
+static inline void PUTC_LL(char ch)
+{
+ while (!(debug_ll_read_reg(NS16550_LSR) & NS16550_LSR_THRE))
+ ;
+
+ debug_ll_write_reg(NS16550_THR, ch);
+}
+
+static inline uint16_t debug_ll_ns16550_calc_divisor(unsigned long clk)
+{
+ return clk / (115200 * 16);
+}
+
+static inline void debug_ll_ns16550_init(uint16_t divisor)
+{
+ debug_ll_write_reg(NS16550_LCR, 0x0); /* select ier reg */
+ debug_ll_write_reg(0x00, NS16550_IER);
+
+ debug_ll_write_reg(NS16550_LCR, NS16550_LCR_BKSE);
+ debug_ll_write_reg(NS16550_DLL, divisor & 0xff);
+ debug_ll_write_reg(NS16550_DLM, (divisor >> 8) & 0xff);
+ debug_ll_write_reg(NS16550_LCR, NS16550_LCR_VAL);
+ debug_ll_write_reg(NS16550_MCR, NS16550_MCR_VAL);
+ debug_ll_write_reg(NS16550_FCR, NS16550_FCR_VAL);
+}
+
+#endif
diff --git a/arch/arm/include/asm/debug_ll_pl011.h b/include/debug_ll/pl011.h
index db015a373b..db015a373b 100644
--- a/arch/arm/include/asm/debug_ll_pl011.h
+++ b/include/debug_ll/pl011.h