[U-Boot] [PATCH 0/29] dm: Introduce device tree support in SPL (for Rockchip)

With driver model SPL support in place the remaining driver difference between U-Boot proper and SPL is that SPL does not support device tree. This series adds this support, using a Rockchip board as an example.
One problem with device tree is that U-Boot has no way of dropping features it does not need or use. For SPL this problem needs to be solved and this series uses the preprocessor for this. The 45KB Firefly device tree reduces to 693 bytes when unused material is removed. A better solution might involve the 'fdtgrep' tool but this has not made it into the device tree compiler as yet.
This series includes some changes aimed at reduce code size in SPL, including: - dropping alias sequence support (the aliases node) since many boards just use a single UART in SPL - adding a smaller panic() function that does not support printf()-format strings - removing device unbind code which will never be used in SPL
Overall the resulting SPL binary is 8829 bytes with my Linaro 4.8.2 compiler, including the device tree, using Thumb-2. Of this:
1768 bytes is driver model core code 1556 bytes is device tree code 693 bytes is the device tree itself 4756 is other code, including serial drivers, rodata and data
The last figure includes rodata incorrectly added by the tool chain [1]. With a bug-fixed gcc 4.9.2 the total size is 6893 bytes including device tree.
Approximately 750 bytes is used for strings and driver data (root device and serial) associated with driver model and device tree. This adds up an overhead of around 4750 bytes for driver model and device tree, including the code, rodata and device tree itself.
It should therefore be possible to use driver model and device tree in SPL for board that have enough SRAM. Clearly 4KB is impossible without further work (perhaps removing some error strings). I suspect 8KB would be tricky, allowing only 3KB for stack and other code. But 16KB should work OK.
SRAM sizes for recent SoCs I am aware of are:
Rockchip RK3288: 96KB Tegra 124: 128KB Samsung Exynos 5420: 384KB
The Rockchip Firefly was chosen for this work since it is a fairly recent board and is readily available. Rockchip engineers have been actively upstreaming code to Linux in the past year and there is a very full-featured U-Boot available. But it is invisible to most U-Boot people - mainline Rockchip support seems well overdue. This series does not make a serious start on that, since it only prints a message in SPL and then hangs, but additional work should get it booting to a prompt.
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54303
Simon Glass (29): serial: ns16550: Add an option to specify the debug UART register shift dm: ns16550: Support non-byte register spacing with driver model dm: ns16550: Support CONFIG_SYS_NS16550_MEM32 with driver model serial: ns16550: Remove unnecessary init on UART setup fdt: arm: Drop device tree padding dm: core: Allow sequence alias support to be removed for SPL dm: core: Remove unbind operations when not required dm: Add a panic_str() function to reduce code size dm: core: Drop device removal error path when not supported fdt: sandbox: Move setup code from board_f to fdtdec fdt: Rename setup_fdt() and make it prepare also Move initf_malloc() to a common place Correct malloc_limit value for pre-relocation malloc() fdt: Add an option to disable device tree in SPL dts: Disable device tree for SPL on all boards fdt: Allow FDT functions to be built for SPL dm: core: Select device tree control correctly for SPL dm: Init device tree as well as driver model in SPL dm: serial: Don't support CONFIG_CONS_INDEX with device tree Remove SPL undefine of CONFIG_OF_CONTROL fdt: arm: Build device tree in SPL dm: rockchip: Add serial support rockchip: Bring in RK3288 device tree file includes and bindings rockchip: dts: Adjust device tree files for U-Boot SPL rockchip: Add base SoC files rockchip: Add basic support for firefly-rk3288 mkimage: Display a better list of available image types rockchip: Add the beginnings of an image tool rockchip: Add a simple README
arch/arm/Kconfig | 11 + arch/arm/Makefile | 1 + arch/arm/cpu/armv7/exynos/Kconfig | 8 + arch/arm/cpu/armv7/s5pc1xx/Kconfig | 2 + arch/arm/cpu/u-boot-spl.lds | 2 +- arch/arm/dts/Makefile | 6 +- arch/arm/dts/rk3288-firefly.dts | 82 ++ arch/arm/dts/rk3288-firefly.dtsi | 496 +++++++ arch/arm/dts/rk3288-thermal.dtsi | 90 ++ arch/arm/dts/rk3288.dtsi | 1480 ++++++++++++++++++++ arch/arm/include/asm/arch-rockchip/clock.h | 12 + arch/arm/include/asm/arch-rockchip/gpio.h | 5 + arch/arm/include/asm/arch-rockchip/grf.h | 181 +++ arch/arm/mach-rockchip/Kconfig | 44 + arch/arm/mach-rockchip/Makefile | 12 + arch/arm/mach-rockchip/board-spl.c | 54 + arch/arm/mach-rockchip/board.c | 17 + arch/arm/mach-rockchip/common.c | 11 + arch/arm/mach-rockchip/rk3288/Kconfig | 16 + arch/arm/mach-tegra/Kconfig | 3 + arch/sandbox/cpu/cpu.c | 41 + arch/sandbox/include/asm/u-boot-sandbox.h | 8 + board/firefly/firefly-rk3288/Kconfig | 15 + board/firefly/firefly-rk3288/MAINTAINERS | 6 + board/firefly/firefly-rk3288/Makefile | 7 + board/firefly/firefly-rk3288/firefly-rk3288.c | 7 + common/board_f.c | 84 +- common/dlmalloc.c | 11 + common/image.c | 55 +- common/spl/spl.c | 22 +- configs/Linksprite_pcDuino3_fdt_defconfig | 1 + configs/am335x_boneblack_vboot_defconfig | 1 + configs/arches_defconfig | 1 + configs/canyonlands_defconfig | 1 + configs/firefly-rk3288_defconfig | 11 + configs/galileo_defconfig | 1 + configs/microblaze-generic_defconfig | 1 + configs/odroid_defconfig | 1 + configs/origen_defconfig | 1 + configs/s5pc210_universal_defconfig | 1 + configs/socfpga_socrates_defconfig | 1 + configs/trats2_defconfig | 1 + configs/trats_defconfig | 1 + configs/zynq_microzed_defconfig | 1 + configs/zynq_zc70x_defconfig | 1 + configs/zynq_zc770_xm010_defconfig | 1 + configs/zynq_zc770_xm012_defconfig | 1 + configs/zynq_zc770_xm013_defconfig | 1 + configs/zynq_zed_defconfig | 1 + configs/zynq_zybo_defconfig | 1 + doc/README.rockchip | 83 ++ .../clock/rockchip,rk3288-cru.txt | 61 + doc/device-tree-bindings/clock/rockchip.txt | 77 + .../pinctrl/rockchip,pinctrl.txt | 157 +++ .../thermal/rockchip-thermal.txt | 68 + drivers/core/Kconfig | 9 + drivers/core/Makefile | 2 + drivers/core/device.c | 54 +- drivers/core/root.c | 14 +- drivers/core/uclass.c | 4 + drivers/serial/Kconfig | 19 + drivers/serial/Makefile | 1 + drivers/serial/ns16550.c | 44 +- drivers/serial/serial-uclass.c | 69 +- drivers/serial/serial_rockchip.c | 41 + dts/Kconfig | 11 +- dts/Makefile | 9 +- include/config_uncmd_spl.h | 3 + include/configs/firefly-rk3288.h | 50 + include/dm/uclass-internal.h | 8 + include/dt-bindings/clock/rk3288-cru.h | 378 +++++ include/dt-bindings/clock/rockchip,rk808.h | 11 + include/dt-bindings/pinctrl/rockchip.h | 34 + include/dt-bindings/power-domain/rk3288.h | 11 + include/dt-bindings/thermal/thermal.h | 17 + include/fdtdec.h | 16 + include/image.h | 12 + include/malloc.h | 3 + include/vsprintf.h | 23 + lib/Makefile | 6 + lib/fdtdec.c | 39 +- lib/vsprintf.c | 23 +- scripts/Makefile.lib | 12 +- scripts/Makefile.spl | 35 + scripts/Makefile.uncmd_spl | 2 + tools/Makefile | 1 + tools/mkimage.c | 59 +- tools/rkimage.c | 63 + 88 files changed, 4136 insertions(+), 212 deletions(-) create mode 100644 arch/arm/dts/rk3288-firefly.dts create mode 100644 arch/arm/dts/rk3288-firefly.dtsi create mode 100644 arch/arm/dts/rk3288-thermal.dtsi create mode 100644 arch/arm/dts/rk3288.dtsi create mode 100644 arch/arm/include/asm/arch-rockchip/clock.h create mode 100644 arch/arm/include/asm/arch-rockchip/gpio.h create mode 100644 arch/arm/include/asm/arch-rockchip/grf.h create mode 100644 arch/arm/mach-rockchip/Kconfig create mode 100644 arch/arm/mach-rockchip/Makefile create mode 100644 arch/arm/mach-rockchip/board-spl.c create mode 100644 arch/arm/mach-rockchip/board.c create mode 100644 arch/arm/mach-rockchip/common.c create mode 100644 arch/arm/mach-rockchip/rk3288/Kconfig create mode 100644 board/firefly/firefly-rk3288/Kconfig create mode 100644 board/firefly/firefly-rk3288/MAINTAINERS create mode 100644 board/firefly/firefly-rk3288/Makefile create mode 100644 board/firefly/firefly-rk3288/firefly-rk3288.c create mode 100644 configs/firefly-rk3288_defconfig create mode 100644 doc/README.rockchip create mode 100644 doc/device-tree-bindings/clock/rockchip,rk3288-cru.txt create mode 100644 doc/device-tree-bindings/clock/rockchip.txt create mode 100644 doc/device-tree-bindings/pinctrl/rockchip,pinctrl.txt create mode 100644 doc/device-tree-bindings/thermal/rockchip-thermal.txt create mode 100644 drivers/serial/serial_rockchip.c create mode 100644 include/configs/firefly-rk3288.h create mode 100644 include/dt-bindings/clock/rk3288-cru.h create mode 100644 include/dt-bindings/clock/rockchip,rk808.h create mode 100644 include/dt-bindings/pinctrl/rockchip.h create mode 100644 include/dt-bindings/power-domain/rk3288.h create mode 100644 include/dt-bindings/thermal/thermal.h create mode 100644 tools/rkimage.c

This UART permits different register spacing. To support the debug UART on devices which have a spacing other than 1 byte, allow the shift value to be specified.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/serial/Kconfig | 10 ++++++++++ drivers/serial/ns16550.c | 25 +++++++++++++++---------- 2 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 1686a1f..54e6f26 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -66,6 +66,16 @@ config DEBUG_UART_CLOCK A default should be provided by your board, but if not you will need to use the correct value here.
+config DEBUG_UART_SHIFT + int "UART register shift" + depends on DEBUG_UART + default 0 if DEBUG_UART + help + Some UARTs (notably ns16550) support different register layouts + where the registers are spaced either as bytes, words or some other + value. Use this value to specify the shift to use, where 0=byte + registers, 2=32-bit word registers, etc. + config UNIPHIER_SERIAL bool "UniPhier on-chip UART support" depends on ARCH_UNIPHIER && DM_SERIAL diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index eb00f1c..54f432f 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -253,15 +253,20 @@ void debug_uart_init(void) */ baud_divisor = calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE); - - serial_out_shift(&com_port->ier, 0, CONFIG_SYS_NS16550_IER); - serial_out_shift(&com_port->mcr, 0, UART_MCRVAL); - serial_out_shift(&com_port->fcr, 0, UART_FCRVAL); - - serial_out_shift(&com_port->lcr, 0, UART_LCR_BKSE | UART_LCRVAL); - serial_out_shift(&com_port->dll, 0, baud_divisor & 0xff); - serial_out_shift(&com_port->dlm, 0, (baud_divisor >> 8) & 0xff); - serial_out_shift(&com_port->lcr, 0, UART_LCRVAL); + baud_divisor = 13; + serial_out_shift(&com_port->ier, CONFIG_DEBUG_UART_SHIFT, + CONFIG_SYS_NS16550_IER); + serial_out_shift(&com_port->mcr, CONFIG_DEBUG_UART_SHIFT, UART_MCRVAL); + serial_out_shift(&com_port->fcr, CONFIG_DEBUG_UART_SHIFT, UART_FCRVAL); + + serial_out_shift(&com_port->lcr, CONFIG_DEBUG_UART_SHIFT, + UART_LCR_BKSE | UART_LCRVAL); + serial_out_shift(&com_port->dll, CONFIG_DEBUG_UART_SHIFT, + baud_divisor & 0xff); + serial_out_shift(&com_port->dlm, CONFIG_DEBUG_UART_SHIFT, + (baud_divisor >> 8) & 0xff); + serial_out_shift(&com_port->lcr, CONFIG_DEBUG_UART_SHIFT, + UART_LCRVAL); }
static inline void _debug_uart_putc(int ch) @@ -270,7 +275,7 @@ static inline void _debug_uart_putc(int ch)
while (!(serial_in_shift(&com_port->lsr, 0) & UART_LSR_THRE)) ; - serial_out_shift(&com_port->thr, 0, ch); + serial_out_shift(&com_port->thr, CONFIG_DEBUG_UART_SHIFT, ch); }
DEBUG_UART_FUNCS

Allow this driver to support boards where the register shift is not 0. This fixes some compiler warnings which appear in that case.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/serial/ns16550.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 54f432f..cfa91e2 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -56,7 +56,7 @@ DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_DM_SERIAL
-static inline void serial_out_shift(unsigned char *addr, int shift, int value) +static inline void serial_out_shift(void *addr, int shift, int value) { #ifdef CONFIG_SYS_NS16550_PORT_MAPPED outb(value, (ulong)addr); @@ -71,7 +71,7 @@ static inline void serial_out_shift(unsigned char *addr, int shift, int value) #endif }
-static inline int serial_in_shift(unsigned char *addr, int shift) +static inline int serial_in_shift(void *addr, int shift) { #ifdef CONFIG_SYS_NS16550_PORT_MAPPED return inb((ulong)addr); @@ -113,9 +113,11 @@ static int ns16550_readb(NS16550_t port, int offset)
/* We can clean these up once everything is moved to driver model */ #define serial_out(value, addr) \ - ns16550_writeb(com_port, addr - (unsigned char *)com_port, value) + ns16550_writeb(com_port, \ + (unsigned char *)addr - (unsigned char *)com_port, value) #define serial_in(addr) \ - ns16550_readb(com_port, addr - (unsigned char *)com_port) + ns16550_readb(com_port, \ + (unsigned char *)addr - (unsigned char *)com_port) #endif
static inline int calc_divisor(NS16550_t port, int clock, int baudrate)

This option is used by some boards, so support it with driver model. This is really ugly - we should rewrite this driver once all users are moved to driver model.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/serial/ns16550.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index cfa91e2..eddd075 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -64,6 +64,8 @@ static inline void serial_out_shift(void *addr, int shift, int value) out_le32(addr, value); #elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN) out_be32(addr, value); +#elif defined(CONFIG_SYS_NS16550_MEM32) + writel(value, addr); #elif defined(CONFIG_SYS_BIG_ENDIAN) writeb(value, addr + (1 << shift) - 1); #else @@ -79,6 +81,8 @@ static inline int serial_in_shift(void *addr, int shift) return in_le32(addr); #elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN) return in_be32(addr); +#elif defined(CONFIG_SYS_NS16550_MEM32) + return readl(addr); #elif defined(CONFIG_SYS_BIG_ENDIAN) return readb(addr + (1 << reg_shift) - 1); #else @@ -91,7 +95,9 @@ static void ns16550_writeb(NS16550_t port, int offset, int value) struct ns16550_platdata *plat = port->plat; unsigned char *addr;
+#ifndef CONFIG_SYS_NS16550_MEM32 offset *= 1 << plat->reg_shift; +#endif addr = map_sysmem(plat->base, 0) + offset; /* * As far as we know it doesn't make sense to support selection of @@ -105,7 +111,9 @@ static int ns16550_readb(NS16550_t port, int offset) struct ns16550_platdata *plat = port->plat; unsigned char *addr;
+#ifndef CONFIG_SYS_NS16550_MEM32 offset *= 1 << plat->reg_shift; +#endif addr = map_sysmem(plat->base, 0) + offset;
return serial_in_shift(addr, plat->reg_shift);

It is not necessary to write a zero baud rate to the device, and for some chips this will cause problems. Drop this code.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/serial/ns16550.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index eddd075..6a3a989 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -182,7 +182,6 @@ void NS16550_init(NS16550_t com_port, int baud_divisor) defined(CONFIG_TI81XX) || defined(CONFIG_AM43XX) serial_out(0x7, &com_port->mdr1); /* mode select reset TL16C750*/ #endif - NS16550_setbrg(com_port, 0); serial_out(UART_MCRVAL, &com_port->mcr); serial_out(UART_FCRVAL, &com_port->fcr); if (baud_divisor != -1)

The 4KB padding doesn't seem necessary since we don't normally adjust the control device tree file within U-Boot.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/dts/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index fac16cc..121725e 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -53,7 +53,7 @@ dtb-$(CONFIG_SOCFPGA) += socfpga_cyclone5_socrates.dtb
targets += $(dtb-y)
-DTC_FLAGS += -R 4 -p 0x1000 +DTC_FLAGS += -R 4
PHONY += dtbs dtbs: $(addprefix $(obj)/, $(dtb-y))

Hi Simon,
2015-02-28 14:06 GMT+09:00 Simon Glass sjg@chromium.org:
The 4KB padding doesn't seem necessary since we don't normally adjust the control device tree file within U-Boot.
Signed-off-by: Simon Glass sjg@chromium.org
arch/arm/dts/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index fac16cc..121725e 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -53,7 +53,7 @@ dtb-$(CONFIG_SOCFPGA) += socfpga_cyclone5_socrates.dtb
targets += $(dtb-y)
-DTC_FLAGS += -R 4 -p 0x1000 +DTC_FLAGS += -R 4
PHONY += dtbs dtbs: $(addprefix $(obj)/, $(dtb-y))
I think "-R 4" is not necessary, either. We do not use the reserve map for OF_CONROL. This option was also introduced by commit bbb0b128c, but its git-description does not explain the reason for its necessity.
I vote for dropping "DTC_FLAGS += -R 4 -p 0x1000" line from
./arch/arm/dts/Makefile ./arch/powerpc/dts/Makefile ./arch/microblaze/dts/Makefile ./arch/sandbox/dts/Makefile ./arch/x86/dts/Makefile ./arch/arc/dts/Makefile

Hi Masahiro,
On 22 April 2015 at 23:40, Masahiro Yamada yamada.masahiro@socionext.com wrote:
Hi Simon,
2015-02-28 14:06 GMT+09:00 Simon Glass sjg@chromium.org:
The 4KB padding doesn't seem necessary since we don't normally adjust the control device tree file within U-Boot.
Signed-off-by: Simon Glass sjg@chromium.org
arch/arm/dts/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index fac16cc..121725e 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -53,7 +53,7 @@ dtb-$(CONFIG_SOCFPGA) += socfpga_cyclone5_socrates.dtb
targets += $(dtb-y)
-DTC_FLAGS += -R 4 -p 0x1000 +DTC_FLAGS += -R 4
PHONY += dtbs dtbs: $(addprefix $(obj)/, $(dtb-y))
I think "-R 4" is not necessary, either. We do not use the reserve map for OF_CONROL. This option was also introduced by commit bbb0b128c, but its git-description does not explain the reason for its necessity.
I vote for dropping "DTC_FLAGS += -R 4 -p 0x1000" line from
./arch/arm/dts/Makefile ./arch/powerpc/dts/Makefile ./arch/microblaze/dts/Makefile ./arch/sandbox/dts/Makefile ./arch/x86/dts/Makefile ./arch/arc/dts/Makefile
Agreed, thanks for spotting this. I'll work up a patch.
Regards, Simon

In many cases SPL only uses a single serial port and there is no need for alias sequence support. We will just use the serial port pointed to by stdout-path in the /chosen node.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/core/Kconfig | 9 +++++++++ drivers/core/device.c | 28 +++++++++++++++------------- include/config_uncmd_spl.h | 1 + 3 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 75d182d..2861b43 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -46,3 +46,12 @@ config DM_STDIO Normally serial drivers register with stdio so that they can be used as normal output devices. In SPL we don't normally use stdio, so we can omit this feature. + +config DM_SEQ_ALIAS + bool "Support numbered aliases in device tree" + depends on DM + default y + help + Most boards will have a '/aliases' node containing the path to + numbered devices (e.g. serial0 = &serial0). This feature can be + disabled if it is not required, to save code space in SPL. diff --git a/drivers/core/device.c b/drivers/core/device.c index 73c3e07..78c9525 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -55,21 +55,23 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name,
dev->seq = -1; dev->req_seq = -1; -#ifdef CONFIG_OF_CONTROL - /* - * Some devices, such as a SPI bus, I2C bus and serial ports are - * numbered using aliases. - * - * This is just a 'requested' sequence, and will be - * resolved (and ->seq updated) when the device is probed. - */ - if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) { - if (uc->uc_drv->name && of_offset != -1) { - fdtdec_get_alias_seq(gd->fdt_blob, uc->uc_drv->name, - of_offset, &dev->req_seq); + if (IS_ENABLED(CONFIG_OF_CONTROL) && IS_ENABLED(CONFIG_DM_SEQ_ALIAS)) { + /* + * Some devices, such as a SPI bus, I2C bus and serial ports + * are numbered using aliases. + * + * This is just a 'requested' sequence, and will be + * resolved (and ->seq updated) when the device is probed. + */ + if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) { + if (uc->uc_drv->name && of_offset != -1) { + fdtdec_get_alias_seq(gd->fdt_blob, + uc->uc_drv->name, of_offset, + &dev->req_seq); + } } } -#endif + if (!dev->platdata && drv->platdata_auto_alloc_size) { dev->flags |= DM_FLAG_ALLOC_PDATA; dev->platdata = calloc(1, drv->platdata_auto_alloc_size); diff --git a/include/config_uncmd_spl.h b/include/config_uncmd_spl.h index a9106f4..38cb0e8 100644 --- a/include/config_uncmd_spl.h +++ b/include/config_uncmd_spl.h @@ -31,6 +31,7 @@
#undef CONFIG_DM_WARN #undef CONFIG_DM_DEVICE_REMOVE +#undef CONFIG_DM_SEQ_ALIAS #undef CONFIG_DM_STDIO
#endif /* CONFIG_SPL_BUILD */

The CONFIG_DM_DEVICE_REMOVE option takes out code related to removing devices. It should also remove the 'unbind' code since if we cannot remove we probably don't need to unbind.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/core/uclass.c | 4 ++++ include/dm/uclass-internal.h | 8 ++++++++ 2 files changed, 12 insertions(+)
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 289a5d2..e8282d2 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -344,6 +344,7 @@ err: return ret; }
+#ifdef CONFIG_DM_DEVICE_REMOVE int uclass_unbind_device(struct udevice *dev) { struct uclass *uc; @@ -359,6 +360,7 @@ int uclass_unbind_device(struct udevice *dev) list_del(&dev->uclass_node); return 0; } +#endif
int uclass_resolve_seq(struct udevice *dev) { @@ -414,6 +416,7 @@ int uclass_post_probe_device(struct udevice *dev) return 0; }
+#ifdef CONFIG_DM_DEVICE_REMOVE int uclass_pre_remove_device(struct udevice *dev) { struct uclass_driver *uc_drv; @@ -435,3 +438,4 @@ int uclass_pre_remove_device(struct udevice *dev)
return 0; } +#endif diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h index f2f254a..4a492d6 100644 --- a/include/dm/uclass-internal.h +++ b/include/dm/uclass-internal.h @@ -41,7 +41,11 @@ int uclass_bind_device(struct udevice *dev); * @dev: Pointer to the device * #return 0 on success, -ve on error */ +#ifdef CONFIG_DM_DEVICE_REMOVE int uclass_unbind_device(struct udevice *dev); +#else +static inline int uclass_unbind_device(struct udevice *dev) { return 0; } +#endif
/** * uclass_pre_probe_child() - Deal with a child that is about to be probed @@ -73,7 +77,11 @@ int uclass_post_probe_device(struct udevice *dev); * @dev: Pointer to the device * #return 0 on success, -ve on error */ +#ifdef CONFIG_DM_DEVICE_REMOVE int uclass_pre_remove_device(struct udevice *dev); +#else +static inline int uclass_pre_remove_device(struct udevice *dev) { return 0; } +#endif
/** * uclass_find() - Find uclass by its id

The printf() in panic() adds about 1.5KB of code size to SPL when compiled with Thumb-2. Provide a smaller version that does not support printf()-style arguments and use it in two commonly compiled places.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/serial/serial-uclass.c | 2 +- include/vsprintf.h | 23 +++++++++++++++++++++++ lib/fdtdec.c | 8 +++++--- lib/vsprintf.c | 23 ++++++++++++++++++----- 4 files changed, 47 insertions(+), 9 deletions(-)
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 3fc7104..13ba606 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -72,7 +72,7 @@ static void serial_find_console_or_panic(void) if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) && uclass_get_device(UCLASS_SERIAL, INDEX, &dev) && (uclass_first_device(UCLASS_SERIAL, &dev) || !dev)) - panic("No serial driver found"); + panic_str("No serial driver found"); #undef INDEX gd->cur_serial_dev = dev; } diff --git a/include/vsprintf.h b/include/vsprintf.h index 5624482..09c8abd 100644 --- a/include/vsprintf.h +++ b/include/vsprintf.h @@ -39,10 +39,33 @@ int strict_strtoul(const char *cp, unsigned int base, unsigned long *res); unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base); long simple_strtol(const char *cp, char **endp, unsigned int base); + +/** + * panic() - Print a message and reset/hang + * + * Prints a message on the console(s) and then resets. If CONFIG_PANIC_HANG is + * defined, then it will hang instead of reseting. + * + * @param fmt: printf() format string for message, which should not include + * \n, followed by arguments + */ void panic(const char *fmt, ...) __attribute__ ((format (__printf__, 1, 2), noreturn));
/** + * panic_str() - Print a message and reset/hang + * + * Prints a message on the console(s) and then resets. If CONFIG_PANIC_HANG is + * defined, then it will hang instead of reseting. + * + * This function can be used instead of panic() when your board does not + * already use printf(), * to keep code size small. + * + * @param fmt: string to display, which should not include \n + */ +void panic_str(const char *str) __attribute__ ((noreturn)); + +/** * Format a string and place it in a buffer * * @param buf The buffer to place the result into diff --git a/lib/fdtdec.c b/lib/fdtdec.c index dd58bbb..cc5ba20 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -564,9 +564,11 @@ int fdtdec_prepare_fdt(void) { if (!gd->fdt_blob || ((uintptr_t)gd->fdt_blob & 3) || fdt_check_header(gd->fdt_blob)) { - printf("No valid FDT found - please append one to U-Boot " - "binary, use u-boot-dtb.bin or define " - "CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n"); +#ifdef CONFIG_SPL_BUILD + puts("Missing DTB\n"); +#else + puts("No valid device tree binary found - please append one to U-Boot binary, use u-boot-dtb.bin or define CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n"); +#endif return -1; } return 0; diff --git a/lib/vsprintf.c b/lib/vsprintf.c index e0f2648..bedc865 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -842,13 +842,11 @@ int sprintf(char *buf, const char *fmt, ...) return i; }
-void panic(const char *fmt, ...) +static void panic_finish(void) __attribute__ ((noreturn)); + +static void panic_finish(void) { - va_list args; - va_start(args, fmt); - vprintf(fmt, args); putc('\n'); - va_end(args); #if defined(CONFIG_PANIC_HANG) hang(); #else @@ -859,6 +857,21 @@ void panic(const char *fmt, ...) ; }
+void panic_str(const char *str) +{ + puts(str); + panic_finish(); +} + +void panic(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + panic_finish(); +} + void __assert_fail(const char *assertion, const char *file, unsigned line, const char *function) {

When CONFIG_DM_DEVICE_REMOVE is not enabled, such as in SPL, we cannot remove or unbind devices and do not expect to get errors when binding and probing devices. So drop the error path to reduce code size.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/core/device.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/core/device.c b/drivers/core/device.c index 78c9525..37dc882 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -124,21 +124,27 @@ int device_bind(struct udevice *parent, struct driver *drv, const char *name, return 0;
fail_child_post_bind: - if (drv->unbind && drv->unbind(dev)) { - dm_warn("unbind() method failed on dev '%s' on error path\n", - dev->name); + if (IS_ENABLED(DM_DEVICE_REMOVE)) { + if (drv->unbind && drv->unbind(dev)) { + dm_warn("unbind() method failed on dev '%s' on error path\n", + dev->name); + } }
fail_bind: - if (uclass_unbind_device(dev)) { - dm_warn("Failed to unbind dev '%s' on error path\n", - dev->name); + if (IS_ENABLED(DM_DEVICE_REMOVE)) { + if (uclass_unbind_device(dev)) { + dm_warn("Failed to unbind dev '%s' on error path\n", + dev->name); + } } fail_uclass_bind: - list_del(&dev->sibling_node); - if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) { - free(dev->parent_platdata); - dev->parent_platdata = NULL; + if (IS_ENABLED(DM_DEVICE_REMOVE)) { + list_del(&dev->sibling_node); + if (dev->flags & DM_FLAG_ALLOC_PARENT_PDATA) { + free(dev->parent_platdata); + dev->parent_platdata = NULL; + } } fail_alloc2: if (dev->flags & DM_FLAG_ALLOC_PDATA) {

We want to be able to set up the device tree in SPL, so move this code to a common place.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/sandbox/cpu/cpu.c | 41 +++++++++++++++++++ arch/sandbox/include/asm/u-boot-sandbox.h | 8 ++++ common/board_f.c | 67 +------------------------------ include/fdtdec.h | 6 +++ lib/fdtdec.c | 31 ++++++++++++++ 5 files changed, 88 insertions(+), 65 deletions(-)
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index 1aa397c..1e10452 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -6,6 +6,7 @@ #include <common.h> #include <dm/root.h> #include <os.h> +#include <asm/io.h> #include <asm/state.h>
DECLARE_GLOBAL_DATA_PTR; @@ -70,3 +71,43 @@ phys_addr_t map_to_sysmem(const void *ptr) void flush_dcache_range(unsigned long start, unsigned long stop) { } + +int sandbox_read_fdt_from_file(void) +{ + struct sandbox_state *state = state_get_current(); + const char *fname = state->fdt_fname; + void *blob; + loff_t size; + int err; + int fd; + + blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0); + if (!state->fdt_fname) { + err = fdt_create_empty_tree(blob, 256); + if (!err) + goto done; + printf("Unable to create empty FDT: %s\n", fdt_strerror(err)); + return -EINVAL; + } + + err = os_get_filesize(fname, &size); + if (err < 0) { + printf("Failed to file FDT file '%s'\n", fname); + return err; + } + fd = os_open(fname, OS_O_RDONLY); + if (fd < 0) { + printf("Failed to open FDT file '%s'\n", fname); + return -EACCES; + } + if (os_read(fd, blob, size) != size) { + os_close(fd); + return -EIO; + } + os_close(fd); + +done: + gd->fdt_blob = blob; + + return 0; +} diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h index 770ab5c..6802618 100644 --- a/arch/sandbox/include/asm/u-boot-sandbox.h +++ b/arch/sandbox/include/asm/u-boot-sandbox.h @@ -27,4 +27,12 @@ int cleanup_before_linux(void); /* drivers/video/sandbox_sdl.c */ int sandbox_lcd_sdl_early_init(void);
+/** + * sandbox_read_fdt_from_file() - Read a device tree from a file + * + * Read a device tree file from a host file and set it up for use as the + * control FDT. + */ +int sandbox_read_fdt_from_file(void); + #endif /* _U_BOOT_SANDBOX_H_ */ diff --git a/common/board_f.c b/common/board_f.c index 4d8b8a6..2499664 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -280,49 +280,6 @@ __weak int arch_cpu_init(void) return 0; }
-#ifdef CONFIG_OF_HOSTFILE - -static int read_fdt_from_file(void) -{ - struct sandbox_state *state = state_get_current(); - const char *fname = state->fdt_fname; - void *blob; - loff_t size; - int err; - int fd; - - blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0); - if (!state->fdt_fname) { - err = fdt_create_empty_tree(blob, 256); - if (!err) - goto done; - printf("Unable to create empty FDT: %s\n", fdt_strerror(err)); - return -EINVAL; - } - - err = os_get_filesize(fname, &size); - if (err < 0) { - printf("Failed to file FDT file '%s'\n", fname); - return err; - } - fd = os_open(fname, OS_O_RDONLY); - if (fd < 0) { - printf("Failed to open FDT file '%s'\n", fname); - return -EACCES; - } - if (os_read(fd, blob, size) != size) { - os_close(fd); - return -EIO; - } - os_close(fd); - -done: - gd->fdt_blob = blob; - - return 0; -} -#endif - #ifdef CONFIG_SANDBOX static int setup_ram_buf(void) { @@ -335,28 +292,6 @@ static int setup_ram_buf(void) } #endif
-static int setup_fdt(void) -{ -#ifdef CONFIG_OF_CONTROL -# ifdef CONFIG_OF_EMBED - /* Get a pointer to the FDT */ - gd->fdt_blob = __dtb_dt_begin; -# elif defined CONFIG_OF_SEPARATE - /* FDT is at end of image */ - gd->fdt_blob = (ulong *)&_end; -# elif defined(CONFIG_OF_HOSTFILE) - if (read_fdt_from_file()) { - puts("Failed to read control FDT\n"); - return -1; - } -# endif - /* Allow the early environment to override the fdt address */ - gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, - (uintptr_t)gd->fdt_blob); -#endif - return 0; -} - /* Get the top of usable RAM */ __weak ulong board_get_usable_ram_top(ulong total_size) { @@ -792,7 +727,9 @@ static init_fnc_t init_sequence_f[] = { setup_ram_buf, #endif setup_mon_len, +#ifdef CONFIG_OF_CONTROL setup_fdt, +#endif #ifdef CONFIG_TRACE trace_early_init, #endif diff --git a/include/fdtdec.h b/include/fdtdec.h index 1bc70db..ea92c2b 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -778,4 +778,10 @@ int fdt_get_named_resource(const void *fdt, int node, const char *property, int fdtdec_decode_memory_region(const void *blob, int node, const char *mem_type, const char *suffix, fdt_addr_t *basep, fdt_size_t *sizep); + +/** + * Set up the device tree ready for use + */ +int setup_fdt(void); + #endif diff --git a/lib/fdtdec.c b/lib/fdtdec.c index cc5ba20..4668217 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -9,6 +9,7 @@ #include <serial.h> #include <libfdt.h> #include <fdtdec.h> +#include <asm/sections.h> #include <linux/ctype.h>
DECLARE_GLOBAL_DATA_PTR; @@ -1036,4 +1037,34 @@ int fdtdec_decode_memory_region(const void *blob, int config_node,
return 0; } + +int setup_fdt(void) +{ +#ifdef CONFIG_OF_CONTROL +# ifdef CONFIG_OF_EMBED + /* Get a pointer to the FDT */ + gd->fdt_blob = __dtb_dt_begin; +# elif defined CONFIG_OF_SEPARATE +# ifdef CONFIG_SPL_BUILD + /* FDT is at end of BSS */ + gd->fdt_blob = (ulong *)&__bss_end; +# else + /* FDT is at end of image */ + gd->fdt_blob = (ulong *)&_end; +#endif +# elif defined(CONFIG_OF_HOSTFILE) + if (sandbox_read_fdt_from_file()) { + puts("Failed to read control FDT\n"); + return -1; + } +# endif +# ifndef CONFIG_SPL_BUILD + /* Allow the early environment to override the fdt address */ + gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, + (uintptr_t)gd->fdt_blob); +# endif #endif + return 0; +} + +#endif /* !USE_HOSTCC */

There is little reason to split these two functions. Bring them together which simplifies the init sequence.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/board_f.c | 5 +---- include/fdtdec.h | 2 +- lib/fdtdec.c | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/common/board_f.c b/common/board_f.c index 2499664..eab0050 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -728,7 +728,7 @@ static init_fnc_t init_sequence_f[] = { #endif setup_mon_len, #ifdef CONFIG_OF_CONTROL - setup_fdt, + fdtdec_setup, #endif #ifdef CONFIG_TRACE trace_early_init, @@ -740,9 +740,6 @@ static init_fnc_t init_sequence_f[] = { #endif arch_cpu_init, /* basic arch cpu dependent setup */ mark_bootstage, -#ifdef CONFIG_OF_CONTROL - fdtdec_check_fdt, -#endif initf_dm, #if defined(CONFIG_BOARD_EARLY_INIT_F) board_early_init_f, diff --git a/include/fdtdec.h b/include/fdtdec.h index ea92c2b..a49a184 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -782,6 +782,6 @@ int fdtdec_decode_memory_region(const void *blob, int node, /** * Set up the device tree ready for use */ -int setup_fdt(void); +int fdtdec_setup(void);
#endif diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 4668217..67b2f34 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1038,7 +1038,7 @@ int fdtdec_decode_memory_region(const void *blob, int config_node, return 0; }
-int setup_fdt(void) +int fdtdec_setup(void) { #ifdef CONFIG_OF_CONTROL # ifdef CONFIG_OF_EMBED @@ -1064,7 +1064,7 @@ int setup_fdt(void) (uintptr_t)gd->fdt_blob); # endif #endif - return 0; + return fdtdec_prepare_fdt(); }
#endif /* !USE_HOSTCC */

To allow this function to be used from SPL, move it to the malloc() code.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/board_f.c | 12 +----------- common/dlmalloc.c | 11 +++++++++++ include/malloc.h | 3 +++ 3 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/common/board_f.c b/common/board_f.c index eab0050..82b8a66 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -23,6 +23,7 @@ #include <i2c.h> #include <initcall.h> #include <logbuff.h> +#include <malloc.h>
/* TODO: Can we move these into arch/ headers? */ #ifdef CONFIG_8xx @@ -692,17 +693,6 @@ static int mark_bootstage(void) return 0; }
-static int initf_malloc(void) -{ -#ifdef CONFIG_SYS_MALLOC_F_LEN - assert(gd->malloc_base); /* Set up by crt0.S */ - gd->malloc_limit = gd->malloc_base + CONFIG_SYS_MALLOC_F_LEN; - gd->malloc_ptr = 0; -#endif - - return 0; -} - static int initf_dm(void) { #if defined(CONFIG_DM) && defined(CONFIG_SYS_MALLOC_F_LEN) diff --git a/common/dlmalloc.c b/common/dlmalloc.c index 6453ee9..741215b 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -3257,6 +3257,17 @@ int mALLOPt(param_number, value) int param_number; int value; } }
+int initf_malloc(void) +{ +#ifdef CONFIG_SYS_MALLOC_F_LEN + assert(gd->malloc_base); /* Set up by crt0.S */ + gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN; + gd->malloc_ptr = 0; +#endif + + return 0; +} + /*
History: diff --git a/include/malloc.h b/include/malloc.h index 5df6348..f4da9e6 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -906,6 +906,9 @@ void *realloc_simple(void *ptr, size_t size);
#endif
+/* Set up pre-relocation malloc() ready for use */ +int initf_malloc(void); + /* Public routines */
/* Simple versions which can be used when space is tight */

The limit is measured from the start of the malloc() area and is not an absolute address. Correct this.
Signed-off-by: Simon Glass sjg@chromium.org --- This bug has been there for a while but was not causing problems. I have been meaning to send a patch for a while.
common/spl/spl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/common/spl/spl.c b/common/spl/spl.c index cd75bbc..c655332 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -146,7 +146,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2) CONFIG_SYS_SPL_MALLOC_SIZE); gd->flags |= GD_FLG_FULL_MALLOC_INIT; #elif defined(CONFIG_SYS_MALLOC_F_LEN) - gd->malloc_limit = gd->malloc_base + CONFIG_SYS_MALLOC_F_LEN; + gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN; gd->malloc_ptr = 0; #endif #ifdef CONFIG_SPL_DM

Some boards cannot support device tree due to lack of memory. Add an option to allow these boards to continue to work (and even use driver model). This is a 'negative' option since most boards are expected to support device tree in SPL.
Signed-off-by: Simon Glass sjg@chromium.org ---
dts/Kconfig | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/dts/Kconfig b/dts/Kconfig index ca5bd6f..957f5c7 100644 --- a/dts/Kconfig +++ b/dts/Kconfig @@ -1,9 +1,6 @@ # # Device Tree Control # -# TODO: -# This feature is not currently supported for SPL, -# but this restriction should be removed in the future.
config SUPPORT_OF_CONTROL bool @@ -17,6 +14,14 @@ config OF_CONTROL This feature provides for run-time configuration of U-Boot via a flattened device tree.
+config SPL_DISABLE_OF_CONTROL + bool "Disable run-time configuration via Device Tree in SPL" + depends on OF_CONTROL + help + Some boards use device tree in U-Boot but only have 4KB of SRAM + which is not enough to support device tree. Enable this option to + allow such boards to be supported by U-Boot SPL. + choice prompt "Provider of DTB for DT control" depends on OF_CONTROL

We plan to enable device tree in SPL by default. Before doing this, explicitly disable it for all boards.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/Kconfig | 2 ++ arch/arm/cpu/armv7/exynos/Kconfig | 8 ++++++++ arch/arm/cpu/armv7/s5pc1xx/Kconfig | 2 ++ arch/arm/mach-tegra/Kconfig | 3 +++ configs/Linksprite_pcDuino3_fdt_defconfig | 1 + configs/am335x_boneblack_vboot_defconfig | 1 + configs/arches_defconfig | 1 + configs/canyonlands_defconfig | 1 + configs/galileo_defconfig | 1 + configs/microblaze-generic_defconfig | 1 + configs/odroid_defconfig | 1 + configs/origen_defconfig | 1 + configs/s5pc210_universal_defconfig | 1 + configs/socfpga_socrates_defconfig | 1 + configs/trats2_defconfig | 1 + configs/trats_defconfig | 1 + configs/zynq_microzed_defconfig | 1 + configs/zynq_zc70x_defconfig | 1 + configs/zynq_zc770_xm010_defconfig | 1 + configs/zynq_zc770_xm012_defconfig | 1 + configs/zynq_zc770_xm013_defconfig | 1 + configs/zynq_zed_defconfig | 1 + configs/zynq_zybo_defconfig | 1 + 23 files changed, 34 insertions(+)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7a2f91c..f0e6dec 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -597,6 +597,7 @@ config TEGRA select SUPPORT_SPL select SPL select OF_CONTROL + select SPL_DISABLE_OF_CONTROL select CPU_V7
config TARGET_VEXPRESS64_AEMV8A @@ -690,6 +691,7 @@ config ARCH_UNIPHIER select SUPPORT_SPL select SPL select OF_CONTROL + select SPL_DISABLE_OF_CONTROL
endchoice
diff --git a/arch/arm/cpu/armv7/exynos/Kconfig b/arch/arm/cpu/armv7/exynos/Kconfig index eb86a7f..46be502 100644 --- a/arch/arm/cpu/armv7/exynos/Kconfig +++ b/arch/arm/cpu/armv7/exynos/Kconfig @@ -7,6 +7,7 @@ config TARGET_SMDKV310 select SUPPORT_SPL bool "Exynos4210 SMDKV310 board" select OF_CONTROL + select SPL_DISABLE_OF_CONTROL
config TARGET_TRATS bool "Exynos4210 Trats board" @@ -27,6 +28,7 @@ config TARGET_ODROID config TARGET_ODROID_XU3 bool "Exynos5422 Odroid board" select OF_CONTROL + select SPL_DISABLE_OF_CONTROL
config TARGET_ARNDALE bool "Exynos5250 Arndale board" @@ -34,31 +36,37 @@ config TARGET_ARNDALE select CPU_V7_HAS_VIRT select SUPPORT_SPL select OF_CONTROL + select SPL_DISABLE_OF_CONTROL
config TARGET_SMDK5250 bool "SMDK5250 board" select SUPPORT_SPL select OF_CONTROL + select SPL_DISABLE_OF_CONTROL
config TARGET_SNOW bool "Snow board" select SUPPORT_SPL select OF_CONTROL + select SPL_DISABLE_OF_CONTROL
config TARGET_SMDK5420 bool "SMDK5420 board" select SUPPORT_SPL select OF_CONTROL + select SPL_DISABLE_OF_CONTROL
config TARGET_PEACH_PI bool "Peach Pi board" select SUPPORT_SPL select OF_CONTROL + select SPL_DISABLE_OF_CONTROL
config TARGET_PEACH_PIT bool "Peach Pit board" select SUPPORT_SPL select OF_CONTROL + select SPL_DISABLE_OF_CONTROL
endchoice
diff --git a/arch/arm/cpu/armv7/s5pc1xx/Kconfig b/arch/arm/cpu/armv7/s5pc1xx/Kconfig index bc73813..65cc9eb 100644 --- a/arch/arm/cpu/armv7/s5pc1xx/Kconfig +++ b/arch/arm/cpu/armv7/s5pc1xx/Kconfig @@ -6,10 +6,12 @@ choice config TARGET_S5P_GONI bool "S5P Goni board" select OF_CONTROL + select SPL_DISABLE_OF_CONTROL
config TARGET_SMDKC100 bool "Support smdkc100 board" select OF_CONTROL + select SPL_DISABLE_OF_CONTROL
endchoice
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index fccfd79..45b3148 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -47,6 +47,9 @@ config DM_I2C config DM_GPIO default y
+config SPL_DISABLE_OF_CONTROL + default y + source "arch/arm/mach-tegra/tegra20/Kconfig" source "arch/arm/mach-tegra/tegra30/Kconfig" source "arch/arm/mach-tegra/tegra114/Kconfig" diff --git a/configs/Linksprite_pcDuino3_fdt_defconfig b/configs/Linksprite_pcDuino3_fdt_defconfig index 1e749cd..cf9e090 100644 --- a/configs/Linksprite_pcDuino3_fdt_defconfig +++ b/configs/Linksprite_pcDuino3_fdt_defconfig @@ -6,6 +6,7 @@ CONFIG_DM_GPIO=y CONFIG_DM_SERIAL=y CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-pcduino3" CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_OF_SEPARATE=y +S:CONFIG_ARM=y +S:CONFIG_ARCH_SUNXI=y diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig index 51bf370..c241f47 100644 --- a/configs/am335x_boneblack_vboot_defconfig +++ b/configs/am335x_boneblack_vboot_defconfig @@ -3,6 +3,7 @@ CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT,ENABLE_VBOOT" +S:CONFIG_ARM=y +S:CONFIG_TARGET_AM335X_EVM=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="am335x-boneblack" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y diff --git a/configs/arches_defconfig b/configs/arches_defconfig index 30c6932..2af8446 100644 --- a/configs/arches_defconfig +++ b/configs/arches_defconfig @@ -4,4 +4,5 @@ CONFIG_TARGET_CANYONLANDS=y CONFIG_ARCHES=y CONFIG_DEFAULT_DEVICE_TREE="arches" CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_OF_SEPARATE=y diff --git a/configs/canyonlands_defconfig b/configs/canyonlands_defconfig index 44d4fbd..09172b1 100644 --- a/configs/canyonlands_defconfig +++ b/configs/canyonlands_defconfig @@ -4,4 +4,5 @@ CONFIG_TARGET_CANYONLANDS=y CONFIG_CANYONLANDS=y CONFIG_DEFAULT_DEVICE_TREE="canyonlands" CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_OF_EMBED=y diff --git a/configs/galileo_defconfig b/configs/galileo_defconfig index f208651..60704d6 100644 --- a/configs/galileo_defconfig +++ b/configs/galileo_defconfig @@ -2,5 +2,6 @@ CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0xfff10000" CONFIG_X86=y CONFIG_TARGET_GALILEO=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_OF_SEPARATE=y CONFIG_DEFAULT_DEVICE_TREE="galileo" diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 5cfd596..074d4bf 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -2,5 +2,6 @@ CONFIG_SPL=y +S:CONFIG_MICROBLAZE=y +S:CONFIG_TARGET_MICROBLAZE_GENERIC=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_OF_EMBED=y CONFIG_DEFAULT_DEVICE_TREE="microblaze-generic" diff --git a/configs/odroid_defconfig b/configs/odroid_defconfig index 816a3fa..4ae891c 100644 --- a/configs/odroid_defconfig +++ b/configs/odroid_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_ARCH_EXYNOS=y CONFIG_TARGET_ODROID=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="exynos4412-odroid" CONFIG_DM_I2C=y CONFIG_DM_I2C_COMPAT=y diff --git a/configs/origen_defconfig b/configs/origen_defconfig index 2a7f83b..e831817 100644 --- a/configs/origen_defconfig +++ b/configs/origen_defconfig @@ -3,4 +3,5 @@ CONFIG_SPL=y +S:CONFIG_ARCH_EXYNOS=y +S:CONFIG_TARGET_ORIGEN=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="exynos4210-origen" diff --git a/configs/s5pc210_universal_defconfig b/configs/s5pc210_universal_defconfig index cdce39f..3419704 100644 --- a/configs/s5pc210_universal_defconfig +++ b/configs/s5pc210_universal_defconfig @@ -2,4 +2,5 @@ CONFIG_ARM=y CONFIG_ARCH_EXYNOS=y CONFIG_TARGET_S5PC210_UNIVERSAL=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="exynos4210-universal_c210" diff --git a/configs/socfpga_socrates_defconfig b/configs/socfpga_socrates_defconfig index 888bbb6..f2ddc31 100644 --- a/configs/socfpga_socrates_defconfig +++ b/configs/socfpga_socrates_defconfig @@ -2,6 +2,7 @@ CONFIG_SPL=y +S:CONFIG_ARM=y +S:CONFIG_TARGET_SOCFPGA_CYCLONE5=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="socfpga_cyclone5_socrates" CONFIG_DM=y CONFIG_DM_SPI=y diff --git a/configs/trats2_defconfig b/configs/trats2_defconfig index 1b98b73..c285a68 100644 --- a/configs/trats2_defconfig +++ b/configs/trats2_defconfig @@ -2,4 +2,5 @@ CONFIG_ARM=y CONFIG_ARCH_EXYNOS=y CONFIG_TARGET_TRATS2=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="exynos4412-trats2" diff --git a/configs/trats_defconfig b/configs/trats_defconfig index 901a014..db71c9b 100644 --- a/configs/trats_defconfig +++ b/configs/trats_defconfig @@ -2,4 +2,5 @@ CONFIG_ARM=y CONFIG_ARCH_EXYNOS=y CONFIG_TARGET_TRATS=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="exynos4210-trats" diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig index 8b985fe..1fa47ab 100644 --- a/configs/zynq_microzed_defconfig +++ b/configs/zynq_microzed_defconfig @@ -3,6 +3,7 @@ CONFIG_SPL=y +S:CONFIG_ZYNQ=y +S:CONFIG_TARGET_ZYNQ_MICROZED=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y diff --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig index cceb321..849a162 100644 --- a/configs/zynq_zc70x_defconfig +++ b/configs/zynq_zc70x_defconfig @@ -3,6 +3,7 @@ CONFIG_SPL=y +S:CONFIG_ZYNQ=y +S:CONFIG_TARGET_ZYNQ_ZC70X=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig index 2935c0d..5fe8e50 100644 --- a/configs/zynq_zc770_xm010_defconfig +++ b/configs/zynq_zc770_xm010_defconfig @@ -4,6 +4,7 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010" +S:CONFIG_ZYNQ=y +S:CONFIG_TARGET_ZYNQ_ZC770=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig index 0401739..f15eb1b 100644 --- a/configs/zynq_zc770_xm012_defconfig +++ b/configs/zynq_zc770_xm012_defconfig @@ -4,6 +4,7 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM012" +S:CONFIG_ZYNQ=y +S:CONFIG_TARGET_ZYNQ_ZC770=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig index a95970a..ae33688 100644 --- a/configs/zynq_zc770_xm013_defconfig +++ b/configs/zynq_zc770_xm013_defconfig @@ -4,6 +4,7 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013" +S:CONFIG_ZYNQ=y +S:CONFIG_TARGET_ZYNQ_ZC770=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig index 0fbc41a..bc86bde 100644 --- a/configs/zynq_zed_defconfig +++ b/configs/zynq_zed_defconfig @@ -3,6 +3,7 @@ CONFIG_SPL=y +S:CONFIG_ZYNQ=y +S:CONFIG_TARGET_ZYNQ_ZED=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zed" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig index 4e66760..7467d42 100644 --- a/configs/zynq_zybo_defconfig +++ b/configs/zynq_zybo_defconfig @@ -3,6 +3,7 @@ CONFIG_SPL=y +S:CONFIG_ZYNQ=y +S:CONFIG_TARGET_ZYNQ_ZYBO=y CONFIG_OF_CONTROL=y +CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y

Remove the implicit assumption that SPL does not support device tree.
Signed-off-by: Simon Glass sjg@chromium.org ---
lib/Makefile | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/lib/Makefile b/lib/Makefile index 07d175f..97ed398 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -44,6 +44,12 @@ obj-$(CONFIG_BITREVERSE) += bitrev.o obj-y += list_sort.o endif
+ifndef CONFIG_SPL_DISABLE_OF_CONTROL +obj-$(CONFIG_OF_LIBFDT) += libfdt/ +obj-$(CONFIG_OF_CONTROL) += fdtdec_common.o +obj-$(CONFIG_OF_CONTROL) += fdtdec.o +endif + ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o

Some boards will not use device tree for SPL even with driver model. Add the logic to support this.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/core/root.c | 14 ++++++++------ include/fdtdec.h | 10 ++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/drivers/core/root.c b/drivers/core/root.c index 9b5c6bb..12d0460 100644 --- a/drivers/core/root.c +++ b/drivers/core/root.c @@ -197,13 +197,15 @@ int dm_init_and_scan(bool pre_reloc_only) debug("dm_scan_platdata() failed: %d\n", ret); return ret; } -#ifdef CONFIG_OF_CONTROL - ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only); - if (ret) { - debug("dm_scan_fdt() failed: %d\n", ret); - return ret; + + if (OF_CONTROL) { + ret = dm_scan_fdt(gd->fdt_blob, pre_reloc_only); + if (ret) { + debug("dm_scan_fdt() failed: %d\n", ret); + return ret; + } } -#endif + ret = dm_scan_other(pre_reloc_only); if (ret) return ret; diff --git a/include/fdtdec.h b/include/fdtdec.h index a49a184..489e8a6 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -41,6 +41,16 @@ struct fdt_memory { fdt_addr_t end; };
+#ifdef CONFIG_OF_CONTROL +# if defined(CONFIG_SPL_BUILD) && defined(SPL_DISABLE_OF_CONTROL) +# define OF_CONTROL 0 +# else +# define OF_CONTROL 1 +# endif +#else +# define OF_CONTROL 0 +#endif + /* * Information about a resource. start is the first address of the resource * and end is the last address (inclusive). The length of the resource will

If enabled, make sure that the device tree is available in SPL before setting up driver model.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/spl/spl.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/common/spl/spl.c b/common/spl/spl.c index c655332..1e263b3 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -139,6 +139,8 @@ static void spl_ram_load_image(void) void board_init_r(gd_t *dummy1, ulong dummy2) { u32 boot_device; + int ret; + debug(">>spl:board_init_r()\n");
#if defined(CONFIG_SYS_SPL_MALLOC_START) @@ -149,9 +151,21 @@ void board_init_r(gd_t *dummy1, ulong dummy2) gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN; gd->malloc_ptr = 0; #endif -#ifdef CONFIG_SPL_DM - dm_init_and_scan(true); -#endif + if (IS_ENABLED(CONFIG_OF_CONTROL) && + !IS_ENABLED(CONFIG_SPL_DISABLE_OF_CONTROL)) { + ret = fdtdec_setup(); + if (ret) { + debug("fdtdec_setup() returned error %d\n", ret); + hang(); + } + } + if (IS_ENABLED(CONFIG_SPL_DM)) { + ret = dm_init_and_scan(true); + if (ret) { + debug("dm_init_and_scan() returned error %d\n", ret); + hang(); + } + }
#ifndef CONFIG_PPC /*

This feature should be deprecated for new boards, and significantly adds to SPL code size. Drop it. Instead, we can use stdout-path in the /chosen node.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/serial/serial-uclass.c | 69 ++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 32 deletions(-)
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 13ba606..6531841 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -32,49 +32,54 @@ static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE; static void serial_find_console_or_panic(void) { struct udevice *dev; - -#ifdef CONFIG_OF_CONTROL int node;
- /* Check for a chosen console */ - node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path"); - if (node < 0) - node = fdt_path_offset(gd->fdt_blob, "console"); - if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &dev)) { - gd->cur_serial_dev = dev; - return; - } - - /* - * If the console is not marked to be bound before relocation, bind - * it anyway. - */ - if (node > 0 && - !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &dev)) { - if (!device_probe(dev)) { + if (OF_CONTROL) { + /* Check for a chosen console */ + node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path"); + if (node < 0) + node = fdt_path_offset(gd->fdt_blob, "console"); + if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, + &dev)) { gd->cur_serial_dev = dev; return; } - } -#endif - /* - * Try to use CONFIG_CONS_INDEX if available (it is numbered from 1!). - * - * Failing that, get the device with sequence number 0, or in extremis - * just the first serial device we can find. But we insist on having - * a console (even if it is silent). - */ + + /* + * If the console is not marked to be bound before relocation, + * bind it anyway. + */ + if (node > 0 && + !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &dev)) { + if (!device_probe(dev)) { + gd->cur_serial_dev = dev; + return; + } + } + } else { + /* + * Try to use CONFIG_CONS_INDEX if available (it is numbered + * from 1!). + * + * Failing that, get the device with sequence number 0, or in + * extremis just the first serial device we can find. But we + * insist on having a console (even if it is silent). + */ #ifdef CONFIG_CONS_INDEX #define INDEX (CONFIG_CONS_INDEX - 1) #else #define INDEX 0 #endif - if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) && - uclass_get_device(UCLASS_SERIAL, INDEX, &dev) && - (uclass_first_device(UCLASS_SERIAL, &dev) || !dev)) - panic_str("No serial driver found"); + if (!uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) || + !uclass_get_device(UCLASS_SERIAL, INDEX, &dev) || + (!uclass_first_device(UCLASS_SERIAL, &dev) || dev)) { + gd->cur_serial_dev = dev; + return; + } #undef INDEX - gd->cur_serial_dev = dev; + } + + panic_str("No serial driver found"); }
/* Called prior to relocation */

Allow SPL to be built with this option so that we can support device tree control. Disable the simple bus for now in SPL. It may be needed later.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/core/Makefile | 2 ++ include/config_uncmd_spl.h | 2 ++ scripts/Makefile.uncmd_spl | 2 ++ 3 files changed, 6 insertions(+)
diff --git a/drivers/core/Makefile b/drivers/core/Makefile index f14695b..a3fec38 100644 --- a/drivers/core/Makefile +++ b/drivers/core/Makefile @@ -5,5 +5,7 @@ #
obj-$(CONFIG_DM) += device.o lists.o root.o uclass.o util.o +ifndef CONFIG_SPL_BUILD obj-$(CONFIG_OF_CONTROL) += simple-bus.o +endif obj-$(CONFIG_DM_DEVICE_REMOVE) += device-remove.o diff --git a/include/config_uncmd_spl.h b/include/config_uncmd_spl.h index 38cb0e8..c191f56 100644 --- a/include/config_uncmd_spl.h +++ b/include/config_uncmd_spl.h @@ -20,7 +20,9 @@ #undef CONFIG_CMD_SNTP #undef CONFIG_CMD_TFTPPUT #undef CONFIG_CMD_TFTPSRV +#ifdef CONFIG_SPL_DISABLE_OF_CONTROL #undef CONFIG_OF_CONTROL +#endif
#ifndef CONFIG_SPL_DM #undef CONFIG_DM_SERIAL diff --git a/scripts/Makefile.uncmd_spl b/scripts/Makefile.uncmd_spl index 343c3fc..4f05652 100644 --- a/scripts/Makefile.uncmd_spl +++ b/scripts/Makefile.uncmd_spl @@ -3,7 +3,9 @@ # TODO: Invent a better way
ifdef CONFIG_SPL_BUILD +ifdef CONFIG_SPL_DISABLE_OF_CONTROL CONFIG_OF_CONTROL= +endif
ifndef CONFIG_SPL_DM CONFIG_DM_SERIAL=

For SPL we want to support building device tree files. Due to limited memory some boards will include only a subset of the full device tree file. So build these files separately for SPL.
SPL does not relocate itself so we cannot use the BSS space for the device tree. Instead we place it at the end of BSS and provide a 'pad' file to overlay on the BSS space.
So far, CONFIG_OF_EMBED is not supported for SPL. There does not seem to be any reason for it other than debugging.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/cpu/u-boot-spl.lds | 2 +- arch/arm/dts/Makefile | 2 +- dts/Makefile | 9 ++++++--- scripts/Makefile.lib | 12 ++++++++---- scripts/Makefile.spl | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/arch/arm/cpu/u-boot-spl.lds b/arch/arm/cpu/u-boot-spl.lds index a8be204..4b6e0f6 100644 --- a/arch/arm/cpu/u-boot-spl.lds +++ b/arch/arm/cpu/u-boot-spl.lds @@ -66,7 +66,7 @@ SECTIONS . = ALIGN(4); __bss_end = .; } - + __bss_size = __bss_end - __bss_start; .dynsym _image_binary_end : { *(.dynsym) } .dynbss : { *(.dynbss) } .dynstr : { *(.dynstr*) } diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 121725e..6b9d8ea 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -56,7 +56,7 @@ targets += $(dtb-y) DTC_FLAGS += -R 4
PHONY += dtbs -dtbs: $(addprefix $(obj)/, $(dtb-y)) +dtbs: $(addprefix $(DTB_PATH)$(obj)/, $(dtb-y)) @:
clean-files := *.dtb diff --git a/dts/Makefile b/dts/Makefile index d3122aa..f8f06f0 100644 --- a/dts/Makefile +++ b/dts/Makefile @@ -6,6 +6,7 @@
# This Makefile builds the internal U-Boot fdt if CONFIG_OF_CONTROL is # enabled. See doc/README.fdt-control for more details. +# DTB_PATH is empty for U-Boot proper, and "spl/" for SPL
DEVICE_TREE ?= $(CONFIG_DEFAULT_DEVICE_TREE:"%"=%) ifeq ($(DEVICE_TREE),) @@ -13,11 +14,13 @@ DEVICE_TREE := unset endif
ifneq ($(EXT_DTB),) -DTB := $(EXT_DTB) +BASE_DTB := $(EXT_DTB) else -DTB := arch/$(ARCH)/dts/$(DEVICE_TREE).dtb +BASE_DTB := arch/$(ARCH)/dts/$(DEVICE_TREE).dtb endif
+DTB := $(DTB_PATH)$(BASE_DTB) + $(obj)/dt.dtb: $(DTB) FORCE $(call if_changed,shipped)
@@ -33,7 +36,7 @@ $(DTB): arch-dtbs /bin/false)
arch-dtbs: - $(Q)$(MAKE) $(build)=arch/$(ARCH)/dts dtbs + $(Q)$(MAKE) $(build)=arch/$(ARCH)/dts DTB_PATH=$(DTB_PATH) dtbs
.SECONDARY: $(obj)/dt.dtb.S
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 13af604..04d9b50 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -150,11 +150,11 @@ cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(UBOOTINCLUDE) \
ld_flags = $(LDFLAGS) $(ldflags-y)
-# Modified for U-Boot +# Modified for U-Boot, include KBUILD_CPPFLAGS for CONFIG_SPL/TPL_BUILD dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \ -I$(srctree)/arch/$(ARCH)/dts \ -I$(srctree)/arch/$(ARCH)/dts/include \ - -undef -D__DTS__ + -undef -D__DTS__ $(KBUILD_CPPFLAGS)
# Finds the multi-part object the current object will be linked into modname-multi = $(sort $(foreach m,$(multi-used),\ @@ -272,15 +272,19 @@ cmd_dt_S_dtb= \ $(obj)/%.dtb.S: $(obj)/%.dtb $(call cmd,dt_S_dtb)
+# Can we remove the duplication here? +quiet_cmd_dtcspl = DTC SPL $@ +# Modified for U-Boot quiet_cmd_dtc = DTC $@ # Modified for U-Boot -cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ +cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \ dtc -O dtb -o $@ -b 0 \ -i $(dir $<) $(DTC_FLAGS) \ -d $(depfile).dtc.tmp $(dtc-tmp) ; \ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
-$(obj)/%.dtb: $(src)/%.dts FORCE +$(obj)/%.dtb spl/$(obj)/%.dtb tpl/$(obj)/%.dtb: $(src)/%.dts FORCE + $(Q)mkdir -p $(dir $@) $(call if_changed_dep,dtc)
dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp) diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index ea67137..def962c 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -31,10 +31,14 @@ endif
ifeq ($(CONFIG_TPL_BUILD),y) SPL_BIN := u-boot-tpl +DTB_PATH := tpl/ else SPL_BIN := u-boot-spl +DTB_PATH := spl/ endif
+export DTB_PATH + include $(srctree)/config.mk include $(srctree)/arch/$(ARCH)/Makefile
@@ -50,6 +54,7 @@ HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(srctree)/board/$(VENDOR)/common/Makef
libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/) libs-$(HAVE_VENDOR_COMMON_LIB) += board/$(VENDOR)/common/ +libs-$(CONFIG_OF_EMBED) += dts/
libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/ libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/ @@ -151,6 +156,8 @@ boot.bin: $(obj)/u-boot-spl.bin
ALL-y += $(obj)/$(SPL_BIN).bin $(obj)/$(SPL_BIN).cfg
+ALL-$(CONFIG_OF_SEPARATE) += $(obj)/$(SPL_BIN)-pad.bin $(obj)/$(SPL_BIN)-dtb.bin + ifdef CONFIG_SAMSUNG ALL-y += $(obj)/$(BOARD)-spl.bin endif @@ -163,8 +170,36 @@ ifeq ($(CONFIG_SYS_SOC),"at91") ALL-y += boot.bin endif
+checkdtc: + @if test $(call dtc-version) -lt 0104; then \ + echo '*** Your dtc is too old, please upgrade to dtc 1.4 or newer'; \ + false; \ + fi + all: $(ALL-y)
+quiet_cmd_cat = CAT $@ +cmd_cat = cat $(filter-out $(PHONY), $^) > $@ + +$(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN).bin $(obj)/$(SPL_BIN)-pad.bin \ + $(obj)/$(SPL_BIN).dtb FORCE + $(call if_changed,cat) + +# Create a file that provings pads from the end of u-boot-spl.bin to bss_end +$(obj)/$(SPL_BIN)-pad.bin: $(obj)/$(SPL_BIN) + @bss_size_str=$(shell $(NM) $< | awk 'BEGIN {size = 0} /__bss_size/ {size = $$1} END {print "ibase=16; " size}' | bc); \ + dd if=/dev/zero of=$@ bs=1 count=$${bss_size_str} 2>/dev/null; + +quiet_cmd_copy = COPY $@ + cmd_copy = cp $< $@ + +$(obj)/$(SPL_BIN).dtb: $(obj)/dts/dt.dtb + $(call cmd,copy) + +PHONY += dtbs +dtbs $(obj)/dts/dt.dtb: checkdtc $(obj)/$(SPL_BIN) + $(Q)$(MAKE) $(build)=$(obj)/dts DTB_PATH=$(DTB_PATH) dtbs + quiet_cmd_cpp_cfg = CFG $@ cmd_cpp_cfg = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \ -D__ASSEMBLY__ -x assembler-with-cpp -P -dM -E -o $@ $<

Add support for the Rockchip serial device using the ns16550 driver. This uses driver model and device tree for both SPL and U-Boot proper.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/serial/Kconfig | 9 +++++++++ drivers/serial/Makefile | 1 + drivers/serial/serial_rockchip.c | 41 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 drivers/serial/serial_rockchip.c
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 54e6f26..2e87199 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -76,6 +76,15 @@ config DEBUG_UART_SHIFT value. Use this value to specify the shift to use, where 0=byte registers, 2=32-bit word registers, etc.
+config ROCKCHIP_SERIAL + bool "Rockchip on-chip UART support" + depends on ARCH_UNIPHIER && DM_SERIAL + help + Select this to enable a debug UART for Rockchip devices. This uses + the ns16550 driver. You will need to #define CONFIG_SYS_NS16550 in + your board config header. The clock input is automatically set to + use the oscillator (24MHz). + config UNIPHIER_SERIAL bool "UniPhier on-chip UART support" depends on ARCH_UNIPHIER && DM_SERIAL diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index b385852..434d7fc 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_ZYNQ_SERIAL) += serial_zynq.o obj-$(CONFIG_BFIN_SERIAL) += serial_bfin.o obj-$(CONFIG_FSL_LPUART) += serial_lpuart.o obj-$(CONFIG_MXS_AUART) += mxs_auart.o +obj-$(CONFIG_ROCKCHIP_SERIAL) += serial_rockchip.o obj-$(CONFIG_ARC_SERIAL) += serial_arc.o obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o diff --git a/drivers/serial/serial_rockchip.c b/drivers/serial/serial_rockchip.c new file mode 100644 index 0000000..319e350 --- /dev/null +++ b/drivers/serial/serial_rockchip.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dm.h> +#include <ns16550.h> +#include <serial.h> +#include <asm/arch/clock.h> + +static const struct udevice_id rockchip_serial_ids[] = { + { .compatible = "rockchip,rk3288-uart" }, + { } +}; + +static int rockchip_serial_ofdata_to_platdata(struct udevice *dev) +{ + struct ns16550_platdata *plat = dev_get_platdata(dev); + int ret; + + ret = ns16550_serial_ofdata_to_platdata(dev); + if (ret) + return ret; + plat->clock = OSC_HZ; + + return 0; +} + +U_BOOT_DRIVER(serial_ns16550) = { + .name = "serial_rockchip", + .id = UCLASS_SERIAL, + .of_match = rockchip_serial_ids, + .ofdata_to_platdata = rockchip_serial_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct ns16550_platdata), + .priv_auto_alloc_size = sizeof(struct NS16550), + .probe = ns16550_serial_probe, + .ops = &ns16550_serial_ops, + .flags = DM_FLAG_PRE_RELOC, +};

Bring in required device tree files from Linux. Since mainline Linux is somewhat behind, use the files from the Chromium tree. We can re-sync once further code is acccepted upstream.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/dts/rk3288-thermal.dtsi | 90 ++ arch/arm/dts/rk3288.dtsi | 1466 ++++++++++++++++++++ .../clock/rockchip,rk3288-cru.txt | 61 + doc/device-tree-bindings/clock/rockchip.txt | 77 + .../pinctrl/rockchip,pinctrl.txt | 157 +++ .../thermal/rockchip-thermal.txt | 68 + include/dt-bindings/clock/rk3288-cru.h | 378 +++++ include/dt-bindings/clock/rockchip,rk808.h | 11 + include/dt-bindings/pinctrl/rockchip.h | 34 + include/dt-bindings/power-domain/rk3288.h | 11 + include/dt-bindings/thermal/thermal.h | 17 + 11 files changed, 2370 insertions(+) create mode 100644 arch/arm/dts/rk3288-thermal.dtsi create mode 100644 arch/arm/dts/rk3288.dtsi create mode 100644 doc/device-tree-bindings/clock/rockchip,rk3288-cru.txt create mode 100644 doc/device-tree-bindings/clock/rockchip.txt create mode 100644 doc/device-tree-bindings/pinctrl/rockchip,pinctrl.txt create mode 100644 doc/device-tree-bindings/thermal/rockchip-thermal.txt create mode 100644 include/dt-bindings/clock/rk3288-cru.h create mode 100644 include/dt-bindings/clock/rockchip,rk808.h create mode 100644 include/dt-bindings/pinctrl/rockchip.h create mode 100644 include/dt-bindings/power-domain/rk3288.h create mode 100644 include/dt-bindings/thermal/thermal.h
diff --git a/arch/arm/dts/rk3288-thermal.dtsi b/arch/arm/dts/rk3288-thermal.dtsi new file mode 100644 index 0000000..1fde97c --- /dev/null +++ b/arch/arm/dts/rk3288-thermal.dtsi @@ -0,0 +1,90 @@ +/* + * Device Tree Source for RK3288 SoC thermal + * + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include <dt-bindings/thermal/thermal.h> + +reserve_thermal: reserve_thermal { + polling-delay-passive = <1000>; /* milliseconds */ + polling-delay = <5000>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&tsadc 0>; + +}; + +cpu_thermal: cpu_thermal { + polling-delay-passive = <100>; /* milliseconds */ + polling-delay = <5000>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&tsadc 1>; + linux,hwmon; + + trips { + cpu_alert0: cpu_alert0 { + temperature = <70000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + cpu_alert1: cpu_alert1 { + temperature = <75000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + cpu_crit: cpu_crit { + temperature = <100000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT 6>; + }; + map1 { + trip = <&cpu_alert1>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +gpu_thermal: gpu_thermal { + polling-delay-passive = <100>; /* milliseconds */ + polling-delay = <5000>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&tsadc 2>; + linux,hwmon; + + trips { + gpu_alert0: gpu_alert0 { + temperature = <80000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + gpu_crit: gpu_crit { + temperature = <100000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&gpu_alert0>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; diff --git a/arch/arm/dts/rk3288.dtsi b/arch/arm/dts/rk3288.dtsi new file mode 100644 index 0000000..8251441 --- /dev/null +++ b/arch/arm/dts/rk3288.dtsi @@ -0,0 +1,1466 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/pinctrl/rockchip.h> +#include <dt-bindings/clock/rk3288-cru.h> +#include <dt-bindings/power-domain/rk3288.h> +#include <dt-bindings/thermal/thermal.h> +#include "skeleton.dtsi" + +/ { + compatible = "rockchip,rk3288"; + + interrupt-parent = <&gic>; + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + mmc0 = &emmc; + mmc1 = &sdmmc; + mmc2 = &sdio0; + mmc3 = &sdio1; + mshc0 = &emmc; + mshc1 = &sdmmc; + mshc2 = &sdio0; + mshc3 = &sdio1; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + serial4 = &uart4; + spi0 = &spi0; + spi1 = &spi1; + spi2 = &spi2; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + enable-method = "rockchip,rk3066-smp"; + rockchip,pmu = <&pmu>; + + cpu0: cpu@500 { + device_type = "cpu"; + compatible = "arm,cortex-a12"; + reg = <0x500>; + operating-points = < + /* KHz uV */ + 1800000 1400000 + 1704000 1350000 + 1608000 1300000 + 1512000 1250000 + 1416000 1200000 + 1200000 1100000 + 1008000 1050000 + 816000 1000000 + 696000 950000 + 600000 900000 + 408000 900000 + 216000 900000 + 126000 900000 + >; + #cooling-cells = <2>; /* min followed by max */ + clock-latency = <40000>; + clocks = <&cru ARMCLK>; + resets = <&cru SRST_CORE0>; + }; + cpu@501 { + device_type = "cpu"; + compatible = "arm,cortex-a12"; + reg = <0x501>; + resets = <&cru SRST_CORE1>; + }; + cpu@502 { + device_type = "cpu"; + compatible = "arm,cortex-a12"; + reg = <0x502>; + resets = <&cru SRST_CORE2>; + }; + cpu@503 { + device_type = "cpu"; + compatible = "arm,cortex-a12"; + reg = <0x503>; + resets = <&cru SRST_CORE3>; + }; + }; + + amba { + compatible = "arm,amba-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + dmac_peri: dma-controller@ff250000 { + compatible = "arm,pl330", "arm,primecell"; + broken-no-flushp; + reg = <0xff250000 0x4000>; + interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <1>; + clocks = <&cru ACLK_DMAC2>; + clock-names = "apb_pclk"; + }; + + dmac_bus_ns: dma-controller@ff600000 { + compatible = "arm,pl330", "arm,primecell"; + broken-no-flushp; + reg = <0xff600000 0x4000>; + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <1>; + clocks = <&cru ACLK_DMAC1>; + clock-names = "apb_pclk"; + status = "disabled"; + }; + + dmac_bus_s: dma-controller@ffb20000 { + compatible = "arm,pl330", "arm,primecell"; + broken-no-flushp; + reg = <0xffb20000 0x4000>; + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <1>; + clocks = <&cru ACLK_DMAC1>; + clock-names = "apb_pclk"; + }; + }; + + xin24m: oscillator { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "xin24m"; + #clock-cells = <0>; + }; + + timer { + arm,use-physical-timer; + compatible = "arm,armv7-timer"; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + clock-frequency = <24000000>; + always-on; + }; + + display-subsystem { + compatible = "rockchip,display-subsystem"; + ports = <&vopl_out>, <&vopb_out>; + }; + + sdmmc: dwmmc@ff0c0000 { + compatible = "rockchip,rk3288-dw-mshc"; + clock-freq-min-max = <400000 150000000>; + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>, + <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + fifo-depth = <0x100>; + interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; + reg = <0xff0c0000 0x4000>; + status = "disabled"; + }; + + sdio0: dwmmc@ff0d0000 { + compatible = "rockchip,rk3288-dw-mshc"; + clock-freq-min-max = <400000 150000000>; + clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>, + <&cru SCLK_SDIO0_DRV>, <&cru SCLK_SDIO0_SAMPLE>; + clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + fifo-depth = <0x100>; + interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; + reg = <0xff0d0000 0x4000>; + status = "disabled"; + }; + + sdio1: dwmmc@ff0e0000 { + compatible = "rockchip,rk3288-dw-mshc"; + clock-freq-min-max = <400000 150000000>; + clocks = <&cru HCLK_SDIO1>, <&cru SCLK_SDIO1>, + <&cru SCLK_SDIO1_DRV>, <&cru SCLK_SDIO1_SAMPLE>; + clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + fifo-depth = <0x100>; + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; + reg = <0xff0e0000 0x4000>; + status = "disabled"; + }; + + emmc: dwmmc@ff0f0000 { + compatible = "rockchip,rk3288-dw-mshc"; + clock-freq-min-max = <400000 150000000>; + clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>, + <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu_drv", "ciu_sample"; + fifo-depth = <0x100>; + interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; + reg = <0xff0f0000 0x4000>; + status = "disabled"; + }; + + saradc: saradc@ff100000 { + compatible = "rockchip,saradc"; + reg = <0xff100000 0x100>; + interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; + #io-channel-cells = <1>; + clocks = <&cru SCLK_SARADC>, <&cru PCLK_SARADC>; + clock-names = "saradc", "apb_pclk"; + status = "disabled"; + }; + + spi0: spi@ff110000 { + compatible = "rockchip,rk3288-spi", "rockchip,rk3066-spi"; + clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>; + clock-names = "spiclk", "apb_pclk"; + dmas = <&dmac_peri 11>, <&dmac_peri 12>; + dma-names = "tx", "rx"; + interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_clk &spi0_tx &spi0_rx &spi0_cs0>; + reg = <0xff110000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi1: spi@ff120000 { + compatible = "rockchip,rk3288-spi", "rockchip,rk3066-spi"; + clocks = <&cru SCLK_SPI1>, <&cru PCLK_SPI1>; + clock-names = "spiclk", "apb_pclk"; + dmas = <&dmac_peri 13>, <&dmac_peri 14>; + dma-names = "tx", "rx"; + interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_clk &spi1_tx &spi1_rx &spi1_cs0>; + reg = <0xff120000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + spi2: spi@ff130000 { + compatible = "rockchip,rk3288-spi", "rockchip,rk3066-spi"; + clocks = <&cru SCLK_SPI2>, <&cru PCLK_SPI2>; + clock-names = "spiclk", "apb_pclk"; + dmas = <&dmac_peri 15>, <&dmac_peri 16>; + dma-names = "tx", "rx"; + interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&spi2_clk &spi2_tx &spi2_rx &spi2_cs0>; + reg = <0xff130000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c@ff140000 { + compatible = "rockchip,rk3288-i2c"; + reg = <0xff140000 0x1000>; + interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "i2c"; + clocks = <&cru PCLK_I2C1>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_xfer>; + status = "disabled"; + }; + + i2c3: i2c@ff150000 { + compatible = "rockchip,rk3288-i2c"; + reg = <0xff150000 0x1000>; + interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "i2c"; + clocks = <&cru PCLK_I2C3>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_xfer>; + status = "disabled"; + }; + + i2c4: i2c@ff160000 { + compatible = "rockchip,rk3288-i2c"; + reg = <0xff160000 0x1000>; + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "i2c"; + clocks = <&cru PCLK_I2C4>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_xfer>; + status = "disabled"; + }; + + i2c5: i2c@ff170000 { + compatible = "rockchip,rk3288-i2c"; + reg = <0xff170000 0x1000>; + interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "i2c"; + clocks = <&cru PCLK_I2C5>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c5_xfer>; + status = "disabled"; + }; + uart0: serial@ff180000 { + compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; + reg = <0xff180000 0x100>; + interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; + clock-names = "baudclk", "apb_pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer>; + status = "disabled"; + }; + + uart1: serial@ff190000 { + compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; + reg = <0xff190000 0x100>; + interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; + clock-names = "baudclk", "apb_pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&uart1_xfer>; + status = "disabled"; + }; + + uart2: serial@ff690000 { + compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; + reg = <0xff690000 0x100>; + interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; + clock-names = "baudclk", "apb_pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&uart2_xfer>; + status = "disabled"; + }; + uart3: serial@ff1b0000 { + compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; + reg = <0xff1b0000 0x100>; + interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; + clock-names = "baudclk", "apb_pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&uart3_xfer>; + status = "disabled"; + }; + + uart4: serial@ff1c0000 { + compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; + reg = <0xff1c0000 0x100>; + interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; + clock-names = "baudclk", "apb_pclk"; + pinctrl-names = "default"; + pinctrl-0 = <&uart4_xfer>; + status = "disabled"; + }; + thermal: thermal-zones { + #include "rk3288-thermal.dtsi" + }; + + tsadc: tsadc@ff280000 { + compatible = "rockchip,rk3288-tsadc"; + reg = <0xff280000 0x100>; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; + clock-names = "tsadc", "apb_pclk"; + resets = <&cru SRST_TSADC>; + reset-names = "tsadc-apb"; + pinctrl-names = "otp_out"; + pinctrl-0 = <&otp_out>; + #thermal-sensor-cells = <1>; + hw-shut-temp = <125000>; + status = "disabled"; + }; + + gmac: ethernet@ff290000 { + compatible = "rockchip,rk3288-gmac"; + reg = <0xff290000 0x10000>; + interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; + rockchip,grf = <&grf>; + clocks = <&cru SCLK_MAC>, + <&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>, + <&cru SCLK_MACREF>, <&cru SCLK_MACREF_OUT>, + <&cru ACLK_GMAC>, <&cru PCLK_GMAC>; + clock-names = "stmmaceth", + "mac_clk_rx", "mac_clk_tx", + "clk_mac_ref", "clk_mac_refout", + "aclk_mac", "pclk_mac"; + }; + + usb_host0_ehci: usb@ff500000 { + compatible = "generic-ehci"; + reg = <0xff500000 0x100>; + interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru HCLK_USBHOST0>; + clock-names = "usbhost"; + phys = <&usbphy1>; + phy-names = "usb"; + status = "disabled"; + }; + + /* NOTE: ohci@ff520000 doesn't actually work on hardware */ + + usb_host1: usb@ff540000 { + compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", + "snps,dwc2"; + reg = <0xff540000 0x40000>; + interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru HCLK_USBHOST1>; + clock-names = "otg"; + phys = <&usbphy2>; + phy-names = "usb2-phy"; + status = "disabled"; + }; + + usb_otg: usb@ff580000 { + compatible = "rockchip,rk3288-usb", "rockchip,rk3066-usb", + "snps,dwc2"; + reg = <0xff580000 0x40000>; + interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru HCLK_OTG0>; + clock-names = "otg"; + phys = <&usbphy0>; + phy-names = "usb2-phy"; + status = "disabled"; + }; + + usb_hsic: usb@ff5c0000 { + compatible = "generic-ehci"; + reg = <0xff5c0000 0x100>; + interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru HCLK_HSIC>; + clock-names = "usbhost"; + status = "disabled"; + }; + + dmc: dmc@ff610000 { + compatible = "rockchip,rk3288-dmc", "syscon"; + rockchip,cru = <&cru>; + rockchip,grf = <&grf>; + rockchip,pmu = <&pmu>; + rockchip,sgrf = <&sgrf>; + rockchip,noc = <&noc>; + reg = <0xff610000 0x3fc + 0xff620000 0x294 + 0xff630000 0x3fc + 0xff640000 0x294>; + rockchip,sram = <&ddr_sram>; + clocks = <&cru PCLK_DDRUPCTL0>, <&cru PCLK_PUBL0>, + <&cru PCLK_DDRUPCTL1>, <&cru PCLK_PUBL1>, + <&cru ARMCLK>; + clock-names = "pclk_ddrupctl0", "pclk_publ0", + "pclk_ddrupctl1", "pclk_publ1", + "arm_clk"; + }; + + i2c0: i2c@ff650000 { + compatible = "rockchip,rk3288-i2c"; + reg = <0xff650000 0x1000>; + interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "i2c"; + clocks = <&cru PCLK_I2C0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_xfer>; + status = "disabled"; + }; + + i2c2: i2c@ff660000 { + compatible = "rockchip,rk3288-i2c"; + reg = <0xff660000 0x1000>; + interrupts = <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clock-names = "i2c"; + clocks = <&cru PCLK_I2C2>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_xfer>; + status = "disabled"; + }; + + pwm0: pwm@ff680000 { + compatible = "rockchip,rk3288-pwm"; + reg = <0xff680000 0x10>; + #pwm-cells = <3>; + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pin>; + clocks = <&cru PCLK_PWM>; + clock-names = "pwm"; + rockchip,grf = <&grf>; + status = "disabled"; + }; + + pwm1: pwm@ff680010 { + compatible = "rockchip,rk3288-pwm"; + reg = <0xff680010 0x10>; + #pwm-cells = <3>; + pinctrl-names = "default"; + pinctrl-0 = <&pwm1_pin>; + clocks = <&cru PCLK_PWM>; + clock-names = "pwm"; + rockchip,grf = <&grf>; + status = "disabled"; + }; + + pwm2: pwm@ff680020 { + compatible = "rockchip,rk3288-pwm"; + reg = <0xff680020 0x10>; + #pwm-cells = <3>; + pinctrl-names = "default"; + pinctrl-0 = <&pwm2_pin>; + clocks = <&cru PCLK_PWM>; + clock-names = "pwm"; + rockchip,grf = <&grf>; + status = "disabled"; + }; + + pwm3: pwm@ff680030 { + compatible = "rockchip,rk3288-pwm"; + reg = <0xff680030 0x10>; + #pwm-cells = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&pwm3_pin>; + clocks = <&cru PCLK_PWM>; + clock-names = "pwm"; + rockchip,grf = <&grf>; + status = "disabled"; + }; + + bus_intmem@ff700000 { + compatible = "mmio-sram"; + reg = <0xff700000 0x18000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0xff700000 0x18000>; + smp-sram@0 { + compatible = "rockchip,rk3066-smp-sram"; + reg = <0x00 0x10>; + }; + ddr_sram: ddr-sram@1000 { + compatible = "rockchip,rk3288-ddr-sram"; + reg = <0x1000 0x4000>; + }; + }; + + sram@ff720000 { + compatible = "rockchip,rk3288-pmu-sram", "mmio-sram"; + reg = <0xff720000 0x1000>; + }; + + pmu: power-management@ff730000 { + compatible = "rockchip,rk3288-pmu", "syscon"; + reg = <0xff730000 0x100>; + }; + + sgrf: syscon@ff740000 { + compatible = "rockchip,rk3288-sgrf", "syscon"; + reg = <0xff740000 0x1000>; + }; + + cru: clock-controller@ff760000 { + compatible = "rockchip,rk3288-cru"; + reg = <0xff760000 0x1000>; + rockchip,grf = <&grf>; + #clock-cells = <1>; + #reset-cells = <1>; + assigned-clocks = <&cru DCLK_VOP0>, <&cru DCLK_VOP1>, + <&cru PLL_GPLL>, <&cru PLL_CPLL>, + <&cru PLL_NPLL>, <&cru ACLK_CPU>, + <&cru HCLK_CPU>, <&cru PCLK_CPU>, + <&cru ACLK_PERI>, <&cru HCLK_PERI>, + <&cru PCLK_PERI>; + assigned-clock-rates = <0>, <0>, + <594000000>, <400000000>, + <500000000>, <300000000>, + <150000000>, <75000000>, + <300000000>, <150000000>, + <75000000>; + assigned-clock-parents = <&cru PLL_NPLL>, <&cru PLL_GPLL>; + }; + + grf: syscon@ff770000 { + compatible = "rockchip,rk3288-grf", "syscon"; + reg = <0xff770000 0x1000>; + }; + + wdt: watchdog@ff800000 { + compatible = "rockchip,rk3288-wdt", "snps,dw-wdt"; + reg = <0xff800000 0x100>; + clocks = <&cru PCLK_WDT>; + interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + i2s: i2s@ff890000 { + compatible = "rockchip,rk3288-i2s", "rockchip,rk3066-i2s"; + reg = <0xff890000 0x10000>; + interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + dmas = <&dmac_bus_s 0>, <&dmac_bus_s 1>; + dma-names = "tx", "rx"; + clock-names = "i2s_hclk", "i2s_clk"; + clocks = <&cru HCLK_I2S0>, <&cru SCLK_I2S0>; + pinctrl-names = "default"; + pinctrl-0 = <&i2s0_bus>; + status = "disabled"; + }; + + vopb: vop@ff930000 { + compatible = "rockchip,rk3288-vop"; + reg = <0xff930000 0x19c>; + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>; + clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; + resets = <&cru SRST_LCDC0_AXI>, <&cru SRST_LCDC0_AHB>, <&cru SRST_LCDC0_DCLK>; + reset-names = "axi", "ahb", "dclk"; + iommus = <&vopb_mmu>; + power-domains = <&power RK3288_PD_VIO>; + status = "disabled"; + vopb_out: port { + #address-cells = <1>; + #size-cells = <0>; + vopb_out_edp: endpoint@0 { + reg = <0>; + remote-endpoint = <&edp_in_vopb>; + }; + vopb_out_hdmi: endpoint@1 { + reg = <1>; + remote-endpoint = <&hdmi_in_vopb>; + }; + }; + }; + + vopb_mmu: iommu@ff930300 { + compatible = "rockchip,iommu"; + reg = <0xff930300 0x100>; + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "vopb_mmu"; + power-domains = <&power RK3288_PD_VIO>; + #iommu-cells = <0>; + status = "disabled"; + }; + + vopl: vop@ff940000 { + compatible = "rockchip,rk3288-vop"; + reg = <0xff940000 0x19c>; + interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru ACLK_VOP1>, <&cru DCLK_VOP1>, <&cru HCLK_VOP1>; + clock-names = "aclk_vop", "dclk_vop", "hclk_vop"; + resets = <&cru SRST_LCDC1_AXI>, <&cru SRST_LCDC1_AHB>, <&cru SRST_LCDC1_DCLK>; + reset-names = "axi", "ahb", "dclk"; + iommus = <&vopl_mmu>; + power-domains = <&power RK3288_PD_VIO>; + status = "disabled"; + vopl_out: port { + #address-cells = <1>; + #size-cells = <0>; + vopl_out_edp: endpoint@0 { + reg = <0>; + remote-endpoint = <&edp_in_vopl>; + }; + vopl_out_hdmi: endpoint@1 { + reg = <1>; + remote-endpoint = <&hdmi_in_vopl>; + }; + + }; + }; + + vopl_mmu: iommu@ff940300 { + compatible = "rockchip,iommu"; + reg = <0xff940300 0x100>; + interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "vopl_mmu"; + power-domains = <&power RK3288_PD_VIO>; + #iommu-cells = <0>; + status = "disabled"; + }; + + edp: edp@ff970000 { + compatible = "rockchip,rk3288-edp"; + reg = <0xff970000 0x4000>; + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru SCLK_EDP>, <&cru SCLK_EDP_24M>, <&cru PCLK_EDP_CTRL>; + rockchip,grf = <&grf>; + clock-names = "clk_edp", "clk_edp_24m", "pclk_edp"; + resets = <&cru 111>; + reset-names = "edp"; + power-domains = <&power RK3288_PD_VIO>; + status = "disabled"; + ports { + edp_in: port { + #address-cells = <1>; + #size-cells = <0>; + edp_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_edp>; + }; + edp_in_vopl: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_edp>; + }; + }; + }; + }; + + hdmi: hdmi@ff980000 { + compatible = "rockchip,rk3288-dw-hdmi"; + reg = <0xff980000 0x20000>; + reg-io-width = <4>; + ddc-i2c-bus = <&i2c5>; + rockchip,grf = <&grf>; + interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_HDMI_CTRL>, <&cru SCLK_HDMI_HDCP>; + clock-names = "iahb", "isfr"; + status = "disabled"; + ports { + hdmi_in: port { + #address-cells = <1>; + #size-cells = <0>; + hdmi_in_vopb: endpoint@0 { + reg = <0>; + remote-endpoint = <&vopb_out_hdmi>; + }; + hdmi_in_vopl: endpoint@1 { + reg = <1>; + remote-endpoint = <&vopl_out_hdmi>; + }; + }; + }; + }; + + hdmi_audio: hdmi_audio { + compatible = "rockchip,rk3288-hdmi-audio"; + i2s-controller = <&i2s>; + status = "disable"; + }; + + vpu: video-codec@ff9a0000 { + compatible = "rockchip,rk3288-vpu"; + reg = <0xff9a0000 0x800>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "vepu", "vdpu"; + clocks = <&cru ACLK_VCODEC>, <&cru HCLK_VCODEC>; + clock-names = "aclk_vcodec", "hclk_vcodec"; + power-domains = <&power RK3288_PD_VIDEO>; + iommus = <&vpu_mmu>; + }; + + vpu_mmu: iommu@ff9a0800 { + compatible = "rockchip,iommu"; + reg = <0xff9a0800 0x100>; + interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "vpu_mmu"; + power-domains = <&power RK3288_PD_VIDEO>; + #iommu-cells = <0>; + }; + + gpu: gpu@ffa30000 { + compatible = "arm,malit764", + "arm,malit76x", + "arm,malit7xx", + "arm,mali-midgard"; + reg = <0xffa30000 0x10000>; + interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "JOB", "MMU", "GPU"; + clocks = <&cru ACLK_GPU>; + clock-names = "aclk_gpu"; + operating-points = < + /* KHz uV */ + 100000 950000 + 200000 950000 + 300000 1000000 + 400000 1100000 + /* 500000 1200000 - See crosbug.com/p/33857 */ + 600000 1250000 + >; + power-domains = <&power RK3288_PD_GPU>; + status = "disabled"; + }; + + noc: syscon@ffac0000 { + compatible = "rockchip,rk3288-noc", "syscon"; + reg = <0xffac0000 0x2000>; + }; + + efuse: efuse@ffb40000 { + compatible = "rockchip,rk3288-efuse"; + reg = <0xffb40000 0x10000>; + status = "disabled"; + }; + + gic: interrupt-controller@ffc01000 { + compatible = "arm,gic-400"; + interrupt-controller; + #interrupt-cells = <3>; + #address-cells = <0>; + + reg = <0xffc01000 0x1000>, + <0xffc02000 0x1000>, + <0xffc04000 0x2000>, + <0xffc06000 0x2000>; + interrupts = <GIC_PPI 9 0xf04>; + }; + + cpuidle: cpuidle { + compatible = "rockchip,rk3288-cpuidle"; + }; + + usbphy: phy { + compatible = "rockchip,rk3288-usb-phy"; + rockchip,grf = <&grf>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + usbphy0: usb-phy0 { + #phy-cells = <0>; + reg = <0x320>; + clocks = <&cru SCLK_OTGPHY0>; + clock-names = "phyclk"; + }; + + usbphy1: usb-phy1 { + #phy-cells = <0>; + reg = <0x334>; + clocks = <&cru SCLK_OTGPHY1>; + clock-names = "phyclk"; + }; + + usbphy2: usb-phy2 { + #phy-cells = <0>; + reg = <0x348>; + clocks = <&cru SCLK_OTGPHY2>; + clock-names = "phyclk"; + }; + }; + + pinctrl: pinctrl { + compatible = "rockchip,rk3288-pinctrl"; + rockchip,grf = <&grf>; + rockchip,pmu = <&pmu>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio0: gpio0@ff750000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff750000 0x100>; + interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_GPIO0>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio1@ff780000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff780000 0x100>; + interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_GPIO1>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio2: gpio2@ff790000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff790000 0x100>; + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_GPIO2>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio3: gpio3@ff7a0000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff7a0000 0x100>; + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_GPIO3>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio4: gpio4@ff7b0000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff7b0000 0x100>; + interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_GPIO4>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio5: gpio5@ff7c0000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff7c0000 0x100>; + interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_GPIO5>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio6: gpio6@ff7d0000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff7d0000 0x100>; + interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_GPIO6>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio7: gpio7@ff7e0000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff7e0000 0x100>; + interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_GPIO7>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio8: gpio8@ff7f0000 { + compatible = "rockchip,gpio-bank"; + reg = <0xff7f0000 0x100>; + interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru PCLK_GPIO8>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + pcfg_pull_up: pcfg-pull-up { + bias-pull-up; + }; + + pcfg_pull_down: pcfg-pull-down { + bias-pull-down; + }; + + pcfg_pull_none: pcfg-pull-none { + bias-disable; + }; + + pcfg_pull_none_12ma: pcfg-pull-none-12ma { + bias-disable; + drive-strength = <12>; + }; + + sleep { + global_pwroff: global-pwroff { + rockchip,pins = <0 0 RK_FUNC_1 &pcfg_pull_none>; + }; + + ddrio_pwroff: ddrio-pwroff { + rockchip,pins = <0 1 RK_FUNC_1 &pcfg_pull_none>; + }; + + ddr0_retention: ddr0-retention { + rockchip,pins = <0 2 RK_FUNC_1 &pcfg_pull_up>; + }; + + ddr1_retention: ddr1-retention { + rockchip,pins = <0 3 RK_FUNC_1 &pcfg_pull_up>; + }; + }; + + i2c0 { + i2c0_xfer: i2c0-xfer { + rockchip,pins = <0 15 RK_FUNC_1 &pcfg_pull_none>, + <0 16 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + i2c1 { + i2c1_xfer: i2c1-xfer { + rockchip,pins = <8 4 RK_FUNC_1 &pcfg_pull_none>, + <8 5 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + i2c2 { + i2c2_xfer: i2c2-xfer { + rockchip,pins = <6 9 RK_FUNC_1 &pcfg_pull_none>, + <6 10 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + i2c3 { + i2c3_xfer: i2c3-xfer { + rockchip,pins = <2 16 RK_FUNC_1 &pcfg_pull_none>, + <2 17 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + i2c4 { + i2c4_xfer: i2c4-xfer { + rockchip,pins = <7 17 RK_FUNC_1 &pcfg_pull_none>, + <7 18 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + i2c5 { + i2c5_xfer: i2c5-xfer { + rockchip,pins = <7 19 RK_FUNC_1 &pcfg_pull_none>, + <7 20 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + i2s0 { + i2s0_bus: i2s0-bus { + rockchip,pins = <6 0 RK_FUNC_1 &pcfg_pull_none>, + <6 1 RK_FUNC_1 &pcfg_pull_none>, + <6 2 RK_FUNC_1 &pcfg_pull_none>, + <6 3 RK_FUNC_1 &pcfg_pull_none>, + <6 4 RK_FUNC_1 &pcfg_pull_none>, + <6 8 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + sdmmc { + sdmmc_clk: sdmmc-clk { + rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none>; + }; + + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdmmc_cd: sdmcc-cd { + rockchip,pins = <6 22 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdmmc_bus1: sdmmc-bus1 { + rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up>, + <6 17 RK_FUNC_1 &pcfg_pull_up>, + <6 18 RK_FUNC_1 &pcfg_pull_up>, + <6 19 RK_FUNC_1 &pcfg_pull_up>; + }; + }; + + sdio0 { + sdio0_bus1: sdio0-bus1 { + rockchip,pins = <4 20 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_bus4: sdio0-bus4 { + rockchip,pins = <4 20 RK_FUNC_1 &pcfg_pull_up>, + <4 21 RK_FUNC_1 &pcfg_pull_up>, + <4 22 RK_FUNC_1 &pcfg_pull_up>, + <4 23 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_cmd: sdio0-cmd { + rockchip,pins = <4 24 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_clk: sdio0-clk { + rockchip,pins = <4 25 RK_FUNC_1 &pcfg_pull_none>; + }; + + sdio0_cd: sdio0-cd { + rockchip,pins = <4 26 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_wp: sdio0-wp { + rockchip,pins = <4 27 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_pwr: sdio0-pwr { + rockchip,pins = <4 28 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_bkpwr: sdio0-bkpwr { + rockchip,pins = <4 29 RK_FUNC_1 &pcfg_pull_up>; + }; + + sdio0_int: sdio0-int { + rockchip,pins = <4 30 RK_FUNC_1 &pcfg_pull_up>; + }; + }; + + sdio1 { + sdio1_bus1: sdio1-bus1 { + rockchip,pins = <3 24 RK_FUNC_4 &pcfg_pull_up>; + }; + + sdio1_bus4: sdio1-bus4 { + rockchip,pins = <3 24 RK_FUNC_4 &pcfg_pull_up>, + <3 25 RK_FUNC_4 &pcfg_pull_up>, + <3 26 RK_FUNC_4 &pcfg_pull_up>, + <3 27 RK_FUNC_4 &pcfg_pull_up>; + }; + + sdio1_cd: sdio1-cd { + rockchip,pins = <3 28 RK_FUNC_4 &pcfg_pull_up>; + }; + + sdio1_wp: sdio1-wp { + rockchip,pins = <3 29 RK_FUNC_4 &pcfg_pull_up>; + }; + + sdio1_bkpwr: sdio1-bkpwr { + rockchip,pins = <3 30 RK_FUNC_4 &pcfg_pull_up>; + }; + + sdio1_int: sdio1-int { + rockchip,pins = <3 31 RK_FUNC_4 &pcfg_pull_up>; + }; + + sdio1_cmd: sdio1-cmd { + rockchip,pins = <4 6 RK_FUNC_4 &pcfg_pull_up>; + }; + + sdio1_clk: sdio1-clk { + rockchip,pins = <4 7 RK_FUNC_4 &pcfg_pull_none>; + }; + + sdio1_pwr: sdio1-pwr { + rockchip,pins = <4 9 RK_FUNC_4 &pcfg_pull_up>; + }; + }; + + emmc { + emmc_clk: emmc-clk { + rockchip,pins = <3 18 RK_FUNC_2 &pcfg_pull_none>; + }; + + emmc_cmd: emmc-cmd { + rockchip,pins = <3 16 RK_FUNC_2 &pcfg_pull_up>; + }; + + emmc_pwr: emmc-pwr { + rockchip,pins = <3 9 RK_FUNC_2 &pcfg_pull_up>; + }; + + emmc_bus1: emmc-bus1 { + rockchip,pins = <3 0 RK_FUNC_2 &pcfg_pull_up>; + }; + + emmc_bus4: emmc-bus4 { + rockchip,pins = <3 0 RK_FUNC_2 &pcfg_pull_up>, + <3 1 RK_FUNC_2 &pcfg_pull_up>, + <3 2 RK_FUNC_2 &pcfg_pull_up>, + <3 3 RK_FUNC_2 &pcfg_pull_up>; + }; + + emmc_bus8: emmc-bus8 { + rockchip,pins = <3 0 RK_FUNC_2 &pcfg_pull_up>, + <3 1 RK_FUNC_2 &pcfg_pull_up>, + <3 2 RK_FUNC_2 &pcfg_pull_up>, + <3 3 RK_FUNC_2 &pcfg_pull_up>, + <3 4 RK_FUNC_2 &pcfg_pull_up>, + <3 5 RK_FUNC_2 &pcfg_pull_up>, + <3 6 RK_FUNC_2 &pcfg_pull_up>, + <3 7 RK_FUNC_2 &pcfg_pull_up>; + }; + }; + + spi0 { + spi0_clk: spi0-clk { + rockchip,pins = <5 12 RK_FUNC_1 &pcfg_pull_up>; + }; + spi0_cs0: spi0-cs0 { + rockchip,pins = <5 13 RK_FUNC_1 &pcfg_pull_up>; + }; + spi0_tx: spi0-tx { + rockchip,pins = <5 14 RK_FUNC_1 &pcfg_pull_up>; + }; + spi0_rx: spi0-rx { + rockchip,pins = <5 15 RK_FUNC_1 &pcfg_pull_up>; + }; + spi0_cs1: spi0-cs1 { + rockchip,pins = <5 16 RK_FUNC_1 &pcfg_pull_up>; + }; + }; + spi1 { + spi1_clk: spi1-clk { + rockchip,pins = <7 12 RK_FUNC_2 &pcfg_pull_up>; + }; + spi1_cs0: spi1-cs0 { + rockchip,pins = <7 13 RK_FUNC_2 &pcfg_pull_up>; + }; + spi1_rx: spi1-rx { + rockchip,pins = <7 14 RK_FUNC_2 &pcfg_pull_up>; + }; + spi1_tx: spi1-tx { + rockchip,pins = <7 15 RK_FUNC_2 &pcfg_pull_up>; + }; + }; + + spi2 { + spi2_cs1: spi2-cs1 { + rockchip,pins = <8 3 RK_FUNC_1 &pcfg_pull_up>; + }; + spi2_clk: spi2-clk { + rockchip,pins = <8 6 RK_FUNC_1 &pcfg_pull_up>; + }; + spi2_cs0: spi2-cs0 { + rockchip,pins = <8 7 RK_FUNC_1 &pcfg_pull_up>; + }; + spi2_rx: spi2-rx { + rockchip,pins = <8 8 RK_FUNC_1 &pcfg_pull_up>; + }; + spi2_tx: spi2-tx { + rockchip,pins = <8 9 RK_FUNC_1 &pcfg_pull_up>; + }; + }; + + uart0 { + uart0_xfer: uart0-xfer { + rockchip,pins = <4 16 RK_FUNC_1 &pcfg_pull_up>, + <4 17 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart0_cts: uart0-cts { + rockchip,pins = <4 18 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart0_rts: uart0-rts { + rockchip,pins = <4 19 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + uart1 { + uart1_xfer: uart1-xfer { + rockchip,pins = <5 8 RK_FUNC_1 &pcfg_pull_up>, + <5 9 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart1_cts: uart1-cts { + rockchip,pins = <5 10 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart1_rts: uart1-rts { + rockchip,pins = <5 11 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + uart2 { + uart2_xfer: uart2-xfer { + rockchip,pins = <7 22 RK_FUNC_1 &pcfg_pull_up>, + <7 23 RK_FUNC_1 &pcfg_pull_none>; + }; + /* no rts / cts for uart2 */ + }; + + uart3 { + uart3_xfer: uart3-xfer { + rockchip,pins = <7 7 RK_FUNC_1 &pcfg_pull_up>, + <7 8 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart3_cts: uart3-cts { + rockchip,pins = <7 9 RK_FUNC_1 &pcfg_pull_none>; + }; + + uart3_rts: uart3-rts { + rockchip,pins = <7 10 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + uart4 { + uart4_xfer: uart4-xfer { + rockchip,pins = <5 12 3 &pcfg_pull_up>, + <5 13 3 &pcfg_pull_none>; + }; + + uart4_cts: uart4-cts { + rockchip,pins = <5 14 3 &pcfg_pull_none>; + }; + + uart4_rts: uart4-rts { + rockchip,pins = <5 15 3 &pcfg_pull_none>; + }; + }; + + tsadc { + otp_out: otp-out { + rockchip,pins = <0 10 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + pwm0 { + pwm0_pin: pwm0-pin { + rockchip,pins = <7 0 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + pwm1 { + pwm1_pin: pwm1-pin { + rockchip,pins = <7 1 RK_FUNC_1 &pcfg_pull_none>; + }; + }; + + pwm2 { + pwm2_pin: pwm2-pin { + rockchip,pins = <7 22 RK_FUNC_3 &pcfg_pull_none>; + }; + }; + + pwm3 { + pwm3_pin: pwm3-pin { + rockchip,pins = <7 23 RK_FUNC_3 &pcfg_pull_none>; + }; + }; + + gmac { + rgmii_pins: rgmii-pins { + rockchip,pins = <3 30 3 &pcfg_pull_none>, + <3 31 3 &pcfg_pull_none>, + <3 26 3 &pcfg_pull_none>, + <3 27 3 &pcfg_pull_none>, + <3 28 3 &pcfg_pull_none_12ma>, + <3 29 3 &pcfg_pull_none_12ma>, + <3 24 3 &pcfg_pull_none_12ma>, + <3 25 3 &pcfg_pull_none_12ma>, + <4 0 3 &pcfg_pull_none>, + <4 5 3 &pcfg_pull_none>, + <4 6 3 &pcfg_pull_none>, + <4 9 3 &pcfg_pull_none_12ma>, + <4 4 3 &pcfg_pull_none_12ma>, + <4 1 3 &pcfg_pull_none>, + <4 3 3 &pcfg_pull_none>; + }; + + rmii_pins: rmii-pins { + rockchip,pins = <3 30 3 &pcfg_pull_none>, + <3 31 3 &pcfg_pull_none>, + <3 28 3 &pcfg_pull_none>, + <3 29 3 &pcfg_pull_none>, + <4 0 3 &pcfg_pull_none>, + <4 5 3 &pcfg_pull_none>, + <4 4 3 &pcfg_pull_none>, + <4 1 3 &pcfg_pull_none>, + <4 2 3 &pcfg_pull_none>, + <4 3 3 &pcfg_pull_none>; + }; + }; + }; + + power: power-controller { + compatible = "rockchip,rk3288-power-controller"; + #power-domain-cells = <1>; + rockchip,pmu = <&pmu>; + #address-cells = <1>; + #size-cells = <0>; + + pd_gpu { + reg = <RK3288_PD_GPU>; + clocks = <&cru ACLK_GPU>; + }; + + pd_hevc { + reg = <RK3288_PD_HEVC>; + clocks = <&cru ACLK_HEVC>, + <&cru SCLK_HEVC_CABAC>, + <&cru SCLK_HEVC_CORE>, + <&cru HCLK_HEVC>; + }; + + pd_vio { + reg = <RK3288_PD_VIO>; + clocks = <&cru ACLK_IEP>, + <&cru ACLK_ISP>, + <&cru ACLK_RGA>, + <&cru ACLK_VIP>, + <&cru ACLK_VOP0>, + <&cru ACLK_VOP1>, + <&cru DCLK_VOP0>, + <&cru DCLK_VOP1>, + <&cru HCLK_IEP>, + <&cru HCLK_ISP>, + <&cru HCLK_RGA>, + <&cru HCLK_VIP>, + <&cru HCLK_VOP0>, + <&cru HCLK_VOP1>, + <&cru PCLK_EDP_CTRL>, + <&cru PCLK_HDMI_CTRL>, + <&cru PCLK_LVDS_PHY>, + <&cru PCLK_MIPI_CSI>, + <&cru PCLK_MIPI_DSI0>, + <&cru PCLK_MIPI_DSI1>, + <&cru SCLK_EDP_24M>, + <&cru SCLK_EDP>, + <&cru SCLK_HDMI_CEC>, + <&cru SCLK_HDMI_HDCP>, + <&cru SCLK_ISP_JPE>, + <&cru SCLK_ISP>, + <&cru SCLK_RGA>; + }; + + pd_video { + reg = <RK3288_PD_VIDEO>; + clocks = <&cru ACLK_VCODEC>, + <&cru HCLK_VCODEC>; + }; + }; +}; diff --git a/doc/device-tree-bindings/clock/rockchip,rk3288-cru.txt b/doc/device-tree-bindings/clock/rockchip,rk3288-cru.txt new file mode 100644 index 0000000..c9fbb76 --- /dev/null +++ b/doc/device-tree-bindings/clock/rockchip,rk3288-cru.txt @@ -0,0 +1,61 @@ +* Rockchip RK3288 Clock and Reset Unit + +The RK3288 clock controller generates and supplies clock to various +controllers within the SoC and also implements a reset controller for SoC +peripherals. + +Required Properties: + +- compatible: should be "rockchip,rk3288-cru" +- reg: physical base address of the controller and length of memory mapped + region. +- #clock-cells: should be 1. +- #reset-cells: should be 1. + +Optional Properties: + +- rockchip,grf: phandle to the syscon managing the "general register files" + If missing pll rates are not changable, due to the missing pll lock status. + +Each clock is assigned an identifier and client nodes can use this identifier +to specify the clock which they consume. All available clocks are defined as +preprocessor macros in the dt-bindings/clock/rk3288-cru.h headers and can be +used in device tree sources. Similar macros exist for the reset sources in +these files. + +External clocks: + +There are several clocks that are generated outside the SoC. It is expected +that they are defined using standard clock bindings with following +clock-output-names: + - "xin24m" - crystal input - required, + - "xin32k" - rtc clock - optional, + - "ext_i2s" - external I2S clock - optional, + - "ext_hsadc" - external HSADC clock - optional, + - "ext_edp_24m" - external display port clock - optional, + - "ext_vip" - external VIP clock - optional, + - "ext_isp" - external ISP clock - optional, + - "ext_jtag" - external JTAG clock - optional + +Example: Clock controller node: + + cru: cru@20000000 { + compatible = "rockchip,rk3188-cru"; + reg = <0x20000000 0x1000>; + rockchip,grf = <&grf>; + + #clock-cells = <1>; + #reset-cells = <1>; + }; + +Example: UART controller node that consumes the clock generated by the clock + controller: + + uart0: serial@10124000 { + compatible = "snps,dw-apb-uart"; + reg = <0x10124000 0x400>; + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <1>; + clocks = <&cru SCLK_UART0>; + }; diff --git a/doc/device-tree-bindings/clock/rockchip.txt b/doc/device-tree-bindings/clock/rockchip.txt new file mode 100644 index 0000000..22f6769 --- /dev/null +++ b/doc/device-tree-bindings/clock/rockchip.txt @@ -0,0 +1,77 @@ +Device Tree Clock bindings for arch-rockchip + +This binding uses the common clock binding[1]. + +[1] Documentation/devicetree/bindings/clock/clock-bindings.txt + +== Gate clocks == + +These bindings are deprecated! +Please use the soc specific CRU bindings instead. + +The gate registers form a continuos block which makes the dt node +structure a matter of taste, as either all gates can be put into +one gate clock spanning all registers or they can be divided into +the 10 individual gates containing 16 clocks each. +The code supports both approaches. + +Required properties: +- compatible : "rockchip,rk2928-gate-clk" +- reg : shall be the control register address(es) for the clock. +- #clock-cells : from common clock binding; shall be set to 1 +- clock-output-names : the corresponding gate names that the clock controls +- clocks : should contain the parent clock for each individual gate, + therefore the number of clocks elements should match the number of + clock-output-names + +Example using multiple gate clocks: + + clk_gates0: gate-clk@200000d0 { + compatible = "rockchip,rk2928-gate-clk"; + reg = <0x200000d0 0x4>; + clocks = <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>, + <&dummy>, <&dummy>; + + clock-output-names = + "gate_core_periph", "gate_cpu_gpll", + "gate_ddrphy", "gate_aclk_cpu", + "gate_hclk_cpu", "gate_pclk_cpu", + "gate_atclk_cpu", "gate_i2s0", + "gate_i2s0_frac", "gate_i2s1", + "gate_i2s1_frac", "gate_i2s2", + "gate_i2s2_frac", "gate_spdif", + "gate_spdif_frac", "gate_testclk"; + + #clock-cells = <1>; + }; + + clk_gates1: gate-clk@200000d4 { + compatible = "rockchip,rk2928-gate-clk"; + reg = <0x200000d4 0x4>; + clocks = <&xin24m>, <&xin24m>, + <&xin24m>, <&dummy>, + <&dummy>, <&xin24m>, + <&xin24m>, <&dummy>, + <&xin24m>, <&dummy>, + <&xin24m>, <&dummy>, + <&xin24m>, <&dummy>, + <&xin24m>, <&dummy>; + + clock-output-names = + "gate_timer0", "gate_timer1", + "gate_timer2", "gate_jtag", + "gate_aclk_lcdc1_src", "gate_otgphy0", + "gate_otgphy1", "gate_ddr_gpll", + "gate_uart0", "gate_frac_uart0", + "gate_uart1", "gate_frac_uart1", + "gate_uart2", "gate_frac_uart2", + "gate_uart3", "gate_frac_uart3"; + + #clock-cells = <1>; + }; diff --git a/doc/device-tree-bindings/pinctrl/rockchip,pinctrl.txt b/doc/device-tree-bindings/pinctrl/rockchip,pinctrl.txt new file mode 100644 index 0000000..388b213 --- /dev/null +++ b/doc/device-tree-bindings/pinctrl/rockchip,pinctrl.txt @@ -0,0 +1,157 @@ +* Rockchip Pinmux Controller + +The Rockchip Pinmux Controller, enables the IC +to share one PAD to several functional blocks. The sharing is done by +multiplexing the PAD input/output signals. For each PAD there are several +muxing options with option 0 being the use as a GPIO. + +Please refer to pinctrl-bindings.txt in this directory for details of the +common pinctrl bindings used by client devices, including the meaning of the +phrase "pin configuration node". + +The Rockchip pin configuration node is a node of a group of pins which can be +used for a specific device or function. This node represents both mux and +config of the pins in that group. The 'pins' selects the function mode(also +named pin mode) this pin can work on and the 'config' configures various pad +settings such as pull-up, etc. + +The pins are grouped into up to 5 individual pin banks which need to be +defined as gpio sub-nodes of the pinmux controller. + +Required properties for iomux controller: + - compatible: one of "rockchip,rk2928-pinctrl", "rockchip,rk3066a-pinctrl" + "rockchip,rk3066b-pinctrl", "rockchip,rk3188-pinctrl" + "rockchip,rk3288-pinctrl" + - rockchip,grf: phandle referencing a syscon providing the + "general register files" + +Optional properties for iomux controller: + - rockchip,pmu: phandle referencing a syscon providing the pmu registers + as some SoCs carry parts of the iomux controller registers there. + Required for at least rk3188 and rk3288. + +Deprecated properties for iomux controller: + - reg: first element is the general register space of the iomux controller + It should be large enough to contain also separate pull registers. + second element is the separate pull register space of the rk3188. + Use rockchip,grf and rockchip,pmu described above instead. + +Required properties for gpio sub nodes: + - compatible: "rockchip,gpio-bank" + - reg: register of the gpio bank (different than the iomux registerset) + - interrupts: base interrupt of the gpio bank in the interrupt controller + - clocks: clock that drives this bank + - gpio-controller: identifies the node as a gpio controller and pin bank. + - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO + binding is used, the amount of cells must be specified as 2. See generic + GPIO binding documentation for description of particular cells. + - interrupt-controller: identifies the controller node as interrupt-parent. + - #interrupt-cells: the value of this property should be 2 and the interrupt + cells should use the standard two-cell scheme described in + bindings/interrupt-controller/interrupts.txt + +Deprecated properties for gpio sub nodes: + - compatible: "rockchip,rk3188-gpio-bank0" + - reg: second element: separate pull register for rk3188 bank0, use + rockchip,pmu described above instead + +Required properties for pin configuration node: + - rockchip,pins: 3 integers array, represents a group of pins mux and config + setting. The format is rockchip,pins = <PIN_BANK PIN_BANK_IDX MUX &phandle>. + The MUX 0 means gpio and MUX 1 to N mean the specific device function. + The phandle of a node containing the generic pinconfig options + to use, as described in pinctrl-bindings.txt in this directory. + +Examples: + +#include <dt-bindings/pinctrl/rockchip.h> + +... + +pinctrl@20008000 { + compatible = "rockchip,rk3066a-pinctrl"; + rockchip,grf = <&grf>; + + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio0: gpio0@20034000 { + compatible = "rockchip,gpio-bank"; + reg = <0x20034000 0x100>; + interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk_gates8 9>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + ... + + pcfg_pull_default: pcfg_pull_default { + bias-pull-pin-default + }; + + uart2 { + uart2_xfer: uart2-xfer { + rockchip,pins = <RK_GPIO1 8 1 &pcfg_pull_default>, + <RK_GPIO1 9 1 &pcfg_pull_default>; + }; + }; +}; + +uart2: serial@20064000 { + compatible = "snps,dw-apb-uart"; + reg = <0x20064000 0x400>; + interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; + reg-shift = <2>; + reg-io-width = <1>; + clocks = <&mux_uart2>; + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&uart2_xfer>; +}; + +Example for rk3188: + + pinctrl@20008000 { + compatible = "rockchip,rk3188-pinctrl"; + rockchip,grf = <&grf>; + rockchip,pmu = <&pmu>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + gpio0: gpio0@0x2000a000 { + compatible = "rockchip,rk3188-gpio-bank0"; + reg = <0x2000a000 0x100>; + interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk_gates8 9>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio1@0x2003c000 { + compatible = "rockchip,gpio-bank"; + reg = <0x2003c000 0x100>; + interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk_gates8 10>; + + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + + ... + + }; diff --git a/doc/device-tree-bindings/thermal/rockchip-thermal.txt b/doc/device-tree-bindings/thermal/rockchip-thermal.txt new file mode 100644 index 0000000..ef802de --- /dev/null +++ b/doc/device-tree-bindings/thermal/rockchip-thermal.txt @@ -0,0 +1,68 @@ +* Temperature Sensor ADC (TSADC) on rockchip SoCs + +Required properties: +- compatible : "rockchip,rk3288-tsadc" +- reg : physical base address of the controller and length of memory mapped + region. +- interrupts : The interrupt number to the cpu. The interrupt specifier format + depends on the interrupt controller. +- clocks : Must contain an entry for each entry in clock-names. +- clock-names : Shall be "tsadc" for the converter-clock, and "apb_pclk" for + the peripheral clock. +- resets : Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names : Must include the name "tsadc-apb". +- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description. +- rockchip,hw-tshut-temp : The hardware-controlled shutdown temperature value. +- rockchip,hw-tshut-mode : The hardware-controlled shutdown mode 0:CRU 1:GPIO. +- rockchip,hw-tshut-polarity : The hardware-controlled active polarity 0:LOW + 1:HIGH. + +Exiample: +tsadc: tsadc@ff280000 { + compatible = "rockchip,rk3288-tsadc"; + reg = <0xff280000 0x100>; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>; + clock-names = "tsadc", "apb_pclk"; + resets = <&cru SRST_TSADC>; + reset-names = "tsadc-apb"; + pinctrl-names = "default"; + pinctrl-0 = <&otp_out>; + #thermal-sensor-cells = <1>; + rockchip,hw-tshut-temp = <95000>; + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; +}; + +Example: referring to thermal sensors: +thermal-zones { + cpu_thermal: cpu_thermal { + polling-delay-passive = <1000>; /* milliseconds */ + polling-delay = <5000>; /* milliseconds */ + + /* sensor ID */ + thermal-sensors = <&tsadc 1>; + + trips { + cpu_alert0: cpu_alert { + temperature = <70000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "passive"; + }; + cpu_crit: cpu_crit { + temperature = <90000>; /* millicelsius */ + hysteresis = <2000>; /* millicelsius */ + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert0>; + cooling-device = + <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +}; diff --git a/include/dt-bindings/clock/rk3288-cru.h b/include/dt-bindings/clock/rk3288-cru.h new file mode 100644 index 0000000..dea4197 --- /dev/null +++ b/include/dt-bindings/clock/rk3288-cru.h @@ -0,0 +1,378 @@ +/* + * Copyright (c) 2014 MundoReader S.L. + * Author: Heiko Stuebner heiko@sntech.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + */ + +/* core clocks */ +#define PLL_APLL 1 +#define PLL_DPLL 2 +#define PLL_CPLL 3 +#define PLL_GPLL 4 +#define PLL_NPLL 5 +#define ARMCLK 6 + +/* sclk gates (special clocks) */ +#define SCLK_GPU 64 +#define SCLK_SPI0 65 +#define SCLK_SPI1 66 +#define SCLK_SPI2 67 +#define SCLK_SDMMC 68 +#define SCLK_SDIO0 69 +#define SCLK_SDIO1 70 +#define SCLK_EMMC 71 +#define SCLK_TSADC 72 +#define SCLK_SARADC 73 +#define SCLK_PS2C 74 +#define SCLK_NANDC0 75 +#define SCLK_NANDC1 76 +#define SCLK_UART0 77 +#define SCLK_UART1 78 +#define SCLK_UART2 79 +#define SCLK_UART3 80 +#define SCLK_UART4 81 +#define SCLK_I2S0 82 +#define SCLK_SPDIF 83 +#define SCLK_SPDIF8CH 84 +#define SCLK_TIMER0 85 +#define SCLK_TIMER1 86 +#define SCLK_TIMER2 87 +#define SCLK_TIMER3 88 +#define SCLK_TIMER4 89 +#define SCLK_TIMER5 90 +#define SCLK_TIMER6 91 +#define SCLK_HSADC 92 +#define SCLK_OTGPHY0 93 +#define SCLK_OTGPHY1 94 +#define SCLK_OTGPHY2 95 +#define SCLK_OTG_ADP 96 +#define SCLK_HSICPHY480M 97 +#define SCLK_HSICPHY12M 98 +#define SCLK_MACREF 99 +#define SCLK_LCDC_PWM0 100 +#define SCLK_LCDC_PWM1 101 +#define SCLK_MAC_RX 102 +#define SCLK_MAC_TX 103 +#define SCLK_EDP_24M 104 +#define SCLK_EDP 105 +#define SCLK_RGA 106 +#define SCLK_ISP 107 +#define SCLK_ISP_JPE 108 +#define SCLK_HDMI_HDCP 109 +#define SCLK_HDMI_CEC 110 +#define SCLK_HEVC_CABAC 111 +#define SCLK_HEVC_CORE 112 +#define SCLK_I2S0_OUT 113 +#define SCLK_SDMMC_DRV 114 +#define SCLK_SDIO0_DRV 115 +#define SCLK_SDIO1_DRV 116 +#define SCLK_EMMC_DRV 117 +#define SCLK_SDMMC_SAMPLE 118 +#define SCLK_SDIO0_SAMPLE 119 +#define SCLK_SDIO1_SAMPLE 120 +#define SCLK_EMMC_SAMPLE 121 +#define SCLK_USBPHY480M_SRC 122 +#define SCLK_PVTM_CORE 123 +#define SCLK_PVTM_GPU 124 + +#define SCLK_MAC 151 +#define SCLK_MACREF_OUT 152 + +#define DCLK_VOP0 190 +#define DCLK_VOP1 191 + +/* aclk gates */ +#define ACLK_GPU 192 +#define ACLK_DMAC1 193 +#define ACLK_DMAC2 194 +#define ACLK_MMU 195 +#define ACLK_GMAC 196 +#define ACLK_VOP0 197 +#define ACLK_VOP1 198 +#define ACLK_CRYPTO 199 +#define ACLK_RGA 200 +#define ACLK_RGA_NIU 201 +#define ACLK_IEP 202 +#define ACLK_VIO0_NIU 203 +#define ACLK_VIP 204 +#define ACLK_ISP 205 +#define ACLK_VIO1_NIU 206 +#define ACLK_HEVC 207 +#define ACLK_VCODEC 208 +#define ACLK_CPU 209 +#define ACLK_PERI 210 + +/* pclk gates */ +#define PCLK_GPIO0 320 +#define PCLK_GPIO1 321 +#define PCLK_GPIO2 322 +#define PCLK_GPIO3 323 +#define PCLK_GPIO4 324 +#define PCLK_GPIO5 325 +#define PCLK_GPIO6 326 +#define PCLK_GPIO7 327 +#define PCLK_GPIO8 328 +#define PCLK_GRF 329 +#define PCLK_SGRF 330 +#define PCLK_PMU 331 +#define PCLK_I2C0 332 +#define PCLK_I2C1 333 +#define PCLK_I2C2 334 +#define PCLK_I2C3 335 +#define PCLK_I2C4 336 +#define PCLK_I2C5 337 +#define PCLK_SPI0 338 +#define PCLK_SPI1 339 +#define PCLK_SPI2 340 +#define PCLK_UART0 341 +#define PCLK_UART1 342 +#define PCLK_UART2 343 +#define PCLK_UART3 344 +#define PCLK_UART4 345 +#define PCLK_TSADC 346 +#define PCLK_SARADC 347 +#define PCLK_SIM 348 +#define PCLK_GMAC 349 +#define PCLK_PWM 350 +#define PCLK_RKPWM 351 +#define PCLK_PS2C 352 +#define PCLK_TIMER 353 +#define PCLK_TZPC 354 +#define PCLK_EDP_CTRL 355 +#define PCLK_MIPI_DSI0 356 +#define PCLK_MIPI_DSI1 357 +#define PCLK_MIPI_CSI 358 +#define PCLK_LVDS_PHY 359 +#define PCLK_HDMI_CTRL 360 +#define PCLK_VIO2_H2P 361 +#define PCLK_CPU 362 +#define PCLK_PERI 363 +#define PCLK_DDRUPCTL0 364 +#define PCLK_PUBL0 365 +#define PCLK_DDRUPCTL1 366 +#define PCLK_PUBL1 367 +#define PCLK_WDT 368 + +/* hclk gates */ +#define HCLK_GPS 448 +#define HCLK_OTG0 449 +#define HCLK_USBHOST0 450 +#define HCLK_USBHOST1 451 +#define HCLK_HSIC 452 +#define HCLK_NANDC0 453 +#define HCLK_NANDC1 454 +#define HCLK_TSP 455 +#define HCLK_SDMMC 456 +#define HCLK_SDIO0 457 +#define HCLK_SDIO1 458 +#define HCLK_EMMC 459 +#define HCLK_HSADC 460 +#define HCLK_CRYPTO 461 +#define HCLK_I2S0 462 +#define HCLK_SPDIF 463 +#define HCLK_SPDIF8CH 464 +#define HCLK_VOP0 465 +#define HCLK_VOP1 466 +#define HCLK_ROM 467 +#define HCLK_IEP 468 +#define HCLK_ISP 469 +#define HCLK_RGA 470 +#define HCLK_VIO_AHB_ARBI 471 +#define HCLK_VIO_NIU 472 +#define HCLK_VIP 473 +#define HCLK_VIO2_H2P 474 +#define HCLK_HEVC 475 +#define HCLK_VCODEC 476 +#define HCLK_CPU 477 +#define HCLK_PERI 478 + +#define CLK_NR_CLKS (HCLK_PERI + 1) + +/* soft-reset indices */ +#define SRST_CORE0 0 +#define SRST_CORE1 1 +#define SRST_CORE2 2 +#define SRST_CORE3 3 +#define SRST_CORE0_PO 4 +#define SRST_CORE1_PO 5 +#define SRST_CORE2_PO 6 +#define SRST_CORE3_PO 7 +#define SRST_PDCORE_STRSYS 8 +#define SRST_PDBUS_STRSYS 9 +#define SRST_L2C 10 +#define SRST_TOPDBG 11 +#define SRST_CORE0_DBG 12 +#define SRST_CORE1_DBG 13 +#define SRST_CORE2_DBG 14 +#define SRST_CORE3_DBG 15 + +#define SRST_PDBUG_AHB_ARBITOR 16 +#define SRST_EFUSE256 17 +#define SRST_DMAC1 18 +#define SRST_INTMEM 19 +#define SRST_ROM 20 +#define SRST_SPDIF8CH 21 +#define SRST_TIMER 22 +#define SRST_I2S0 23 +#define SRST_SPDIF 24 +#define SRST_TIMER0 25 +#define SRST_TIMER1 26 +#define SRST_TIMER2 27 +#define SRST_TIMER3 28 +#define SRST_TIMER4 29 +#define SRST_TIMER5 30 +#define SRST_EFUSE 31 + +#define SRST_GPIO0 32 +#define SRST_GPIO1 33 +#define SRST_GPIO2 34 +#define SRST_GPIO3 35 +#define SRST_GPIO4 36 +#define SRST_GPIO5 37 +#define SRST_GPIO6 38 +#define SRST_GPIO7 39 +#define SRST_GPIO8 40 +#define SRST_I2C0 42 +#define SRST_I2C1 43 +#define SRST_I2C2 44 +#define SRST_I2C3 45 +#define SRST_I2C4 46 +#define SRST_I2C5 47 + +#define SRST_DWPWM 48 +#define SRST_MMC_PERI 49 +#define SRST_PERIPH_MMU 50 +#define SRST_DAP 51 +#define SRST_DAP_SYS 52 +#define SRST_TPIU 53 +#define SRST_PMU_APB 54 +#define SRST_GRF 55 +#define SRST_PMU 56 +#define SRST_PERIPH_AXI 57 +#define SRST_PERIPH_AHB 58 +#define SRST_PERIPH_APB 59 +#define SRST_PERIPH_NIU 60 +#define SRST_PDPERI_AHB_ARBI 61 +#define SRST_EMEM 62 +#define SRST_USB_PERI 63 + +#define SRST_DMAC2 64 +#define SRST_MAC 66 +#define SRST_GPS 67 +#define SRST_RKPWM 69 +#define SRST_CCP 71 +#define SRST_USBHOST0 72 +#define SRST_HSIC 73 +#define SRST_HSIC_AUX 74 +#define SRST_HSIC_PHY 75 +#define SRST_HSADC 76 +#define SRST_NANDC0 77 +#define SRST_NANDC1 78 + +#define SRST_TZPC 80 +#define SRST_SPI0 83 +#define SRST_SPI1 84 +#define SRST_SPI2 85 +#define SRST_SARADC 87 +#define SRST_PDALIVE_NIU 88 +#define SRST_PDPMU_INTMEM 89 +#define SRST_PDPMU_NIU 90 +#define SRST_SGRF 91 + +#define SRST_VIO_ARBI 96 +#define SRST_RGA_NIU 97 +#define SRST_VIO0_NIU_AXI 98 +#define SRST_VIO_NIU_AHB 99 +#define SRST_LCDC0_AXI 100 +#define SRST_LCDC0_AHB 101 +#define SRST_LCDC0_DCLK 102 +#define SRST_VIO1_NIU_AXI 103 +#define SRST_VIP 104 +#define SRST_RGA_CORE 105 +#define SRST_IEP_AXI 106 +#define SRST_IEP_AHB 107 +#define SRST_RGA_AXI 108 +#define SRST_RGA_AHB 109 +#define SRST_ISP 110 +#define SRST_EDP 111 + +#define SRST_VCODEC_AXI 112 +#define SRST_VCODEC_AHB 113 +#define SRST_VIO_H2P 114 +#define SRST_MIPIDSI0 115 +#define SRST_MIPIDSI1 116 +#define SRST_MIPICSI 117 +#define SRST_LVDS_PHY 118 +#define SRST_LVDS_CON 119 +#define SRST_GPU 120 +#define SRST_HDMI 121 +#define SRST_CORE_PVTM 124 +#define SRST_GPU_PVTM 125 + +#define SRST_MMC0 128 +#define SRST_SDIO0 129 +#define SRST_SDIO1 130 +#define SRST_EMMC 131 +#define SRST_USBOTG_AHB 132 +#define SRST_USBOTG_PHY 133 +#define SRST_USBOTG_CON 134 +#define SRST_USBHOST0_AHB 135 +#define SRST_USBHOST0_PHY 136 +#define SRST_USBHOST0_CON 137 +#define SRST_USBHOST1_AHB 138 +#define SRST_USBHOST1_PHY 139 +#define SRST_USBHOST1_CON 140 +#define SRST_USB_ADP 141 +#define SRST_ACC_EFUSE 142 + +#define SRST_CORESIGHT 144 +#define SRST_PD_CORE_AHB_NOC 145 +#define SRST_PD_CORE_APB_NOC 146 +#define SRST_PD_CORE_MP_AXI 147 +#define SRST_GIC 148 +#define SRST_LCDC_PWM0 149 +#define SRST_LCDC_PWM1 150 +#define SRST_VIO0_H2P_BRG 151 +#define SRST_VIO1_H2P_BRG 152 +#define SRST_RGA_H2P_BRG 153 +#define SRST_HEVC 154 +#define SRST_TSADC 159 + +#define SRST_DDRPHY0 160 +#define SRST_DDRPHY0_APB 161 +#define SRST_DDRCTRL0 162 +#define SRST_DDRCTRL0_APB 163 +#define SRST_DDRPHY0_CTRL 164 +#define SRST_DDRPHY1 165 +#define SRST_DDRPHY1_APB 166 +#define SRST_DDRCTRL1 167 +#define SRST_DDRCTRL1_APB 168 +#define SRST_DDRPHY1_CTRL 169 +#define SRST_DDRMSCH0 170 +#define SRST_DDRMSCH1 171 +#define SRST_CRYPTO 174 +#define SRST_C2C_HOST 175 + +#define SRST_LCDC1_AXI 176 +#define SRST_LCDC1_AHB 177 +#define SRST_LCDC1_DCLK 178 +#define SRST_UART0 179 +#define SRST_UART1 180 +#define SRST_UART2 181 +#define SRST_UART3 182 +#define SRST_UART4 183 +#define SRST_SIMC 186 +#define SRST_PS2C 187 +#define SRST_TSP 188 +#define SRST_TSP_CLKIN0 189 +#define SRST_TSP_CLKIN1 190 +#define SRST_TSP_27M 191 diff --git a/include/dt-bindings/clock/rockchip,rk808.h b/include/dt-bindings/clock/rockchip,rk808.h new file mode 100644 index 0000000..1a87343 --- /dev/null +++ b/include/dt-bindings/clock/rockchip,rk808.h @@ -0,0 +1,11 @@ +/* + * This header provides constants clk index RK808 pmic clkout + */ +#ifndef _CLK_ROCKCHIP_RK808 +#define _CLK_ROCKCHIP_RK808 + +/* CLOCKOUT index */ +#define RK808_CLKOUT0 0 +#define RK808_CLKOUT1 1 + +#endif diff --git a/include/dt-bindings/pinctrl/rockchip.h b/include/dt-bindings/pinctrl/rockchip.h new file mode 100644 index 0000000..743e66a --- /dev/null +++ b/include/dt-bindings/pinctrl/rockchip.h @@ -0,0 +1,34 @@ +/* + * Header providing constants for Rockchip pinctrl bindings. + * + * Copyright (c) 2013 MundoReader S.L. + * Author: Heiko Stuebner heiko@sntech.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 __DT_BINDINGS_ROCKCHIP_PINCTRL_H__ +#define __DT_BINDINGS_ROCKCHIP_PINCTRL_H__ + +#define RK_GPIO0 0 +#define RK_GPIO1 1 +#define RK_GPIO2 2 +#define RK_GPIO3 3 +#define RK_GPIO4 4 +#define RK_GPIO6 6 + +#define RK_FUNC_GPIO 0 +#define RK_FUNC_1 1 +#define RK_FUNC_2 2 +#define RK_FUNC_3 3 +#define RK_FUNC_4 4 + +#endif diff --git a/include/dt-bindings/power-domain/rk3288.h b/include/dt-bindings/power-domain/rk3288.h new file mode 100644 index 0000000..ca68c11 --- /dev/null +++ b/include/dt-bindings/power-domain/rk3288.h @@ -0,0 +1,11 @@ +#ifndef __DT_BINDINGS_POWER_DOMAIN_RK3288_H__ +#define __DT_BINDINGS_POWER_DOMAIN_RK3288_H__ + +/* RK3288 power domain index */ +#define RK3288_PD_GPU 0 +#define RK3288_PD_VIO 1 +#define RK3288_PD_VIDEO 2 +#define RK3288_PD_HEVC 3 +#define RK3288_PD_PERI 4 + +#endif diff --git a/include/dt-bindings/thermal/thermal.h b/include/dt-bindings/thermal/thermal.h new file mode 100644 index 0000000..59822a9 --- /dev/null +++ b/include/dt-bindings/thermal/thermal.h @@ -0,0 +1,17 @@ +/* + * This header provides constants for most thermal bindings. + * + * Copyright (C) 2013 Texas Instruments + * Eduardo Valentin eduardo.valentin@ti.com + * + * GPLv2 only + */ + +#ifndef _DT_BINDINGS_THERMAL_THERMAL_H +#define _DT_BINDINGS_THERMAL_THERMAL_H + +/* On cooling devices upper and lower limits */ +#define THERMAL_NO_LIMIT (-1UL) + +#endif +

The 'fdtgrep' tool would probably provide a better solution here, but for now we can use the C preprocessor to remove the parts of the device tree which are not needed in SPL.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/dts/rk3288.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/arch/arm/dts/rk3288.dtsi b/arch/arm/dts/rk3288.dtsi index 8251441..8386bb2 100644 --- a/arch/arm/dts/rk3288.dtsi +++ b/arch/arm/dts/rk3288.dtsi @@ -22,8 +22,11 @@ / { compatible = "rockchip,rk3288";
+#ifndef CONFIG_SPL_BUILD interrupt-parent = <&gic>; +#endif aliases { +#ifndef CONFIG_SPL_BUILD i2c0 = &i2c0; i2c1 = &i2c1; i2c2 = &i2c2; @@ -38,16 +41,22 @@ mshc1 = &sdmmc; mshc2 = &sdio0; mshc3 = &sdio1; +#endif +#ifndef CONFIG_SPL_BUILD serial0 = &uart0; serial1 = &uart1; +#endif serial2 = &uart2; +#ifndef CONFIG_SPL_BUILD serial3 = &uart3; serial4 = &uart4; spi0 = &spi0; spi1 = &spi1; spi2 = &spi2; +#endif };
+#ifndef CONFIG_SPL_BUILD cpus { #address-cells = <1>; #size-cells = <0>; @@ -342,6 +351,7 @@ pinctrl-0 = <&uart1_xfer>; status = "disabled"; }; +#endif
uart2: serial@ff690000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; @@ -349,12 +359,15 @@ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; reg-shift = <2>; reg-io-width = <4>; +#ifndef CONFIG_SPL_BUILD clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; clock-names = "baudclk", "apb_pclk"; pinctrl-names = "default"; pinctrl-0 = <&uart2_xfer>; +#endif status = "disabled"; }; +#ifndef CONFIG_SPL_BUILD uart3: serial@ff1b0000 { compatible = "rockchip,rk3288-uart", "snps,dw-apb-uart"; reg = <0xff1b0000 0x100>; @@ -1463,4 +1476,5 @@ <&cru HCLK_VCODEC>; }; }; +#endif };

Add some basic files required to allow the SoC to start up. This is a minimal set, enough only to display a serial message in SPL and hang.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/Kconfig | 9 ++ arch/arm/Makefile | 1 + arch/arm/include/asm/arch-rockchip/clock.h | 12 ++ arch/arm/include/asm/arch-rockchip/gpio.h | 5 + arch/arm/include/asm/arch-rockchip/grf.h | 181 +++++++++++++++++++++++++++++ arch/arm/mach-rockchip/Kconfig | 44 +++++++ arch/arm/mach-rockchip/Makefile | 12 ++ arch/arm/mach-rockchip/board-spl.c | 54 +++++++++ arch/arm/mach-rockchip/board.c | 17 +++ arch/arm/mach-rockchip/common.c | 11 ++ arch/arm/mach-rockchip/rk3288/Kconfig | 6 + 11 files changed, 352 insertions(+) create mode 100644 arch/arm/include/asm/arch-rockchip/clock.h create mode 100644 arch/arm/include/asm/arch-rockchip/gpio.h create mode 100644 arch/arm/include/asm/arch-rockchip/grf.h create mode 100644 arch/arm/mach-rockchip/Kconfig create mode 100644 arch/arm/mach-rockchip/Makefile create mode 100644 arch/arm/mach-rockchip/board-spl.c create mode 100644 arch/arm/mach-rockchip/board.c create mode 100644 arch/arm/mach-rockchip/common.c create mode 100644 arch/arm/mach-rockchip/rk3288/Kconfig
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f0e6dec..1eee2d8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -693,6 +693,13 @@ config ARCH_UNIPHIER select OF_CONTROL select SPL_DISABLE_OF_CONTROL
+config ARCH_ROCKCHIP + bool "Support Rockchip SoCs" + select SUPPORT_SPL + select SPL + select OF_CONTROL + select CPU_V7 + endchoice
source "arch/arm/mach-at91/Kconfig" @@ -721,6 +728,8 @@ source "arch/arm/mach-orion5x/Kconfig"
source "arch/arm/cpu/armv7/rmobile/Kconfig"
+source "arch/arm/mach-rockchip/Kconfig" + source "arch/arm/cpu/armv7/s5pc1xx/Kconfig"
source "arch/arm/mach-tegra/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 878ae26..29945c4 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -14,6 +14,7 @@ machine-$(CONFIG_KIRKWOOD) += kirkwood machine-$(CONFIG_ARCH_NOMADIK) += nomadik # TODO: rename CONFIG_ORION5X -> CONFIG_ARCH_ORION5X machine-$(CONFIG_ORION5X) += orion5x +machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip machine-$(CONFIG_TEGRA) += tegra machine-$(CONFIG_ARCH_VERSATILE) += versatile
diff --git a/arch/arm/include/asm/arch-rockchip/clock.h b/arch/arm/include/asm/arch-rockchip/clock.h new file mode 100644 index 0000000..9314585 --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/clock.h @@ -0,0 +1,12 @@ +/* + * (C) Copyright 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef _ASM_ARCH_CLOCK_H +#define _ASM_ARCH_CLOCK_H + +#define OSC_HZ (24 * 1000 * 1000) + +#endif diff --git a/arch/arm/include/asm/arch-rockchip/gpio.h b/arch/arm/include/asm/arch-rockchip/gpio.h new file mode 100644 index 0000000..607949c --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/gpio.h @@ -0,0 +1,5 @@ +/* + * (C) Copyright 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ diff --git a/arch/arm/include/asm/arch-rockchip/grf.h b/arch/arm/include/asm/arch-rockchip/grf.h new file mode 100644 index 0000000..8722a89 --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/grf.h @@ -0,0 +1,181 @@ +/* + * (C) Copyright 2015 Google, Inc + * Copyright 2014 Rockchip Inc. + * + * SPDX-License-Identifier: GPL-2.0 + * + * From coreboot file of the same name + */ + +#ifndef _ASM_ARCH_GRF_H +#define _ASM_ARCH_GRF_H + +struct rk3288_grf_gpio_lh { + u32 l; + u32 h; +}; + +struct rk3288_grf_regs { + u32 reserved[3]; + union { + u32 gpio1d_iomux; + u32 iomux_lcdc; + }; + u32 gpio2a_iomux; + u32 gpio2b_iomux; + union { + u32 gpio2c_iomux; + u32 iomux_i2c3; + }; + u32 reserved2; + union { + u32 gpio3a_iomux; + u32 iomux_emmcdata; + }; + union { + u32 gpio3b_iomux; + u32 iomux_emmcpwren; + }; + union { + u32 gpio3c_iomux; + u32 iomux_emmccmd; + }; + u32 gpio3dl_iomux; + u32 gpio3dh_iomux; + u32 gpio4al_iomux; + u32 gpio4ah_iomux; + u32 gpio4bl_iomux; + u32 reserved3; + u32 gpio4c_iomux; + u32 gpio4d_iomux; + u32 reserved4; + union { + u32 gpio5b_iomux; + u32 iomux_spi0; + }; + u32 gpio5c_iomux; + u32 reserved5; + union { + u32 gpio6a_iomux; + u32 iomux_i2s; + }; + union { + u32 gpio6b_iomux; + u32 iomux_i2c2; + u32 iomux_i2sclk; + }; + union { + u32 gpio6c_iomux; + u32 iomux_sdmmc0; + }; + u32 reserved6; + union { + u32 gpio7a_iomux; + u32 iomux_pwm0; + u32 iomux_pwm1; + }; + union { + u32 gpio7b_iomux; + u32 iomux_edp_hotplug; + }; + union { + u32 gpio7cl_iomux; + u32 iomux_i2c5sda; + u32 iomux_i2c4; + }; + union { + u32 gpio7ch_iomux; + u32 iomux_uart2; + u32 iomux_i2c5scl; + }; + u32 reserved7; + union { + u32 gpio8a_iomux; + u32 iomux_spi2csclk; + u32 iomux_i2c1; + }; + union { + u32 gpio8b_iomux; + u32 iomux_spi2txrx; + }; + u32 reserved8[30]; + struct rk3288_grf_gpio_lh gpio_sr[8]; + u32 gpio1_p[8][4]; + u32 gpio1_e[8][4]; + u32 gpio_smt; + u32 soc_con0; + u32 soc_con1; + u32 soc_con2; + u32 soc_con3; + u32 soc_con4; + u32 soc_con5; + u32 soc_con6; + u32 soc_con7; + u32 soc_con8; + u32 soc_con9; + u32 soc_con10; + u32 soc_con11; + u32 soc_con12; + u32 soc_con13; + u32 soc_con14; + u32 soc_status[22]; + u32 reserved9[2]; + u32 peridmac_con[4]; + u32 ddrc0_con0; + u32 ddrc1_con0; + u32 cpu_con[5]; + u32 reserved10[3]; + u32 cpu_status0; + u32 reserved11; + u32 uoc0_con[5]; + u32 uoc1_con[5]; + u32 uoc2_con[4]; + u32 uoc3_con[2]; + u32 uoc4_con[2]; + u32 pvtm_con[3]; + u32 pvtm_status[3]; + u32 io_vsel; + u32 saradc_testbit; + u32 tsadc_testbit_l; + u32 tsadc_testbit_h; + u32 os_reg[4]; + u32 reserved12; + u32 soc_con15; + u32 soc_con16; +}; + +struct rk3288_sgrf_regs { + u32 soc_con0; + u32 soc_con1; + u32 soc_con2; + u32 soc_con3; + u32 soc_con4; + u32 soc_con5; + u32 reserved1[(0x20-0x18)/4]; + u32 busdmac_con[2]; + u32 reserved2[(0x40-0x28)/4]; + u32 cpu_con[3]; + u32 reserved3[(0x50-0x4c)/4]; + u32 soc_con6; + u32 soc_con7; + u32 soc_con8; + u32 soc_con9; + u32 soc_con10; + u32 soc_con11; + u32 soc_con12; + u32 soc_con13; + u32 soc_con14; + u32 soc_con15; + u32 soc_con16; + u32 soc_con17; + u32 soc_con18; + u32 soc_con19; + u32 soc_con20; + u32 soc_con21; + u32 reserved4[(0x100-0x90)/4]; + u32 soc_status[2]; + u32 reserved5[(0x120-0x108)/4]; + u32 fast_boot_addr; +}; + +#endif diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig new file mode 100644 index 0000000..dba0a45 --- /dev/null +++ b/arch/arm/mach-rockchip/Kconfig @@ -0,0 +1,44 @@ +if ARCH_ROCKCHIP + +config ROCKCHIP_RK3288 + bool "Support Rockchip RK3288" + help + The Rockchip RK3288 is a ARM-based SoC with a quad-core Cortex-A17 + including NEON and GPU, 1MB L2 cache, Mali-T7 graphics, two + video interfaces supporting HDMI and eDP, several DDR3 options + and video codec support. Peripherals include Gigabit Ethernet, + USB2 host and OTG, SDIO, I2S, UART,s, SPI, I2C and PWMs. + +config SYS_MALLOC_F + default y + +config SYS_MALLOC_F_LEN + default 0x800 + +config DM + default y + +config SPL_DM + default y + +config DM_SERIAL + default y + +config DM_SPI + default y + +config DM_SPI_FLASH + default y + +config DM_I2C + default y + +config DM_GPIO + default y + +config ROCKCHIP_SERIAL + default y + +source "arch/arm/mach-rockchip/rk3288/Kconfig" + +endif diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile new file mode 100644 index 0000000..0cef0a2 --- /dev/null +++ b/arch/arm/mach-rockchip/Makefile @@ -0,0 +1,12 @@ +# +# Copyright (c) 2014 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifdef CONFIG_SPL_BUILD +obj-y += board-spl.o +else +obj-y += board.o +endif +obj-y += common.o diff --git a/arch/arm/mach-rockchip/board-spl.c b/arch/arm/mach-rockchip/board-spl.c new file mode 100644 index 0000000..a6e0ec9 --- /dev/null +++ b/arch/arm/mach-rockchip/board-spl.c @@ -0,0 +1,54 @@ +/* + * (C) Copyright 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <fdtdec.h> +#include <malloc.h> +#include <spl.h> +#include <asm/io.h> +#include <asm/arch/grf.h> +#include <dm/root.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define RK_CLRSETBITS(clr, set) ((((clr) | (set)) << 16) | set) +#define IOMUX_UART2 RK_CLRSETBITS(7 << 12 | 3 << 8, 1 << 12 | 1 << 8) +#define GRF_BASE 0xFF770000 + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_SPI; +} + +void spl_board_load_image(void) +{ +} + +void board_init_f(ulong dummy) +{ + struct rk3288_grf_regs * const rk3288_grf = (void *)GRF_BASE; + + writel(IOMUX_UART2, &rk3288_grf->iomux_uart2); + + /* + * Debug UART can be used from here if required: + * + * debug_uart_init(); + * printch('a'); + * printhex8(0x1234); + * printascii("string"); + */ + + /* Clear the BSS */ + memset(__bss_start, 0, __bss_end - __bss_start); + + board_init_r(NULL, 0); +} + +void spl_board_init(void) +{ + preloader_console_init(); +} diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c new file mode 100644 index 0000000..38d2b40 --- /dev/null +++ b/arch/arm/mach-rockchip/board.c @@ -0,0 +1,17 @@ +/* + * (C) Copyright 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +int board_init(void) +{ + return 0; +} + +int dram_init(void) +{ + return 0; +} diff --git a/arch/arm/mach-rockchip/common.c b/arch/arm/mach-rockchip/common.c new file mode 100644 index 0000000..51ea34d --- /dev/null +++ b/arch/arm/mach-rockchip/common.c @@ -0,0 +1,11 @@ +/* + * (C) Copyright 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +void reset_cpu(ulong addr) +{ +} diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig new file mode 100644 index 0000000..26d5951 --- /dev/null +++ b/arch/arm/mach-rockchip/rk3288/Kconfig @@ -0,0 +1,6 @@ +if ROCKCHIP_RK3288 + +config SYS_SOC + default "rockchip" + +endif

The Firefly RK3288 is a suitable target board for initial mainline Rockchip support. It includes a good set of peripherals, a recent SoC and it is readily available.
This adds only some basic files required to allow the baord to display a serial message in SPL and hang.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/dts/Makefile | 2 + arch/arm/dts/rk3288-firefly.dts | 82 +++++ arch/arm/dts/rk3288-firefly.dtsi | 496 ++++++++++++++++++++++++++ arch/arm/mach-rockchip/rk3288/Kconfig | 10 + board/firefly/firefly-rk3288/Kconfig | 15 + board/firefly/firefly-rk3288/MAINTAINERS | 6 + board/firefly/firefly-rk3288/Makefile | 7 + board/firefly/firefly-rk3288/firefly-rk3288.c | 7 + configs/firefly-rk3288_defconfig | 11 + include/configs/firefly-rk3288.h | 50 +++ 10 files changed, 686 insertions(+) create mode 100644 arch/arm/dts/rk3288-firefly.dts create mode 100644 arch/arm/dts/rk3288-firefly.dtsi create mode 100644 board/firefly/firefly-rk3288/Kconfig create mode 100644 board/firefly/firefly-rk3288/MAINTAINERS create mode 100644 board/firefly/firefly-rk3288/Makefile create mode 100644 board/firefly/firefly-rk3288/firefly-rk3288.c create mode 100644 configs/firefly-rk3288_defconfig create mode 100644 include/configs/firefly-rk3288.h
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 6b9d8ea..234254f 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -15,6 +15,8 @@ dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \ exynos5420-peach-pit.dtb \ exynos5800-peach-pi.dtb \ exynos5422-odroidxu3.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += \ + rk3288-firefly.dtb dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \ tegra20-medcom-wide.dtb \ tegra20-paz00.dtb \ diff --git a/arch/arm/dts/rk3288-firefly.dts b/arch/arm/dts/rk3288-firefly.dts new file mode 100644 index 0000000..f18bccf --- /dev/null +++ b/arch/arm/dts/rk3288-firefly.dts @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2014, 2015 FUKAUMI Naoki naobsd@gmail.com + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "rk3288-firefly.dtsi" + +/ { + model = "Firefly-RK3288"; + compatible = "firefly,firefly-rk3288", "rockchip,rk3288"; + + chosen { + stdout-path = &uart2; + }; +}; + +#ifndef CONFIG_SPL_BUILD +&ir { + gpios = <&gpio7 0 GPIO_ACTIVE_LOW>; +}; + +&pinctrl { + act8846 { + pmic_vsel: pmic-vsel { + rockchip,pins = <7 14 RK_FUNC_GPIO &pcfg_output_low>; + }; + }; + + ir { + ir_int: ir-int { + rockchip,pins = <7 0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&pwm1 { + status = "okay"; +}; + +&uart2 { + u-boot,dm-pre-reloc; +}; + +#endif diff --git a/arch/arm/dts/rk3288-firefly.dtsi b/arch/arm/dts/rk3288-firefly.dtsi new file mode 100644 index 0000000..d65fbb9 --- /dev/null +++ b/arch/arm/dts/rk3288-firefly.dtsi @@ -0,0 +1,496 @@ +/* + * Copyright (c) 2014, 2015 FUKAUMI Naoki naobsd@gmail.com + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "rk3288.dtsi" + +/ { + memory { + reg = <0 0x80000000>; + }; + +#ifndef CONFIG_SPL_BUILD + ext_gmac: external-gmac-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + clock-output-names = "ext_gmac"; + }; + + ir: ir-receiver { + compatible = "gpio-ir-receiver"; + pinctrl-names = "default"; + pinctrl-0 = <&ir_int>; + }; + + keys: gpio-keys { + compatible = "gpio-keys"; + #address-cells = <1>; + #size-cells = <0>; + + button@0 { + gpio-key,wakeup = <1>; + gpios = <&gpio0 5 GPIO_ACTIVE_LOW>; + label = "GPIO Power"; + linux,code = <116>; + pinctrl-names = "default"; + pinctrl-0 = <&pwr_key>; + }; + }; + + leds { + compatible = "gpio-leds"; + + work { + gpios = <&gpio8 1 GPIO_ACTIVE_LOW>; + label = "firefly:blue:user"; + linux,default-trigger = "rc-feedback"; + pinctrl-names = "default"; + pinctrl-0 = <&work_led>; + }; + + power { + gpios = <&gpio8 2 GPIO_ACTIVE_LOW>; + label = "firefly:green:power"; + linux,default-trigger = "default-on"; + pinctrl-names = "default"; + pinctrl-0 = <&power_led>; + }; + }; + + vcc_sys: vsys-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + }; + + vcc_sd: sdmmc-regulator { + compatible = "regulator-fixed"; + gpio = <&gpio7 11 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_pwr>; + regulator-name = "vcc_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <100000>; + vin-supply = <&vcc_io>; + }; + + vcc_flash: flash-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_flash"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_io>; + }; + + vcc_5v: usb-regulator { + compatible = "regulator-fixed"; + regulator-name = "vcc_5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; + }; + + vcc_host_5v: usb-host-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 14 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&host_vbus_drv>; + regulator-name = "vcc_host_5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + vin-supply = <&vcc_5v>; + }; + + vcc_otg_5v: usb-otg-regulator { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&otg_vbus_drv>; + regulator-name = "vcc_otg_5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + vin-supply = <&vcc_5v>; + }; +#endif +}; + +#ifndef CONFIG_SPL_BUILD +&cpu0 { + cpu0-supply = <&vdd_cpu>; +}; + +&emmc { + broken-cd; + bus-width = <8>; + cap-mmc-highspeed; + disable-wp; + non-removable; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk>, <&emmc_cmd>, <&emmc_pwr>, <&emmc_bus8>; + vmmc-supply = <&vcc_io>; + vqmmc-supply = <&vcc_flash>; + status = "okay"; +}; + +&hdmi { + ddc-i2c-bus = <&i2c5>; + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + status = "okay"; + + vdd_cpu: syr827@40 { + compatible = "silergy,syr827"; + fcs,suspend-voltage-selector = <1>; + reg = <0x40>; + regulator-name = "vdd_cpu"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vcc_sys>; + }; + + vdd_gpu: syr828@41 { + compatible = "silergy,syr828"; + fcs,suspend-voltage-selector = <1>; + reg = <0x41>; + regulator-name = "vdd_gpu"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <1350000>; + regulator-always-on; + vin-supply = <&vcc_sys>; + }; + + hym8563: hym8563@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "xin32k"; + interrupt-parent = <&gpio7>; + interrupts = <4 IRQ_TYPE_EDGE_FALLING>; + pinctrl-names = "default"; + pinctrl-0 = <&rtc_int>; + }; + + act8846: act8846@5a { + compatible = "active-semi,act8846"; + reg = <0x5a>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_vsel>, <&pwr_hold>; + system-power-controller; + + regulators { + vcc_ddr: REG1 { + regulator-name = "vcc_ddr"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + vcc_io: REG2 { + regulator-name = "vcc_io"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_log: REG3 { + regulator-name = "vdd_log"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + }; + + vcc_20: REG4 { + regulator-name = "vcc_20"; + regulator-min-microvolt = <2000000>; + regulator-max-microvolt = <2000000>; + regulator-always-on; + }; + + vccio_sd: REG5 { + regulator-name = "vccio_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd10_lcd: REG6 { + regulator-name = "vdd10_lcd"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + }; + + vcca_18: REG7 { + regulator-name = "vcca_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + vcca_33: REG8 { + regulator-name = "vcca_33"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + vcc_lan: REG9 { + regulator-name = "vcc_lan"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + vdd_10: REG10 { + regulator-name = "vdd_10"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + }; + + vcc_18: REG11 { + regulator-name = "vcc_18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + vcc18_lcd: REG12 { + regulator-name = "vcc18_lcd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + }; + }; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; +}; + +&i2c5 { + status = "okay"; +}; + +&pinctrl { + pcfg_output_high: pcfg-output-high { + output-high; + }; + + pcfg_output_low: pcfg-output-low { + output-low; + }; + + act8846 { + pwr_hold: pwr-hold { + rockchip,pins = <0 1 RK_FUNC_GPIO &pcfg_output_high>; + }; + }; + + gmac { + phy_int: phy-int { + rockchip,pins = <0 9 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + phy_pmeb: phy-pmeb { + rockchip,pins = <0 8 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + phy_rst: phy-rst { + rockchip,pins = <4 8 RK_FUNC_GPIO &pcfg_output_high>; + }; + }; + + hym8563 { + rtc_int: rtc-int { + rockchip,pins = <7 4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + keys { + pwr_key: pwr-key { + rockchip,pins = <0 5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + leds { + power_led: power-led { + rockchip,pins = <8 2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + work_led: work-led { + rockchip,pins = <8 1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sdmmc { + sdmmc_pwr: sdmmc-pwr { + rockchip,pins = <7 11 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb_host { + host_vbus_drv: host-vbus-drv { + rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + usbhub_rst: usbhub-rst { + rockchip,pins = <8 3 RK_FUNC_GPIO &pcfg_output_high>; + }; + }; + + usb_otg { + otg_vbus_drv: otg-vbus-drv { + rockchip,pins = <0 12 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&saradc { + vref-supply = <&vcc_18>; + status = "okay"; +}; + +&sdio0 { + broken-cd; + bus-width = <4>; + disable-wp; + non-removable; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdio0_bus4>, <&sdio0_cmd>, <&sdio0_clk>; + vmmc-supply = <&vcc_18>; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + card-detect-delay = <200>; + disable-wp; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_cd>, <&sdmmc_bus4>; + vmmc-supply = <&vcc_sd>; + status = "okay"; +}; + +&spi0 { + pinctrl-names = "default"; + pinctrl-0 = <&spi0_clk>, <&spi0_cs0>, <&spi0_tx>, <&spi0_rx>, <&spi0_cs1>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer>, <&uart0_cts>, <&uart0_rts>; + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; +#endif + +&uart2 { + status = "okay"; +}; + +#ifndef CONFIG_SPL_BUILD +&uart3 { + status = "okay"; +}; + +&usb_host1 { + pinctrl-names = "default"; + pinctrl-0 = <&usbhub_rst>; + status = "okay"; +}; + +&usb_otg { + status = "okay"; +}; + +&vopb { + status = "okay"; +}; + +&vopb_mmu { + status = "okay"; +}; + +&vopl { + status = "okay"; +}; + +&vopl_mmu { + status = "okay"; +}; + +&wdt { + status = "okay"; +}; +#endif diff --git a/arch/arm/mach-rockchip/rk3288/Kconfig b/arch/arm/mach-rockchip/rk3288/Kconfig index 26d5951..7a77615 100644 --- a/arch/arm/mach-rockchip/rk3288/Kconfig +++ b/arch/arm/mach-rockchip/rk3288/Kconfig @@ -1,6 +1,16 @@ if ROCKCHIP_RK3288
+config TARGET_FIREFLY_RK3288 + bool "Firefly-RK3288" + help + Firefly is a RK3288-based development board with 2 USB ports, + HDMI, VGA, micro-SD card, audio, WiFi and Gigabit Ethernet, It + also includes on-board eMMC and 1GB of SDRAM. Expansion connectors + provide access to display pins, I2C, SPI, UART and GPIOs. + config SYS_SOC default "rockchip"
+source "board/firefly/firefly-rk3288/Kconfig" + endif diff --git a/board/firefly/firefly-rk3288/Kconfig b/board/firefly/firefly-rk3288/Kconfig new file mode 100644 index 0000000..1c2bca8 --- /dev/null +++ b/board/firefly/firefly-rk3288/Kconfig @@ -0,0 +1,15 @@ +if TARGET_FIREFLY_RK3288 + +config SYS_BOARD + default "firefly-rk3288" + +config SYS_VENDOR + default "firefly" + +config SYS_CONFIG_NAME + default "firefly-rk3288" + +config BOARD_SPECIFIC_OPTIONS # dummy + def_bool y + +endif diff --git a/board/firefly/firefly-rk3288/MAINTAINERS b/board/firefly/firefly-rk3288/MAINTAINERS new file mode 100644 index 0000000..42db0bd --- /dev/null +++ b/board/firefly/firefly-rk3288/MAINTAINERS @@ -0,0 +1,6 @@ +FIREFLY +M: Simon Glass sjg@chromium.org +S: Maintained +F: board/firefly/firefly-rk3288 +F: include/configs/firefly-rk3288.h +F: configs/firefly-rk3288_defconfig diff --git a/board/firefly/firefly-rk3288/Makefile b/board/firefly/firefly-rk3288/Makefile new file mode 100644 index 0000000..6716845 --- /dev/null +++ b/board/firefly/firefly-rk3288/Makefile @@ -0,0 +1,7 @@ +# +# (C) Copyright 2015 Google, Inc +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += firefly-rk3288.o diff --git a/board/firefly/firefly-rk3288/firefly-rk3288.c b/board/firefly/firefly-rk3288/firefly-rk3288.c new file mode 100644 index 0000000..5119e95 --- /dev/null +++ b/board/firefly/firefly-rk3288/firefly-rk3288.c @@ -0,0 +1,7 @@ +/* + * (C) Copyright 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig new file mode 100644 index 0000000..a6db3d9 --- /dev/null +++ b/configs/firefly-rk3288_defconfig @@ -0,0 +1,11 @@ ++S:CONFIG_ARM=y ++S:CONFIG_ARCH_ROCKCHIP=y ++S:CONFIG_ROCKCHIP_RK3288=y ++S:CONFIG_TARGET_FIREFLY_RK3288=y ++S:CONFIG_DEFAULT_DEVICE_TREE="rk3288-firefly" ++S:CONFIG_DEBUG_UART=y ++S:CONFIG_DEBUG_UART_NS16550=y ++S:CONFIG_DEBUG_UART_BASE=0xff690000 ++S:CONFIG_DEBUG_UART_CLOCK=24000000 ++S:CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_USE_PRIVATE_LIBGCC=y diff --git a/include/configs/firefly-rk3288.h b/include/configs/firefly-rk3288.h new file mode 100644 index 0000000..beb8ee3 --- /dev/null +++ b/include/configs/firefly-rk3288.h @@ -0,0 +1,50 @@ +/* + * (C) Copyright 2015 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define CONFIG_SYS_NO_FLASH +#define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_ENV_IS_NOWHERE +#define CONFIG_ENV_SIZE 0x2000 +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_MALLOC_LEN (32 << 20) +#define CONFIG_SYS_CBSIZE 1024 +#define CONFIG_SKIP_LOWLEVEL_INIT +#define CONFIG_SYS_ARCH_TIMER +#define CONFIG_SYS_THUMB_BUILD +#define CONFIG_OF_LIBFDT + +/* TODO: Fix this */ +#define CONFIG_SYS_HZ_CLOCK 1000000 + +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_BOARD_LOAD_IMAGE +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_MEM32 +#define CONFIG_SPL_BOARD_INIT + +#ifdef CONFIG_SPL_BUILD +#define CONFIG_SYS_MALLOC_SIMPLE +#endif + +#define CONFIG_SYS_TEXT_BASE 0x00100000 +#define CONFIG_SYS_INIT_SP_ADDR 0x00100000 +#define CONFIG_SYS_LOAD_ADDR 0x00800800 +#define CONFIG_SPL_STACK 0xff718000 +#define CONFIG_SPL_TEXT_BASE 0xff704004 + +#ifndef CONFIG_SPL_BUILD +#include <config_distro_defaults.h> +#endif + +#endif

Offer to display the available image types in help. Also, rather than hacking the genimg_get_type_id() function to display a list of types, do this in the tool. Also, sort the list.
The list of image types is quite long, and hard to discover. Print it out when we show help information.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/image.c | 54 +++++++++++++++++++++++++++++----------------------- include/image.h | 11 +++++++++++ tools/mkimage.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 93 insertions(+), 31 deletions(-)
diff --git a/common/image.c b/common/image.c index a911aa9..7faa91a 100644 --- a/common/image.c +++ b/common/image.c @@ -541,6 +541,15 @@ void genimg_print_time(time_t timestamp) } #endif
+const table_entry_t *get_table_entry(const table_entry_t *table, int id) +{ + for (; table->id >= 0; ++table) { + if (table->id == id) + return table; + } + return NULL; +} + /** * get_table_entry_name - translate entry id to long name * @table: pointer to a translation table for entries of a specific type @@ -557,15 +566,14 @@ void genimg_print_time(time_t timestamp) */ char *get_table_entry_name(const table_entry_t *table, char *msg, int id) { - for (; table->id >= 0; ++table) { - if (table->id == id) + table = get_table_entry(table, id); + if (!table) + return msg; #if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC) - return table->lname; + return table->lname; #else - return table->lname + gd->reloc_off; + return table->lname + gd->reloc_off; #endif - } - return (msg); }
const char *genimg_get_os_name(uint8_t os) @@ -584,6 +592,20 @@ const char *genimg_get_type_name(uint8_t type) return (get_table_entry_name(uimage_type, "Unknown Image", type)); }
+const char *genimg_get_type_short_name(uint8_t type) +{ + const table_entry_t *table; + + table = get_table_entry(uimage_type, type); + if (!table) + return "unknown"; +#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC) + return table->sname; +#else + return table->sname + gd->reloc_off; +#endif +} + const char *genimg_get_comp_name(uint8_t comp) { return (get_table_entry_name(uimage_comp, "Unknown Compression", @@ -608,23 +630,7 @@ int get_table_entry_id(const table_entry_t *table, const char *table_name, const char *name) { const table_entry_t *t; -#ifdef USE_HOSTCC - int first = 1; - - for (t = table; t->id >= 0; ++t) { - if (t->sname && strcasecmp(t->sname, name) == 0) - return(t->id); - }
- fprintf(stderr, "\nInvalid %s Type - valid names are", table_name); - for (t = table; t->id >= 0; ++t) { - if (t->sname == NULL) - continue; - fprintf(stderr, "%c %s", (first) ? ':' : ',', t->sname); - first = 0; - } - fprintf(stderr, "\n"); -#else for (t = table; t->id >= 0; ++t) { #ifdef CONFIG_NEEDS_MANUAL_RELOC if (t->sname && strcmp(t->sname + gd->reloc_off, name) == 0) @@ -634,8 +640,8 @@ int get_table_entry_id(const table_entry_t *table, return (t->id); } debug("Invalid %s Type: %s\n", table_name, name); -#endif /* USE_HOSTCC */ - return (-1); + + return -1; }
int genimg_get_os_id(const char *name) diff --git a/include/image.h b/include/image.h index 0e6af00..da17a6b 100644 --- a/include/image.h +++ b/include/image.h @@ -243,6 +243,8 @@ struct lmb; #define IH_TYPE_SOCFPGAIMAGE 19 /* Altera SOCFPGA Preloader */ #define IH_TYPE_X86_SETUP 20 /* x86 setup.bin Image */
+#define IH_TYPE_COUNT 21 /* Number of image types */ + /* * Compression Types */ @@ -408,6 +410,15 @@ char *get_table_entry_name(const table_entry_t *table, char *msg, int id); const char *genimg_get_os_name(uint8_t os); const char *genimg_get_arch_name(uint8_t arch); const char *genimg_get_type_name(uint8_t type); + +/** + * genimg_get_type_short_name() - get the short name for an image type + * + * @param type Image type (IH_TYPE_...) + * @return image short name, or "unknown" if unknown + */ +const char *genimg_get_type_short_name(uint8_t type); + const char *genimg_get_comp_name(uint8_t comp); int genimg_get_os_id(const char *name); int genimg_get_arch_id(const char *name); diff --git a/tools/mkimage.c b/tools/mkimage.c index 5ccd951..8808d70 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -26,8 +26,48 @@ struct image_tool_params params = { .imagename2 = "", };
-int -main (int argc, char **argv) +static int h_compare_image_name(const void *vtype1, const void *vtype2) +{ + const int *type1 = vtype1; + const int *type2 = vtype2; + const char *name1 = genimg_get_type_short_name(*type1); + const char *name2 = genimg_get_type_short_name(*type2); + + return strcmp(name1, name2); +} + +/* Show all image types supported by mkimage */ +static void show_image_types(void) +{ + struct image_type_params *tparams; + int order[IH_TYPE_COUNT]; + int count; + int type; + int i; + + /* Sort the names in order of short name for easier reading */ + memset(order, '\0', sizeof(order)); + for (count = 0, type = 0; type < IH_TYPE_COUNT; type++) { + tparams = imagetool_get_type(type); + if (tparams) + order[count++] = type; + } + qsort(order, count, sizeof(int), h_compare_image_name); + + fprintf(stderr, "\nInvalid image type. Supported image types:\n"); + for (i = 0; i < count; i++) { + type = order[i]; + tparams = imagetool_get_type(type); + if (tparams) { + fprintf(stderr, "\t%-15s %s\n", + genimg_get_type_short_name(type), + genimg_get_type_name(type)); + } + } + fprintf(stderr, "\n"); +} + +int main(int argc, char **argv) { int ifd = -1; struct stat sbuf; @@ -75,12 +115,16 @@ main (int argc, char **argv) usage (); goto NXTARG; case 'T': - if ((--argc <= 0) || - (params.type = - genimg_get_type_id (*++argv)) < 0) - usage (); + params.type = -1; + if (--argc >= 0 && argv[1]) { + params.type = + genimg_get_type_id(*++argv); + } + if (params.type < 0) { + show_image_types(); + usage(); + } goto NXTARG; - case 'a': if (--argc <= 0) usage (); @@ -546,6 +590,7 @@ static void usage(void) #endif fprintf (stderr, " %s -V ==> print version information and exit\n", params.cmdname); + fprintf(stderr, "Use -T to see a list of available image types\n");
exit (EXIT_FAILURE); }

Rockchip SoCs require certain formats for code that they execute, The simplest format is a 4-byte header at the start of a binary file. Add support for this intiially.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/image.c | 1 + include/image.h | 3 ++- tools/Makefile | 1 + tools/rkimage.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 tools/rkimage.c
diff --git a/common/image.c b/common/image.c index 7faa91a..940ad6d 100644 --- a/common/image.c +++ b/common/image.c @@ -149,6 +149,7 @@ static const table_entry_t uimage_type[] = { { IH_TYPE_MXSIMAGE, "mxsimage", "Freescale MXS Boot Image",}, { IH_TYPE_ATMELIMAGE, "atmelimage", "ATMEL ROM-Boot Image",}, { IH_TYPE_X86_SETUP, "x86_setup", "x86 setup.bin", }, + { IH_TYPE_ROCKCHIP, "rockchip", "Rockchip Boot Image" }, { -1, "", "", }, };
diff --git a/include/image.h b/include/image.h index da17a6b..100acbb 100644 --- a/include/image.h +++ b/include/image.h @@ -242,8 +242,9 @@ struct lmb; #define IH_TYPE_ATMELIMAGE 18 /* ATMEL ROM bootable Image */ #define IH_TYPE_SOCFPGAIMAGE 19 /* Altera SOCFPGA Preloader */ #define IH_TYPE_X86_SETUP 20 /* x86 setup.bin Image */ +#define IH_TYPE_ROCKCHIP 21 /* Rockchip Boot Image */
-#define IH_TYPE_COUNT 21 /* Number of image types */ +#define IH_TYPE_COUNT 22 /* Number of image types */
/* * Compression Types diff --git a/tools/Makefile b/tools/Makefile index 88770b0..a3ab7a3 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -88,6 +88,7 @@ dumpimage-mkimage-objs := aisimage.o \ os_support.o \ pblimage.o \ pbl_crc32.o \ + rkimage.o \ socfpgaimage.o \ lib/sha1.o \ lib/sha256.o \ diff --git a/tools/rkimage.c b/tools/rkimage.c new file mode 100644 index 0000000..433b5eb --- /dev/null +++ b/tools/rkimage.c @@ -0,0 +1,63 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass sjg@chromium.org + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "imagetool.h" +#include <image.h> + +static uint32_t header; + +static int rkimage_check_params(struct image_tool_params *params) +{ + return 0; +} + +static int rkimage_verify_header(unsigned char *buf, int size, + struct image_tool_params *params) +{ + return 0; +} + +static void rkimage_print_header(const void *buf) +{ +} + +static void rkimage_set_header(void *buf, struct stat *sbuf, int ifd, + struct image_tool_params *params) +{ + memcpy(buf, "RK32", 4); +} + +static int rkimage_extract_subimage(void *buf, struct image_tool_params *params) +{ + return 0; +} + +static int rkimage_check_image_type(uint8_t type) +{ + if (type == IH_TYPE_ROCKCHIP) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; +} + +/* + * rk_image parameters + */ +U_BOOT_IMAGE_TYPE( + rkimage, + "Rockchip Boot Image support", + 4, + &header, + rkimage_check_params, + rkimage_verify_header, + rkimage_print_header, + rkimage_set_header, + rkimage_extract_subimage, + rkimage_check_image_type, + NULL, + NULL +);

Add a few notes on how to try out the Rockchip support so far.
Signed-off-by: Simon Glass sjg@chromium.org ---
doc/README.rockchip | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 doc/README.rockchip
diff --git a/doc/README.rockchip b/doc/README.rockchip new file mode 100644 index 0000000..2f26814 --- /dev/null +++ b/doc/README.rockchip @@ -0,0 +1,83 @@ +# +# Copyright (C) 2015 Google. Inc +# Written by Simon Glass sjg@chromium.org +# +# SPDX-License-Identifier: GPL-2.0+ +# + +U-Boot on Rockchip +================== + +There are several repositories available with versions of U-Boot that support +many Rockchip devices [1] [2]. + +The current mainline support is experimental only and is not useful for +anything. It should provide a base on which to build. + + +Prerequisites +============= + +You will need: + + - Firefly RK3288 baord + - Power connection to 5V using the supplied micro-USB power cable + - Separate USB serial cable attached to your computer and the Firefly + (connect to the micro-USB connector below the logo) + - rkflashtool [3] + - openssl (sudo apt-get install openssl) + - Serial UART connection [4] + - Suitable ARM cross compiler, e.g.: + sudo apt-get install gcc-4.7-arm-linux-gnueabi + + +Building +======== + +At present, only Firefly RK3288 is supported. You can use the firefly-rk3288 +configuration for this. + + CROSS_COMPILE=arm-linux-gnueabi- make O=firefly firefly-rk3288_defconfig all + +(or you can use another cross compiler if you prefer) + + +Writing to the board +==================== + +Only USB is supported. For this to work you must get your board into ROM +boot mode, either by erasing your MMC or (perhaps) holding the recovery +button when you boot the board. To erase your MMC, you can boot into Linux +and type (as root) 'dd if=/dev/zero of=/dev/mmcblk0 bs=1M'. + +To create a suitable image and write it to the board: + + ./firefly/tools/mkimage -T rockchip -d firefly/spl/u-boot-spl-dtb.bin out + cat out | openssl rc4 -K 7c4e0304550509072d2c7b38170d1711 | rkflashtool l + +If all goes well you should something like: + + U-Boot SPL 2015.04-rc2-00123-gc5b539a-dirty (Feb 27 2015 - 09:35:31) + SPL: Unsupported Boot Device! + ### ERROR ### Please RESET the board ### + +You will need to reset the board before each time you try. Yes, that's all +it does so far. + + +Future work +=========== + +Immediate priorities are: + +- Support SPL clock init +- Support loading U-Boot from MMC +- Boot U-Boot to a prompt + +There are plenty of patches in the links below to help with this work. + + +[1] https://github.com/rkchrome/uboot.git +[2] https://github.com/linux-rockchip/u-boot-rockchip.git branch u-boot-rk3288 +[3] https://github.com/linux-rockchip/rkflashtool.git +[4] http://wiki.t-firefly.com/index.php/Firefly-RK3288/Serial_debug/en

Hi,
On 27 February 2015 at 22:06, Simon Glass sjg@chromium.org wrote:
With driver model SPL support in place the remaining driver difference between U-Boot proper and SPL is that SPL does not support device tree. This series adds this support, using a Rockchip board as an example.
One problem with device tree is that U-Boot has no way of dropping features it does not need or use. For SPL this problem needs to be solved and this series uses the preprocessor for this. The 45KB Firefly device tree reduces to 693 bytes when unused material is removed. A better solution might involve the 'fdtgrep' tool but this has not made it into the device tree compiler as yet.
This series includes some changes aimed at reduce code size in SPL, including:
- dropping alias sequence support (the aliases node) since many boards just use a single UART in SPL
- adding a smaller panic() function that does not support printf()-format strings
- removing device unbind code which will never be used in SPL
Overall the resulting SPL binary is 8829 bytes with my Linaro 4.8.2 compiler, including the device tree, using Thumb-2. Of this:
1768 bytes is driver model core code 1556 bytes is device tree code 693 bytes is the device tree itself 4756 is other code, including serial drivers, rodata and data
The last figure includes rodata incorrectly added by the tool chain [1]. With a bug-fixed gcc 4.9.2 the total size is 6893 bytes including device tree.
Approximately 750 bytes is used for strings and driver data (root device and serial) associated with driver model and device tree. This adds up an overhead of around 4750 bytes for driver model and device tree, including the code, rodata and device tree itself.
It should therefore be possible to use driver model and device tree in SPL for board that have enough SRAM. Clearly 4KB is impossible without further work (perhaps removing some error strings). I suspect 8KB would be tricky, allowing only 3KB for stack and other code. But 16KB should work OK.
SRAM sizes for recent SoCs I am aware of are:
Rockchip RK3288: 96KB Tegra 124: 128KB Samsung Exynos 5420: 384KB
The Rockchip Firefly was chosen for this work since it is a fairly recent board and is readily available. Rockchip engineers have been actively upstreaming code to Linux in the past year and there is a very full-featured U-Boot available. But it is invisible to most U-Boot people - mainline Rockchip support seems well overdue. This series does not make a serious start on that, since it only prints a message in SPL and then hangs, but additional work should get it booting to a prompt.
I've held off pushing this into u-boot-dm/next since it is RFC and the device tree part needs work. But I'm thinking of respinning it to apply it within the upcoming merge window, or at least the core patches.
Does anyone have comments at this stage?
Regards, Simon

Hi
On Apr 10, 2015 7:38 PM, "Simon Glass" sjg@chromium.org wrote:
Hi,
On 27 February 2015 at 22:06, Simon Glass sjg@chromium.org wrote:
With driver model SPL support in place the remaining driver difference between U-Boot proper and SPL is that SPL does not support device tree. This series adds this support, using a Rockchip board as an example.
Glad to test on my firefly. Can you please give some basic test to flash on eMmc e/o on SDcard?
Michael
One problem with device tree is that U-Boot has no way of dropping
features
it does not need or use. For SPL this problem needs to be solved and
this
series uses the preprocessor for this. The 45KB Firefly device tree
reduces
to 693 bytes when unused material is removed. A better solution might involve the 'fdtgrep' tool but this has not made it into the device tree compiler as yet.
This series includes some changes aimed at reduce code size in SPL, including:
- dropping alias sequence support (the aliases node) since many boards
just
use a single UART in SPL
- adding a smaller panic() function that does not support
printf()-format
strings
- removing device unbind code which will never be used in SPL
Overall the resulting SPL binary is 8829 bytes with my Linaro 4.8.2
compiler,
including the device tree, using Thumb-2. Of this:
1768 bytes is driver model core code 1556 bytes is device tree code 693 bytes is the device tree itself 4756 is other code, including serial drivers, rodata and data
The last figure includes rodata incorrectly added by the tool chain [1]. With a bug-fixed gcc 4.9.2 the total size is 6893 bytes including device tree.
Approximately 750 bytes is used for strings and driver data (root device and serial) associated with driver model and device tree. This adds up
an
overhead of around 4750 bytes for driver model and device tree,
including
the code, rodata and device tree itself.
It should therefore be possible to use driver model and device tree in SPL for board that have enough SRAM. Clearly 4KB is impossible without further work (perhaps removing some error strings). I suspect 8KB would be tricky, allowing only 3KB for stack and other code. But 16KB should work OK.
SRAM sizes for recent SoCs I am aware of are:
Rockchip RK3288: 96KB Tegra 124: 128KB Samsung Exynos 5420: 384KB
The Rockchip Firefly was chosen for this work since it is a fairly
recent
board and is readily available. Rockchip engineers have been actively upstreaming code to Linux in the past year and there is a very full-featured U-Boot available. But it is invisible to most U-Boot people - mainline Rockchip support seems well overdue. This series does not make a serious start on that, since it only prints a message in SPL and then hangs, but additional work should get it booting to a prompt.
I've held off pushing this into u-boot-dm/next since it is RFC and the device tree part needs work. But I'm thinking of respinning it to apply it within the upcoming merge window, or at least the core patches.
Does anyone have comments at this stage?
Regards, Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

Hi Michael,
On 10 April 2015 at 11:40, Michael Trimarchi michael@amarulasolutions.com wrote:
Hi
On Apr 10, 2015 7:38 PM, "Simon Glass" sjg@chromium.org wrote:
Hi,
On 27 February 2015 at 22:06, Simon Glass sjg@chromium.org wrote:
With driver model SPL support in place the remaining driver difference between U-Boot proper and SPL is that SPL does not support device tree. This series adds this support, using a Rockchip board as an example.
Glad to test on my firefly. Can you please give some basic test to flash on eMmc e/o on SDcard?
Thanks. There is a README here:
http://patchwork.ozlabs.org/patch/444783/
Warning: it only prints a message on serial and hangs, so don't expect much!
[snip]
Regards, Simon

Hi
On Apr 10, 2015 7:46 PM, "Simon Glass" sjg@chromium.org wrote:
Hi Michael,
On 10 April 2015 at 11:40, Michael Trimarchi michael@amarulasolutions.com wrote:
Hi
On Apr 10, 2015 7:38 PM, "Simon Glass" sjg@chromium.org wrote:
Hi,
On 27 February 2015 at 22:06, Simon Glass sjg@chromium.org wrote:
With driver model SPL support in place the remaining driver
difference
between U-Boot proper and SPL is that SPL does not support device
tree.
This series adds this support, using a Rockchip board as an example.
Glad to test on my firefly. Can you please give some basic test to
flash on
eMmc e/o on SDcard?
Thanks. There is a README here:
http://patchwork.ozlabs.org/patch/444783/
Warning: it only prints a message on serial and hangs, so don't expect
much!
It's already good to have this. Memory and serial is fine. I have read it and it's pretty simple.
Michael
[snip]
Regards, Simon
participants (3)
-
Masahiro Yamada
-
Michael Trimarchi
-
Simon Glass