diff --git a/Documentation/boards/mvebu.rst b/Documentation/boards/mvebu.rst index 8e56122..b28fd44 100644 --- a/Documentation/boards/mvebu.rst +++ b/Documentation/boards/mvebu.rst @@ -37,9 +37,15 @@ The mvebu SoCs support booting from UART. For this there is a tool available in barebox called ``kwboot``. Quite some mvebu boards are reset once more when -they already started to read the first block of the image to boot. If you want -to boot such a board, use the parameter ``-n 15`` for ``kwboot``. (The number -might have to be adapted per board.) +they already started to read the first block of the image to boot which +obviously results in a failure to boot this image. If you want to boot such a +board, use the parameter ``-n 15`` for ``kwboot`` to delay uploading the image +and try to hit the right (i.e. second) window harder. +(The number might have to be adapted per board. The semantic is that the magic +string is sent until the 15th NAK is seen and only then the image is sent.) A +typical commandline is: + + kwboot -b barebox.img -n 15 -B 115200 -t /dev/ttyUSB mvebu boards ------------ diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index f2d4d38..9bbdd68 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -125,6 +125,7 @@ obj-$(CONFIG_MACH_TOSHIBA_AC100) += toshiba-ac100/ obj-$(CONFIG_MACH_TQMA53) += tqma53/ obj-$(CONFIG_MACH_TQMA6X) += tqma6x/ +obj-$(CONFIG_MACH_TURRIS_OMNIA) += turris-omnia/ obj-$(CONFIG_MACH_TX25) += karo-tx25/ obj-$(CONFIG_MACH_TX28) += karo-tx28/ obj-$(CONFIG_MACH_TX51) += karo-tx51/ diff --git a/arch/arm/boards/turris-omnia/Makefile b/arch/arm/boards/turris-omnia/Makefile new file mode 100644 index 0000000..01c7a25 --- /dev/null +++ b/arch/arm/boards/turris-omnia/Makefile @@ -0,0 +1,2 @@ +obj-y += board.o +lwl-y += lowlevel.o diff --git a/arch/arm/boards/turris-omnia/board.c b/arch/arm/boards/turris-omnia/board.c new file mode 100644 index 0000000..40a8c17 --- /dev/null +++ b/arch/arm/boards/turris-omnia/board.c @@ -0,0 +1 @@ +/* empty */ diff --git a/arch/arm/boards/turris-omnia/kwbimage.cfg b/arch/arm/boards/turris-omnia/kwbimage.cfg new file mode 100644 index 0000000..789ee5d --- /dev/null +++ b/arch/arm/boards/turris-omnia/kwbimage.cfg @@ -0,0 +1,7 @@ +VERSION 1 +BOOT_FROM spi +DESTADDR 00800000 +EXECADDR 00800000 +NAND_BLKSZ 00000000 +NAND_BADBLK_LOCATION 00 +BINARY binary.0 0000005b 00000068 diff --git a/arch/arm/boards/turris-omnia/lowlevel.c b/arch/arm/boards/turris-omnia/lowlevel.c new file mode 100644 index 0000000..3f20908 --- /dev/null +++ b/arch/arm/boards/turris-omnia/lowlevel.c @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2017 Pengutronix, Uwe Kleine-Koenig + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2, as published by the Free Software Foundation. + * + * 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 +#include +#include +#include + +#include + +extern char __dtb_armada_385_turris_omnia_bb_start[]; + +ENTRY_FUNCTION(start_turris_omnia, r0, r1, r2) +{ + void *fdt; + + arm_cpu_lowlevel_init(); + + fdt = __dtb_armada_385_turris_omnia_bb_start - + get_runtime_offset(); + + armada_370_xp_barebox_entry(fdt); +} diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 806d386..d8abe45 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -83,6 +83,7 @@ pbl-dtb-$(CONFIG_MACH_TX25) += imx25-karo-tx25.dtb.o pbl-dtb-$(CONFIG_MACH_TX6X) += imx6dl-tx6u.dtb.o pbl-dtb-$(CONFIG_MACH_TX6X) += imx6q-tx6q.dtb.o +pbl-dtb-$(CONFIG_MACH_TURRIS_OMNIA) += armada-385-turris-omnia-bb.dtb.o pbl-dtb-$(CONFIG_MACH_UDOO) += imx6q-udoo.dtb.o pbl-dtb-$(CONFIG_MACH_USI_TOPKICK) += kirkwood-topkick-bb.dtb.o pbl-dtb-$(CONFIG_MACH_VARISCITE_MX6) += imx6q-var-custom.dtb.o diff --git a/arch/arm/dts/armada-385-turris-omnia-bb.dts b/arch/arm/dts/armada-385-turris-omnia-bb.dts new file mode 100644 index 0000000..53bef01 --- /dev/null +++ b/arch/arm/dts/armada-385-turris-omnia-bb.dts @@ -0,0 +1,7 @@ +#include "arm/armada-385-turris-omnia.dts" + +/ { + chosen { + stdout-path = "/soc/internal-regs/serial@12000"; + }; +}; diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 148b4f6..ad97e83 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -17,6 +17,11 @@ select CPU_V7 select CLOCKSOURCE_MVEBU +config ARCH_ARMADA_38X + bool + select CPU_V7 + select CLOCKSOURCE_MVEBU + config ARCH_DOVE bool select CPU_V7 @@ -64,6 +69,16 @@ select ARCH_ARMADA_XP # +# Armada 38x SoC boards +# + +comment "Armada 38x based boards" + +config MACH_TURRIS_OMNIA + bool "Turris Omnia" + select ARCH_ARMADA_38X + +# # Dove 88AP510 SoC boards # diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile index 89805ba..87a8511 100644 --- a/arch/arm/mach-mvebu/Makefile +++ b/arch/arm/mach-mvebu/Makefile @@ -1,6 +1,7 @@ obj-pbl-y += common.o obj-$(CONFIG_ARCH_ARMADA_370) += armada-370-xp.o obj-$(CONFIG_ARCH_ARMADA_XP) += armada-370-xp.o +obj-$(CONFIG_ARCH_ARMADA_38X) += armada-370-xp.o obj-$(CONFIG_ARCH_DOVE) += dove.o obj-$(CONFIG_ARCH_KIRKWOOD) += kirkwood.o obj-$(CONFIG_BOOTM) += kwbootimage.o diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile index 4b2c3c8..53c759e 100644 --- a/drivers/clk/mvebu/Makefile +++ b/drivers/clk/mvebu/Makefile @@ -1,5 +1,6 @@ obj-y += common.o obj-$(CONFIG_ARCH_ARMADA_370) += armada-370.o corediv.o obj-$(CONFIG_ARCH_ARMADA_XP) += armada-xp.o corediv.o +obj-$(CONFIG_ARCH_ARMADA_38X) += armada-38x.o corediv.o obj-$(CONFIG_ARCH_DOVE) += dove.o obj-$(CONFIG_ARCH_KIRKWOOD) += kirkwood.o diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c new file mode 100644 index 0000000..d2d7c2a --- /dev/null +++ b/drivers/clk/mvebu/armada-38x.c @@ -0,0 +1,144 @@ +/* + * Marvell Armada 380/385 SoC clocks + * + * Copyright (C) 2014 Marvell + * + * Gregory CLEMENT + * Sebastian Hesselbarth + * Andrew Lunn + * + * 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 +#include + +#include "common.h" + +/* + * Core Clocks + * + * Armada XP Sample At Reset is a 64 bit bitfiled split in two + * register of 32 bits + */ + +#define SAR_A380_TCLK_FREQ_OPT 15 +#define SAR_A380_TCLK_FREQ_OPT_MASK 0x1 +#define SAR_A380_CPU_DDR_L2_FREQ_OPT 10 +#define SAR_A380_CPU_DDR_L2_FREQ_OPT_MASK 0x1f + +/* Armada XP TCLK frequency is fixed to 250MHz */ +static u32 a38x_get_tclk_freq(void __iomem *sar) +{ + if ((readl(sar) >> SAR_A380_TCLK_FREQ_OPT) & SAR_A380_TCLK_FREQ_OPT_MASK) + return 200000000; + else + return 250000000; +} + +static const u32 a38x_cpu_freqs[] = { + 0, 0, 0, 0, + 1666000000, 0, 0, 0, + 1332000000, 0, 0, 0, + 1600000000, +}; + +static u32 a38x_get_cpu_freq(void __iomem *sar) +{ + u32 cpu_freq_select = ((readl(sar) >> SAR_A380_CPU_DDR_L2_FREQ_OPT) & + SAR_A380_CPU_DDR_L2_FREQ_OPT_MASK); + + if (cpu_freq_select >= ARRAY_SIZE(a38x_cpu_freqs)) { + pr_err("CPU freq select unsupported: %d\n", cpu_freq_select); + return 0; + } + + return a38x_cpu_freqs[cpu_freq_select]; +} + +enum { A380_CPU_TO_DDR, A380_CPU_TO_L2 }; + +static const struct coreclk_ratio a38x_coreclk_ratios[] = { + { .id = A380_CPU_TO_L2, .name = "l2clk" }, + { .id = A380_CPU_TO_DDR, .name = "ddrclk" }, +}; + +static const int armada_38x_cpu_l2_ratios[32][2] = { + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, +}; + +static const int armada_38x_cpu_ddr_ratios[32][2] = { + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, +}; + +static void a38x_get_clk_ratio( + void __iomem *sar, int id, int *mult, int *div) +{ + u32 opt = ((readl(sar) >> SAR_A380_CPU_DDR_L2_FREQ_OPT) & + SAR_A380_CPU_DDR_L2_FREQ_OPT_MASK); + + switch (id) { + case A380_CPU_TO_L2: + *mult = armada_38x_cpu_l2_ratios[opt][0]; + *div = armada_38x_cpu_l2_ratios[opt][1]; + break; + case A380_CPU_TO_DDR: + *mult = armada_38x_cpu_ddr_ratios[opt][0]; + *div = armada_38x_cpu_ddr_ratios[opt][1]; + break; + } +} + +const struct coreclk_soc_desc armada_38x_coreclks = { + .get_tclk_freq = a38x_get_tclk_freq, + .get_cpu_freq = a38x_get_cpu_freq, + .get_clk_ratio = a38x_get_clk_ratio, + .ratios = a38x_coreclk_ratios, + .num_ratios = ARRAY_SIZE(a38x_coreclk_ratios), +}; + +/* + * Clock Gating Control + */ +const struct clk_gating_soc_desc armada_38x_gating_desc[] = { + { "audio", NULL, 0 }, + { "ge2", NULL, 2 }, + { "ge1", NULL, 3 }, + { "ge0", NULL, 4 }, + { "pex1", NULL, 5 }, + { "pex2", NULL, 6 }, + { "pex3", NULL, 7 }, + { "pex0", NULL, 8 }, + { "usb3h0", NULL, 9 }, + { "usb3h1", NULL, 10 }, + { "usb3d", NULL, 11 }, + { "bm", NULL, 13 }, + { "crypto0z", NULL, 14 }, + { "sata0", NULL, 15 }, + { "crypto1z", NULL, 16 }, + { "sdio", NULL, 17 }, + { "usb2", NULL, 18 }, + { "crypto1", NULL, 21 }, + { "xor0", NULL, 22 }, + { "crypto0", NULL, 23 }, + { "tdm", NULL, 25 }, + { "xor1", NULL, 28 }, + { "sata1", NULL, 30 }, + { } +}; diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index a06b29f..f6f118f 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c @@ -29,6 +29,8 @@ static struct of_device_id mvebu_coreclk_ids[] = { { .compatible = "marvell,armada-370-core-clock", .data = &armada_370_coreclks }, + { .compatible = "marvell,armada-380-core-clock", + .data = &armada_38x_coreclks }, { .compatible = "marvell,armada-xp-core-clock", .data = &armada_xp_coreclks }, { .compatible = "marvell,dove-core-clock", @@ -144,6 +146,8 @@ .data = &armada_370_gating_desc }, { .compatible = "marvell,armada-xp-gating-clock", .data = &armada_xp_gating_desc }, + { .compatible = "marvell,armada-380-gating-clock", + .data = &armada_38x_gating_desc }, { .compatible = "marvell,dove-gating-clock", .data = &dove_gating_desc }, { .compatible = "marvell,kirkwood-gating-clock", diff --git a/drivers/clk/mvebu/common.h b/drivers/clk/mvebu/common.h index 522ccde..a3b2724 100644 --- a/drivers/clk/mvebu/common.h +++ b/drivers/clk/mvebu/common.h @@ -49,6 +49,14 @@ static const u32 armada_xp_gating_desc; #endif +#ifdef CONFIG_ARCH_ARMADA_38X +extern const struct coreclk_soc_desc armada_38x_coreclks; +extern const struct clk_gating_soc_desc armada_38x_gating_desc[]; +#else +static const u32 armada_38x_coreclks; +static const u32 armada_38x_gating_desc; +#endif + #ifdef CONFIG_ARCH_DOVE extern const struct coreclk_soc_desc dove_coreclks; extern const struct clk_gating_soc_desc dove_gating_desc[]; diff --git a/images/Makefile.mvebu b/images/Makefile.mvebu index b57291c..17fa061 100644 --- a/images/Makefile.mvebu +++ b/images/Makefile.mvebu @@ -51,6 +51,14 @@ image-$(CONFIG_MACH_NETGEAR_RN2120) += barebox-netgear-rn2120.img image-$(CONFIG_MACH_NETGEAR_RN2120) += barebox-netgear-rn2120-2nd.img +# ----------------------- Armada 38x based boards --------------------------- +TURRIS_OMNIA_KWBOPTS = ${KWBOPTS} -i $(board)/turris-omnia/kwbimage.cfg +OPTS_start_turris_omnia.pblx.kwbimg = $(TURRIS_OMNIA_KWBOPTS) +FILE_barebox-turris-omnia.img = start_turris_omnia.pblx.kwbimg +FILE_barebox-turris-omnia-2nd.img = start_turris_omnia.pblx +pblx-$(CONFIG_MACH_TURRIS_OMNIA) += start_turris_omnia +image-$(CONFIG_MACH_TURRIS_OMNIA) += barebox-turris-omnia.img + PLATHOME_OPENBLOCKS_AX3_KWBOPTS = ${KWBOPTS} -i $(board)/plathome-openblocks-ax3/kwbimage.cfg OPTS_start_plathome_openblocks_ax3.pblx.kwbimg = $(PLATHOME_OPENBLOCKS_AX3_KWBOPTS) FILE_barebox-plathome-openblocks-ax3.img = start_plathome_openblocks_ax3.pblx.kwbimg diff --git a/scripts/kwboot.c b/scripts/kwboot.c index 4c6b19a..db177ce 100644 --- a/scripts/kwboot.c +++ b/scripts/kwboot.c @@ -716,7 +716,7 @@ kwboot_usage(FILE *stream, char *progname) { fprintf(stream, - "Usage: %s [-d | -b | -D ] [ -t ] [-B ] \n", + "Usage: %s [-d | -b [ -n ] | -D ] [ -t ] [-B ] \n", progname); fprintf(stream, "\n"); fprintf(stream, @@ -724,6 +724,8 @@ fprintf(stream, " -D : boot without preamble (Dove)\n"); fprintf(stream, " -d: enter debug mode\n"); + fprintf(stream, + " -n : wait for NAK before uploading image (default: 1)\n"); fprintf(stream, "\n"); fprintf(stream, " -t: mini terminal\n"); fprintf(stream, "\n");