diff options
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 |