Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-spi
- sunXi SPI fixups (Andre)
- bcm iproc qspi (Rayagonda)
diff --git a/.mailmap b/.mailmap
index b36ae66..1f88ea9 100644
--- a/.mailmap
+++ b/.mailmap
@@ -22,11 +22,13 @@
Aneesh V <aneesh@ti.com>
Anup Patel <anup@brainfault.org> <anup.patel@wdc.com>
Atish Patra <atishp@atishpatra.org> <atish.patra@wdc.com>
+Bin Meng <bmeng.cn@gmail.com> <bin.meng@windriver.com>
Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@bootlin.com>
Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@free-electrons.com>
Dirk Behme <dirk.behme@googlemail.com>
Fabio Estevam <fabio.estevam@nxp.com>
Heinrich Schuchardt <xypron.glpk@gmx.de> <heinrich.schuchardt@canonical.com>
+Heinrich Schuchardt <xypron.glpk@gmx.de> xypron.glpk@gmx.de <xypron.glpk@gmx.de>
Jagan Teki <402jagan@gmail.com>
Jagan Teki <jaganna@gmail.com>
Jagan Teki <jaganna@xilinx.com>
@@ -35,7 +37,15 @@
Jernej Skrabec <jernej.skrabec@gmail.com> <jernej.skrabec@siol.net>
Igor Opaniuk <igor.opaniuk@gmail.com> <igor.opaniuk@linaro.org>
Igor Opaniuk <igor.opaniuk@gmail.com> <igor.opaniuk@toradex.com>
+Marek Vasut <marex@denx.de> <marek.vasut+renesas@gmail.com>
+Marek Vasut <marex@denx.de> <marek.vasut@gmail.com>
+Marek Vasut <marex@denx.de> <marex at denx.de>
Markus Klotzbuecher <mk@denx.de>
+Masahiro Yamada <yamada.masahiro@socionext.com> <yamada.m@jp.panasonic.com>
+Masahiro Yamada <yamada.masahiro@socionext.com> <masahiroy@kernel.org>
+Michal Simek <michal.simek@xilinx.com> <monstr@monstr.eu>
+Michal Simek <michal.simek@xilinx.com> <Monstr@seznam.cz>
+Michal Simek <michal.simek@xilinx.com> <root@monstr.eu>
Nicolas Saenz Julienne <nsaenz@kernel.org> <nsaenzjulienne@suse.de>
Patrice Chotard <patrice.chotard@foss.st.com> <patrice.chotard@st.com>
Patrick Delaunay <patrick.delaunay@foss.st.com> <patrick.delaunay@st.com>
@@ -47,10 +57,19 @@
Ruchika Gupta <ruchika.gupta@nxp.com> <ruchika.gupta@freescale.com>
Sandeep Paulraj <s-paulraj@ti.com>
Shaohui Xie <Shaohui.Xie@freescale.com>
-Stefan Roese <stroese>
+Stefan Roese <sr@denx.de> <stroese>
Stefano Babic <sbabic@denx.de>
+Tom Rini <trini@konsulko.com> <trini@ti.com>
TsiChung Liew <Tsi-Chung.Liew@freescale.com>
-Wolfgang Denk <wdenk>
+Wolfgang Denk <wd@denx.de> <wdenk>
+Wolfgang Denk <wd@denx.de> <wd@pollux.denx.de>
+Wolfgang Denk <wd@denx.de> <wd@pollux.(none)>
+Wolfgang Denk <wd@denx.de> <wd@fifi.denx.de>
+Wolfgang Denk <wd@denx.de> <wd@nyx.denx.de>
+Wolfgang Denk <wd@denx.de> <wd@atlas.denx.de>
+Wolfgang Denk <wd@denx.de> <wd@castor.denx.de>
+Wolfgang Denk <wd@denx.de> <wd@xpert.denx.de>
+Wolfgang Denk <wd@denx.de> <wd@nyx.(none)>
York Sun <yorksun@freescale.com>
York Sun <york.sun@nxp.com>
Ćukasz Majewski <l.majewski@samsung.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index fb171e0..82fc49e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1161,6 +1161,13 @@
T: git https://source.denx.de/u-boot/custodians/u-boot-sh.git
F: arch/sh/
+SL28CLPD
+M: Michael Walle <michael@walle.cc>
+S: Maintained
+F: drivers/gpio/sl28cpld-gpio.c
+F: drivers/misc/sl28cpld.c
+F: drivers/watchdog/sl28cpld-wdt.c
+
SPI
M: Jagan Teki <jagan@amarulasolutions.com>
S: Maintained
@@ -1319,6 +1326,14 @@
F: test/dm/virtio.c
F: doc/develop/driver-model/virtio.rst
+WATCHDOG
+M: Stefan Roese <sr@denx.de>
+S: Maintained
+T: git https://source.denx.de/u-boot/custodians/u-boot-watchdog.git
+F: cmd/wdt.c
+F: drivers/watchdog/
+F: include/watchdog*.h
+
X86
M: Simon Glass <sjg@chromium.org>
M: Bin Meng <bmeng.cn@gmail.com>
diff --git a/Makefile b/Makefile
index 697cc51..f8f3f24 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
VERSION = 2022
PATCHLEVEL = 04
SUBLEVEL =
-EXTRAVERSION = -rc2
+EXTRAVERSION = -rc3
NAME =
# *DOCUMENTATION*
@@ -1411,7 +1411,7 @@
$(if $(KEYDIR),-k $(KEYDIR))
MKIMAGEFLAGS_u-boot.pbl = -n $(srctree)/$(CONFIG_SYS_FSL_PBL_RCW:"%"=%) \
- -R $(srctree)/$(CONFIG_SYS_FSL_PBL_PBI:"%"=%) -T pblimage
+ -R $(srctree)/$(CONFIG_SYS_FSL_PBL_PBI:"%"=%) -A $(ARCH) -T pblimage
ifeq ($(CONFIG_MPC85xx)$(CONFIG_OF_SEPARATE),yy)
UBOOT_BIN := u-boot-with-dtb.bin
@@ -2227,7 +2227,8 @@
-o -name '*.asn1.[ch]' \
-o -name '*.symtypes' -o -name 'modules.order' \
-o -name modules.builtin -o -name '.tmp_*.o.*' \
- -o -name 'dsdt.aml' -o -name 'dsdt.asl.tmp' -o -name 'dsdt.c' \
+ -o -name 'dsdt_generated.aml' -o -name 'dsdt_generated.asl.tmp' \
+ -o -name 'dsdt_generated.c' \
-o -name '*.efi' -o -name '*.gcno' -o -name '*.so' \) \
-type f -print | xargs rm -f
diff --git a/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S b/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S
index 08be7ed..2592403 100644
--- a/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S
+++ b/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S
@@ -25,9 +25,9 @@
mov sp, r0
mov lr, r1
ldr r0, =fel_stash
- ldr r1, [r0, #16]
- mcr p15, 0, r1, c1, c0, 0 @ Write CP15 Control Register
ldr r1, [r0, #12]
+ mcr p15, 0, r1, c1, c0, 0 @ Write CP15 SCTLR register
+ ldr r1, [r0, #8]
msr cpsr, r1 @ Write CPSR
bx lr
ENDPROC(return_to_fel)
diff --git a/arch/arm/dts/fsl-ls1028a-kontron-sl28-u-boot.dtsi b/arch/arm/dts/fsl-ls1028a-kontron-sl28-u-boot.dtsi
index d4b8332..2dcb3c2 100644
--- a/arch/arm/dts/fsl-ls1028a-kontron-sl28-u-boot.dtsi
+++ b/arch/arm/dts/fsl-ls1028a-kontron-sl28-u-boot.dtsi
@@ -27,6 +27,7 @@
fit {
offset = <CONFIG_SPL_PAD_TO>;
description = "FIT image with multiple configurations";
+ fit,fdt-list = "of-list";
images {
uboot {
@@ -41,95 +42,20 @@
};
};
- fdt-1 {
- description = "fsl-ls1028a-kontron-sl28";
+ @fdt-SEQ {
+ description = "NAME";
type = "flat_dt";
- arch = "arm";
compression = "none";
-
- blob {
- filename = "arch/arm/dts/fsl-ls1028a-kontron-sl28.dtb";
- };
- };
-
- fdt-2 {
- description = "fsl-ls1028a-kontron-sl28-var1";
- type = "flat_dt";
- arch = "arm";
- compression = "none";
-
- blob {
- filename = "arch/arm/dts/fsl-ls1028a-kontron-sl28-var1.dtb";
- };
- };
-
- fdt-3 {
- description = "fsl-ls1028a-kontron-sl28-var2";
- type = "flat_dt";
- arch = "arm";
- compression = "none";
-
- blob {
- filename = "arch/arm/dts/fsl-ls1028a-kontron-sl28-var2.dtb";
- };
- };
-
- fdt-4 {
- description = "fsl-ls1028a-kontron-sl28-var3";
- type = "flat_dt";
- arch = "arm";
- compression = "none";
-
- blob {
- filename = "arch/arm/dts/fsl-ls1028a-kontron-sl28-var3.dtb";
- };
- };
-
- fdt-5 {
- description = "fsl-ls1028a-kontron-sl28-var4";
- type = "flat_dt";
- arch = "arm";
- compression = "none";
-
- blob {
- filename = "arch/arm/dts/fsl-ls1028a-kontron-sl28-var4.dtb";
- };
};
};
configurations {
- default = "conf-1";
+ default = "@config-DEFAULT-SEQ";
- conf-1 {
- description = "fsl-ls1028a-kontron-sl28";
+ @config-SEQ {
+ description = "NAME";
firmware = "uboot";
- fdt = "fdt-1";
- };
-
- conf-2 {
- description = "fsl-ls1028a-kontron-sl28-var1";
- firmware = "uboot";
- fdt = "fdt-2";
- };
-
- conf-3 {
- description = "fsl-ls1028a-kontron-sl28-var2";
- firmware = "uboot";
- fdt = "fdt-3";
- };
-
- conf-4 {
- description = "fsl-ls1028a-kontron-sl28-var3";
- firmware = "uboot";
- loadables = "uboot";
- fdt = "fdt-4";
- };
-
- conf-5 {
- description = "fsl-ls1028a-kontron-sl28-var4";
- firmware = "uboot";
- loadables = "uboot";
- fdt = "fdt-5";
+ fdt = "fdt-SEQ";
};
};
};
@@ -189,27 +115,7 @@
};
configurations {
- conf-1 {
- firmware = "bl31";
- loadables = "uboot";
- };
-
- conf-2 {
- firmware = "bl31";
- loadables = "uboot";
- };
-
- conf-3 {
- firmware = "bl31";
- loadables = "uboot";
- };
-
- conf-4 {
- firmware = "bl31";
- loadables = "uboot";
- };
-
- conf-5 {
+ @config-SEQ {
firmware = "bl31";
loadables = "uboot";
};
@@ -238,23 +144,7 @@
};
configurations {
- conf-1 {
- loadables = "uboot", "bl32";
- };
-
- conf-2 {
- loadables = "uboot", "bl32";
- };
-
- conf-3 {
- loadables = "uboot", "bl32";
- };
-
- conf-4 {
- loadables = "uboot", "bl32";
- };
-
- conf-5 {
+ @config-SEQ {
loadables = "uboot", "bl32";
};
};
diff --git a/arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi b/arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi
index 286e25f..d80c550 100644
--- a/arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi
+++ b/arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (c) Siemens AG, 2018-2021
+ * Copyright (c) Siemens AG, 2018-2022
*
* Authors:
* Le Jin <le.jin@siemens.com>
@@ -27,6 +27,29 @@
&cbass_mcu {
u-boot,dm-spl;
+
+ mcu_navss: bus@28380000 {
+ ringacc@2b800000 {
+ reg = <0x0 0x2b800000 0x0 0x400000>,
+ <0x0 0x2b000000 0x0 0x400000>,
+ <0x0 0x28590000 0x0 0x100>,
+ <0x0 0x2a500000 0x0 0x40000>,
+ <0x0 0x28440000 0x0 0x40000>;
+ reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target", "cfg";
+ ti,dma-ring-reset-quirk;
+ };
+
+ dma-controller@285c0000 {
+ reg = <0x0 0x285c0000 0x0 0x100>,
+ <0x0 0x284c0000 0x0 0x4000>,
+ <0x0 0x2a800000 0x0 0x40000>,
+ <0x0 0x284a0000 0x0 0x4000>,
+ <0x0 0x2aa00000 0x0 0x40000>,
+ <0x0 0x28400000 0x0 0x2000>;
+ reg-names = "gcfg", "rchan", "rchanrt", "tchan",
+ "tchanrt", "rflow";
+ };
+ };
};
&cbass_wakeup {
diff --git a/arch/arm/dts/sama7g5ek.dts b/arch/arm/dts/sama7g5ek.dts
index 6adb044..ac6f23f 100644
--- a/arch/arm/dts/sama7g5ek.dts
+++ b/arch/arm/dts/sama7g5ek.dts
@@ -125,7 +125,9 @@
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gmac0_default &pinctrl_gmac0_txc_default>;
+ pinctrl-0 = <&pinctrl_gmac0_default
+ &pinctrl_gmac0_mdio_default
+ &pinctrl_gmac0_txc_default>;
phy-mode = "rgmii-id";
status = "okay";
@@ -138,7 +140,7 @@
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gmac1_default>;
+ pinctrl-0 = <&pinctrl_gmac1_default &pinctrl_gmac1_mdio_default>;
phy-mode = "rmii";
status = "okay";
@@ -235,14 +237,20 @@
<PIN_PA15__G0_TXEN>,
<PIN_PA30__G0_RXCK>,
<PIN_PA18__G0_RXDV>,
- <PIN_PA22__G0_MDC>,
- <PIN_PA23__G0_MDIO>,
<PIN_PA25__G0_125CK>;
+ slew-rate = <0>;
+ bias-disable;
+ };
+
+ pinctrl_gmac0_mdio_default: gmac0_mdio_default {
+ pinmux = <PIN_PA22__G0_MDC>,
+ <PIN_PA23__G0_MDIO>;
bias-disable;
};
pinctrl_gmac0_txc_default: gmac0_txc_default {
pinmux = <PIN_PA24__G0_TXCK>;
+ slew-rate = <0>;
bias-pull-up;
};
@@ -254,8 +262,13 @@
<PIN_PD25__G1_RX0>,
<PIN_PD26__G1_RX1>,
<PIN_PD27__G1_RXER>,
- <PIN_PD24__G1_RXDV>,
- <PIN_PD28__G1_MDC>,
+ <PIN_PD24__G1_RXDV>;
+ slew-rate = <0>;
+ bias-disable;
+ };
+
+ pinctrl_gmac1_mdio_default: gmac1_mdio_default {
+ pinmux = <PIN_PD28__G1_MDC>,
<PIN_PD29__G1_MDIO>;
bias-disable;
};
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index 7f7eb05..edd0fbf 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -160,6 +160,7 @@
#define SUNXI_GPC_SDC2 3
#define SUN6I_GPC_SDC3 4
#define SUN50I_GPC_SPI0 4
+#define SUNIV_GPC_SPI0 2
#define SUNXI_GPD_LCD0 2
#define SUNXI_GPD_LVDS0 3
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
index 58cdf80..b543d24 100644
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -19,6 +19,15 @@
#define SUNXI_BOOTED_FROM_MMC0_HIGH 0x10
#define SUNXI_BOOTED_FROM_MMC2_HIGH 0x12
+/*
+ * Values taken from the F1C200s BootROM stack
+ * to determine where we booted from.
+ */
+#define SUNIV_BOOTED_FROM_MMC0 0xffff40f8
+#define SUNIV_BOOTED_FROM_NAND 0xffff4114
+#define SUNIV_BOOTED_FROM_SPI 0xffff4130
+#define SUNIV_BOOTED_FROM_MMC1 0xffff4150
+
#define is_boot0_magic(addr) (memcmp((void *)(addr), BOOT0_MAGIC, 8) == 0)
uint32_t sunxi_get_boot_device(void);
diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c
index f9f8a2f..54005f3 100644
--- a/arch/arm/mach-apple/board.c
+++ b/arch/arm/mach-apple/board.c
@@ -265,3 +265,36 @@
{
return SZ_256K;
}
+
+int board_late_init(void)
+{
+ unsigned long base;
+ unsigned long top;
+ u32 status = 0;
+
+ /* Reserve 4M each for scriptaddr and pxefile_addr_r at the top of RAM
+ * at least 1M below the stack.
+ */
+ top = gd->start_addr_sp - CONFIG_STACK_SIZE - SZ_8M - SZ_1M;
+ top = ALIGN_DOWN(top, SZ_8M);
+
+ status |= env_set_hex("scriptaddr", top + SZ_4M);
+ status |= env_set_hex("pxefile_addr_r", top);
+
+ /* somewhat based on the Linux Kernel boot requirements:
+ * align by 2M and maximal FDT size 2M
+ */
+ base = ALIGN(gd->ram_base, SZ_2M);
+
+ status |= env_set_hex("fdt_addr_r", base);
+ status |= env_set_hex("kernel_addr_r", base + SZ_2M);
+ status |= env_set_hex("ramdisk_addr_r", base + SZ_128M);
+ status |= env_set_hex("loadaddr", base + SZ_2G);
+ status |= env_set_hex("kernel_comp_addr_r", base + SZ_2G - SZ_128M);
+ status |= env_set_hex("kernel_comp_size", SZ_128M);
+
+ if (status)
+ log_warning("late_init: Failed to set run time variables\n");
+
+ return 0;
+}
diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c
index ffb7aad..8a6b1de 100644
--- a/arch/arm/mach-k3/am6_init.c
+++ b/arch/arm/mach-k3/am6_init.c
@@ -251,7 +251,8 @@
k3_sysfw_print_ver();
/* Perform EEPROM-based board detection */
- do_board_detect();
+ if (IS_ENABLED(CONFIG_TI_I2C_BOARD_DETECT))
+ do_board_detect();
#if defined(CONFIG_CPU_V7R) && defined(CONFIG_K3_AVS0)
ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(k3_avs),
diff --git a/arch/arm/mach-mvebu/armada3700/cpu.c b/arch/arm/mach-mvebu/armada3700/cpu.c
index 23492f4..52b5109 100644
--- a/arch/arm/mach-mvebu/armada3700/cpu.c
+++ b/arch/arm/mach-mvebu/armada3700/cpu.c
@@ -316,8 +316,8 @@
int a3700_fdt_fix_pcie_regions(void *blob)
{
- int acells, pacells, scells;
- u32 base, fix_offset;
+ u32 base, lowest_cpu_addr, fix_offset;
+ int pci_cells, cpu_cells, size_cells;
const u32 *ranges;
int node, pnode;
int ret, i, len;
@@ -331,51 +331,80 @@
return node;
ranges = fdt_getprop(blob, node, "ranges", &len);
- if (!ranges || len % sizeof(u32))
- return -ENOENT;
+ if (!ranges || !len || len % sizeof(u32))
+ return -EINVAL;
/*
* The "ranges" property is an array of
- * { <child address> <parent address> <size in child address space> }
+ * { <PCI address> <CPU address> <size in PCI address space> }
+ * where number of PCI address cells and size cells is stored in the
+ * "#address-cells" and "#size-cells" properties of the same node
+ * containing the "ranges" property and number of CPU address cells
+ * is stored in the parent's "#address-cells" property.
*
- * All 3 elements can span a diffent number of cells. Fetch their sizes.
+ * All 3 elements can span a diffent number of cells. Fetch them.
*/
pnode = fdt_parent_offset(blob, node);
- acells = fdt_address_cells(blob, node);
- pacells = fdt_address_cells(blob, pnode);
- scells = fdt_size_cells(blob, node);
+ pci_cells = fdt_address_cells(blob, node);
+ cpu_cells = fdt_address_cells(blob, pnode);
+ size_cells = fdt_size_cells(blob, node);
- /* Child PCI addresses always use 3 cells */
- if (acells != 3)
- return -ENOENT;
+ /* PCI addresses always use 3 cells */
+ if (pci_cells != 3)
+ return -EINVAL;
- /* Calculate fixup offset from first child address (in last cell) */
- fix_offset = base - fdt32_to_cpu(ranges[2]);
+ /* CPU addresses on Armada 37xx always use 2 cells */
+ if (cpu_cells != 2)
+ return -EINVAL;
- /* If fixup offset is zero then there is nothing to fix */
+ for (i = 0; i < len / sizeof(u32);
+ i += pci_cells + cpu_cells + size_cells) {
+ /*
+ * Parent CPU addresses on Armada 37xx are always 32-bit, so
+ * check that the high word is zero.
+ */
+ if (fdt32_to_cpu(ranges[i + pci_cells]))
+ return -EINVAL;
+
+ if (i == 0 ||
+ fdt32_to_cpu(ranges[i + pci_cells + 1]) < lowest_cpu_addr)
+ lowest_cpu_addr = fdt32_to_cpu(ranges[i + pci_cells + 1]);
+ }
+
+ /* Calculate fixup offset from the lowest (first) CPU address */
+ fix_offset = base - lowest_cpu_addr;
+
+ /* If fixup offset is zero there is nothing to fix */
if (!fix_offset)
return 0;
/*
- * Fix address (last cell) of each child address and each parent
- * address
+ * Fix each CPU address and corresponding PCI address if PCI address
+ * is not already remapped (has the same value)
*/
- for (i = 0; i < len / sizeof(u32); i += acells + pacells + scells) {
+ for (i = 0; i < len / sizeof(u32);
+ i += pci_cells + cpu_cells + size_cells) {
+ u32 cpu_addr;
+ u64 pci_addr;
int idx;
- /* fix child address */
- idx = i + acells - 1;
+ /* Fix CPU address */
+ idx = i + pci_cells + cpu_cells - 1;
+ cpu_addr = fdt32_to_cpu(ranges[idx]);
ret = fdt_setprop_inplace_u32_partial(blob, node, "ranges", idx,
- fdt32_to_cpu(ranges[idx]) +
- fix_offset);
+ cpu_addr + fix_offset);
if (ret)
return ret;
- /* fix parent address */
- idx = i + acells + pacells - 1;
+ /* Fix PCI address only if it isn't remapped (is same as CPU) */
+ idx = i + pci_cells - 1;
+ pci_addr = ((u64)fdt32_to_cpu(ranges[idx - 1]) << 32) |
+ fdt32_to_cpu(ranges[idx]);
+ if (cpu_addr != pci_addr)
+ continue;
+
ret = fdt_setprop_inplace_u32_partial(blob, node, "ranges", idx,
- fdt32_to_cpu(ranges[idx]) +
- fix_offset);
+ cpu_addr + fix_offset);
if (ret)
return ret;
}
diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig
index 4dab917..73da6b8 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -1035,7 +1035,7 @@
config SPL_SPI_SUNXI
bool "Support for SPI Flash on Allwinner SoCs in SPL"
- depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || MACH_SUN50I_H6
+ depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I || MACH_SUNXI_H3_H5 || MACH_SUN50I || MACH_SUN8I_R40 || MACH_SUN50I_H6 || MACH_SUNIV
help
Enable support for SPI Flash. This option allows SPL to read from
sunxi SPI Flash. It uses the same method as the boot ROM, so does
diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c
index 57078f7..0071de1 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -191,12 +191,48 @@
#define SUNXI_INVALID_BOOT_SOURCE -1
+static int suniv_get_boot_source(void)
+{
+ /* Get the last function call from BootROM's stack. */
+ u32 brom_call = *(u32 *)(uintptr_t)(fel_stash.sp - 4);
+
+ /* translate SUNIV BootROM stack to standard SUNXI boot sources */
+ switch (brom_call) {
+ case SUNIV_BOOTED_FROM_MMC0:
+ return SUNXI_BOOTED_FROM_MMC0;
+ case SUNIV_BOOTED_FROM_SPI:
+ return SUNXI_BOOTED_FROM_SPI;
+ case SUNIV_BOOTED_FROM_MMC1:
+ return SUNXI_BOOTED_FROM_MMC2;
+ /* SPI NAND is not supported yet. */
+ case SUNIV_BOOTED_FROM_NAND:
+ return SUNXI_INVALID_BOOT_SOURCE;
+ }
+ /* If we get here something went wrong try to boot from FEL.*/
+ printf("Unknown boot source from BROM: 0x%x\n", brom_call);
+ return SUNXI_INVALID_BOOT_SOURCE;
+}
+
static int sunxi_get_boot_source(void)
{
+ /*
+ * On the ARMv5 SoCs, the SPL header in SRAM is overwritten by the
+ * exception vectors in U-Boot proper, so we won't find any
+ * information there. Also the FEL stash is only valid in the SPL,
+ * so we can't use that either. So if this is called from U-Boot
+ * proper, just return MMC0 as a placeholder, for now.
+ */
+ if (IS_ENABLED(CONFIG_MACH_SUNIV) &&
+ !IS_ENABLED(CONFIG_SPL_BUILD))
+ return SUNXI_BOOTED_FROM_MMC0;
+
if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */
return SUNXI_INVALID_BOOT_SOURCE;
- return readb(SPL_ADDR + 0x28);
+ if (IS_ENABLED(CONFIG_MACH_SUNIV))
+ return suniv_get_boot_source();
+ else
+ return readb(SPL_ADDR + 0x28);
}
/* The sunxi internal brom will try to loader external bootloader
@@ -276,36 +312,10 @@
return sector;
}
-#ifdef CONFIG_MACH_SUNIV
-/*
- * The suniv BROM does not pass the boot media type to SPL, so we try with the
- * boot sequence in BROM: mmc0->spinor->fail.
- * TODO: This has the slight chance of being wrong (invalid SPL signature,
- * but valid U-Boot legacy image on the SD card), but this should be rare.
- * It looks like we can deduce from some BROM state upon entering the SPL
- * (registers, SP, or stack itself) where the BROM was coming from and use
- * that here.
- */
-void board_boot_order(u32 *spl_boot_list)
-{
- /*
- * See the comments above in sunxi_get_boot_device() for information
- * about FEL boot.
- */
- if (!is_boot0_magic(SPL_ADDR + 4)) {
- spl_boot_list[0] = BOOT_DEVICE_BOARD;
- return;
- }
-
- spl_boot_list[0] = BOOT_DEVICE_MMC1;
- spl_boot_list[1] = BOOT_DEVICE_SPI;
-}
-#else
u32 spl_boot_device(void)
{
return sunxi_get_boot_device();
}
-#endif
__weak void sunxi_sram_init(void)
{
diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c
index 910e805..734c165 100644
--- a/arch/arm/mach-sunxi/spl_spi_sunxi.c
+++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c
@@ -90,6 +90,7 @@
#define SPI0_CLK_DIV_BY_2 0x1000
#define SPI0_CLK_DIV_BY_4 0x1001
+#define SPI0_CLK_DIV_BY_32 0x100f
/*****************************************************************************/
@@ -132,7 +133,8 @@
if (IS_ENABLED(CONFIG_MACH_SUN50I_H6))
return 0x05010000;
- if (!is_sun6i_gen_spi())
+ if (!is_sun6i_gen_spi() ||
+ IS_ENABLED(CONFIG_MACH_SUNIV))
return 0x01C05000;
return 0x01C68000;
@@ -156,11 +158,16 @@
if (!IS_ENABLED(CONFIG_MACH_SUN50I_H6))
setbits_le32(CCM_AHB_GATING0, (1 << AHB_GATE_OFFSET_SPI0));
- /* Divide by 4 */
- writel(SPI0_CLK_DIV_BY_4, base + (is_sun6i_gen_spi() ?
- SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL));
- /* 24MHz from OSC24M */
- writel((1 << 31), CCM_SPI0_CLK);
+ if (IS_ENABLED(CONFIG_MACH_SUNIV)) {
+ /* Divide by 32, clock source is AHB clock 200MHz */
+ writel(SPI0_CLK_DIV_BY_32, base + SUN6I_SPI0_CCTL);
+ } else {
+ /* Divide by 4 */
+ writel(SPI0_CLK_DIV_BY_4, base + (is_sun6i_gen_spi() ?
+ SUN6I_SPI0_CCTL : SUN4I_SPI0_CCTL));
+ /* 24MHz from OSC24M */
+ writel((1 << 31), CCM_SPI0_CLK);
+ }
if (is_sun6i_gen_spi()) {
/* Enable SPI in the master mode and do a soft reset */
@@ -191,7 +198,8 @@
SUN4I_CTL_ENABLE);
/* Disable the SPI0 clock */
- writel(0, CCM_SPI0_CLK);
+ if (!IS_ENABLED(CONFIG_MACH_SUNIV))
+ writel(0, CCM_SPI0_CLK);
/* Close the SPI0 gate */
if (!IS_ENABLED(CONFIG_MACH_SUN50I_H6))
@@ -212,6 +220,8 @@
if (IS_ENABLED(CONFIG_MACH_SUN50I) ||
IS_ENABLED(CONFIG_MACH_SUN50I_H6))
pin_function = SUN50I_GPC_SPI0;
+ else if (IS_ENABLED(CONFIG_MACH_SUNIV))
+ pin_function = SUNIV_GPC_SPI0;
spi0_pinmux_setup(pin_function);
spi0_enable_clock();
diff --git a/board/advantech/som-db5800-som-6867/.gitignore b/board/advantech/som-db5800-som-6867/.gitignore
index 6eb8a54..39e46ba 100644
--- a/board/advantech/som-db5800-som-6867/.gitignore
+++ b/board/advantech/som-db5800-som-6867/.gitignore
@@ -1,3 +1,3 @@
-dsdt.aml
-dsdt.asl.tmp
-dsdt.c
+dsdt_generated.aml
+dsdt_generated.asl.tmp
+dsdt_generated.c
diff --git a/board/advantech/som-db5800-som-6867/Makefile b/board/advantech/som-db5800-som-6867/Makefile
index 7975547..95af6c4 100644
--- a/board/advantech/som-db5800-som-6867/Makefile
+++ b/board/advantech/som-db5800-som-6867/Makefile
@@ -3,4 +3,4 @@
# Copyright (C) 2015, Google, Inc
obj-y += som-db5800-som-6867.o
-obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt.o
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt_generated.o
diff --git a/board/alliedtelesis/x530/x530.c b/board/alliedtelesis/x530/x530.c
index 8b31045..c0ec2af 100644
--- a/board/alliedtelesis/x530/x530.c
+++ b/board/alliedtelesis/x530/x530.c
@@ -73,6 +73,7 @@
{0}, /* timing parameters */
{ {0} }, /* electrical configuration */
{0}, /* electrical parameters */
+ 0, /* ODT configuration */
0, /* Clock enable mask */
160 /* Clock delay */
};
diff --git a/board/congatec/conga-qeval20-qa3-e3845/.gitignore b/board/congatec/conga-qeval20-qa3-e3845/.gitignore
index 6eb8a54..39e46ba 100644
--- a/board/congatec/conga-qeval20-qa3-e3845/.gitignore
+++ b/board/congatec/conga-qeval20-qa3-e3845/.gitignore
@@ -1,3 +1,3 @@
-dsdt.aml
-dsdt.asl.tmp
-dsdt.c
+dsdt_generated.aml
+dsdt_generated.asl.tmp
+dsdt_generated.c
diff --git a/board/congatec/conga-qeval20-qa3-e3845/Makefile b/board/congatec/conga-qeval20-qa3-e3845/Makefile
index 451a4fc..215f568 100644
--- a/board/congatec/conga-qeval20-qa3-e3845/Makefile
+++ b/board/congatec/conga-qeval20-qa3-e3845/Makefile
@@ -3,4 +3,4 @@
# Copyright (C) 2015, Google, Inc
obj-y += conga-qeval20-qa3.o
-obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt.o
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt_generated.o
diff --git a/board/dfi/dfi-bt700/Makefile b/board/dfi/dfi-bt700/Makefile
index 50d88f2..1c4329a 100644
--- a/board/dfi/dfi-bt700/Makefile
+++ b/board/dfi/dfi-bt700/Makefile
@@ -3,4 +3,4 @@
# Copyright (C) 2015, Google, Inc
obj-y += dfi-bt700.o
-obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt.o
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt_generated.o
diff --git a/board/eets/pdu001/Makefile b/board/eets/pdu001/Makefile
index a5990ce3..35ea397 100644
--- a/board/eets/pdu001/Makefile
+++ b/board/eets/pdu001/Makefile
@@ -6,8 +6,4 @@
# SPDX-License-Identifier: GPL-2.0+
#
-ifeq ($(CONFIG_$(SPL_)SKIP_LOWLEVEL_INIT),)
-obj-y := mux.o
-endif
-
-obj-y += board.o
+obj-y := board.o mux.o
diff --git a/board/eets/pdu001/board.c b/board/eets/pdu001/board.c
index 9f3cfd4..2b483da 100644
--- a/board/eets/pdu001/board.c
+++ b/board/eets/pdu001/board.c
@@ -216,6 +216,36 @@
return &dpll_ddr;
}
+void set_uart_mux_conf(void)
+{
+ switch (CONFIG_CONS_INDEX) {
+ case 1: {
+ enable_uart0_pin_mux();
+ break;
+ }
+ case 2: {
+ enable_uart1_pin_mux();
+ break;
+ }
+ case 3: {
+ enable_uart2_pin_mux();
+ break;
+ }
+ case 4: {
+ enable_uart3_pin_mux();
+ break;
+ }
+ case 5: {
+ enable_uart4_pin_mux();
+ break;
+ }
+ case 6: {
+ enable_uart5_pin_mux();
+ break;
+ }
+ }
+}
+
void set_mux_conf_regs(void)
{
/* done first by the ROM and afterwards by the pin controller driver */
@@ -240,6 +270,8 @@
#ifdef CONFIG_DEBUG_UART
void board_debug_uart_init(void)
{
+ setup_early_clocks();
+
/* done by pin controller driver if not debugging */
enable_uart_pin_mux(CONFIG_DEBUG_UART_BASE);
}
diff --git a/board/google/chromebook_coral/Makefile b/board/google/chromebook_coral/Makefile
index f7a0ca6..846558d 100644
--- a/board/google/chromebook_coral/Makefile
+++ b/board/google/chromebook_coral/Makefile
@@ -3,4 +3,4 @@
# Copyright 2019 Google LLC
obj-y += coral.o
-obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt.o
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt_generated.o
diff --git a/board/intel/bayleybay/.gitignore b/board/intel/bayleybay/.gitignore
index 6eb8a54..39e46ba 100644
--- a/board/intel/bayleybay/.gitignore
+++ b/board/intel/bayleybay/.gitignore
@@ -1,3 +1,3 @@
-dsdt.aml
-dsdt.asl.tmp
-dsdt.c
+dsdt_generated.aml
+dsdt_generated.asl.tmp
+dsdt_generated.c
diff --git a/board/intel/bayleybay/Makefile b/board/intel/bayleybay/Makefile
index d194471..fa263b7 100644
--- a/board/intel/bayleybay/Makefile
+++ b/board/intel/bayleybay/Makefile
@@ -3,4 +3,4 @@
# Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
obj-y += bayleybay.o
-obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt.o
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt_generated.o
diff --git a/board/intel/edison/.gitignore b/board/intel/edison/.gitignore
index 6eb8a54..39e46ba 100644
--- a/board/intel/edison/.gitignore
+++ b/board/intel/edison/.gitignore
@@ -1,3 +1,3 @@
-dsdt.aml
-dsdt.asl.tmp
-dsdt.c
+dsdt_generated.aml
+dsdt_generated.asl.tmp
+dsdt_generated.c
diff --git a/board/intel/edison/Makefile b/board/intel/edison/Makefile
index 1eaf7ca..f7f70df 100644
--- a/board/intel/edison/Makefile
+++ b/board/intel/edison/Makefile
@@ -5,4 +5,4 @@
#
obj-y += edison.o
-obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt.o
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt_generated.o
diff --git a/board/intel/galileo/.gitignore b/board/intel/galileo/.gitignore
index 6eb8a54..39e46ba 100644
--- a/board/intel/galileo/.gitignore
+++ b/board/intel/galileo/.gitignore
@@ -1,3 +1,3 @@
-dsdt.aml
-dsdt.asl.tmp
-dsdt.c
+dsdt_generated.aml
+dsdt_generated.asl.tmp
+dsdt_generated.c
diff --git a/board/intel/galileo/Makefile b/board/intel/galileo/Makefile
index 4130bb0..7d5f4df 100644
--- a/board/intel/galileo/Makefile
+++ b/board/intel/galileo/Makefile
@@ -3,4 +3,4 @@
# Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
obj-y += galileo.o
-obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt.o
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt_generated.o
diff --git a/board/intel/minnowmax/.gitignore b/board/intel/minnowmax/.gitignore
index 6eb8a54..39e46ba 100644
--- a/board/intel/minnowmax/.gitignore
+++ b/board/intel/minnowmax/.gitignore
@@ -1,3 +1,3 @@
-dsdt.aml
-dsdt.asl.tmp
-dsdt.c
+dsdt_generated.aml
+dsdt_generated.asl.tmp
+dsdt_generated.c
diff --git a/board/intel/minnowmax/Makefile b/board/intel/minnowmax/Makefile
index d339b5a..a20322a 100644
--- a/board/intel/minnowmax/Makefile
+++ b/board/intel/minnowmax/Makefile
@@ -3,4 +3,4 @@
# Copyright (C) 2015, Google, Inc
obj-y += minnowmax.o
-obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt.o
+obj-$(CONFIG_GENERATE_ACPI_TABLE) += dsdt_generated.o
diff --git a/board/kontron/sl28/sl28.c b/board/kontron/sl28/sl28.c
index e84b356..3c48a91 100644
--- a/board/kontron/sl28/sl28.c
+++ b/board/kontron/sl28/sl28.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
#include <common.h>
+#include <dm.h>
#include <malloc.h>
#include <errno.h>
#include <fsl_ddr.h>
@@ -14,7 +15,9 @@
#include <asm/arch/soc.h>
#include <fsl_immap.h>
#include <netdev.h>
+#include <wdt.h>
+#include <sl28cpld.h>
#include <fdtdec.h>
#include <miiphy.h>
@@ -39,16 +42,68 @@
return pci_eth_init(bis);
}
+static int __sl28cpld_read(uint reg)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = uclass_get_device_by_driver(UCLASS_NOP,
+ DM_DRIVER_GET(sl28cpld), &dev);
+ if (ret)
+ return ret;
+
+ return sl28cpld_read(dev, reg);
+}
+
+static void print_cpld_version(void)
+{
+ int version = __sl28cpld_read(SL28CPLD_VERSION);
+
+ if (version < 0)
+ printf("CPLD: error reading version (%d)\n", version);
+ else
+ printf("CPLD: v%d\n", version);
+}
+
int checkboard(void)
{
printf("EL: %d\n", current_el());
+ if (CONFIG_IS_ENABLED(SL28CPLD))
+ print_cpld_version();
+
+ return 0;
+}
+
+static void stop_recovery_watchdog(void)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = uclass_get_device_by_driver(UCLASS_WDT,
+ DM_DRIVER_GET(sl28cpld_wdt), &dev);
+ if (!ret)
+ wdt_stop(dev);
+}
+
+int fsl_board_late_init(void)
+{
+ /*
+ * Usually, the after a board reset, the watchdog is enabled by
+ * default. This is to supervise the bootloader boot-up. Therefore,
+ * to prevent a watchdog reset if we don't actively kick it, we have
+ * to disable it.
+ *
+ * If the watchdog isn't enabled at reset (which is a configuration
+ * option) disabling it doesn't hurt either.
+ */
+ if (!CONFIG_IS_ENABLED(WATCHDOG_AUTOSTART))
+ stop_recovery_watchdog();
+
return 0;
}
void detail_board_ddr_info(void)
{
- puts("\nDDR ");
- print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
print_ddr_info(0);
}
diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c
index c920cf8..03adb59 100644
--- a/board/solidrun/clearfog/clearfog.c
+++ b/board/solidrun/clearfog/clearfog.c
@@ -147,6 +147,7 @@
{0}, /* timing parameters */
{ {0} }, /* electrical configuration */
{0,}, /* electrical parameters */
+ 0, /* ODT configuration */
0x3, /* clock enable mask */
};
diff --git a/board/ste/stemmy/stemmy.c b/board/ste/stemmy/stemmy.c
index 5f1150c..060d562 100644
--- a/board/ste/stemmy/stemmy.c
+++ b/board/ste/stemmy/stemmy.c
@@ -4,6 +4,7 @@
*/
#include <common.h>
#include <env.h>
+#include <fdt_support.h>
#include <init.h>
#include <log.h>
#include <stdlib.h>
@@ -95,6 +96,33 @@
env_set("serial#", serial);
}
+#define SBL_BOARD "board_id="
+#define SBL_LCDTYPE "lcdtype="
+static ulong board_id = 0;
+static ulong lcdtype = 0;
+
+static void parse_cmdline(const struct tag_cmdline *cmdline)
+{
+ char *buf;
+
+ /* Export this to sbl_cmdline (secondary boot loader command line) */
+ env_set("sbl_cmdline", cmdline->cmdline);
+
+ buf = strstr(cmdline->cmdline, SBL_BOARD);
+ if (!buf)
+ return;
+ buf += strlen(SBL_BOARD);
+
+ board_id = simple_strtoul(buf, NULL, 10);
+
+ buf = strstr(cmdline->cmdline, SBL_LCDTYPE);
+ if (!buf)
+ return;
+ buf += strlen(SBL_LCDTYPE);
+
+ lcdtype = simple_strtoul(buf, NULL, 10);
+}
+
/*
* The downstream/vendor kernel (provided by Samsung) uses ATAGS for booting.
* It also requires an extremely long cmdline provided by the primary bootloader
@@ -126,6 +154,9 @@
if (t->hdr.tag == ATAG_SERIAL)
parse_serial(&t->u.serialnr);
+ if (t->hdr.tag == ATAG_CMDLINE)
+ parse_cmdline(&t->u.cmdline);
+
fw_atags_size += t->hdr.size * sizeof(u32);
}
@@ -165,3 +196,287 @@
memcpy(*in_params, fw_atags_copy, fw_atags_size);
*(u8 **)in_params += fw_atags_size;
}
+
+/* These numbers are unique per product but not across all products */
+#define SAMSUNG_CODINA_LCD_LMS380KF01 4
+#define SAMSUNG_CODINA_LCD_S6D27A1 13
+#define SAMSUNG_SKOMER_LCD_HVA40WV1 10
+#define SAMSUNG_SKOMER_LCD_NT35512 12
+
+static void codina_patch_display(void *fdt)
+{
+ int node;
+ int ret;
+
+ node = fdt_path_offset(fdt, "/spi-gpio-0/panel");
+ if (node < 0) {
+ printf("cannot find Codina panel node\n");
+ return;
+ }
+ if (lcdtype == SAMSUNG_CODINA_LCD_LMS380KF01) {
+ ret = fdt_setprop_string(fdt, node, "compatible", "samsung,lms380kf01");
+ if (ret < 0)
+ printf("could not set LCD compatible\n");
+ else
+ printf("updated LCD compatible to LMS380KF01\n");
+ } else if (lcdtype == SAMSUNG_CODINA_LCD_S6D27A1) {
+ ret = fdt_setprop_string(fdt, node, "compatible", "samsung,s6d27a1");
+ if (ret < 0)
+ printf("could not set LCD compatible\n");
+ else
+ printf("updated LCD compatible to S6D27A1\n");
+ } else {
+ printf("unknown LCD type\n");
+ }
+}
+
+static void skomer_kyle_patch_display(void *fdt)
+{
+ int node;
+ int ret;
+
+ node = fdt_path_offset(fdt, "/soc/mcde/dsi/panel");
+ if (node < 0) {
+ printf("cannot find Skomer/Kyle panel node\n");
+ return;
+ }
+ if (lcdtype == SAMSUNG_SKOMER_LCD_HVA40WV1) {
+ ret = fdt_setprop_string(fdt, node, "compatible", "hydis,hva40wv1");
+ if (ret < 0)
+ printf("could not set LCD compatible\n");
+ else
+ printf("updated LCD compatible to Hydis HVA40WV1\n");
+ } else if (lcdtype == SAMSUNG_SKOMER_LCD_NT35512) {
+ /*
+ * FIXME: This panel is actually a BOE product, but we don't know
+ * the exact product name, so the compatible for the NT35512
+ * is used for the time being. The vendor drivers also call it NT35512.
+ */
+ ret = fdt_setprop_string(fdt, node, "compatible", "novatek,nt35512");
+ if (ret < 0)
+ printf("could not set LCD compatible\n");
+ else
+ printf("updated LCD compatible to Novatek NT35512\n");
+ } else {
+ printf("unknown LCD type\n");
+ }
+}
+
+int ft_board_setup(void *fdt, struct bd_info *bd)
+{
+ const char *str;
+ int node;
+ int ret;
+
+ printf("stemmy patch: DTB at 0x%08lx\n", (ulong)fdt);
+
+ /* Inspect FDT to see what we've got here */
+ ret = fdt_check_header(fdt);
+ if (ret < 0) {
+ printf("invalid DTB\n");
+ return ret;
+ }
+ node = fdt_path_offset(fdt, "/");
+ if (node < 0) {
+ printf("cannot find root node\n");
+ return node;
+ }
+ str = fdt_stringlist_get(fdt, node, "compatible", 0, NULL);
+ if (!str) {
+ printf("could not find board compatible\n");
+ return -1;
+ }
+
+ if (!strcmp(str, "samsung,janice")) {
+ switch(board_id) {
+ case 7:
+ printf("Janice GT-I9070 Board Rev 0.0\n");
+ break;
+ case 8:
+ printf("Janice GT-I9070 Board Rev 0.1\n");
+ break;
+ case 9:
+ printf("Janice GT-I9070 Board Rev 0.2\n");
+ break;
+ case 10:
+ printf("Janice GT-I9070 Board Rev 0.3\n");
+ break;
+ case 11:
+ printf("Janice GT-I9070 Board Rev 0.4\n");
+ break;
+ case 12:
+ printf("Janice GT-I9070 Board Rev 0.5\n");
+ break;
+ case 13:
+ printf("Janice GT-I9070 Board Rev 0.6\n");
+ break;
+ default:
+ break;
+ }
+ } else if (!strcmp(str, "samsung,gavini")) {
+ switch(board_id) {
+ case 7:
+ printf("Gavini GT-I8530 Board Rev 0.0\n");
+ break;
+ case 8:
+ printf("Gavini GT-I8530 Board Rev 0.0A\n");
+ break;
+ case 9:
+ printf("Gavini GT-I8530 Board Rev 0.0B\n");
+ break;
+ case 10:
+ printf("Gavini GT-I8530 Board Rev 0.0A_EMUL\n");
+ break;
+ case 11:
+ printf("Gavini GT-I8530 Board Rev 0.0C\n");
+ break;
+ case 12:
+ printf("Gavini GT-I8530 Board Rev 0.0D\n");
+ break;
+ case 13:
+ printf("Gavini GT-I8530 Board Rev 0.1\n");
+ break;
+ case 14:
+ printf("Gavini GT-I8530 Board Rev 0.3\n");
+ break;
+ default:
+ break;
+ }
+ } else if (!strcmp(str, "samsung,codina")) {
+ switch(board_id) {
+ case 7:
+ printf("Codina GT-I8160 Board Rev 0.0\n");
+ break;
+ case 8:
+ printf("Codina GT-I8160 Board Rev 0.1\n");
+ break;
+ case 9:
+ printf("Codina GT-I8160 Board Rev 0.2\n");
+ break;
+ case 10:
+ printf("Codina GT-I8160 Board Rev 0.3\n");
+ break;
+ case 11:
+ printf("Codina GT-I8160 Board Rev 0.4\n");
+ break;
+ case 12:
+ printf("Codina GT-I8160 Board Rev 0.5\n");
+ break;
+ default:
+ break;
+ }
+ codina_patch_display(fdt);
+ } else if (!strcmp(str, "samsung,codina-tmo")) {
+ switch(board_id) {
+ case 0x101:
+ printf("Codina SGH-T599 Board pre-Rev 0.0\n");
+ break;
+ case 0x102:
+ printf("Codina SGH-T599 Board Rev 0.0\n");
+ break;
+ case 0x103:
+ printf("Codina SGH-T599 Board Rev 0.1\n");
+ break;
+ case 0x104:
+ printf("Codina SGH-T599 Board Rev 0.2\n");
+ break;
+ case 0x105:
+ printf("Codina SGH-T599 Board Rev 0.4\n");
+ break;
+ case 0x106:
+ printf("Codina SGH-T599 Board Rev 0.6\n");
+ break;
+ case 0x107:
+ printf("Codina SGH-T599 Board Rev 0.7\n");
+ break;
+ default:
+ break;
+ }
+ codina_patch_display(fdt);
+ } else if (!strcmp(str, "samsung,golden")) {
+ switch(board_id) {
+ case 0x102:
+ printf("Golden GT-I8190 Board SW bringup\n");
+ break;
+ case 0x103:
+ printf("Golden GT-I8190 Board Rev 0.2\n");
+ break;
+ case 0x104:
+ printf("Golden GT-I8190 Board Rev 0.3\n");
+ break;
+ case 0x105:
+ printf("Golden GT-I8190 Board Rev 0.4\n");
+ break;
+ case 0x106:
+ printf("Golden GT-I8190 Board Rev 0.5\n");
+ break;
+ case 0x107:
+ printf("Golden GT-I8190 Board Rev 0.6\n");
+ break;
+ default:
+ break;
+ }
+ } else if (!strcmp(str, "samsung,skomer")) {
+ switch(board_id) {
+ case 0x101:
+ printf("Skomer GT-S7710 Board Rev 0.0\n");
+ break;
+ case 0x102:
+ printf("Skomer GT-S7710 Board Rev 0.1\n");
+ break;
+ case 0x103:
+ printf("Skomer GT-S7710 Board Rev 0.2\n");
+ break;
+ case 0x104:
+ printf("Skomer GT-S7710 Board Rev 0.3\n");
+ break;
+ case 0x105:
+ printf("Skomer GT-S7710 Board Rev 0.4\n");
+ break;
+ case 0x106:
+ printf("Skomer GT-S7710 Board Rev 0.5\n");
+ break;
+ case 0x107:
+ printf("Skomer GT-S7710 Board Rev 0.6\n");
+ break;
+ case 0x108:
+ printf("Skomer GT-S7710 Board Rev 0.7\n");
+ break;
+ case 0x109:
+ printf("Skomer GT-S7710 Board Rev 0.8\n");
+ break;
+ default:
+ break;
+ }
+ skomer_kyle_patch_display(fdt);
+ } else if (!strcmp(str, "samsung,kyle")) {
+ switch(board_id) {
+ case 0x101:
+ printf("Kyle SGH-I407 Board Rev 0.0\n");
+ break;
+ case 0x102:
+ printf("Kyle SGH-I407 Board Rev 0.1\n");
+ break;
+ case 0x103:
+ printf("Kyle SGH-I407 Board Rev 0.2\n");
+ break;
+ case 0x104:
+ printf("Kyle SGH-I407 Board Rev 0.3\n");
+ break;
+ case 0x105:
+ printf("Kyle SGH-I407 Board Rev 0.4\n");
+ break;
+ case 0x106:
+ printf("Kyle SGH-I407 Board Rev 0.5\n");
+ break;
+ case 0x107:
+ printf("Kyle SGH-I407 Board Rev 0.6\n");
+ break;
+ default:
+ break;
+ }
+ skomer_kyle_patch_display(fdt);
+ }
+
+ return 0;
+}
diff --git a/board/ti/am65x/evm.c b/board/ti/am65x/evm.c
index fbe33cb..7182a8c 100644
--- a/board/ti/am65x/evm.c
+++ b/board/ti/am65x/evm.c
@@ -129,6 +129,7 @@
}
#endif
+#ifdef CONFIG_TI_I2C_BOARD_DETECT
int do_board_detect(void)
{
int ret;
@@ -353,23 +354,26 @@
return 0;
}
+#endif
int board_late_init(void)
{
- struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
+ if (IS_ENABLED(CONFIG_TI_I2C_BOARD_DETECT)) {
+ struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
- setup_board_eeprom_env();
+ setup_board_eeprom_env();
- /*
- * The first MAC address for ethernet a.k.a. ethernet0 comes from
- * efuse populated via the am654 gigabit eth switch subsystem driver.
- * All the other ones are populated via EEPROM, hence continue with
- * an index of 1.
- */
- board_ti_am6_set_ethaddr(1, ep->mac_addr_cnt);
+ /*
+ * The first MAC address for ethernet a.k.a. ethernet0 comes from
+ * efuse populated via the am654 gigabit eth switch subsystem driver.
+ * All the other ones are populated via EEPROM, hence continue with
+ * an index of 1.
+ */
+ board_ti_am6_set_ethaddr(1, ep->mac_addr_cnt);
- /* Check for and probe any plugged-in daughtercards */
- probe_daughtercards();
+ /* Check for and probe any plugged-in daughtercards */
+ probe_daughtercards();
+ }
return 0;
}
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 94d18ca..46eebd5 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -353,6 +353,19 @@
/* On ARM switch from EL3 or secure mode to EL2 or non-secure mode */
switch_to_non_secure_mode();
+ /*
+ * The UEFI standard requires that the watchdog timer is set to five
+ * minutes when invoking an EFI boot option.
+ *
+ * Unified Extensible Firmware Interface (UEFI), version 2.7 Errata A
+ * 7.5. Miscellaneous Boot Services - EFI_BOOT_SERVICES.SetWatchdogTimer
+ */
+ ret = efi_set_watchdog(300);
+ if (ret != EFI_SUCCESS) {
+ log_err("ERROR: Failed to set watchdog timer\n");
+ goto out;
+ }
+
/* Call our payload! */
ret = EFI_CALL(efi_start_image(handle, &exit_data_size, &exit_data));
if (ret != EFI_SUCCESS) {
@@ -366,11 +379,15 @@
efi_restore_gd();
+out:
free(load_options);
if (IS_ENABLED(CONFIG_EFI_LOAD_FILE2_INITRD))
efi_initrd_deregister();
+ /* Control is returned to U-Boot, disable EFI watchdog */
+ efi_set_watchdog(0);
+
return ret;
}
diff --git a/cmd/clk.c b/cmd/clk.c
index dbbdc31..a483fd8 100644
--- a/cmd/clk.c
+++ b/cmd/clk.c
@@ -99,20 +99,6 @@
}
#if CONFIG_IS_ENABLED(DM) && CONFIG_IS_ENABLED(CLK)
-struct udevice *clk_lookup(const char *name)
-{
- int i = 0;
- struct udevice *dev;
-
- do {
- uclass_get_device(UCLASS_CLK, i++, &dev);
- if (!strcmp(name, dev->name))
- return dev;
- } while (dev);
-
- return NULL;
-}
-
static int do_clk_setfreq(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
@@ -120,16 +106,17 @@
s32 freq;
struct udevice *dev;
+ if (argc != 3)
+ return CMD_RET_USAGE;
+
freq = dectoul(argv[2], NULL);
- dev = clk_lookup(argv[1]);
-
- if (dev)
+ if (!uclass_get_device_by_name(UCLASS_CLK, argv[1], &dev))
clk = dev_get_clk_ptr(dev);
if (!clk) {
printf("clock '%s' not found.\n", argv[1]);
- return -EINVAL;
+ return CMD_RET_FAILURE;
}
freq = clk_set_rate(clk, freq);
@@ -173,7 +160,7 @@
#ifdef CONFIG_SYS_LONGHELP
static char clk_help_text[] =
"dump - Print clock frequencies\n"
- "setfreq [clk] [freq] - Set clock frequency";
+ "clk setfreq [clk] [freq] - Set clock frequency";
#endif
U_BOOT_CMD(clk, 4, 1, do_clk, "CLK sub-system", clk_help_text);
diff --git a/cmd/pwm.c b/cmd/pwm.c
index 7947e61..7e82955 100644
--- a/cmd/pwm.c
+++ b/cmd/pwm.c
@@ -111,5 +111,5 @@
"invert <pwm_dev_num> <channel> <polarity> - invert polarity\n"
"pwm config <pwm_dev_num> <channel> <period_ns> <duty_ns> - config PWM\n"
"pwm enable <pwm_dev_num> <channel> - enable PWM output\n"
- "pwm disable <pwm_dev_num> <channel> - eisable PWM output\n"
+ "pwm disable <pwm_dev_num> <channel> - disable PWM output\n"
"Note: All input values are in decimal");
diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig
index 9254e24..360ec3f 100644
--- a/configs/apple_m1_defconfig
+++ b/configs/apple_m1_defconfig
@@ -3,10 +3,11 @@
CONFIG_DEFAULT_DEVICE_TREE="t8103-j274"
CONFIG_DEBUG_UART_BASE=0x235200000
CONFIG_DEBUG_UART_CLOCK=24000000
-CONFIG_SYS_LOAD_ADDR=0x880000000
+CONFIG_SYS_LOAD_ADDR=0x0
CONFIG_USE_PREBOOT=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_BOARD_LATE_INIT=y
# CONFIG_NET is not set
CONFIG_APPLE_SPI_KEYB=y
# CONFIG_MMC is not set
diff --git a/configs/gazerbeam_defconfig b/configs/gazerbeam_defconfig
index 5d8d199..199afb4 100644
--- a/configs/gazerbeam_defconfig
+++ b/configs/gazerbeam_defconfig
@@ -157,7 +157,7 @@
CONFIG_AXI=y
CONFIG_IHS_AXI=y
CONFIG_CLK=y
-CONFIG_ICS8N3QV01=y
+CONFIG_CLK_ICS8N3QV01=y
CONFIG_CPU=y
CONFIG_CPU_MPC83XX=y
CONFIG_SYS_BR0_PRELIM_BOOL=y
diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig
index b843a84..60c96f8 100644
--- a/configs/j721e_evm_a72_defconfig
+++ b/configs/j721e_evm_a72_defconfig
@@ -193,3 +193,4 @@
CONFIG_CADENCE_UFS=y
CONFIG_TI_J721E_UFS=y
CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_MMC_SPEED_MODE_SET=y
diff --git a/configs/j721e_hs_evm_a72_defconfig b/configs/j721e_hs_evm_a72_defconfig
index ae184b0..6479f9b 100644
--- a/configs/j721e_hs_evm_a72_defconfig
+++ b/configs/j721e_hs_evm_a72_defconfig
@@ -162,3 +162,4 @@
CONFIG_CADENCE_UFS=y
CONFIG_TI_J721E_UFS=y
CONFIG_OF_LIBFDT_OVERLAY=y
+CONFIG_MMC_SPEED_MODE_SET=y
diff --git a/configs/kontron_sl28_defconfig b/configs/kontron_sl28_defconfig
index b61276c..cf8aedf 100644
--- a/configs/kontron_sl28_defconfig
+++ b/configs/kontron_sl28_defconfig
@@ -42,23 +42,23 @@
CONFIG_CMD_NVEDIT_EFI=y
CONFIG_CMD_DFU=y
CONFIG_CMD_DM=y
+CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_PCI=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_CMD_WDT=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_EFIDEBUG=y
CONFIG_CMD_RNG=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
-CONFIG_OF_LIST=""
+CONFIG_OF_LIST="fsl-ls1028a-kontron-sl28 fsl-ls1028a-kontron-sl28-var1 fsl-ls1028a-kontron-sl28-var2 fsl-ls1028a-kontron-sl28-var3 fsl-ls1028a-kontron-sl28-var4"
CONFIG_ENV_OVERWRITE=y
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
-CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_NETCONSOLE=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SATA=y
CONFIG_SCSI_AHCI=y
@@ -69,8 +69,10 @@
CONFIG_ECC_INIT_VIA_DDRCONTROLLER=y
CONFIG_DFU_MMC=y
CONFIG_DFU_SF=y
+CONFIG_SL28CPLD_GPIO=y
CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
CONFIG_I2C_MUX=y
+CONFIG_SL28CPLD=y
CONFIG_MMC_HS400_SUPPORT=y
CONFIG_FSL_ESDHC=y
CONFIG_FSL_ESDHC_SUPPORT_ADMA2=y
@@ -102,6 +104,11 @@
CONFIG_USB_DWC3_LAYERSCAPE=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DOWNLOAD=y
+# CONFIG_WATCHDOG is not set
+# CONFIG_WATCHDOG_AUTOSTART is not set
+CONFIG_WDT=y
+CONFIG_WDT_SL28CPLD=y
+CONFIG_WDT_SP805=y
CONFIG_OF_LIBFDT_ASSUME_MASK=0x0
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_EFI_SET_TIME=y
diff --git a/configs/licheepi_nano_defconfig b/configs/licheepi_nano_defconfig
index 2ac0ef4..67b7b85 100644
--- a/configs/licheepi_nano_defconfig
+++ b/configs/licheepi_nano_defconfig
@@ -9,3 +9,5 @@
CONFIG_DRAM_CLK=156
CONFIG_DRAM_ZQ=0
# CONFIG_VIDEO_SUNXI is not set
+CONFIG_SPL_SPI_SUNXI=y
+# CONFIG_SYSRESET is not set
diff --git a/configs/rzg2_beacon_defconfig b/configs/rzg2_beacon_defconfig
index e6a0d68..91b3fa2 100644
--- a/configs/rzg2_beacon_defconfig
+++ b/configs/rzg2_beacon_defconfig
@@ -62,7 +62,7 @@
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_BITBANGMII=y
-CONFIG_PHY_REALTEK=y
+CONFIG_PHY_ATHEROS=y
CONFIG_DM_ETH=y
CONFIG_RENESAS_RAVB=y
CONFIG_DM_REGULATOR=y
diff --git a/configs/stemmy_defconfig b/configs/stemmy_defconfig
index ea43cb6..c02db99 100644
--- a/configs/stemmy_defconfig
+++ b/configs/stemmy_defconfig
@@ -36,3 +36,5 @@
CONFIG_SYS_WHITE_ON_BLACK=y
CONFIG_VIDEO_MCDE_SIMPLE=y
# CONFIG_EFI_LOADER is not set
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_OF_LIBFDT=y
diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig
index 280dd55..5b1fdbf 100644
--- a/configs/turris_omnia_defconfig
+++ b/configs/turris_omnia_defconfig
@@ -93,3 +93,4 @@
CONFIG_USB_EHCI_HCD=y
CONFIG_WDT=y
CONFIG_WDT_ORION=y
+CONFIG_EXT4_WRITE=y
diff --git a/doc/api/clk.rst b/doc/api/clk.rst
new file mode 100644
index 0000000..7c27066
--- /dev/null
+++ b/doc/api/clk.rst
@@ -0,0 +1,19 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Clock API
+=========
+
+.. kernel-doc:: include/clk.h
+ :doc: Overview
+
+Client API
+----------
+
+.. kernel-doc:: include/clk.h
+ :internal:
+
+Driver API
+----------
+
+.. kernel-doc:: include/clk-uclass.h
+ :internal:
diff --git a/doc/api/index.rst b/doc/api/index.rst
index 3f36174..72fea98 100644
--- a/doc/api/index.rst
+++ b/doc/api/index.rst
@@ -6,6 +6,7 @@
.. toctree::
:maxdepth: 2
+ clk
dfu
dm
efi
diff --git a/doc/arch/x86.rst b/doc/arch/x86.rst
index 5494155..634387a 100644
--- a/doc/arch/x86.rst
+++ b/doc/arch/x86.rst
@@ -732,7 +732,7 @@
To generate SMBIOS tables in U-Boot, for use by the OS, enable the
CONFIG_GENERATE_SMBIOS_TABLE option. The easiest way to provide the values to
use is via the device tree. For details see
-device-tree-bindings/sysinfo/smbios.txt
+:download:`smbios.txt <../device-tree-bindings/sysinfo/smbios.txt>`.
TODO List
---------
diff --git a/doc/board/kontron/sl28.rst b/doc/board/kontron/sl28.rst
index c7b18be..44435d9 100644
--- a/doc/board/kontron/sl28.rst
+++ b/doc/board/kontron/sl28.rst
@@ -23,34 +23,17 @@
Install the bootloader on the board
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Please note, this bootloader doesn't support the builtin watchdog (yet),
-therefore you have to disable it, see below. Otherwise you'll end up in
-the failsafe bootloader on every reset::
+To install the bootloader binary use the following command::
> tftp path/to/u-boot.rom
> sf probe 0
> sf update $fileaddr 0x210000 $filesize
-The board is fully failsafe, you can't break anything. But because you've
-disabled the builtin watchdog you might have to manually enter failsafe
-mode by asserting the ``FORCE_RECOV#`` line during board reset.
-
-Disable the builtin watchdog
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-- boot into the failsafe bootloader, either by asserting the
- ``FORCE_RECOV#`` line or if you still have the original bootloader
- installed you can use the command::
-
- > wdt dev cpld_watchdog@4a; wdt expire 1
-
-- in the failsafe bootloader use the "sl28 nvm" command to disable
- the automatic start of the builtin watchdog::
-
- > sl28 nvm 0008
-
-- power-cycle the board
-
+The board is fully failsafe, you can't break anything. If builtin watchdog
+is enabled, you'll automatically end up in the failsafe bootloader if
+something goes wrong. If the watchdog is disabled, you have to manually
+enter failsafe mode by asserting the ``FORCE_RECOV#`` line during board
+reset.
Update image
------------
@@ -67,20 +50,41 @@
folder. On the next EFI boot this will automatically update your
bootloader.
-Useful I2C tricks
------------------
+Builtin watchdog
+----------------
-The board has a board management controller which is not supported in
-u-boot (yet). But you can use the i2c command to access it.
+The builtin watchdog will supervise the bootloader startup. If anything
+goes wrong it will reset the board and boot into the failsafe bootloader.
-- reset into failsafe bootloader::
+Once the bootloader is started successfully, it will disable the watchdog
+timer.
- > i2c mw 4a 5.1 0; i2c mw 4a 6.1 6b; i2c mw 4a 4.1 42
+wdt command flags
+^^^^^^^^^^^^^^^^^
-- read board management controller version::
+The `wdt start` as well as the `wdt expire` command take a flags argument.
+The supported bitmask is as follows.
- > i2c md 4a 3.1 1
+| Bit | Description |
+| --- | ----------------------------- |
+| 0 | Enable failsafe mode |
+| 1 | Lock the control register |
+| 2 | Disable board reset |
+| 3 | Enable WDT_TIME_OUT# line |
+For example, you can use `wdt expire 1` to issue a reset and boot into the
+failsafe bootloader.
+
+Disable the builtin watchdog
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If for some reason, this isn't a desired behavior, the watchdog can also
+be configured to not be enabled on board reset. It's configuration is saved
+in the non-volatile board configuration bits. To change these you can use
+the `sl28 nvm` command.
+
+For more information on the non-volatile board configuration bits, see the
+following section.
Non-volatile Board Configuration Bits
-------------------------------------
diff --git a/doc/develop/index.rst b/doc/develop/index.rst
index 9714887..93ebfa4 100644
--- a/doc/develop/index.rst
+++ b/doc/develop/index.rst
@@ -22,6 +22,7 @@
makefiles
menus
printf
+ smbios
uefi/index
version
diff --git a/doc/develop/smbios.rst b/doc/develop/smbios.rst
new file mode 100644
index 0000000..a4efb0a
--- /dev/null
+++ b/doc/develop/smbios.rst
@@ -0,0 +1,22 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+SMBIOS tables
+=============
+
+The System Management BIOS (SMBIOS) table is used to deliver management
+information from the firmware to the operating system. The content is
+standardized in [1]_.
+
+In Linux you can use the dmidecode command to view the contents of the SMBIOS
+table.
+
+When booting via UEFI the SMBIOS table is transferred as an UEFI configuration
+table to the operating system.
+
+To generate SMBIOS tables in U-Boot, the CONFIG_GENERATE_SMBIOS_TABLE option
+must be enabled. The easiest way to provide the values to use is via the device
+tree. For details see
+:download:`smbios.txt <../device-tree-bindings/sysinfo/smbios.txt>`.
+
+.. [1] `System Management BIOS (SMBIOS) Reference, version 3.5
+ <https://www.dmtf.org/content/dmtf-releases-smbios-35>`_
diff --git a/doc/kwboot.1 b/doc/kwboot.1
index acdea89..f555ff2 100644
--- a/doc/kwboot.1
+++ b/doc/kwboot.1
@@ -1,4 +1,4 @@
-.TH KWBOOT 1 "2021-08-25"
+.TH KWBOOT 1 "2022-03-02"
.SH NAME
kwboot \- Boot Marvell Kirkwood (and others 32-bit) SoCs over a serial link.
@@ -11,7 +11,7 @@
.SH "DESCRIPTION"
The \fBkwboot\fP program boots boards based on Marvell's 32-bit
-platforms including Kirkwood, Dove, A370, AXP, A375, A38x
+platforms including Kirkwood, Dove, Avanta, A370, AXP, A375, A38x
and A39x over their integrated UART. Boot image files will typically
contain a second stage boot loader, such as U-Boot. The image file
must conform to Marvell's BootROM firmware image format
@@ -48,6 +48,48 @@
written to stdout after the header is sent.
.TP
+.B "\-b"
+Do only handshake on \fITTY\fP without uploading any file. File upload
+could be done later via option \fB\-D\fP or via any other Xmodem
+application, like \fBsx\fP(1).
+
+.TP
+.B "\-d"
+Do special handshake on \fITTY\fP for console debug mode.
+
+This will instruct BootROM to enter builtin simple console debug mode.
+Should be combined with option \fB\-t\fP.
+
+To get a BootROM help, type this command followed by ENTER key:
+
+.RS 1.2i
+.TP
+.B ?
+.RE
+.IP
+
+Armada 38x BootROM has a bug which cause that BootROM's standard output
+is turned off on UART when SPI-NOR contains valid boot image. Nevertheless
+BootROM's standard input and BootROM's terminal echo are active and working
+fine. To workaround this BootROM bug with standard output, it is possible
+to manually overwrite BootROM variables stored in SRAM which BootROM use
+for checking if standard output is enabled or not. To enable BootROM
+standard output on UART, type this command folled by ENTER key:
+
+.RS 1.2i
+.TP
+.B w 0x40034100 1
+.RE
+
+.TP
+.BI "\-D" " image"
+Upload file \fIimage\fP over \fITTY\fP without initial handshake.
+
+This method is used primary on Dove platforms, where BootROM does
+not support initial handshake for entering UART upload mode and
+strapping pins (exported via e.g. buttons) are used instead.
+
+.TP
.BI "\-p"
Obsolete. Does nothing.
@@ -56,12 +98,32 @@
default.
.TP
+.B "\-q"
+Obsolete. Does nothing.
+
+It is unknown whether it did something in the past.
+
+.TP
+.BI "\-s" " response-timeout"
+Specify custom response timeout when doing handshake. Default value is 50 ms.
+It is the timeout between sending two consecutive handshake patterns, meaning
+how long to wait for response from BootROM. Affects only option \fB\-b\fP with
+image file and option \fB\-d\fP.
+
+Option \fB-a\fP specify response timeout suitable for Armada XP BootROM and
+currently it is 1000 ms.
+
+Some testing showed that specifying 24 ms as response timeout make handshake
+with Armada 385 BootROM more stable.
+
+.TP
.BI "\-t"
Run a terminal program, connecting standard input and output to
.RB \fITTY\fP.
-If used in combination with \fB-b\fP, terminal mode is entered
-immediately following a successful image upload.
+If used in combination with \fB\-b\fP, \fB\-D\fP or \fB\-d\fP option,
+terminal mode is entered immediately following a successful image upload
+or successful handshake (if not doing image upload).
If standard I/O streams connect to a console, this mode will terminate
after receiving \fBctrl-\e\fP followed by \fBc\fP from console input.
@@ -85,9 +147,42 @@
230400, 460800, 500000, 576000, 921600, 1000000, 1152000, 1500000,
2000000, 2500000, 3125000, 4000000 and 5200000.
+.SH "EXAMPLES"
+
+Instruct BootROM to enter boot Xmodem boot mode, send \fIu-boot-spl.kwb\fP
+kwbimage file via Xmodem on \fI/dev/ttyUSB0\fP at 115200 Bd and run terminal
+program:
+.IP
+.B kwboot -b u-boot-spl.kwb -t /dev/ttyUSB0
+
+.PP
+Instruct BootROM to enter boot Xmodem boot mode, send header of
+\fIu-boot-spl.kwb\fP kwbimage file via Xmodem at 115200 Bd, then instruct
+BootROM to change baudrate to 5200000 Bd, send data part of the kwbimage
+file via Xmodem at high speed and finally run terminal program:
+.IP
+.B kwboot -b u-boot-spl.kwb -B 5200000 -t /dev/ttyUSB0
+
+.PP
+Only send \fIu-boot-spl.kwb\fP kwbimage file via Xmodem on \fI/dev/ttyUSB0\fP
+at 115200 Bd:
+.IP
+.B kwboot -D u-boot-spl.kwb /dev/ttyUSB0
+
+.PP
+Instruct BootROM to enter console debug mode and run terminal program on
+\fI/dev/ttyUSB0\fP at 115200 Bd:
+.IP
+.B kwboot -d -t /dev/ttyUSB0
+
+.PP
+Only run terminal program on \fI/dev/ttyUSB0\fP at 115200 Bd:
+.IP
+.B kwboot -t /dev/ttyUSB0
+
.SH "SEE ALSO"
.PP
-\fBmkimage\fP(1)
+\fBmkimage\fP(1), \fBsx\fP(1)
.SH "AUTHORS"
diff --git a/doc/mkimage.1 b/doc/mkimage.1
index fc84cca..2870062 100644
--- a/doc/mkimage.1
+++ b/doc/mkimage.1
@@ -1,10 +1,10 @@
-.TH MKIMAGE 1 "2010-05-16"
+.TH MKIMAGE 1 "2022-02-07"
.SH NAME
mkimage \- Generate image for U-Boot
.SH SYNOPSIS
.B mkimage
-.RB "\-l [" "uimage file name" "]"
+.RB [ \-T " \fItype\fP] " \-l " [\fIuimage file name\fP]"
.B mkimage
.RB [\fIoptions\fP] " \-f [" "image tree source file" "]" " [" "uimage file name" "]"
@@ -47,6 +47,12 @@
.BI "\-l [" "uimage file name" "]"
mkimage lists the information contained in the header of an existing U-Boot image.
+.TP
+.BI "\-T [" "image type" "]"
+Parse image file as type.
+Pass \-h as the image to see the list of supported image type.
+Without this option image type is autodetected.
+
.P
.B Create old legacy image:
diff --git a/doc/usage/fatload.rst b/doc/usage/fatload.rst
new file mode 100644
index 0000000..93acb27
--- /dev/null
+++ b/doc/usage/fatload.rst
@@ -0,0 +1,80 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+fatload command
+===============
+
+Synopsis
+--------
+
+::
+
+ fatload <interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]
+
+Description
+-----------
+
+The fatload command is used to read a file from a FAT filesystem into memory.
+You can always use the :doc:`load command <load>` instead.
+
+The number of transferred bytes is saved in the environment variable filesize.
+The load address is saved in the environment variable fileaddr.
+
+interface
+ interface for accessing the block device (mmc, sata, scsi, usb, ....)
+
+dev
+ device number
+
+part
+ partition number, defaults to 0 (whole device)
+
+addr
+ load address, defaults to environment variable loadaddr or if loadaddr is
+ not set to configuration variable CONFIG_SYS_LOAD_ADDR
+
+filename
+ path to file, defaults to environment variable bootfile
+
+bytes
+ maximum number of bytes to load
+
+pos
+ number of bytes to skip
+
+addr, bytes, pos are hexadecimal numbers.
+
+If either 'pos' or 'bytes' are not aligned according to the minimum alignment
+requirement for DMA transfer (ARCH_DMA_MINALIGN) additional buffering will be
+used, a misaligned buffer warning will be printed, and performance will suffer
+for the load.
+
+Example
+-------
+
+::
+
+ => fatload mmc 0:1 ${kernel_addr_r} snp.efi
+ 149280 bytes read in 11 ms (12.9 MiB/s)
+ =>
+ => fatload mmc 0:1 ${kernel_addr_r} snp.efi 1000000
+ 149280 bytes read in 9 ms (15.8 MiB/s)
+ =>
+ => fatload mmc 0:1 ${kernel_addr_r} snp.efi 1000000 100
+ 149024 bytes read in 10 ms (14.2 MiB/s)
+ =>
+ => fatload mmc 0:1 ${kernel_addr_r} snp.efi 10
+ 16 bytes read in 1 ms (15.6 KiB/s)
+ =>
+
+Configuration
+-------------
+
+The fatload command is only available if CONFIG_CMD_FAT=y.
+
+Return value
+------------
+
+The return value $? is set to 0 (true) if the file was successfully loaded
+even if the number of bytes is less then the specified length.
+
+If an error occurs, the return value $? is set to 1 (false).
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 964d761..0aacf53 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -34,6 +34,7 @@
exit
false
fatinfo
+ fatload
for
load
loady
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index baac8d2..6dc271f 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -30,22 +30,6 @@
setting up clocks within TPL, and allows the same drivers to be
used as U-Boot proper.
-config CLK_BCM6345
- bool "Clock controller driver for BCM6345"
- depends on CLK && ARCH_BMIPS
- default y
- help
- This clock driver adds support for enabling and disabling peripheral
- clocks on BCM6345 SoCs. HW has no rate changing capabilities.
-
-config CLK_BOSTON
- def_bool y if TARGET_BOSTON
- depends on CLK
- select REGMAP
- select SYSCON
- help
- Enable this to support the clocks
-
config SPL_CLK_CCF
bool "SPL Common Clock Framework [CCF] support "
depends on SPL
@@ -73,6 +57,37 @@
Enable this option if you want to (re-)use the Linux kernel's Common
Clock Framework [CCF] composite code in U-Boot's clock driver.
+config CLK_BCM6345
+ bool "Clock controller driver for BCM6345"
+ depends on CLK && ARCH_BMIPS
+ default y
+ help
+ This clock driver adds support for enabling and disabling peripheral
+ clocks on BCM6345 SoCs. HW has no rate changing capabilities.
+
+config CLK_BOSTON
+ def_bool y if TARGET_BOSTON
+ depends on CLK
+ select REGMAP
+ select SYSCON
+ help
+ Enable this to support the clocks
+
+config CLK_CDCE9XX
+ bool "Enable CDCD9XX clock driver"
+ depends on CLK
+ help
+ Enable the clock synthesizer driver for CDCE913/925/937/949
+ series of chips.
+
+config CLK_ICS8N3QV01
+ bool "Enable ICS8N3QV01 VCXO driver"
+ depends on CLK
+ help
+ Support for the ICS8N3QV01 Quad-Frequency VCXO (Voltage-Controlled
+ Crystal Oscillator). The output frequency can be programmed via an
+ I2C interface.
+
config CLK_INTEL
bool "Enable clock driver for Intel x86"
depends on CLK && X86
@@ -83,6 +98,25 @@
set up by U-Boot itself but only statically. Thus the driver does not
support changing clock rates, only querying them.
+config CLK_K210
+ bool "Clock support for Kendryte K210"
+ depends on CLK
+ help
+ This enables support clock driver for Kendryte K210 platforms.
+
+config CLK_K210_SET_RATE
+ bool "Enable setting the Kendryte K210 PLL rate"
+ depends on CLK_K210
+ help
+ Add functionality to calculate new rates for K210 PLLs. Enabling this
+ feature adds around 1K to U-Boot's final size.
+
+config CLK_MPC83XX
+ bool "Enable MPC83xx clock driver"
+ depends on CLK
+ help
+ Support for the clock driver of the MPC83xx series of SoCs.
+
config CLK_OCTEON
bool "Clock controller driver for Marvell MIPS Octeon"
depends on CLK && ARCH_OCTEON
@@ -90,6 +124,22 @@
help
Enable this to support the clocks on Octeon MIPS platforms.
+config SANDBOX_CLK_CCF
+ bool "Sandbox Common Clock Framework [CCF] support "
+ depends on SANDBOX
+ select CLK_CCF
+ help
+ Enable this option if you want to test the Linux kernel's Common
+ Clock Framework [CCF] code in U-Boot's Sandbox clock driver.
+
+config CLK_SCMI
+ bool "Enable SCMI clock driver"
+ depends on SCMI_FIRMWARE
+ help
+ Enable this option if you want to support clock devices exposed
+ by a SCMI agent based on SCMI clock protocol communication
+ with a SCMI server.
+
config CLK_STM32F
bool "Enable clock driver support for STM32F family"
depends on CLK && (STM32F7 || STM32F4)
@@ -98,6 +148,14 @@
This clock driver adds support for RCC clock management
for STM32F4 and STM32F7 SoCs.
+config CLK_STM32MP1
+ bool "Enable RCC clock driver for STM32MP1"
+ depends on ARCH_STM32MP && CLK
+ default y
+ help
+ Enable the STM32 clock (RCC) driver. Enable support for
+ manipulating STM32MP1's on-SoC clocks.
+
config CLK_HSDK
bool "Enable cgu clock driver for HSDK boards"
depends on CLK && TARGET_HSDK
@@ -105,6 +163,15 @@
Enable this to support the cgu clocks on Synopsys ARC HSDK and
Synopsys ARC HSDK-4xD boards
+config CLK_VERSACLOCK
+ tristate "Enable VersaClock 5/6 devices"
+ depends on CLK
+ depends on CLK_CCF
+ depends on OF_CONTROL
+ help
+ This driver supports the IDT VersaClock 5 and VersaClock 6
+ programmable clock generators.
+
config CLK_VERSAL
bool "Enable clock driver support for Versal"
depends on ARCH_VERSAL
@@ -120,14 +187,6 @@
This clock driver adds support for clock generators present on
Arm Versatile Express platforms.
-config CLK_ZYNQ
- bool "Enable clock driver support for Zynq"
- depends on CLK && ARCH_ZYNQ
- default y
- help
- This clock driver adds support for clock related settings for
- Zynq platform.
-
config CLK_XLNX_CLKWZRD
bool "Xilinx Clocking Wizard"
depends on CLK
@@ -139,6 +198,14 @@
set_duty_cycle API, this driver only supports set_rate to modify
the frequency.
+config CLK_ZYNQ
+ bool "Enable clock driver support for Zynq"
+ depends on CLK && ARCH_ZYNQ
+ default y
+ help
+ This clock driver adds support for clock related settings for
+ Zynq platform.
+
config CLK_ZYNQMP
bool "Enable clock driver support for ZynqMP"
depends on ARCH_ZYNQMP
@@ -147,42 +214,6 @@
This clock driver adds support for clock realted settings for
ZynqMP platform.
-config CLK_STM32MP1
- bool "Enable RCC clock driver for STM32MP1"
- depends on ARCH_STM32MP && CLK
- default y
- help
- Enable the STM32 clock (RCC) driver. Enable support for
- manipulating STM32MP1's on-SoC clocks.
-
-config CLK_CDCE9XX
- bool "Enable CDCD9XX clock driver"
- depends on CLK
- help
- Enable the clock synthesizer driver for CDCE913/925/937/949
- series of chips.
-
-config CLK_SCMI
- bool "Enable SCMI clock driver"
- depends on SCMI_FIRMWARE
- help
- Enable this option if you want to support clock devices exposed
- by a SCMI agent based on SCMI clock protocol communication
- with a SCMI server.
-
-config CLK_K210
- bool "Clock support for Kendryte K210"
- depends on CLK
- help
- This enables support clock driver for Kendryte K210 platforms.
-
-config CLK_K210_SET_RATE
- bool "Enable setting the Kendryte K210 PLL rate"
- depends on CLK_K210
- help
- Add functionality to calculate new rates for K210 PLLs. Enabling this
- feature adds around 1K to U-Boot's final size.
-
source "drivers/clk/analogbits/Kconfig"
source "drivers/clk/at91/Kconfig"
source "drivers/clk/exynos/Kconfig"
@@ -198,35 +229,4 @@
source "drivers/clk/ti/Kconfig"
source "drivers/clk/uniphier/Kconfig"
-config ICS8N3QV01
- bool "Enable ICS8N3QV01 VCXO driver"
- depends on CLK
- help
- Support for the ICS8N3QV01 Quad-Frequency VCXO (Voltage-Controlled
- Crystal Oscillator). The output frequency can be programmed via an
- I2C interface.
-
-config CLK_MPC83XX
- bool "Enable MPC83xx clock driver"
- depends on CLK
- help
- Support for the clock driver of the MPC83xx series of SoCs.
-
-config SANDBOX_CLK_CCF
- bool "Sandbox Common Clock Framework [CCF] support "
- depends on SANDBOX
- select CLK_CCF
- help
- Enable this option if you want to test the Linux kernel's Common
- Clock Framework [CCF] code in U-Boot's Sandbox clock driver.
-
-config CLK_VERSACLOCK
- tristate "Enable VersaClock 5/6 devices"
- depends on CLK
- depends on CLK_CCF
- depends on OF_CONTROL
- help
- This driver supports the IDT VersaClock 5 and VersaClock 6
- programmable clock generators.
-
endmenu
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 711ae5b..f922a7c 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -15,41 +15,41 @@
obj-y += imx/
obj-y += tegra/
obj-y += ti/
+obj-$(CONFIG_$(SPL_TPL_)CLK_INTEL) += intel/
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
-obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
obj-$(CONFIG_ARCH_MESON) += meson/
+obj-$(CONFIG_ARCH_MTMIPS) += mtmips/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_ARCH_SOCFPGA) += altera/
+obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_CLK_AT91) += at91/
-obj-$(CONFIG_CLK_MVEBU) += mvebu/
obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o
obj-$(CONFIG_CLK_BOSTON) += clk_boston.o
+obj-$(CONFIG_CLK_CDCE9XX) += clk-cdce9xx.o
obj-$(CONFIG_CLK_EXYNOS) += exynos/
-obj-$(CONFIG_$(SPL_TPL_)CLK_INTEL) += intel/
obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o
obj-$(CONFIG_CLK_K210) += clk_kendryte.o
obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o
obj-$(CONFIG_CLK_MPFS) += microchip/
+obj-$(CONFIG_CLK_MVEBU) += mvebu/
obj-$(CONFIG_CLK_OCTEON) += clk_octeon.o
obj-$(CONFIG_CLK_OWL) += owl/
obj-$(CONFIG_CLK_RENESAS) += renesas/
obj-$(CONFIG_CLK_SCMI) += clk_scmi.o
obj-$(CONFIG_CLK_SIFIVE) += sifive/
-obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_CLK_STM32F) += clk_stm32f.o
obj-$(CONFIG_CLK_STM32MP1) += clk_stm32mp1.o
obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
+obj-$(CONFIG_CLK_VERSACLOCK) += clk_versaclock.o
+obj-$(CONFIG_CLK_VERSAL) += clk_versal.o
obj-$(CONFIG_CLK_VEXPRESS_OSC) += clk_vexpress_osc.o
+obj-$(CONFIG_CLK_XLNX_CLKWZRD) += clk-xlnx-clock-wizard.o
obj-$(CONFIG_CLK_ZYNQ) += clk_zynq.o
obj-$(CONFIG_CLK_ZYNQMP) += clk_zynqmp.o
-obj-$(CONFIG_CLK_XLNX_CLKWZRD) += clk-xlnx-clock-wizard.o
-obj-$(CONFIG_ICS8N3QV01) += ics8n3qv01.o
+obj-$(CONFIG_CLK_ICS8N3QV01) += ics8n3qv01.o
obj-$(CONFIG_MACH_PIC32) += clk_pic32.o
+obj-$(CONFIG_SANDBOX_CLK_CCF) += clk_sandbox_ccf.o
obj-$(CONFIG_SANDBOX) += clk_sandbox.o
obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o
-obj-$(CONFIG_SANDBOX_CLK_CCF) += clk_sandbox_ccf.o
obj-$(CONFIG_STM32H7) += clk_stm32h7.o
-obj-$(CONFIG_CLK_VERSAL) += clk_versal.o
-obj-$(CONFIG_CLK_CDCE9XX) += clk-cdce9xx.o
-obj-$(CONFIG_CLK_VERSACLOCK) += clk_versaclock.o
diff --git a/drivers/clk/clk-cdce9xx.c b/drivers/clk/clk-cdce9xx.c
index 6634b7b..f23465d 100644
--- a/drivers/clk/clk-cdce9xx.c
+++ b/drivers/clk/clk-cdce9xx.c
@@ -86,19 +86,13 @@
return ret;
}
-static int cdce9xx_clk_of_xlate(struct clk *clk,
- struct ofnode_phandle_args *args)
+static int cdce9xx_clk_request(struct clk *clk)
{
struct cdce9xx_clk_data *data = dev_get_priv(clk->dev);
- if (args->args_count != 1)
+ if (clk->id > data->chip->num_outputs)
return -EINVAL;
- if (args->args[0] > data->chip->num_outputs)
- return -EINVAL;
-
- clk->id = args->args[0];
-
return 0;
}
@@ -241,7 +235,7 @@
};
static const struct clk_ops cdce9xx_clk_ops = {
- .of_xlate = cdce9xx_clk_of_xlate,
+ .request = cdce9xx_clk_request,
.get_rate = cdce9xx_clk_get_rate,
.set_rate = cdce9xx_clk_set_rate,
};
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index d245b67..c20c928 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -432,17 +432,6 @@
return clk_get_by_index_nodev(node, index, clk);
}
-int clk_get_optional_nodev(ofnode node, const char *name, struct clk *clk)
-{
- int ret;
-
- ret = clk_get_by_name_nodev(node, name, clk);
- if (ret == -ENODATA)
- return 0;
-
- return ret;
-}
-
int clk_release_all(struct clk *clk, int count)
{
int i, ret;
@@ -652,7 +641,7 @@
return 0;
}
if (clkp->dev->parent &&
- device_get_uclass_id(clkp->dev) == UCLASS_CLK) {
+ device_get_uclass_id(clkp->dev->parent) == UCLASS_CLK) {
ret = clk_enable(dev_get_clk_ptr(clkp->dev->parent));
if (ret) {
printf("Enable %s failed\n",
@@ -726,7 +715,7 @@
}
if (clkp && clkp->dev->parent &&
- device_get_uclass_id(clkp->dev) == UCLASS_CLK) {
+ device_get_uclass_id(clkp->dev->parent) == UCLASS_CLK) {
ret = clk_disable(dev_get_clk_ptr(clkp->dev->parent));
if (ret) {
printf("Disable %s failed\n",
@@ -823,16 +812,6 @@
return clk;
}
-struct clk *devm_clk_get_optional(struct udevice *dev, const char *id)
-{
- struct clk *clk = devm_clk_get(dev, id);
-
- if (PTR_ERR(clk) == -ENODATA)
- return NULL;
-
- return clk;
-}
-
void devm_clk_put(struct udevice *dev, struct clk *clk)
{
int rc;
diff --git a/drivers/clk/clk_versaclock.c b/drivers/clk/clk_versaclock.c
index 89c8d02..26c014c 100644
--- a/drivers/clk/clk_versaclock.c
+++ b/drivers/clk/clk_versaclock.c
@@ -618,24 +618,6 @@
return vc5_update_bits(vc->i2c, VC5_OUT_DIV_CONTROL(num), mask, src);
}
-/*
- * The device references to the Versaclock point to the head, so xlate needs to
- * redirect it to clk_out[idx]
- */
-static int vc5_clk_out_xlate(struct clk *hw, struct ofnode_phandle_args *args)
-{
- unsigned int idx = args->args[0];
-
- if (args->args_count != 1) {
- debug("Invalid args_count: %d\n", args->args_count);
- return -EINVAL;
- }
-
- hw->id = idx;
-
- return 0;
-}
-
static unsigned long vc5_clk_out_set_rate(struct clk *hw, unsigned long rate)
{
struct udevice *dev;
@@ -671,7 +653,6 @@
static const struct clk_ops vc5_clk_ops = {
.enable = vc5_clk_out_prepare,
.disable = vc5_clk_out_unprepare,
- .of_xlate = vc5_clk_out_xlate,
.set_rate = vc5_clk_out_set_rate,
.get_rate = vc5_clk_out_get_rate,
};
diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c
index 18915c3..e80500e 100644
--- a/drivers/clk/clk_zynq.c
+++ b/drivers/clk/clk_zynq.c
@@ -472,8 +472,9 @@
for (i = 0; i < 2; i++) {
sprintf(name, "gem%d_emio_clk", i);
- ret = clk_get_by_name(dev, name, &priv->gem_emio_clk[i]);
- if (ret < 0 && ret != -ENODATA) {
+ ret = clk_get_by_name_optional(dev, name,
+ &priv->gem_emio_clk[i]);
+ if (ret) {
dev_err(dev, "failed to get %s clock\n", name);
return ret;
}
diff --git a/drivers/clk/ics8n3qv01.c b/drivers/clk/ics8n3qv01.c
index 6bc1b8b..33fb6ed 100644
--- a/drivers/clk/ics8n3qv01.c
+++ b/drivers/clk/ics8n3qv01.c
@@ -180,11 +180,6 @@
return 0;
}
-static int ics8n3qv01_request(struct clk *clock)
-{
- return 0;
-}
-
static ulong ics8n3qv01_get_rate(struct clk *clk)
{
struct ics8n3qv01_priv *priv = dev_get_priv(clk->dev);
@@ -203,7 +198,6 @@
}
static const struct clk_ops ics8n3qv01_ops = {
- .request = ics8n3qv01_request,
.get_rate = ics8n3qv01_get_rate,
.set_rate = ics8n3qv01_set_rate,
.enable = ics8n3qv01_enable,
diff --git a/drivers/clk/tegra/tegra-car-clk.c b/drivers/clk/tegra/tegra-car-clk.c
index 09a7cf4..c5214b9 100644
--- a/drivers/clk/tegra/tegra-car-clk.c
+++ b/drivers/clk/tegra/tegra-car-clk.c
@@ -30,14 +30,6 @@
return 0;
}
-static int tegra_car_clk_free(struct clk *clk)
-{
- debug("%s(clk=%p) (dev=%p, id=%lu)\n", __func__, clk, clk->dev,
- clk->id);
-
- return 0;
-}
-
static ulong tegra_car_clk_get_rate(struct clk *clk)
{
enum clock_id parent;
@@ -82,7 +74,6 @@
static struct clk_ops tegra_car_clk_ops = {
.request = tegra_car_clk_request,
- .rfree = tegra_car_clk_free,
.get_rate = tegra_car_clk_get_rate,
.set_rate = tegra_car_clk_set_rate,
.enable = tegra_car_clk_enable,
diff --git a/drivers/clk/ti/clk-sci.c b/drivers/clk/ti/clk-sci.c
index acb9ead..74df5a3 100644
--- a/drivers/clk/ti/clk-sci.c
+++ b/drivers/clk/ti/clk-sci.c
@@ -64,18 +64,6 @@
return 0;
}
-static int ti_sci_clk_request(struct clk *clk)
-{
- debug("%s(clk=%p)\n", __func__, clk);
- return 0;
-}
-
-static int ti_sci_clk_free(struct clk *clk)
-{
- debug("%s(clk=%p)\n", __func__, clk);
- return 0;
-}
-
static ulong ti_sci_clk_get_rate(struct clk *clk)
{
struct ti_sci_clk_data *data = dev_get_priv(clk->dev);
@@ -208,8 +196,6 @@
static struct clk_ops ti_sci_clk_ops = {
.of_xlate = ti_sci_clk_of_xlate,
- .request = ti_sci_clk_request,
- .rfree = ti_sci_clk_free,
.get_rate = ti_sci_clk_get_rate,
.set_rate = ti_sci_clk_set_rate,
.set_parent = ti_sci_clk_set_parent,
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8d0e47c..522dfc1 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -544,4 +544,10 @@
are accessed using xilinx firmware. In modepin register, [3:0] bits
set direction, [7:4] bits read IO, [11:8] bits set/clear IO.
+config SL28CPLD_GPIO
+ bool "Kontron sl28cpld GPIO driver"
+ depends on DM_GPIO && SL28CPLD
+ help
+ Support GPIO access on Kontron sl28cpld board management controllers.
+
endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 63e9be6..33f7d41 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -70,4 +70,5 @@
obj-$(CONFIG_SIFIVE_GPIO) += sifive-gpio.o
obj-$(CONFIG_NOMADIK_GPIO) += nmk_gpio.o
obj-$(CONFIG_MAX7320_GPIO) += max7320_gpio.o
+obj-$(CONFIG_SL28CPLD_GPIO) += sl28cpld-gpio.o
obj-$(CONFIG_ZYNQMP_GPIO_MODEPIN) += zynqmp_gpio_modepin.o
diff --git a/drivers/gpio/sl28cpld-gpio.c b/drivers/gpio/sl28cpld-gpio.c
new file mode 100644
index 0000000..700fc3d
--- /dev/null
+++ b/drivers/gpio/sl28cpld-gpio.c
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * GPIO driver for the sl28cpld
+ *
+ * Copyright (c) 2021 Michael Walle <michael@walle.cc>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/gpio.h>
+#include <sl28cpld.h>
+
+/* GPIO flavor */
+#define SL28CPLD_GPIO_DIR 0x00
+#define SL28CPLD_GPIO_OUT 0x01
+#define SL28CPLD_GPIO_IN 0x02
+
+/* input-only flavor */
+#define SL28CPLD_GPI_IN 0x00
+
+/* output-only flavor */
+#define SL28CPLD_GPO_OUT 0x00
+
+enum {
+ SL28CPLD_GPIO,
+ SL28CPLD_GPI,
+ SL28CPLD_GPO,
+};
+
+static int sl28cpld_gpio_get_value(struct udevice *dev, unsigned int gpio)
+{
+ ulong type = dev_get_driver_data(dev);
+ int val, reg;
+
+ switch (type) {
+ case SL28CPLD_GPIO:
+ reg = SL28CPLD_GPIO_IN;
+ break;
+ case SL28CPLD_GPI:
+ reg = SL28CPLD_GPI_IN;
+ break;
+ case SL28CPLD_GPO:
+ /* we are output only, thus just return the output value */
+ reg = SL28CPLD_GPO_OUT;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ val = sl28cpld_read(dev, reg);
+
+ return val < 0 ? val : !!(val & BIT(gpio));
+}
+
+static int sl28cpld_gpio_set_value(struct udevice *dev, unsigned int gpio,
+ int value)
+{
+ ulong type = dev_get_driver_data(dev);
+ uint reg;
+
+ switch (type) {
+ case SL28CPLD_GPIO:
+ reg = SL28CPLD_GPIO_OUT;
+ break;
+ case SL28CPLD_GPO:
+ reg = SL28CPLD_GPO_OUT;
+ break;
+ case SL28CPLD_GPI:
+ default:
+ return -EINVAL;
+ }
+
+ if (value)
+ return sl28cpld_update(dev, reg, 0, BIT(gpio));
+ else
+ return sl28cpld_update(dev, reg, BIT(gpio), 0);
+}
+
+static int sl28cpld_gpio_direction_input(struct udevice *dev, unsigned int gpio)
+{
+ ulong type = dev_get_driver_data(dev);
+
+ switch (type) {
+ case SL28CPLD_GPI:
+ return 0;
+ case SL28CPLD_GPIO:
+ return sl28cpld_update(dev, SL28CPLD_GPIO_DIR, BIT(gpio), 0);
+ case SL28CPLD_GPO:
+ default:
+ return -EINVAL;
+ }
+}
+
+static int sl28cpld_gpio_direction_output(struct udevice *dev,
+ unsigned int gpio, int value)
+{
+ ulong type = dev_get_driver_data(dev);
+ int ret;
+
+ /* set_value() will report an error if we are input-only */
+ ret = sl28cpld_gpio_set_value(dev, gpio, value);
+ if (ret)
+ return ret;
+
+ if (type == SL28CPLD_GPIO)
+ return sl28cpld_update(dev, SL28CPLD_GPIO_DIR, 0, BIT(gpio));
+
+ return 0;
+}
+
+static int sl28cpld_gpio_get_function(struct udevice *dev, unsigned int gpio)
+{
+ ulong type = dev_get_driver_data(dev);
+ int val;
+
+ switch (type) {
+ case SL28CPLD_GPIO:
+ val = sl28cpld_read(dev, SL28CPLD_GPIO_DIR);
+ if (val < 0)
+ return val;
+ if (val & BIT(gpio))
+ return GPIOF_OUTPUT;
+ else
+ return GPIOF_INPUT;
+ case SL28CPLD_GPI:
+ return GPIOF_INPUT;
+ case SL28CPLD_GPO:
+ return GPIOF_OUTPUT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct dm_gpio_ops sl28cpld_gpio_ops = {
+ .direction_input = sl28cpld_gpio_direction_input,
+ .direction_output = sl28cpld_gpio_direction_output,
+ .get_value = sl28cpld_gpio_get_value,
+ .set_value = sl28cpld_gpio_set_value,
+ .get_function = sl28cpld_gpio_get_function,
+};
+
+static int sl28cpld_gpio_probe(struct udevice *dev)
+{
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
+
+ uc_priv->gpio_count = 8;
+ uc_priv->bank_name = dev_read_name(dev);
+
+ return 0;
+}
+
+static const struct udevice_id sl28cpld_gpio_ids[] = {
+ { .compatible = "kontron,sl28cpld-gpio", .data = SL28CPLD_GPIO},
+ { .compatible = "kontron,sl28cpld-gpo", .data = SL28CPLD_GPO},
+ { .compatible = "kontron,sl28cpld-gpi", .data = SL28CPLD_GPI},
+ { }
+};
+
+U_BOOT_DRIVER(sl28cpld_gpio) = {
+ .name = "sl28cpld_gpio",
+ .id = UCLASS_GPIO,
+ .of_match = sl28cpld_gpio_ids,
+ .probe = sl28cpld_gpio_probe,
+ .ops = &sl28cpld_gpio_ops,
+};
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 0ade3e3..7029bb7 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -512,4 +512,12 @@
config FSL_IFC
bool
+config SL28CPLD
+ bool "Enable Kontron sl28cpld multi-function driver"
+ depends on DM_I2C
+ help
+ Support for the Kontron sl28cpld management controller. This is
+ the base driver which provides common access methods for the
+ sub-drivers.
+
endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index bca7b24..f22eff6 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -82,3 +82,4 @@
obj-$(CONFIG_K3_AVS0) += k3_avs.o
obj-$(CONFIG_ESM_K3) += k3_esm.o
obj-$(CONFIG_ESM_PMIC) += esm_pmic.o
+obj-$(CONFIG_SL28CPLD) += sl28cpld.o
diff --git a/drivers/misc/sl28cpld.c b/drivers/misc/sl28cpld.c
new file mode 100644
index 0000000..01ef1c6
--- /dev/null
+++ b/drivers/misc/sl28cpld.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 Michael Walle <michael@walle.cc>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <i2c.h>
+
+struct sl28cpld_child_plat {
+ uint offset;
+};
+
+/*
+ * The access methods works either with the first argument being a child
+ * device or with the MFD device itself.
+ */
+static int sl28cpld_read_child(struct udevice *dev, uint offset)
+{
+ struct sl28cpld_child_plat *plat = dev_get_parent_plat(dev);
+ struct udevice *mfd = dev_get_parent(dev);
+
+ return dm_i2c_reg_read(mfd, offset + plat->offset);
+}
+
+int sl28cpld_read(struct udevice *dev, uint offset)
+{
+ if (dev->driver == DM_DRIVER_GET(sl28cpld))
+ return dm_i2c_reg_read(dev, offset);
+ else
+ return sl28cpld_read_child(dev, offset);
+}
+
+static int sl28cpld_write_child(struct udevice *dev, uint offset,
+ uint8_t value)
+{
+ struct sl28cpld_child_plat *plat = dev_get_parent_plat(dev);
+ struct udevice *mfd = dev_get_parent(dev);
+
+ return dm_i2c_reg_write(mfd, offset + plat->offset, value);
+}
+
+int sl28cpld_write(struct udevice *dev, uint offset, uint8_t value)
+{
+ if (dev->driver == DM_DRIVER_GET(sl28cpld))
+ return dm_i2c_reg_write(dev, offset, value);
+ else
+ return sl28cpld_write_child(dev, offset, value);
+}
+
+int sl28cpld_update(struct udevice *dev, uint offset, uint8_t clear,
+ uint8_t set)
+{
+ int val;
+
+ val = sl28cpld_read(dev, offset);
+ if (val < 0)
+ return val;
+
+ val &= ~clear;
+ val |= set;
+
+ return sl28cpld_write(dev, offset, val);
+}
+
+static int sl28cpld_probe(struct udevice *dev)
+{
+ i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS |
+ DM_I2C_CHIP_WR_ADDRESS);
+
+ return 0;
+}
+
+static int sl28cpld_child_post_bind(struct udevice *dev)
+{
+ struct sl28cpld_child_plat *plat = dev_get_parent_plat(dev);
+ int offset;
+
+ if (!dev_has_ofnode(dev))
+ return 0;
+
+ offset = dev_read_u32_default(dev, "reg", -1);
+ if (offset == -1)
+ return -EINVAL;
+
+ plat->offset = offset;
+
+ return 0;
+}
+
+static const struct udevice_id sl28cpld_ids[] = {
+ { .compatible = "kontron,sl28cpld" },
+ {}
+};
+
+U_BOOT_DRIVER(sl28cpld) = {
+ .name = "sl28cpld",
+ .id = UCLASS_NOP,
+ .of_match = sl28cpld_ids,
+ .probe = sl28cpld_probe,
+ .bind = dm_scan_fdt_dev,
+ .flags = DM_FLAG_PRE_RELOC,
+ .per_child_plat_auto = sizeof(struct sl28cpld_child_plat),
+ .child_post_bind = sl28cpld_child_post_bind,
+};
diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
index 1d1118c..4078d33 100644
--- a/drivers/net/ravb.c
+++ b/drivers/net/ravb.c
@@ -52,6 +52,7 @@
#define CSR_OPS 0x0000000F
#define CSR_OPS_CONFIG BIT(1)
+#define APSR_RDM BIT(13)
#define APSR_TDM BIT(14)
#define TCCR_TSRQ0 BIT(0)
@@ -376,6 +377,9 @@
struct ravb_priv *eth = dev_get_priv(dev);
struct eth_pdata *pdata = dev_get_plat(dev);
int ret = 0;
+ int mode = 0;
+ unsigned int delay;
+ bool explicit_delay = false;
/* Set CONFIG mode */
ret = ravb_reset(dev);
@@ -402,9 +406,33 @@
(rmobile_get_cpu_type() == RMOBILE_CPU_TYPE_R8A77995))
return 0;
- if ((pdata->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) ||
- (pdata->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID))
- writel(APSR_TDM, eth->iobase + RAVB_REG_APSR);
+ if (!dev_read_u32(dev, "rx-internal-delay-ps", &delay)) {
+ /* Valid values are 0 and 1800, according to DT bindings */
+ if (delay) {
+ mode |= APSR_RDM;
+ explicit_delay = true;
+ }
+ }
+
+ if (!dev_read_u32(dev, "tx-internal-delay-ps", &delay)) {
+ /* Valid values are 0 and 2000, according to DT bindings */
+ if (delay) {
+ mode |= APSR_TDM;
+ explicit_delay = true;
+ }
+ }
+
+ if (!explicit_delay) {
+ if (pdata->phy_interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ pdata->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID)
+ mode |= APSR_RDM;
+
+ if (pdata->phy_interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ pdata->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID)
+ mode |= APSR_TDM;
+ }
+
+ writel(mode, eth->iobase + RAVB_REG_APSR);
return 0;
}
diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c
index 5a0a59a..f076693 100644
--- a/drivers/pci/pci_mvebu.c
+++ b/drivers/pci/pci_mvebu.c
@@ -30,37 +30,25 @@
#include <linux/sizes.h>
/* PCIe unit register offsets */
-#define SELECT(x, n) ((x >> n) & 1UL)
-
-#define PCIE_DEV_ID_OFF 0x0000
-#define PCIE_CMD_OFF 0x0004
-#define PCIE_DEV_REV_OFF 0x0008
-#define PCIE_BAR_LO_OFF(n) (0x0010 + ((n) << 3))
-#define PCIE_BAR_HI_OFF(n) (0x0014 + ((n) << 3))
-#define PCIE_EXP_ROM_BAR_OFF 0x0030
-#define PCIE_CAPAB_OFF 0x0060
-#define PCIE_CTRL_STAT_OFF 0x0068
-#define PCIE_HEADER_LOG_4_OFF 0x0128
-#define PCIE_BAR_CTRL_OFF(n) (0x1804 + (((n) - 1) * 4))
-#define PCIE_WIN04_CTRL_OFF(n) (0x1820 + ((n) << 4))
-#define PCIE_WIN04_BASE_OFF(n) (0x1824 + ((n) << 4))
-#define PCIE_WIN04_REMAP_OFF(n) (0x182c + ((n) << 4))
-#define PCIE_WIN5_CTRL_OFF 0x1880
-#define PCIE_WIN5_BASE_OFF 0x1884
-#define PCIE_WIN5_REMAP_OFF 0x188c
-#define PCIE_CONF_ADDR_OFF 0x18f8
-#define PCIE_CONF_DATA_OFF 0x18fc
-#define PCIE_MASK_OFF 0x1910
-#define PCIE_MASK_ENABLE_INTS (0xf << 24)
-#define PCIE_CTRL_OFF 0x1a00
-#define PCIE_CTRL_X1_MODE BIT(0)
-#define PCIE_CTRL_RC_MODE BIT(1)
-#define PCIE_STAT_OFF 0x1a04
-#define PCIE_STAT_BUS (0xff << 8)
-#define PCIE_STAT_DEV (0x1f << 16)
-#define PCIE_STAT_LINK_DOWN BIT(0)
-#define PCIE_DEBUG_CTRL 0x1a60
-#define PCIE_DEBUG_SOFT_RESET BIT(20)
+#define MVPCIE_ROOT_PORT_PCI_CFG_OFF 0x0000
+#define MVPCIE_ROOT_PORT_PCI_EXP_OFF 0x0060
+#define MVPCIE_BAR_LO_OFF(n) (0x0010 + ((n) << 3))
+#define MVPCIE_BAR_HI_OFF(n) (0x0014 + ((n) << 3))
+#define MVPCIE_BAR_CTRL_OFF(n) (0x1804 + (((n) - 1) * 4))
+#define MVPCIE_WIN04_CTRL_OFF(n) (0x1820 + ((n) << 4))
+#define MVPCIE_WIN04_BASE_OFF(n) (0x1824 + ((n) << 4))
+#define MVPCIE_WIN04_REMAP_OFF(n) (0x182c + ((n) << 4))
+#define MVPCIE_WIN5_CTRL_OFF 0x1880
+#define MVPCIE_WIN5_BASE_OFF 0x1884
+#define MVPCIE_WIN5_REMAP_OFF 0x188c
+#define MVPCIE_CONF_ADDR_OFF 0x18f8
+#define MVPCIE_CONF_DATA_OFF 0x18fc
+#define MVPCIE_CTRL_OFF 0x1a00
+#define MVPCIE_CTRL_RC_MODE BIT(1)
+#define MVPCIE_STAT_OFF 0x1a04
+#define MVPCIE_STAT_BUS (0xff << 8)
+#define MVPCIE_STAT_DEV (0x1f << 16)
+#define MVPCIE_STAT_LINK_DOWN BIT(0)
#define LINK_WAIT_RETRIES 100
#define LINK_WAIT_TIMEOUT 1000
@@ -77,7 +65,6 @@
u32 lane;
bool is_x4;
int devfn;
- u32 lane_mask;
int sec_busno;
char name[16];
unsigned int mem_target;
@@ -90,8 +77,8 @@
static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
{
u32 val;
- val = readl(pcie->base + PCIE_STAT_OFF);
- return !(val & PCIE_STAT_LINK_DOWN);
+ val = readl(pcie->base + MVPCIE_STAT_OFF);
+ return !(val & MVPCIE_STAT_LINK_DOWN);
}
static void mvebu_pcie_wait_for_link(struct mvebu_pcie *pcie)
@@ -115,20 +102,20 @@
{
u32 stat;
- stat = readl(pcie->base + PCIE_STAT_OFF);
- stat &= ~PCIE_STAT_BUS;
+ stat = readl(pcie->base + MVPCIE_STAT_OFF);
+ stat &= ~MVPCIE_STAT_BUS;
stat |= busno << 8;
- writel(stat, pcie->base + PCIE_STAT_OFF);
+ writel(stat, pcie->base + MVPCIE_STAT_OFF);
}
static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie *pcie, int devno)
{
u32 stat;
- stat = readl(pcie->base + PCIE_STAT_OFF);
- stat &= ~PCIE_STAT_DEV;
+ stat = readl(pcie->base + MVPCIE_STAT_OFF);
+ stat &= ~MVPCIE_STAT_DEV;
stat |= devno << 16;
- writel(stat, pcie->base + PCIE_STAT_OFF);
+ writel(stat, pcie->base + MVPCIE_STAT_OFF);
}
static inline struct mvebu_pcie *hose_to_pcie(struct pci_controller *hose)
@@ -198,18 +185,18 @@
addr = PCI_CONF1_EXT_ADDRESS(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
/* write address */
- writel(addr, pcie->base + PCIE_CONF_ADDR_OFF);
+ writel(addr, pcie->base + MVPCIE_CONF_ADDR_OFF);
/* read data */
switch (size) {
case PCI_SIZE_8:
- data = readb(pcie->base + PCIE_CONF_DATA_OFF + (offset & 3));
+ data = readb(pcie->base + MVPCIE_CONF_DATA_OFF + (offset & 3));
break;
case PCI_SIZE_16:
- data = readw(pcie->base + PCIE_CONF_DATA_OFF + (offset & 2));
+ data = readw(pcie->base + MVPCIE_CONF_DATA_OFF + (offset & 2));
break;
case PCI_SIZE_32:
- data = readl(pcie->base + PCIE_CONF_DATA_OFF);
+ data = readl(pcie->base + MVPCIE_CONF_DATA_OFF);
break;
default:
return -EINVAL;
@@ -289,18 +276,18 @@
addr = PCI_CONF1_EXT_ADDRESS(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
/* write address */
- writel(addr, pcie->base + PCIE_CONF_ADDR_OFF);
+ writel(addr, pcie->base + MVPCIE_CONF_ADDR_OFF);
/* write data */
switch (size) {
case PCI_SIZE_8:
- writeb(value, pcie->base + PCIE_CONF_DATA_OFF + (offset & 3));
+ writeb(value, pcie->base + MVPCIE_CONF_DATA_OFF + (offset & 3));
break;
case PCI_SIZE_16:
- writew(value, pcie->base + PCIE_CONF_DATA_OFF + (offset & 2));
+ writew(value, pcie->base + MVPCIE_CONF_DATA_OFF + (offset & 2));
break;
case PCI_SIZE_32:
- writel(value, pcie->base + PCIE_CONF_DATA_OFF);
+ writel(value, pcie->base + MVPCIE_CONF_DATA_OFF);
break;
default:
return -EINVAL;
@@ -324,20 +311,20 @@
/* First, disable and clear BARs and windows. */
for (i = 1; i < 3; i++) {
- writel(0, pcie->base + PCIE_BAR_CTRL_OFF(i));
- writel(0, pcie->base + PCIE_BAR_LO_OFF(i));
- writel(0, pcie->base + PCIE_BAR_HI_OFF(i));
+ writel(0, pcie->base + MVPCIE_BAR_CTRL_OFF(i));
+ writel(0, pcie->base + MVPCIE_BAR_LO_OFF(i));
+ writel(0, pcie->base + MVPCIE_BAR_HI_OFF(i));
}
for (i = 0; i < 5; i++) {
- writel(0, pcie->base + PCIE_WIN04_CTRL_OFF(i));
- writel(0, pcie->base + PCIE_WIN04_BASE_OFF(i));
- writel(0, pcie->base + PCIE_WIN04_REMAP_OFF(i));
+ writel(0, pcie->base + MVPCIE_WIN04_CTRL_OFF(i));
+ writel(0, pcie->base + MVPCIE_WIN04_BASE_OFF(i));
+ writel(0, pcie->base + MVPCIE_WIN04_REMAP_OFF(i));
}
- writel(0, pcie->base + PCIE_WIN5_CTRL_OFF);
- writel(0, pcie->base + PCIE_WIN5_BASE_OFF);
- writel(0, pcie->base + PCIE_WIN5_REMAP_OFF);
+ writel(0, pcie->base + MVPCIE_WIN5_CTRL_OFF);
+ writel(0, pcie->base + MVPCIE_WIN5_BASE_OFF);
+ writel(0, pcie->base + MVPCIE_WIN5_REMAP_OFF);
/* Setup windows for DDR banks. Count total DDR size on the fly. */
size = 0;
@@ -345,12 +332,12 @@
const struct mbus_dram_window *cs = dram->cs + i;
writel(cs->base & 0xffff0000,
- pcie->base + PCIE_WIN04_BASE_OFF(i));
- writel(0, pcie->base + PCIE_WIN04_REMAP_OFF(i));
+ pcie->base + MVPCIE_WIN04_BASE_OFF(i));
+ writel(0, pcie->base + MVPCIE_WIN04_REMAP_OFF(i));
writel(((cs->size - 1) & 0xffff0000) |
(cs->mbus_attr << 8) |
(dram->mbus_dram_target_id << 4) | 1,
- pcie->base + PCIE_WIN04_CTRL_OFF(i));
+ pcie->base + MVPCIE_WIN04_CTRL_OFF(i));
size += cs->size;
}
@@ -360,14 +347,14 @@
size = 1 << fls(size);
/* Setup BAR[1] to all DRAM banks. */
- writel(dram->cs[0].base | 0xc, pcie->base + PCIE_BAR_LO_OFF(1));
- writel(0, pcie->base + PCIE_BAR_HI_OFF(1));
+ writel(dram->cs[0].base | 0xc, pcie->base + MVPCIE_BAR_LO_OFF(1));
+ writel(0, pcie->base + MVPCIE_BAR_HI_OFF(1));
writel(((size - 1) & 0xffff0000) | 0x1,
- pcie->base + PCIE_BAR_CTRL_OFF(1));
+ pcie->base + MVPCIE_BAR_CTRL_OFF(1));
/* Setup BAR[0] to internal registers. */
- writel(pcie->intregs, pcie->base + PCIE_BAR_LO_OFF(0));
- writel(0, pcie->base + PCIE_BAR_HI_OFF(0));
+ writel(pcie->intregs, pcie->base + MVPCIE_BAR_LO_OFF(0));
+ writel(0, pcie->base + MVPCIE_BAR_HI_OFF(0));
}
/* Only enable PCIe link, do not setup it */
@@ -406,9 +393,9 @@
u32 reg;
/* Setup PCIe controller to Root Complex mode */
- reg = readl(pcie->base + PCIE_CTRL_OFF);
- reg |= PCIE_CTRL_RC_MODE;
- writel(reg, pcie->base + PCIE_CTRL_OFF);
+ reg = readl(pcie->base + MVPCIE_CTRL_OFF);
+ reg |= MVPCIE_CTRL_RC_MODE;
+ writel(reg, pcie->base + MVPCIE_CTRL_OFF);
/*
* Set Maximum Link Width to X1 or X4 in Root Port's PCIe Link
@@ -417,10 +404,10 @@
* be set to number of SerDes PCIe lanes (1 or 4). If this register is
* not set correctly then link with endpoint card is not established.
*/
- reg = readl(pcie->base + PCIE_CAPAB_OFF + PCI_EXP_LNKCAP);
+ reg = readl(pcie->base + MVPCIE_ROOT_PORT_PCI_EXP_OFF + PCI_EXP_LNKCAP);
reg &= ~PCI_EXP_LNKCAP_MLW;
reg |= (pcie->is_x4 ? 4 : 1) << 4;
- writel(reg, pcie->base + PCIE_CAPAB_OFF + PCI_EXP_LNKCAP);
+ writel(reg, pcie->base + MVPCIE_ROOT_PORT_PCI_EXP_OFF + PCI_EXP_LNKCAP);
}
static int mvebu_pcie_probe(struct udevice *dev)
@@ -443,7 +430,7 @@
* have the same format in Marvell's specification as in PCIe
* specification, but their meaning is totally different and they do
* different things: they are aliased into internal mvebu registers
- * (e.g. PCIE_BAR_LO_OFF) and these should not be changed or
+ * (e.g. MVPCIE_BAR_LO_OFF) and these should not be changed or
* reconfigured by pci device drivers.
*
* So our driver converts Type 0 config space to Type 1 and reports
@@ -451,10 +438,10 @@
* Type 1 registers is redirected to the virtual cfgcache[] buffer,
* which avoids changing unrelated registers.
*/
- reg = readl(pcie->base + PCIE_DEV_REV_OFF);
+ reg = readl(pcie->base + MVPCIE_ROOT_PORT_PCI_CFG_OFF + PCI_CLASS_REVISION);
reg &= ~0xffffff00;
reg |= (PCI_CLASS_BRIDGE_PCI << 8) << 8;
- writel(reg, pcie->base + PCIE_DEV_REV_OFF);
+ writel(reg, pcie->base + MVPCIE_ROOT_PORT_PCI_CFG_OFF + PCI_CLASS_REVISION);
/*
* mvebu uses local bus number and local device number to determinate
diff --git a/drivers/phy/nop-phy.c b/drivers/phy/nop-phy.c
index e2ee6e9..d0904f4 100644
--- a/drivers/phy/nop-phy.c
+++ b/drivers/phy/nop-phy.c
@@ -45,11 +45,13 @@
#if CONFIG_IS_ENABLED(DM_GPIO)
/* Take phy out of reset */
- ret = dm_gpio_set_value(&priv->reset_gpio, false);
- if (ret) {
- if (CONFIG_IS_ENABLED(CLK))
- clk_disable_bulk(&priv->bulk);
- return ret;
+ if (dm_gpio_is_valid(&priv->reset_gpio)) {
+ ret = dm_gpio_set_value(&priv->reset_gpio, false);
+ if (ret) {
+ if (CONFIG_IS_ENABLED(CLK))
+ clk_disable_bulk(&priv->bulk);
+ return ret;
+ }
}
#endif
return 0;
diff --git a/drivers/phy/phy-mtk-tphy.c b/drivers/phy/phy-mtk-tphy.c
index 824244b..2dd964f 100644
--- a/drivers/phy/phy-mtk-tphy.c
+++ b/drivers/phy/phy-mtk-tphy.c
@@ -723,13 +723,13 @@
tphy->phys[index] = instance;
index++;
- err = clk_get_optional_nodev(subnode, "ref",
- &instance->ref_clk);
+ err = clk_get_by_name_nodev_optional(subnode, "ref",
+ &instance->ref_clk);
if (err)
return err;
- err = clk_get_optional_nodev(subnode, "da_ref",
- &instance->da_ref_clk);
+ err = clk_get_by_name_nodev_optional(subnode, "da_ref",
+ &instance->da_ref_clk);
if (err)
return err;
}
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
index 1cf1f06..e76ef15 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -162,11 +162,11 @@
PIN_GRP_GPIO("emmc_nb", 27, 9, BIT(2), "emmc"),
PIN_GRP_GPIO_3("pwm0", 11, 1, BIT(3) | BIT(20), 0, BIT(20), BIT(3),
"pwm", "led"),
- PIN_GRP_GPIO_3("pwm1", 11, 1, BIT(4) | BIT(21), 0, BIT(21), BIT(4),
+ PIN_GRP_GPIO_3("pwm1", 12, 1, BIT(4) | BIT(21), 0, BIT(21), BIT(4),
"pwm", "led"),
- PIN_GRP_GPIO_3("pwm2", 11, 1, BIT(5) | BIT(22), 0, BIT(22), BIT(5),
+ PIN_GRP_GPIO_3("pwm2", 13, 1, BIT(5) | BIT(22), 0, BIT(22), BIT(5),
"pwm", "led"),
- PIN_GRP_GPIO_3("pwm3", 11, 1, BIT(6) | BIT(23), 0, BIT(23), BIT(6),
+ PIN_GRP_GPIO_3("pwm3", 14, 1, BIT(6) | BIT(23), 0, BIT(23), BIT(6),
"pwm", "led"),
PIN_GRP_GPIO("pmic1", 7, 1, BIT(7), "pmic"),
PIN_GRP_GPIO("pmic0", 6, 1, BIT(8), "pmic"),
diff --git a/drivers/rng/meson-rng.c b/drivers/rng/meson-rng.c
index 5a4f45a..e0a1e8c 100644
--- a/drivers/rng/meson-rng.c
+++ b/drivers/rng/meson-rng.c
@@ -91,8 +91,8 @@
return -ENODEV;
/* Get optional "core" clock */
- err = clk_get_by_name(dev, "core", &pdata->clk);
- if (err && err != -ENODATA)
+ err = clk_get_by_name_optional(dev, "core", &pdata->clk);
+ if (err)
return err;
return 0;
diff --git a/drivers/rtc/armada38x.c b/drivers/rtc/armada38x.c
index 2d264ac..2af64e3 100644
--- a/drivers/rtc/armada38x.c
+++ b/drivers/rtc/armada38x.c
@@ -121,7 +121,7 @@
armada38x_rtc_write(0, rtc, RTC_CONF_TEST);
mdelay(500);
armada38x_rtc_write(0, rtc, RTC_TIME);
- armada38x_rtc_write(BIT(0) | BIT(1), 0, RTC_STATUS);
+ armada38x_rtc_write(BIT(0) | BIT(1), rtc, RTC_STATUS);
}
return 0;
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 362cedd..f30f352 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -66,7 +66,8 @@
*/
if (node > 0 && !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
devp, NULL, false)) {
- if (!device_probe(*devp))
+ if (device_get_uclass_id(*devp) == UCLASS_SERIAL &&
+ !device_probe(*devp))
return 0;
}
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index cabac29..f90f0ca 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -266,6 +266,13 @@
In the single stage mode, when the timeout is reached, your system
will be reset by WS1. The first signal (WS0) is ignored.
+config WDT_SL28CPLD
+ bool "sl28cpld watchdog timer support"
+ depends on WDT && SL28CPLD
+ help
+ Enable support for the watchdog timer in the Kontron sl28cpld
+ management controller.
+
config WDT_SP805
bool "SP805 watchdog timer support"
depends on WDT
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 6d2b382..a35bd55 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -35,6 +35,7 @@
obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o
obj-$(CONFIG_WDT_SBSA) += sbsa_gwdt.o
obj-$(CONFIG_WDT_K3_RTI) += rti_wdt.o
+obj-$(CONFIG_WDT_SL28CPLD) += sl28cpld-wdt.o
obj-$(CONFIG_WDT_SP805) += sp805_wdt.o
obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o
obj-$(CONFIG_WDT_SUNXI) += sunxi_wdt.o
diff --git a/drivers/watchdog/armada-37xx-wdt.c b/drivers/watchdog/armada-37xx-wdt.c
index 2e119b9..bacebbc 100644
--- a/drivers/watchdog/armada-37xx-wdt.c
+++ b/drivers/watchdog/armada-37xx-wdt.c
@@ -58,13 +58,11 @@
clrbits_le32(priv->reg + CNTR_CTRL(id), CNTR_CTRL_ENABLE);
}
-static int init_counter(struct a37xx_wdt *priv, int id, u32 mode, u32 trig_src)
+static void init_counter(struct a37xx_wdt *priv, int id, u32 mode, u32 trig_src)
{
u32 reg;
reg = readl(priv->reg + CNTR_CTRL(id));
- if (reg & CNTR_CTRL_ACTIVE)
- return -EBUSY;
reg &= ~(CNTR_CTRL_MODE_MASK | CNTR_CTRL_PRESCALE_MASK |
CNTR_CTRL_TRIG_SRC_MASK);
@@ -79,8 +77,6 @@
reg |= trig_src;
writel(reg, priv->reg + CNTR_CTRL(id));
-
- return 0;
}
static int a37xx_wdt_reset(struct udevice *dev)
@@ -116,16 +112,9 @@
static int a37xx_wdt_start(struct udevice *dev, u64 ms, ulong flags)
{
struct a37xx_wdt *priv = dev_get_priv(dev);
- int err;
- err = init_counter(priv, 0, CNTR_CTRL_MODE_ONESHOT, 0);
- if (err < 0)
- return err;
-
- err = init_counter(priv, 1, CNTR_CTRL_MODE_HWSIG,
- CNTR_CTRL_TRIG_SRC_PREV_CNTR);
- if (err < 0)
- return err;
+ init_counter(priv, 0, CNTR_CTRL_MODE_ONESHOT, 0);
+ init_counter(priv, 1, CNTR_CTRL_MODE_HWSIG, CNTR_CTRL_TRIG_SRC_PREV_CNTR);
priv->timeout = ms * priv->clk_rate / 1000 / CNTR_CTRL_PRESCALE_MIN;
diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c
index 253286d..8d93f19 100644
--- a/drivers/watchdog/rti_wdt.c
+++ b/drivers/watchdog/rti_wdt.c
@@ -41,7 +41,7 @@
struct rti_wdt_priv {
phys_addr_t regs;
- unsigned int clk_khz;
+ unsigned int clk_hz;
};
#ifdef CONFIG_WDT_K3_RTI_LOAD_FW
@@ -139,7 +139,7 @@
if (ret < 0)
return ret;
- timer_margin = timeout_ms * priv->clk_khz / 1000;
+ timer_margin = timeout_ms * priv->clk_hz / 1000;
timer_margin >>= WDT_PRELOAD_SHIFT;
if (timer_margin > WDT_PRELOAD_MAX)
timer_margin = WDT_PRELOAD_MAX;
@@ -185,7 +185,15 @@
if (ret)
return ret;
- priv->clk_khz = clk_get_rate(&clk);
+ priv->clk_hz = clk_get_rate(&clk);
+
+ /*
+ * If watchdog is running at 32k clock, it is not accurate.
+ * Adjust frequency down in this case so that it does not expire
+ * earlier than expected.
+ */
+ if (priv->clk_hz < 32768)
+ priv->clk_hz = priv->clk_hz * 9 / 10;
return 0;
}
diff --git a/drivers/watchdog/sl28cpld-wdt.c b/drivers/watchdog/sl28cpld-wdt.c
new file mode 100644
index 0000000..af5a6b1
--- /dev/null
+++ b/drivers/watchdog/sl28cpld-wdt.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Watchdog driver for the sl28cpld
+ *
+ * Copyright (c) 2021 Michael Walle <michael@walle.cc>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <wdt.h>
+#include <sl28cpld.h>
+#include <div64.h>
+
+#define SL28CPLD_WDT_CTRL 0x00
+#define WDT_CTRL_EN0 BIT(0)
+#define WDT_CTRL_EN1 BIT(1)
+#define WDT_CTRL_EN_MASK GENMASK(1, 0)
+#define WDT_CTRL_LOCK BIT(2)
+#define WDT_CTRL_ASSERT_SYS_RESET BIT(6)
+#define WDT_CTRL_ASSERT_WDT_TIMEOUT BIT(7)
+#define SL28CPLD_WDT_TIMEOUT 0x01
+#define SL28CPLD_WDT_KICK 0x02
+#define WDT_KICK_VALUE 0x6b
+
+static int sl28cpld_wdt_reset(struct udevice *dev)
+{
+ return sl28cpld_write(dev, SL28CPLD_WDT_KICK, WDT_KICK_VALUE);
+}
+
+static int sl28cpld_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+ int ret, val;
+
+ val = sl28cpld_read(dev, SL28CPLD_WDT_CTRL);
+ if (val < 0)
+ return val;
+
+ /* (1) disable watchdog */
+ val &= ~WDT_CTRL_EN_MASK;
+ ret = sl28cpld_write(dev, SL28CPLD_WDT_CTRL, val);
+ if (ret)
+ return ret;
+
+ /* (2) set timeout */
+ ret = sl28cpld_write(dev, SL28CPLD_WDT_TIMEOUT, lldiv(timeout, 1000));
+ if (ret)
+ return ret;
+
+ /* (3) kick it, will reset timer to the timeout value */
+ ret = sl28cpld_wdt_reset(dev);
+ if (ret)
+ return ret;
+
+ /* (4) enable either recovery or normal one */
+ if (flags & BIT(0))
+ val |= WDT_CTRL_EN1;
+ else
+ val |= WDT_CTRL_EN0;
+
+ if (flags & BIT(1))
+ val |= WDT_CTRL_LOCK;
+
+ if (flags & BIT(2))
+ val &= ~WDT_CTRL_ASSERT_SYS_RESET;
+ else
+ val |= WDT_CTRL_ASSERT_SYS_RESET;
+
+ if (flags & BIT(3))
+ val |= WDT_CTRL_ASSERT_WDT_TIMEOUT;
+ else
+ val &= ~WDT_CTRL_ASSERT_WDT_TIMEOUT;
+
+ return sl28cpld_write(dev, SL28CPLD_WDT_CTRL, val);
+}
+
+static int sl28cpld_wdt_stop(struct udevice *dev)
+{
+ int val;
+
+ val = sl28cpld_read(dev, SL28CPLD_WDT_CTRL);
+ if (val < 0)
+ return val;
+
+ return sl28cpld_write(dev, SL28CPLD_WDT_CTRL, val & ~WDT_CTRL_EN_MASK);
+}
+
+static int sl28cpld_wdt_expire_now(struct udevice *dev, ulong flags)
+{
+ return sl28cpld_wdt_start(dev, 0, flags);
+}
+
+static const struct wdt_ops sl28cpld_wdt_ops = {
+ .start = sl28cpld_wdt_start,
+ .reset = sl28cpld_wdt_reset,
+ .stop = sl28cpld_wdt_stop,
+ .expire_now = sl28cpld_wdt_expire_now,
+};
+
+static const struct udevice_id sl28cpld_wdt_ids[] = {
+ { .compatible = "kontron,sl28cpld-wdt", },
+ {}
+};
+
+U_BOOT_DRIVER(sl28cpld_wdt) = {
+ .name = "sl28cpld-wdt",
+ .id = UCLASS_WDT,
+ .of_match = sl28cpld_wdt_ids,
+ .ops = &sl28cpld_wdt_ops,
+};
diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c
index 6d0f473..dbf5564 100644
--- a/drivers/watchdog/wdt-uclass.c
+++ b/drivers/watchdog/wdt-uclass.c
@@ -36,6 +36,8 @@
ulong next_reset;
/* Whether watchdog_start() has been called on the device. */
bool running;
+ /* No autostart */
+ bool noautostart;
};
static void init_watchdog_dev(struct udevice *dev)
@@ -52,7 +54,7 @@
dev->name);
}
- if (!IS_ENABLED(CONFIG_WATCHDOG_AUTOSTART)) {
+ if (!IS_ENABLED(CONFIG_WATCHDOG_AUTOSTART) || priv->noautostart) {
printf("WDT: Not starting %s\n", dev->name);
return;
}
@@ -256,16 +258,19 @@
* indicated by a hw_margin_ms property.
*/
ulong reset_period = 1000;
+ bool noautostart = false;
struct wdt_priv *priv;
if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
timeout = dev_read_u32_default(dev, "timeout-sec", timeout);
reset_period = dev_read_u32_default(dev, "hw_margin_ms",
4 * reset_period) / 4;
+ noautostart = dev_read_bool(dev, "u-boot,noautostart");
}
priv = dev_get_uclass_priv(dev);
priv->timeout = timeout;
priv->reset_period = reset_period;
+ priv->noautostart = noautostart;
/*
* Pretend this device was last reset "long" ago so the first
* watchdog_reset will actually call its ->reset method.
diff --git a/include/clk-uclass.h b/include/clk-uclass.h
index 50e8681..e44f1ca 100644
--- a/include/clk-uclass.h
+++ b/include/clk-uclass.h
@@ -16,96 +16,127 @@
/**
* struct clk_ops - The functions that a clock driver must implement.
+ * @of_xlate: Translate a client's device-tree (OF) clock specifier.
+ * @request: Request a translated clock.
+ * @rfree: Free a previously requested clock.
+ * @round_rate: Adjust a rate to the exact rate a clock can provide.
+ * @get_rate: Get current clock rate.
+ * @set_rate: Set current clock rate.
+ * @set_parent: Set current clock parent
+ * @enable: Enable a clock.
+ * @disable: Disable a clock.
+ *
+ * The individual methods are described more fully below.
*/
struct clk_ops {
- /**
- * of_xlate - Translate a client's device-tree (OF) clock specifier.
- *
- * The clock core calls this function as the first step in implementing
- * a client's clk_get_by_*() call.
- *
- * If this function pointer is set to NULL, the clock core will use a
- * default implementation, which assumes #clock-cells = <1>, and that
- * the DT cell contains a simple integer clock ID.
- *
- * At present, the clock API solely supports device-tree. If this
- * changes, other xxx_xlate() functions may be added to support those
- * other mechanisms.
- *
- * @clock: The clock struct to hold the translation result.
- * @args: The clock specifier values from device tree.
- * @return 0 if OK, or a negative error code.
- */
int (*of_xlate)(struct clk *clock,
struct ofnode_phandle_args *args);
- /**
- * request - Request a translated clock.
- *
- * The clock core calls this function as the second step in
- * implementing a client's clk_get_by_*() call, following a successful
- * xxx_xlate() call, or as the only step in implementing a client's
- * clk_request() call.
- *
- * @clock: The clock struct to request; this has been fille in by
- * a previoux xxx_xlate() function call, or by the caller
- * of clk_request().
- * @return 0 if OK, or a negative error code.
- */
int (*request)(struct clk *clock);
- /**
- * rfree - Free a previously requested clock.
- *
- * This is the implementation of the client clk_free() API.
- *
- * @clock: The clock to free.
- * @return 0 if OK, or a negative error code.
- */
int (*rfree)(struct clk *clock);
- /**
- * round_rate() - Adjust a rate to the exact rate a clock can provide.
- *
- * @clk: The clock to manipulate.
- * @rate: Desidered clock rate in Hz.
- * @return rounded rate in Hz, or -ve error code.
- */
ulong (*round_rate)(struct clk *clk, ulong rate);
- /**
- * get_rate() - Get current clock rate.
- *
- * @clk: The clock to query.
- * @return clock rate in Hz, or -ve error code
- */
ulong (*get_rate)(struct clk *clk);
- /**
- * set_rate() - Set current clock rate.
- *
- * @clk: The clock to manipulate.
- * @rate: New clock rate in Hz.
- * @return new rate, or -ve error code.
- */
ulong (*set_rate)(struct clk *clk, ulong rate);
- /**
- * set_parent() - Set current clock parent
- *
- * @clk: The clock to manipulate.
- * @parent: New clock parent.
- * @return zero on success, or -ve error code.
- */
int (*set_parent)(struct clk *clk, struct clk *parent);
- /**
- * enable() - Enable a clock.
- *
- * @clk: The clock to manipulate.
- * @return zero on success, or -ve error code.
- */
int (*enable)(struct clk *clk);
- /**
- * disable() - Disable a clock.
- *
- * @clk: The clock to manipulate.
- * @return zero on success, or -ve error code.
- */
int (*disable)(struct clk *clk);
};
+#if 0 /* For documentation only */
+/**
+ * of_xlate() - Translate a client's device-tree (OF) clock specifier.
+ * @clock: The clock struct to hold the translation result.
+ * @args: The clock specifier values from device tree.
+ *
+ * The clock core calls this function as the first step in implementing
+ * a client's clk_get_by_*() call.
+ *
+ * If this function pointer is set to NULL, the clock core will use a
+ * default implementation, which assumes #clock-cells = <1>, and that
+ * the DT cell contains a simple integer clock ID.
+ *
+ * At present, the clock API solely supports device-tree. If this
+ * changes, other xxx_xlate() functions may be added to support those
+ * other mechanisms.
+ *
+ * Return: 0 if OK, or a negative error code.
+ */
+int of_xlate(struct clk *clock, struct ofnode_phandle_args *args);
+
+/**
+ * request() - Request a translated clock.
+ * @clock: The clock struct to request; this has been fille in by
+ * a previoux xxx_xlate() function call, or by the caller
+ * of clk_request().
+ *
+ * The clock core calls this function as the second step in
+ * implementing a client's clk_get_by_*() call, following a successful
+ * xxx_xlate() call, or as the only step in implementing a client's
+ * clk_request() call.
+ *
+ * Return: 0 if OK, or a negative error code.
+ */
+int request(struct clk *clock);
+
+/**
+ * rfree() - Free a previously requested clock.
+ * @clock: The clock to free.
+ *
+ * This is the implementation of the client clk_free() API.
+ *
+ * Return: 0 if OK, or a negative error code.
+ */
+int rfree(struct clk *clock);
+
+/**
+ * round_rate() - Adjust a rate to the exact rate a clock can provide.
+ * @clk: The clock to manipulate.
+ * @rate: Desidered clock rate in Hz.
+ *
+ * Return: rounded rate in Hz, or -ve error code.
+ */
+ulong round_rate(struct clk *clk, ulong rate);
+
+/**
+ * get_rate() - Get current clock rate.
+ * @clk: The clock to query.
+ *
+ * Return: clock rate in Hz, or -ve error code
+ */
+ulong get_rate(struct clk *clk);
+
+/**
+ * set_rate() - Set current clock rate.
+ * @clk: The clock to manipulate.
+ * @rate: New clock rate in Hz.
+ *
+ * Return: new rate, or -ve error code.
+ */
+ulong set_rate(struct clk *clk, ulong rate);
+
+/**
+ * set_parent() - Set current clock parent
+ * @clk: The clock to manipulate.
+ * @parent: New clock parent.
+ *
+ * Return: zero on success, or -ve error code.
+ */
+int set_parent(struct clk *clk, struct clk *parent);
+
+/**
+ * enable() - Enable a clock.
+ * @clk: The clock to manipulate.
+ *
+ * Return: zero on success, or -ve error code.
+ */
+int enable(struct clk *clk);
+
+/**
+ * disable() - Disable a clock.
+ * @clk: The clock to manipulate.
+ *
+ * Return: zero on success, or -ve error code.
+ */
+int disable(struct clk *clk);
+#endif
+
#endif
diff --git a/include/clk.h b/include/clk.h
index 040d2d6..23e4d4e 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -14,6 +14,8 @@
#include <linux/types.h>
/**
+ * DOC: Overview
+ *
* A clock is a hardware signal that oscillates autonomously at a specific
* frequency and duty cycle. Most hardware modules require one or more clock
* signal to drive their operation. Clock signals are typically generated
@@ -34,22 +36,22 @@
/**
* struct clk - A handle to (allowing control of) a single clock.
+ * @dev: The device which implements the clock signal.
+ * @rate: The clock rate (in HZ).
+ * @flags: Flags used across common clock structure (e.g. %CLK_)
+ * Clock IP blocks specific flags (i.e. mux, div, gate, etc) are defined
+ * in struct's for those devices (e.g. &struct clk_mux).
+ * @enable_count: The number of times this clock has been enabled.
+ * @id: The clock signal ID within the provider.
+ * @data: An optional data field for scenarios where a single integer ID is not
+ * sufficient. If used, it can be populated through an .of_xlate op and
+ * processed during the various clock ops.
*
* Clients provide storage for clock handles. The content of the structure is
* managed solely by the clock API and clock drivers. A clock struct is
* initialized by "get"ing the clock struct. The clock struct is passed to all
* other clock APIs to identify which clock signal to operate upon.
*
- * @dev: The device which implements the clock signal.
- * @rate: The clock rate (in HZ).
- * @flags: Flags used across common clock structure (e.g. CLK_)
- * Clock IP blocks specific flags (i.e. mux, div, gate, etc) are defined
- * in struct's for those devices (e.g. struct clk_mux).
- * @id: The clock signal ID within the provider.
- * @data: An optional data field for scenarios where a single integer ID is not
- * sufficient. If used, it can be populated through an .of_xlate op and
- * processed during the various clock ops.
- *
* Should additional information to identify and configure any clock signal
* for any provider be required in the future, the struct could be expanded to
* either (a) add more fields to allow clock providers to store additional
@@ -72,15 +74,14 @@
/**
* struct clk_bulk - A handle to (allowing control of) a bulk of clocks.
+ * @clks: An array of clock handles.
+ * @count: The number of clock handles in the clks array.
*
* Clients provide storage for the clock bulk. The content of the structure is
* managed solely by the clock API. A clock bulk struct is
* initialized by "get"ing the clock bulk struct.
* The clock bulk struct is passed to all other bulk clock APIs to apply
* the API to all the clock in the bulk struct.
- *
- * @clks: An array of clock handles.
- * @count: The number of clock handles in the clks array.
*/
struct clk_bulk {
struct clk *clks;
@@ -91,16 +92,19 @@
struct phandle_1_arg;
/**
* clk_get_by_phandle() - Get a clock by its phandle information (of-platadata)
+ * @dev: Device containing the phandle
+ * @cells: Phandle info
+ * @clk: A pointer to a clock struct to initialise
*
* This function is used when of-platdata is enabled.
*
* This looks up a clock using the phandle info. With dtoc, each phandle in the
- * 'clocks' property is transformed into an idx representing the device. For
- * example:
+ * 'clocks' property is transformed into an idx representing the device.
+ * For example::
*
* clocks = <&dpll_mpu_ck 23>;
*
- * might result in:
+ * might result in::
*
* .clocks = {1, {23}},},
*
@@ -109,9 +113,6 @@
* this example it would return a clock containing the 'dpll_mpu_ck' device and
* the clock ID 23.
*
- * @dev: Device containing the phandle
- * @cells: Phandle info
- * @clock: A pointer to a clock struct to initialise
* Return: 0 if OK, or a negative error code.
*/
int clk_get_by_phandle(struct udevice *dev, const struct phandle_1_arg *cells,
@@ -119,6 +120,10 @@
/**
* clk_get_by_index() - Get/request a clock by integer index.
+ * @dev: The client device.
+ * @index: The index of the clock to request, within the client's list of
+ * clocks.
+ * @clk: A pointer to a clock struct to initialize.
*
* This looks up and requests a clock. The index is relative to the client
* device; each device is assumed to have n clocks associated with it somehow,
@@ -126,30 +131,26 @@
* device clock indices to provider clocks may be via device-tree properties,
* board-provided mapping tables, or some other mechanism.
*
- * @dev: The client device.
- * @index: The index of the clock to request, within the client's list of
- * clocks.
- * @clock A pointer to a clock struct to initialize.
* Return: 0 if OK, or a negative error code.
*/
int clk_get_by_index(struct udevice *dev, int index, struct clk *clk);
/**
- * clk_get_by_index_nodev - Get/request a clock by integer index
- * without a device.
- *
- * This is a version of clk_get_by_index() that does not use a device.
- *
+ * clk_get_by_index_nodev() - Get/request a clock by integer index without a
+ * device.
* @node: The client ofnode.
* @index: The index of the clock to request, within the client's list of
* clocks.
- * @clock A pointer to a clock struct to initialize.
+ * @clk: A pointer to a clock struct to initialize.
+ *
* Return: 0 if OK, or a negative error code.
*/
int clk_get_by_index_nodev(ofnode node, int index, struct clk *clk);
/**
- * clk_get_bulk - Get/request all clocks of a device.
+ * clk_get_bulk() - Get/request all clocks of a device.
+ * @dev: The client device.
+ * @bulk: A pointer to a clock bulk struct to initialize.
*
* This looks up and requests all clocks of the client device; each device is
* assumed to have n clocks associated with it somehow, and this function finds
@@ -157,14 +158,16 @@
* device clock indices to provider clocks may be via device-tree properties,
* board-provided mapping tables, or some other mechanism.
*
- * @dev: The client device.
- * @bulk A pointer to a clock bulk struct to initialize.
* Return: 0 if OK, or a negative error code.
*/
int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk);
/**
- * clk_get_by_name - Get/request a clock by name.
+ * clk_get_by_name() - Get/request a clock by name.
+ * @dev: The client device.
+ * @name: The name of the clock to request, within the client's list of
+ * clocks.
+ * @clk: A pointer to a clock struct to initialize.
*
* This looks up and requests a clock. The name is relative to the client
* device; each device is assumed to have n clocks associated with it somehow,
@@ -172,83 +175,71 @@
* device clock names to provider clocks may be via device-tree properties,
* board-provided mapping tables, or some other mechanism.
*
- * @dev: The client device.
- * @name: The name of the clock to request, within the client's list of
- * clocks.
- * @clock: A pointer to a clock struct to initialize.
* Return: 0 if OK, or a negative error code.
*/
int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk);
/**
* clk_get_by_name_nodev - Get/request a clock by name without a device.
- *
- * This is a version of clk_get_by_name() that does not use a device.
- *
* @node: The client ofnode.
* @name: The name of the clock to request, within the client's list of
* clocks.
- * @clock: A pointer to a clock struct to initialize.
+ * @clk: A pointer to a clock struct to initialize.
+ *
* Return: 0 if OK, or a negative error code.
*/
int clk_get_by_name_nodev(ofnode node, const char *name, struct clk *clk);
/**
- * clk_get_optional_nodev - Get/request an optinonal clock by name
- * without a device.
- * @node: The client ofnode.
- * @name: The name of the clock to request.
- * @name: The name of the clock to request, within the client's list of
- * clocks.
- * @clock: A pointer to a clock struct to initialize.
- *
- * Behaves the same as clk_get_by_name_nodev() except where there is
- * no clock producer, in this case, skip the error number -ENODATA, and
- * the function returns 0.
- */
-int clk_get_optional_nodev(ofnode node, const char *name, struct clk *clk);
-
-/**
- * devm_clk_get - lookup and obtain a managed reference to a clock producer.
+ * devm_clk_get() - lookup and obtain a managed reference to a clock producer.
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
- * Returns a struct clk corresponding to the clock producer, or
- * valid IS_ERR() condition containing errno. The implementation
- * uses @dev and @id to determine the clock consumer, and thereby
- * the clock producer. (IOW, @id may be identical strings, but
- * clk_get may return different clock producers depending on @dev.)
+ * The implementation uses @dev and @id to determine the clock consumer, and
+ * thereby the clock producer. (IOW, @id may be identical strings, but clk_get
+ * may return different clock producers depending on @dev.)
*
* Drivers must assume that the clock source is not enabled.
*
- * devm_clk_get should not be called from within interrupt context.
- *
* The clock will automatically be freed when the device is unbound
* from the bus.
+ *
+ * Return:
+ * a struct clk corresponding to the clock producer, or
+ * valid IS_ERR() condition containing errno
*/
struct clk *devm_clk_get(struct udevice *dev, const char *id);
/**
- * devm_clk_get_optional - lookup and obtain a managed reference to an optional
- * clock producer.
+ * devm_clk_get_optional() - lookup and obtain a managed reference to an
+ * optional clock producer.
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Behaves the same as devm_clk_get() except where there is no clock producer.
- * In this case, instead of returning -ENOENT, the function returns NULL.
+ * In this case, instead of returning -%ENOENT, the function returns NULL.
*/
-struct clk *devm_clk_get_optional(struct udevice *dev, const char *id);
+static inline struct clk *devm_clk_get_optional(struct udevice *dev,
+ const char *id)
+{
+ struct clk *clk = devm_clk_get(dev, id);
+
+ if (PTR_ERR(clk) == -ENODATA)
+ return NULL;
+
+ return clk;
+}
/**
* clk_release_all() - Disable (turn off)/Free an array of previously
* requested clocks.
+ * @clk: A clock struct array that was previously successfully
+ * requested by clk_request/get_by_*().
+ * @count: Number of clock contained in the array
*
* For each clock contained in the clock array, this function will check if
* clock has been previously requested and then will disable and free it.
*
- * @clk: A clock struct array that was previously successfully
- * requested by clk_request/get_by_*().
- * @count Number of clock contained in the array
* Return: zero on success, or -ve error code.
*/
int clk_release_all(struct clk *clk, int count);
@@ -290,12 +281,6 @@
return -ENOSYS;
}
-static inline int
-clk_get_optional_nodev(ofnode node, const char *name, struct clk *clk)
-{
- return -ENOSYS;
-}
-
static inline int clk_release_all(struct clk *clk, int count)
{
return -ENOSYS;
@@ -303,6 +288,54 @@
#endif
/**
+ * clk_get_by_name_optional() - Get/request a optional clock by name.
+ * @dev: The client device.
+ * @name: The name of the clock to request, within the client's list of
+ * clocks.
+ * @clk: A pointer to a clock struct to initialize.
+ *
+ * Behaves the same as clk_get_by_name(), except when there is no clock
+ * provider. In the latter case, return 0.
+ *
+ * Return: 0 if OK, or a negative error code.
+ */
+static inline int clk_get_by_name_optional(struct udevice *dev,
+ const char *name, struct clk *clk)
+{
+ int ret;
+
+ ret = clk_get_by_name(dev, name, clk);
+ if (ret == -ENODATA)
+ return 0;
+
+ return ret;
+}
+
+/**
+ * clk_get_by_name_nodev_optional - Get/request an optinonal clock by name
+ * without a device.
+ * @node: The client ofnode.
+ * @name: The name of the clock to request, within the client's list of
+ * clocks.
+ * @clk: A pointer to a clock struct to initialize.
+ *
+ * Behaves the same as clk_get_by_name_nodev() except where there is
+ * no clock producer, in this case, skip the error number -%ENODATA, and
+ * the function returns 0.
+ */
+static inline int clk_get_by_name_nodev_optional(ofnode node, const char *name,
+ struct clk *clk)
+{
+ int ret;
+
+ ret = clk_get_by_name_nodev(node, name, clk);
+ if (ret == -ENODATA)
+ return 0;
+
+ return ret;
+}
+
+/**
* enum clk_defaults_stage - What stage clk_set_defaults() is called at
* @CLK_DEFAULTS_PRE: Called before probe. Setting of defaults for clocks owned
* by this clock driver will be defered until after probing.
@@ -327,12 +360,13 @@
#if CONFIG_IS_ENABLED(OF_REAL) && CONFIG_IS_ENABLED(CLK)
/**
- * clk_set_defaults - Process 'assigned-{clocks/clock-parents/clock-rates}'
+ * clk_set_defaults - Process ``assigned-{clocks/clock-parents/clock-rates}``
* properties to configure clocks
- *
* @dev: A device to process (the ofnode associated with this device
* will be processed).
* @stage: The stage of the probing process this function is called during.
+ *
+ * Return: zero on success, or -ve error code.
*/
int clk_set_defaults(struct udevice *dev, enum clk_defaults_stage stage);
#else
@@ -345,12 +379,12 @@
/**
* clk_release_bulk() - Disable (turn off)/Free an array of previously
* requested clocks in a clock bulk struct.
+ * @bulk: A clock bulk struct that was previously successfully
+ * requested by clk_get_bulk().
*
* For each clock contained in the clock bulk struct, this function will check
* if clock has been previously requested and then will disable and free it.
*
- * @clk: A clock bulk struct that was previously successfully
- * requested by clk_get_bulk().
* Return: zero on success, or -ve error code.
*/
static inline int clk_release_bulk(struct clk_bulk *bulk)
@@ -360,35 +394,35 @@
#if CONFIG_IS_ENABLED(CLK)
/**
- * clk_request - Request a clock by provider-specific ID.
+ * clk_request() - Request a clock by provider-specific ID.
+ * @dev: The clock provider device.
+ * @clk: A pointer to a clock struct to initialize. The caller must
+ * have already initialized any field in this struct which the
+ * clock provider uses to identify the clock.
*
* This requests a clock using a provider-specific ID. Generally, this function
* should not be used, since clk_get_by_index/name() provide an interface that
* better separates clients from intimate knowledge of clock providers.
* However, this function may be useful in core SoC-specific code.
*
- * @dev: The clock provider device.
- * @clock: A pointer to a clock struct to initialize. The caller must
- * have already initialized any field in this struct which the
- * clock provider uses to identify the clock.
* Return: 0 if OK, or a negative error code.
*/
int clk_request(struct udevice *dev, struct clk *clk);
/**
- * clk_free - Free a previously requested clock.
- *
- * @clock: A clock struct that was previously successfully requested by
+ * clk_free() - Free a previously requested clock.
+ * @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*().
+ *
* Return: 0 if OK, or a negative error code.
*/
int clk_free(struct clk *clk);
/**
* clk_get_rate() - Get current clock rate.
- *
* @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*().
+ *
* Return: clock rate in Hz on success, 0 for invalid clock, or -ve error code
* for other errors.
*/
@@ -396,98 +430,98 @@
/**
* clk_get_parent() - Get current clock's parent.
- *
* @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*().
+ *
* Return: pointer to parent's struct clk, or error code passed as pointer
*/
struct clk *clk_get_parent(struct clk *clk);
/**
* clk_get_parent_rate() - Get parent of current clock rate.
- *
* @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*().
+ *
* Return: clock rate in Hz, or -ve error code.
*/
long long clk_get_parent_rate(struct clk *clk);
/**
* clk_round_rate() - Adjust a rate to the exact rate a clock can provide
+ * @clk: A clock struct that was previously successfully requested by
+ * clk_request/get_by_*().
+ * @rate: desired clock rate in Hz.
*
* This answers the question "if I were to pass @rate to clk_set_rate(),
* what clock rate would I end up with?" without changing the hardware
- * in any way. In other words:
+ * in any way. In other words::
*
* rate = clk_round_rate(clk, r);
*
- * and:
+ * and::
*
* rate = clk_set_rate(clk, r);
*
* are equivalent except the former does not modify the clock hardware
* in any way.
*
- * @clk: A clock struct that was previously successfully requested by
- * clk_request/get_by_*().
- * @rate: desired clock rate in Hz.
* Return: rounded rate in Hz, or -ve error code.
*/
ulong clk_round_rate(struct clk *clk, ulong rate);
/**
* clk_set_rate() - Set current clock rate.
- *
* @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*().
* @rate: New clock rate in Hz.
+ *
* Return: new rate, or -ve error code.
*/
ulong clk_set_rate(struct clk *clk, ulong rate);
/**
* clk_set_parent() - Set current clock parent.
- *
* @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*().
* @parent: A clock struct that was previously successfully requested by
* clk_request/get_by_*().
+ *
* Return: new rate, or -ve error code.
*/
int clk_set_parent(struct clk *clk, struct clk *parent);
/**
* clk_enable() - Enable (turn on) a clock.
- *
* @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*().
+ *
* Return: zero on success, or -ve error code.
*/
int clk_enable(struct clk *clk);
/**
* clk_enable_bulk() - Enable (turn on) all clocks in a clock bulk struct.
- *
* @bulk: A clock bulk struct that was previously successfully requested
* by clk_get_bulk().
+ *
* Return: zero on success, or -ve error code.
*/
int clk_enable_bulk(struct clk_bulk *bulk);
/**
* clk_disable() - Disable (turn off) a clock.
- *
* @clk: A clock struct that was previously successfully requested by
* clk_request/get_by_*().
+ *
* Return: zero on success, or -ve error code.
*/
int clk_disable(struct clk *clk);
/**
* clk_disable_bulk() - Disable (turn off) all clocks in a clock bulk struct.
- *
* @bulk: A clock bulk struct that was previously successfully requested
* by clk_get_bulk().
+ *
* Return: zero on success, or -ve error code.
*/
int clk_disable_bulk(struct clk_bulk *bulk);
@@ -497,28 +531,25 @@
* @p: clk compared against q
* @q: clk compared against p
*
- * Returns true if the two struct clk pointers both point to the same hardware
- * clock node.
- *
- * Returns false otherwise. Note that two NULL clks are treated as matching.
+ * Return:
+ * %true if the two struct clk pointers both point to the same hardware clock
+ * node, and %false otherwise. Note that two %NULL clks are treated as matching.
*/
bool clk_is_match(const struct clk *p, const struct clk *q);
/**
* clk_get_by_id() - Get the clock by its ID
- *
* @id: The clock ID to search for
- *
* @clkp: A pointer to clock struct that has been found among added clocks
* to UCLASS_CLK
+ *
* Return: zero on success, or -ENOENT on error
*/
int clk_get_by_id(ulong id, struct clk **clkp);
/**
* clk_dev_binded() - Check whether the clk has a device binded
- *
- * @clk A pointer to the clk
+ * @clk: A pointer to the clk
*
* Return: true on binded, or false on no
*/
@@ -604,8 +635,8 @@
/**
* clk_valid() - check if clk is valid
- *
* @clk: the clock to check
+ *
* Return: true if valid, or false
*/
static inline bool clk_valid(struct clk *clk)
diff --git a/include/configs/apple.h b/include/configs/apple.h
index f12e9bd..b06660a 100644
--- a/include/configs/apple.h
+++ b/include/configs/apple.h
@@ -9,10 +9,6 @@
"stdout=serial,vidconsole\0" \
"stderr=serial,vidconsole\0"
-#define ENV_MEM_LAYOUT_SETTINGS \
- "fdt_addr_r=0x960100000\0" \
- "kernel_addr_r=0x960200000\0"
-
#if CONFIG_IS_ENABLED(CMD_NVME)
#define BOOT_TARGET_NVME(func) func(NVME, nvme, 0)
#else
@@ -33,7 +29,6 @@
#define CONFIG_EXTRA_ENV_SETTINGS \
ENV_DEVICE_SETTINGS \
- ENV_MEM_LAYOUT_SETTINGS \
BOOTENV
#endif
diff --git a/include/configs/lx2160a_common.h b/include/configs/lx2160a_common.h
index e31f8d0..4f4b571 100644
--- a/include/configs/lx2160a_common.h
+++ b/include/configs/lx2160a_common.h
@@ -244,12 +244,36 @@
"run distro_bootcmd;run sd2_bootcmd;" \
"env exists secureboot && esbc_halt;"
+#ifdef CONFIG_CMD_USB
+#define BOOT_TARGET_DEVICES_USB(func) func(USB, usb, 0)
+#else
+#define BOOT_TARGET_DEVICES_USB(func)
+#endif
+
+#ifdef CONFIG_MMC
+#define BOOT_TARGET_DEVICES_MMC(func, instance) func(MMC, mmc, instance)
+#else
+#define BOOT_TARGET_DEVICES_MMC(func)
+#endif
+
+#ifdef CONFIG_SCSI
+#define BOOT_TARGET_DEVICES_SCSI(func) func(SCSI, scsi, 0)
+#else
+#define BOOT_TARGET_DEVICES_SCSI(func)
+#endif
+
+#ifdef CONFIG_CMD_DHCP
+#define BOOT_TARGET_DEVICES_DHCP(func) func(DHCP, dhcp, na)
+#else
+#define BOOT_TARGET_DEVICES_DHCP(func)
+#endif
+
#define BOOT_TARGET_DEVICES(func) \
- func(USB, usb, 0) \
- func(MMC, mmc, 0) \
- func(MMC, mmc, 1) \
- func(SCSI, scsi, 0) \
- func(DHCP, dhcp, na)
+ BOOT_TARGET_DEVICES_USB(func) \
+ BOOT_TARGET_DEVICES_MMC(func, 0) \
+ BOOT_TARGET_DEVICES_MMC(func, 1) \
+ BOOT_TARGET_DEVICES_SCSI(func) \
+ BOOT_TARGET_DEVICES_DHCP(func)
#include <config_distro_bootcmd.h>
#endif /* __LX2_COMMON_H */
diff --git a/include/configs/ti_armv7_common.h b/include/configs/ti_armv7_common.h
index 9733707..7483bc8 100644
--- a/include/configs/ti_armv7_common.h
+++ b/include/configs/ti_armv7_common.h
@@ -55,7 +55,7 @@
"do;" \
"setenv overlaystring ${overlaystring}'#'${overlay};" \
"done;\0" \
- "run_fit=bootm ${addr_fit}#${fdtfile}${overlaystring}\0" \
+ "run_fit=bootm ${addr_fit}#conf-${fdtfile}${overlaystring}\0" \
/*
* DDR information. If the CONFIG_NR_DRAM_BANKS is not defined,
diff --git a/include/sl28cpld.h b/include/sl28cpld.h
new file mode 100644
index 0000000..9a7c6de
--- /dev/null
+++ b/include/sl28cpld.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2021 Michael Walle <michael@walle.cc>
+ */
+
+#ifndef __SL28CPLD_H
+#define __SL28CPLD_H
+
+#define SL28CPLD_VERSION 0x03
+
+int sl28cpld_read(struct udevice *dev, uint offset);
+int sl28cpld_write(struct udevice *dev, uint offset, uint8_t value);
+int sl28cpld_update(struct udevice *dev, uint offset, uint8_t clear,
+ uint8_t set);
+
+#endif
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index f4519c7..613b531 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -14,6 +14,7 @@
#include <env.h>
#include <fdtdec.h>
#include <fs.h>
+#include <hang.h>
#include <malloc.h>
#include <mapmem.h>
#include <sort.h>
@@ -1118,10 +1119,13 @@
index = 0;
ret = efi_capsule_read_file(files[i], &capsule);
if (ret == EFI_SUCCESS) {
- ret = EFI_CALL(efi_update_capsule(&capsule, 1, 0));
+ ret = efi_capsule_update_firmware(capsule);
if (ret != EFI_SUCCESS)
- log_err("Applying capsule %ls failed\n",
+ log_err("Applying capsule %ls failed.\n",
files[i]);
+ else
+ log_info("Applying capsule %ls succeeded.\n",
+ files[i]);
/* create CapsuleXXXX */
set_capsule_result(index, capsule, ret);
@@ -1142,6 +1146,16 @@
free(files[i]);
free(files);
- return ret;
+ /*
+ * UEFI spec requires to reset system after complete processing capsule
+ * update on the storage.
+ */
+ log_info("Reboot after firmware update");
+ /* Cold reset is required for loading the new firmware. */
+ do_reset(NULL, 0, 0, NULL);
+ hang();
+ /* not reach here */
+
+ return 0;
}
#endif /* CONFIG_EFI_CAPSULE_ON_DISK */
diff --git a/lib/efi_loader/efi_signature.c b/lib/efi_loader/efi_signature.c
index 1bd1fdc..79ed077 100644
--- a/lib/efi_loader/efi_signature.c
+++ b/lib/efi_loader/efi_signature.c
@@ -518,12 +518,11 @@
goto out;
EFI_PRINT("Verifying last certificate in chain\n");
- if (signer->self_signed) {
- if (efi_lookup_certificate(signer, db))
- if (efi_signature_check_revocation(sinfo,
- signer, dbx))
- break;
- } else if (efi_verify_certificate(signer, db, &root)) {
+ if (efi_lookup_certificate(signer, db))
+ if (efi_signature_check_revocation(sinfo, signer, dbx))
+ break;
+ if (!signer->self_signed &&
+ efi_verify_certificate(signer, db, &root)) {
bool check;
check = efi_signature_check_revocation(sinfo, root,
diff --git a/lib/efi_loader/efi_watchdog.c b/lib/efi_loader/efi_watchdog.c
index 87ca6c5..d741076 100644
--- a/lib/efi_loader/efi_watchdog.c
+++ b/lib/efi_loader/efi_watchdog.c
@@ -75,17 +75,6 @@
printf("ERROR: Failed to register watchdog event\n");
return r;
}
- /*
- * The UEFI standard requires that the watchdog timer is set to five
- * minutes when invoking an EFI boot option.
- *
- * Unified Extensible Firmware Interface (UEFI), version 2.7 Errata A
- * 7.5. Miscellaneous Boot Services - EFI_BOOT_SERVICES.SetWatchdogTimer
- */
- r = efi_set_watchdog(300);
- if (r != EFI_SUCCESS) {
- printf("ERROR: Failed to set watchdog timer\n");
- return r;
- }
+
return EFI_SUCCESS;
}
diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
index 3e7b798..b2a2119 100644
--- a/lib/rsa/rsa-sign.c
+++ b/lib/rsa/rsa-sign.c
@@ -383,12 +383,11 @@
goto err_alloc;
}
- context = EVP_MD_CTX_create();
+ context = EVP_MD_CTX_new();
if (!context) {
ret = rsa_err("EVP context creation failed");
goto err_create;
}
- EVP_MD_CTX_init(context);
ckey = EVP_PKEY_CTX_new(pkey, NULL);
if (!ckey) {
@@ -425,8 +424,7 @@
goto err_sign;
}
- EVP_MD_CTX_reset(context);
- EVP_MD_CTX_destroy(context);
+ EVP_MD_CTX_free(context);
debug("Got signature: %zu bytes, expected %d\n", size, EVP_PKEY_size(pkey));
*sigp = sig;
@@ -435,7 +433,7 @@
return 0;
err_sign:
- EVP_MD_CTX_destroy(context);
+ EVP_MD_CTX_free(context);
err_create:
free(sig);
err_alloc:
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 93cb09a..c14da10 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -456,8 +456,8 @@
# which is pure ASL code. The Intel ASL (ACPI (Advanced Configuration and Power
# Interface) Source Language compiler (iasl) then converts this ASL code into a
# C file containing the hex data to build into U-Boot. This file is called
-# dsdt.hex (despite us setting the prefix to .../dsdt.asl.tmp) so must be
-# renamed to dsdt.c for consumption by the build system.
+# dsdt_generated.hex (despite us setting the prefix to .../dsdt_generated.asl.tmp)
+# so must be renamed to dsdt_generated.c for consumption by the build system.
ASL_TMP = $(patsubst %.c,%.asl.tmp,$@)
quiet_cmd_acpi_c_asl= ASL $<
@@ -468,9 +468,9 @@
$(if $(KBUILD_VERBOSE:1=), >/dev/null) && \
mv $(patsubst %.c,%.hex,$@) $@
-$(obj)/dsdt.c: $(src)/dsdt.asl
+$(obj)/dsdt_generated.c: $(src)/dsdt.asl
$(call cmd,acpi_c_asl)
- $(Q)sed -i -e "s,dsdt_aml_code,AmlCode," $@
+ $(Q)sed -i -e "s,dsdt_generated_aml_code,AmlCode," $@
# Bzip2
# ---------------------------------------------------------------------------
diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware.py b/test/py/tests/test_efi_capsule/test_capsule_firmware.py
index 6e803f6..1dcf1c7 100644
--- a/test/py/tests/test_efi_capsule/test_capsule_firmware.py
+++ b/test/py/tests/test_efi_capsule/test_capsule_firmware.py
@@ -143,13 +143,14 @@
'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
assert 'Test01' in ''.join(output)
- # reboot
- u_boot_console.restart_uboot()
-
capsule_early = u_boot_config.buildconfig.get(
'config_efi_capsule_on_disk_early')
capsule_auth = u_boot_config.buildconfig.get(
'config_efi_capsule_authenticate')
+
+ # reboot
+ u_boot_console.restart_uboot(expect_reset = capsule_early)
+
with u_boot_console.log.section('Test Case 2-b, after reboot'):
if not capsule_early:
# make sure that dfu_alt_info exists even persistent variables
@@ -162,7 +163,7 @@
# need to run uefi command to initiate capsule handling
output = u_boot_console.run_command(
- 'env print -e Capsule0000')
+ 'env print -e Capsule0000', wait_for_reboot = True)
output = u_boot_console.run_command_list([
'host bind 0 %s' % disk_img,
@@ -218,13 +219,14 @@
'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
assert 'Test02' in ''.join(output)
- # reboot
- u_boot_console.restart_uboot()
-
capsule_early = u_boot_config.buildconfig.get(
'config_efi_capsule_on_disk_early')
capsule_auth = u_boot_config.buildconfig.get(
'config_efi_capsule_authenticate')
+
+ # reboot
+ u_boot_console.restart_uboot(expect_reset = capsule_early)
+
with u_boot_console.log.section('Test Case 3-b, after reboot'):
if not capsule_early:
# make sure that dfu_alt_info exists even persistent variables
@@ -237,9 +239,12 @@
# need to run uefi command to initiate capsule handling
output = u_boot_console.run_command(
- 'env print -e Capsule0000')
+ 'env print -e Capsule0000', wait_for_reboot = True)
- output = u_boot_console.run_command_list(['efidebug capsule esrt'])
+ # make sure the dfu_alt_info exists because it is required for making ESRT.
+ output = u_boot_console.run_command_list([
+ 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
+ 'efidebug capsule esrt'])
# ensure that EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID is in the ESRT.
assert 'AE13FF2D-9AD4-4E25-9AC8-6D80B3B22147' in ''.join(output)
@@ -293,13 +298,14 @@
'fatls host 0:1 %s' % CAPSULE_INSTALL_DIR])
assert 'Test03' in ''.join(output)
- # reboot
- u_boot_console.restart_uboot()
-
capsule_early = u_boot_config.buildconfig.get(
'config_efi_capsule_on_disk_early')
capsule_auth = u_boot_config.buildconfig.get(
'config_efi_capsule_authenticate')
+
+ # reboot
+ u_boot_console.restart_uboot(expect_reset = capsule_early)
+
with u_boot_console.log.section('Test Case 4-b, after reboot'):
if not capsule_early:
# make sure that dfu_alt_info exists even persistent variables
@@ -312,9 +318,12 @@
# need to run uefi command to initiate capsule handling
output = u_boot_console.run_command(
- 'env print -e Capsule0000')
+ 'env print -e Capsule0000', wait_for_reboot = True)
- output = u_boot_console.run_command_list(['efidebug capsule esrt'])
+ # make sure the dfu_alt_info exists because it is required for making ESRT.
+ output = u_boot_console.run_command_list([
+ 'env set dfu_alt_info "sf 0:0=u-boot-bin raw 0x100000 0x50000;u-boot-env raw 0x150000 0x200000"',
+ 'efidebug capsule esrt'])
# ensure that EFI_FIRMWARE_IMAGE_TYPE_UBOOT_RAW_GUID is in the ESRT.
assert 'E2BB9C06-70E9-4B14-97A3-5A7913176E3F' in ''.join(output)
diff --git a/test/py/u_boot_console_base.py b/test/py/u_boot_console_base.py
index 384fd53..3938ec1 100644
--- a/test/py/u_boot_console_base.py
+++ b/test/py/u_boot_console_base.py
@@ -139,8 +139,55 @@
self.p.close()
self.logstream.close()
+ def wait_for_boot_prompt(self, loop_num = 1):
+ """Wait for the boot up until command prompt. This is for internal use only.
+ """
+ try:
+ bcfg = self.config.buildconfig
+ config_spl = bcfg.get('config_spl', 'n') == 'y'
+ config_spl_serial = bcfg.get('config_spl_serial', 'n') == 'y'
+ env_spl_skipped = self.config.env.get('env__spl_skipped', False)
+ env_spl2_skipped = self.config.env.get('env__spl2_skipped', True)
+
+ while loop_num > 0:
+ loop_num -= 1
+ if config_spl and config_spl_serial and not env_spl_skipped:
+ m = self.p.expect([pattern_u_boot_spl_signon] +
+ self.bad_patterns)
+ if m != 0:
+ raise Exception('Bad pattern found on SPL console: ' +
+ self.bad_pattern_ids[m - 1])
+ if not env_spl2_skipped:
+ m = self.p.expect([pattern_u_boot_spl2_signon] +
+ self.bad_patterns)
+ if m != 0:
+ raise Exception('Bad pattern found on SPL2 console: ' +
+ self.bad_pattern_ids[m - 1])
+ m = self.p.expect([pattern_u_boot_main_signon] + self.bad_patterns)
+ if m != 0:
+ raise Exception('Bad pattern found on console: ' +
+ self.bad_pattern_ids[m - 1])
+ self.u_boot_version_string = self.p.after
+ while True:
+ m = self.p.expect([self.prompt_compiled,
+ pattern_stop_autoboot_prompt] + self.bad_patterns)
+ if m == 0:
+ break
+ if m == 1:
+ self.p.send(' ')
+ continue
+ raise Exception('Bad pattern found on console: ' +
+ self.bad_pattern_ids[m - 2])
+
+ except Exception as ex:
+ self.log.error(str(ex))
+ self.cleanup_spawn()
+ raise
+ finally:
+ self.log.timestamp()
+
def run_command(self, cmd, wait_for_echo=True, send_nl=True,
- wait_for_prompt=True):
+ wait_for_prompt=True, wait_for_reboot=False):
"""Execute a command via the U-Boot console.
The command is always sent to U-Boot.
@@ -168,6 +215,9 @@
wait_for_prompt: Boolean indicating whether to wait for the
command prompt to be sent by U-Boot. This typically occurs
immediately after the command has been executed.
+ wait_for_reboot: Boolean indication whether to wait for the
+ reboot U-Boot. If this sets True, wait_for_prompt must also
+ be True.
Returns:
If wait_for_prompt == False:
@@ -202,11 +252,14 @@
self.bad_pattern_ids[m - 1])
if not wait_for_prompt:
return
- m = self.p.expect([self.prompt_compiled] + self.bad_patterns)
- if m != 0:
- self.at_prompt = False
- raise Exception('Bad pattern found on console: ' +
- self.bad_pattern_ids[m - 1])
+ if wait_for_reboot:
+ self.wait_for_boot_prompt()
+ else:
+ m = self.p.expect([self.prompt_compiled] + self.bad_patterns)
+ if m != 0:
+ self.at_prompt = False
+ raise Exception('Bad pattern found on console: ' +
+ self.bad_pattern_ids[m - 1])
self.at_prompt = True
self.at_prompt_logevt = self.logstream.logfile.cur_evt
# Only strip \r\n; space/TAB might be significant if testing
@@ -321,7 +374,7 @@
finally:
self.p.timeout = orig_timeout
- def ensure_spawned(self):
+ def ensure_spawned(self, expect_reset=False):
"""Ensure a connection to a correctly running U-Boot instance.
This may require spawning a new Sandbox process or resetting target
@@ -330,7 +383,9 @@
This is an internal function and should not be called directly.
Args:
- None.
+ expect_reset: Boolean indication whether this boot is expected
+ to be reset while the 1st boot process after main boot before
+ prompt. False by default.
Returns:
Nothing.
@@ -349,41 +404,11 @@
if not self.config.gdbserver:
self.p.timeout = 30000
self.p.logfile_read = self.logstream
- bcfg = self.config.buildconfig
- config_spl = bcfg.get('config_spl', 'n') == 'y'
- config_spl_serial = bcfg.get('config_spl_serial',
- 'n') == 'y'
- env_spl_skipped = self.config.env.get('env__spl_skipped',
- False)
- env_spl2_skipped = self.config.env.get('env__spl2_skipped',
- True)
- if config_spl and config_spl_serial and not env_spl_skipped:
- m = self.p.expect([pattern_u_boot_spl_signon] +
- self.bad_patterns)
- if m != 0:
- raise Exception('Bad pattern found on SPL console: ' +
- self.bad_pattern_ids[m - 1])
- if not env_spl2_skipped:
- m = self.p.expect([pattern_u_boot_spl2_signon] +
- self.bad_patterns)
- if m != 0:
- raise Exception('Bad pattern found on SPL2 console: ' +
- self.bad_pattern_ids[m - 1])
- m = self.p.expect([pattern_u_boot_main_signon] + self.bad_patterns)
- if m != 0:
- raise Exception('Bad pattern found on console: ' +
- self.bad_pattern_ids[m - 1])
- self.u_boot_version_string = self.p.after
- while True:
- m = self.p.expect([self.prompt_compiled,
- pattern_stop_autoboot_prompt] + self.bad_patterns)
- if m == 0:
- break
- if m == 1:
- self.p.send(' ')
- continue
- raise Exception('Bad pattern found on console: ' +
- self.bad_pattern_ids[m - 2])
+ if expect_reset:
+ loop_num = 2
+ else:
+ loop_num = 1
+ self.wait_for_boot_prompt(loop_num = loop_num)
self.at_prompt = True
self.at_prompt_logevt = self.logstream.logfile.cur_evt
except Exception as ex:
@@ -416,10 +441,10 @@
pass
self.p = None
- def restart_uboot(self):
+ def restart_uboot(self, expect_reset=False):
"""Shut down and restart U-Boot."""
self.cleanup_spawn()
- self.ensure_spawned()
+ self.ensure_spawned(expect_reset)
def get_spawn_output(self):
"""Return the start-up output from U-Boot
diff --git a/test/py/u_boot_console_sandbox.py b/test/py/u_boot_console_sandbox.py
index 7e1eb0e..ce4ca7e 100644
--- a/test/py/u_boot_console_sandbox.py
+++ b/test/py/u_boot_console_sandbox.py
@@ -57,11 +57,14 @@
cmd += self.sandbox_flags
return Spawn(cmd, cwd=self.config.source_dir)
- def restart_uboot_with_flags(self, flags):
+ def restart_uboot_with_flags(self, flags, expect_reset=False):
"""Run U-Boot with the given command-line flags
Args:
flags: List of flags to pass, each a string
+ expect_reset: Boolean indication whether this boot is expected
+ to be reset while the 1st boot process after main boot before
+ prompt. False by default.
Returns:
A u_boot_spawn.Spawn object that is attached to U-Boot.
@@ -69,7 +72,7 @@
try:
self.sandbox_flags = flags
- return self.restart_uboot()
+ return self.restart_uboot(expect_reset)
finally:
self.sandbox_flags = []
diff --git a/tools/Makefile b/tools/Makefile
index 5409ff2..60231c7 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -196,6 +196,9 @@
hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl
HOSTCFLAGS_mkexynosspl.o := -pedantic
+HOSTCFLAGS_kwboot.o += -pthread
+HOSTLDLIBS_kwboot += -pthread -ltinfo
+
ifdtool-objs := $(LIBFDT_OBJS) ifdtool.o
hostprogs-$(CONFIG_X86) += ifdtool
diff --git a/tools/dumpimage.c b/tools/dumpimage.c
index e548143..4791dd0 100644
--- a/tools/dumpimage.c
+++ b/tools/dumpimage.c
@@ -12,9 +12,7 @@
static void usage(void);
/* parameters initialized by core will be used by the image type code */
-static struct image_tool_params params = {
- .type = IH_TYPE_KERNEL,
-};
+static struct image_tool_params params;
/*
* dumpimage_extract_subimage -
@@ -110,7 +108,7 @@
}
}
- if (argc < 2)
+ if (argc < 2 || (params.iflag && params.lflag))
usage();
if (optind >= argc) {
@@ -122,7 +120,7 @@
/* set tparams as per input type_id */
tparams = imagetool_get_type(params.type);
- if (tparams == NULL) {
+ if (!params.lflag && tparams == NULL) {
fprintf(stderr, "%s: unsupported type: %s\n",
params.cmdname, genimg_get_type_name(params.type));
exit(EXIT_FAILURE);
@@ -132,7 +130,7 @@
* check the passed arguments parameters meets the requirements
* as per image type to be generated/listed
*/
- if (tparams->check_params) {
+ if (tparams && tparams->check_params) {
if (tparams->check_params(¶ms)) {
fprintf(stderr, "%s: Parameter check failed\n",
params.cmdname);
@@ -159,7 +157,7 @@
exit(EXIT_FAILURE);
}
- if ((uint32_t)sbuf.st_size < tparams->header_size) {
+ if (tparams && (uint32_t)sbuf.st_size < tparams->header_size) {
fprintf(stderr, "%s: Bad size: \"%s\" is not valid image\n",
params.cmdname, params.imagefile);
exit(EXIT_FAILURE);
@@ -203,8 +201,9 @@
static void usage(void)
{
- fprintf(stderr, "Usage: %s -l image\n"
- " -l ==> list image header information\n",
+ fprintf(stderr, "Usage: %s [-T type] -l image\n"
+ " -l ==> list image header information\n"
+ " -T ==> parse image file as 'type'\n",
params.cmdname);
fprintf(stderr,
" %s [-T type] [-p position] [-o outfile] image\n"
diff --git a/tools/imagetool.c b/tools/imagetool.c
index ba1f64a..5ad6d74 100644
--- a/tools/imagetool.c
+++ b/tools/imagetool.c
@@ -26,6 +26,12 @@
return NULL;
}
+static int imagetool_verify_print_header_by_type(
+ void *ptr,
+ struct stat *sbuf,
+ struct image_type_params *tparams,
+ struct image_tool_params *params);
+
int imagetool_verify_print_header(
void *ptr,
struct stat *sbuf,
@@ -39,6 +45,9 @@
struct image_type_params **start = __start_image_type;
struct image_type_params **end = __stop_image_type;
+ if (tparams)
+ return imagetool_verify_print_header_by_type(ptr, sbuf, tparams, params);
+
for (curr = start; curr != end; curr++) {
if ((*curr)->verify_header) {
retval = (*curr)->verify_header((unsigned char *)ptr,
@@ -65,7 +74,7 @@
return retval;
}
-int imagetool_verify_print_header_by_type(
+static int imagetool_verify_print_header_by_type(
void *ptr,
struct stat *sbuf,
struct image_type_params *tparams,
diff --git a/tools/imagetool.h b/tools/imagetool.h
index c3f80fc..5169b02 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -178,33 +178,19 @@
/*
* imagetool_verify_print_header() - verifies the image header
*
- * Scan registered image types and verify the image_header for each
- * supported image type. If verification is successful, this prints
- * the respective header.
- *
- * Return: 0 on success, negative if input image format does not match with
- * any of supported image types
- */
-int imagetool_verify_print_header(
- void *ptr,
- struct stat *sbuf,
- struct image_type_params *tparams,
- struct image_tool_params *params);
-
-/*
- * imagetool_verify_print_header_by_type() - verifies the image header
- *
* Verify the image_header for the image type given by tparams.
+ * If tparams is NULL then scan registered image types and verify the
+ * image_header for each supported image type.
* If verification is successful, this prints the respective header.
* @ptr: pointer the the image header
* @sbuf: stat information about the file pointed to by ptr
- * @tparams: image type parameters
+ * @tparams: image type parameters or NULL
* @params: mkimage parameters
*
* Return: 0 on success, negative if input image format does not match with
* the given image type
*/
-int imagetool_verify_print_header_by_type(
+int imagetool_verify_print_header(
void *ptr,
struct stat *sbuf,
struct image_type_params *tparams,
diff --git a/tools/kwboot.c b/tools/kwboot.c
index 68c0ef1..69d1be0 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -1,15 +1,40 @@
/*
* Boot a Marvell SoC, with Xmodem over UART0.
- * supports Kirkwood, Dove, Armada 370, Armada XP, Armada 375, Armada 38x and
- * Armada 39x
+ * supports Kirkwood, Dove, Avanta, Armada 370, Armada XP, Armada 375,
+ * Armada 38x and Armada 39x.
*
* (c) 2012 Daniel Stodden <daniel.stodden@gmail.com>
* (c) 2021 Pali Rohár <pali@kernel.org>
* (c) 2021 Marek Behún <marek.behun@nic.cz>
*
- * References: marvell.com, "88F6180, 88F6190, 88F6192, and 88F6281
- * Integrated Controller: Functional Specifications" December 2,
- * 2008. Chapter 24.2 "BootROM Firmware".
+ * References:
+ * - "88F6180, 88F6190, 88F6192, and 88F6281: Integrated Controller: Functional
+ * Specifications" December 2, 2008. Chapter 24.2 "BootROM Firmware".
+ * https://web.archive.org/web/20130730091033/https://www.marvell.com/embedded-processors/kirkwood/assets/FS_88F6180_9x_6281_OpenSource.pdf
+ * - "88AP510: High-Performance SoC with Integrated CPU, 2D/3D Graphics
+ * Processor, and High-Definition Video Decoder: Functional Specifications"
+ * August 3, 2011. Chapter 5 "BootROM Firmware"
+ * https://web.archive.org/web/20120130172443/https://www.marvell.com/application-processors/armada-500/assets/Armada-510-Functional-Spec.pdf
+ * - "88F6710, 88F6707, and 88F6W11: ARMADA(R) 370 SoC: Functional Specifications"
+ * May 26, 2014. Chapter 6 "BootROM Firmware".
+ * https://web.archive.org/web/20140617183701/https://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-FunctionalSpec-datasheet.pdf
+ * - "MV78230, MV78260, and MV78460: ARMADA(R) XP Family of Highly Integrated
+ * Multi-Core ARMv7 Based SoC Processors: Functional Specifications"
+ * May 29, 2014. Chapter 6 "BootROM Firmware".
+ * https://web.archive.org/web/20180829171131/https://www.marvell.com/embedded-processors/armada-xp/assets/ARMADA-XP-Functional-SpecDatasheet.pdf
+ * - "ARMADA(R) 375 Value-Performance Dual Core CPU System on Chip: Functional
+ * Specifications" Doc. No. MV-S109377-00, Rev. A. September 18, 2013.
+ * Chapter 7 "Boot Sequence"
+ * CONFIDENTIAL, no public documentation available
+ * - "88F6810, 88F6811, 88F6821, 88F6W21, 88F6820, and 88F6828: ARMADA(R) 38x
+ * Family High-Performance Single/Dual CPU System on Chip: Functional
+ * Specifications" Doc. No. MV-S109094-00, Rev. C. August 2, 2015.
+ * Chapter 7 "Boot Flow"
+ * CONFIDENTIAL, no public documentation available
+ * - "88F6920, 88F6925 and 88F6928: ARMADA(R) 39x High-Performance Dual Core CPU
+ * System on Chip Functional Specifications" Doc. No. MV-S109896-00, Rev. B.
+ * December 22, 2015. Chapter 7 "Boot Flow"
+ * CONFIDENTIAL, no public documentation available
*/
#include "kwbimage.h"
@@ -28,6 +53,7 @@
#include <stdint.h>
#include <time.h>
#include <sys/stat.h>
+#include <pthread.h>
#ifdef __linux__
#include "termios_linux.h"
@@ -36,6 +62,13 @@
#endif
/*
+ * These functions are in <term.h> header file, but this header file conflicts
+ * with "termios_linux.h" header file. So declare these functions manually.
+ */
+extern int setupterm(const char *, int, int *);
+extern char *tigetstr(const char *);
+
+/*
* Marvell BootROM UART Sensing
*/
@@ -48,11 +81,9 @@
};
/* Defines known to work on Kirkwood */
-#define KWBOOT_MSG_REQ_DELAY 10 /* ms */
#define KWBOOT_MSG_RSP_TIMEO 50 /* ms */
/* Defines known to work on Armada XP */
-#define KWBOOT_MSG_REQ_DELAY_AXP 1000 /* ms */
#define KWBOOT_MSG_RSP_TIMEO_AXP 1000 /* ms */
/*
@@ -285,7 +316,6 @@
static int kwboot_verbose;
-static int msg_req_delay = KWBOOT_MSG_REQ_DELAY;
static int msg_rsp_timeo = KWBOOT_MSG_RSP_TIMEO;
static int blk_rsp_timeo = KWBOOT_BLK_RSP_TIMEO;
@@ -720,42 +750,120 @@
return rc;
}
-static int
-kwboot_bootmsg(int tty, void *msg)
+static void *
+kwboot_msg_write_handler(void *arg)
{
- struct kwboot_block block;
- int rc;
- char c;
- int count;
+ int tty = *(int *)((void **)arg)[0];
+ const void *msg = ((void **)arg)[1];
+ int rsp_timeo = msg_rsp_timeo;
+ int i, dummy_oldtype;
- if (msg == NULL)
- kwboot_printv("Please reboot the target into UART boot mode...");
- else
- kwboot_printv("Sending boot message. Please reboot the target...");
+ /* allow to cancel this thread at any time */
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &dummy_oldtype);
- do {
- rc = tcflush(tty, TCIOFLUSH);
- if (rc)
- break;
-
- for (count = 0; count < 128; count++) {
- rc = kwboot_tty_send(tty, msg, 8, 0);
- if (rc) {
- usleep(msg_req_delay * 1000);
- continue;
+ while (1) {
+ /* write 128 samples of message pattern into the output queue without waiting */
+ for (i = 0; i < 128; i++) {
+ if (kwboot_tty_send(tty, msg, 8, 1) < 0) {
+ perror("\nFailed to send message pattern");
+ exit(1);
}
}
+ /* wait until output queue is transmitted and then make pause */
+ if (tcdrain(tty) < 0) {
+ perror("\nFailed to send message pattern");
+ exit(1);
+ }
+ /* BootROM requires pause on UART after it detects message pattern */
+ usleep(rsp_timeo * 1000);
+ }
+}
- rc = kwboot_tty_recv(tty, &c, 1, msg_rsp_timeo);
+static int
+kwboot_msg_start_thread(pthread_t *thread, int *tty, void *msg)
+{
+ void *arg[2];
+ int rc;
+ arg[0] = tty;
+ arg[1] = msg;
+ rc = pthread_create(thread, NULL, kwboot_msg_write_handler, arg);
+ if (rc) {
+ errno = rc;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+kwboot_msg_stop_thread(pthread_t thread)
+{
+ int rc;
+
+ rc = pthread_cancel(thread);
+ if (rc) {
+ errno = rc;
+ return -1;
+ }
+
+ rc = pthread_join(thread, NULL);
+ if (rc) {
+ errno = rc;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+kwboot_bootmsg(int tty)
+{
+ struct kwboot_block block;
+ pthread_t write_thread;
+ int rc, err;
+ char c;
+
+ /* flush input and output queue */
+ tcflush(tty, TCIOFLUSH);
+
+ rc = kwboot_msg_start_thread(&write_thread, &tty, kwboot_msg_boot);
+ if (rc) {
+ perror("Failed to start write thread");
+ return rc;
+ }
+
+ kwboot_printv("Sending boot message. Please reboot the target...");
+
+ err = 0;
+ while (1) {
kwboot_spinner();
- } while (rc || c != NAK);
+ rc = kwboot_tty_recv(tty, &c, 1, msg_rsp_timeo);
+ if (rc && errno == ETIMEDOUT) {
+ continue;
+ } else if (rc) {
+ err = errno;
+ break;
+ }
+
+ if (c == NAK)
+ break;
+ }
kwboot_printv("\n");
- if (rc)
+ rc = kwboot_msg_stop_thread(write_thread);
+ if (rc) {
+ perror("Failed to stop write thread");
return rc;
+ }
+
+ if (err) {
+ errno = err;
+ perror("Failed to read response for boot message pattern");
+ return -1;
+ }
/*
* At this stage we have sent more boot message patterns and BootROM
@@ -772,11 +880,19 @@
*/
/* flush output queue with remaining boot message patterns */
- tcflush(tty, TCOFLUSH);
+ rc = tcflush(tty, TCOFLUSH);
+ if (rc) {
+ perror("Failed to flush output queue");
+ return rc;
+ }
/* send one xmodem packet with 0xff bytes to force BootROM to re-sync */
memset(&block, 0xff, sizeof(block));
- kwboot_tty_send(tty, &block, sizeof(block), 0);
+ rc = kwboot_tty_send(tty, &block, sizeof(block), 0);
+ if (rc) {
+ perror("Failed to send sync sequence");
+ return rc;
+ }
/*
* Sending 132 bytes via 115200B/8-N-1 takes 11.45 ms, reading 132 bytes
@@ -785,40 +901,151 @@
usleep(30 * 1000);
/* flush remaining NAK replies from input queue */
- tcflush(tty, TCIFLUSH);
+ rc = tcflush(tty, TCIFLUSH);
+ if (rc) {
+ perror("Failed to flush input queue");
+ return rc;
+ }
return 0;
}
static int
-kwboot_debugmsg(int tty, void *msg)
+kwboot_debugmsg(int tty)
{
- int rc;
+ unsigned char buf[8192];
+ pthread_t write_thread;
+ int rc, err, i, pos;
+ size_t off;
+
+ /* flush input and output queue */
+ tcflush(tty, TCIOFLUSH);
+
+ rc = kwboot_msg_start_thread(&write_thread, &tty, kwboot_msg_debug);
+ if (rc) {
+ perror("Failed to start write thread");
+ return rc;
+ }
kwboot_printv("Sending debug message. Please reboot the target...");
+ kwboot_spinner();
- do {
- char buf[16];
-
- rc = tcflush(tty, TCIOFLUSH);
- if (rc)
- break;
-
- rc = kwboot_tty_send(tty, msg, 8, 0);
- if (rc) {
- usleep(msg_req_delay * 1000);
+ err = 0;
+ off = 0;
+ while (1) {
+ /* Read immediately all bytes in queue without waiting */
+ rc = read(tty, buf + off, sizeof(buf) - off);
+ if ((rc < 0 && errno == EINTR) || rc == 0) {
continue;
+ } else if (rc < 0) {
+ err = errno;
+ break;
}
-
- rc = kwboot_tty_recv(tty, buf, 16, msg_rsp_timeo);
+ off += rc - 1;
kwboot_spinner();
- } while (rc);
+ /*
+ * Check if we received at least 4 debug message patterns
+ * (console echo from BootROM) in cyclic buffer
+ */
+
+ for (pos = 0; pos < sizeof(kwboot_msg_debug); pos++)
+ if (buf[off] == kwboot_msg_debug[(pos + off) % sizeof(kwboot_msg_debug)])
+ break;
+
+ for (i = off; i >= 0; i--)
+ if (buf[i] != kwboot_msg_debug[(pos + i) % sizeof(kwboot_msg_debug)])
+ break;
+
+ off -= i;
+
+ if (off >= 4 * sizeof(kwboot_msg_debug))
+ break;
+
+ /* If not move valid suffix from end of the buffer to the beginning of buffer */
+ memmove(buf, buf + i + 1, off);
+ }
kwboot_printv("\n");
- return rc;
+ rc = kwboot_msg_stop_thread(write_thread);
+ if (rc) {
+ perror("Failed to stop write thread");
+ return rc;
+ }
+
+ if (err) {
+ errno = err;
+ perror("Failed to read response for debug message pattern");
+ return -1;
+ }
+
+ /* flush output queue with remaining debug message patterns */
+ rc = tcflush(tty, TCOFLUSH);
+ if (rc) {
+ perror("Failed to flush output queue");
+ return rc;
+ }
+
+ kwboot_printv("Clearing input buffer...\n");
+
+ /*
+ * Wait until BootROM transmit all remaining echo characters.
+ * Experimentally it was measured that for Armada 385 BootROM
+ * it is required to wait at least 0.415s. So wait 0.5s.
+ */
+ usleep(500 * 1000);
+
+ /*
+ * In off variable is stored number of characters received after the
+ * successful detection of echo reply. So these characters are console
+ * echo for other following debug message patterns. BootROM may have in
+ * its output queue other echo characters which were being transmitting
+ * before above sleep call. So read remaining number of echo characters
+ * sent by the BootROM now.
+ */
+ while ((rc = kwboot_tty_recv(tty, &buf[0], 1, 0)) == 0)
+ off++;
+ if (errno != ETIMEDOUT) {
+ perror("Failed to read response");
+ return rc;
+ }
+
+ /*
+ * Clear every echo character set by the BootROM by backspace byte.
+ * This is required prior writing any command to the BootROM debug
+ * because BootROM command line buffer has limited size. If length
+ * of the command is larger than buffer size then it looks like
+ * that Armada 385 BootROM crashes after sending ENTER. So erase it.
+ * Experimentally it was measured that for Armada 385 BootROM it is
+ * required to send at least 3 backspace bytes for one echo character.
+ * This is unknown why. But lets do it.
+ */
+ off *= 3;
+ memset(buf, '\x08', sizeof(buf));
+ while (off > sizeof(buf)) {
+ rc = kwboot_tty_send(tty, buf, sizeof(buf), 1);
+ if (rc) {
+ perror("Failed to send clear sequence");
+ return rc;
+ }
+ off -= sizeof(buf);
+ }
+ rc = kwboot_tty_send(tty, buf, off, 0);
+ if (rc) {
+ perror("Failed to send clear sequence");
+ return rc;
+ }
+
+ usleep(msg_rsp_timeo * 1000);
+ rc = tcflush(tty, TCIFLUSH);
+ if (rc) {
+ perror("Failed to flush input queue");
+ return rc;
+ }
+
+ return 0;
}
static size_t
@@ -1181,37 +1408,84 @@
}
static int
-kwboot_term_pipe(int in, int out, const char *quit, int *s)
+kwboot_term_pipe(int in, int out, const char *quit, int *s, const char *kbs, int *k)
{
char buf[128];
- ssize_t nin;
+ ssize_t nin, noff;
nin = read(in, buf, sizeof(buf));
if (nin <= 0)
return -1;
- if (quit) {
+ noff = 0;
+
+ if (quit || kbs) {
int i;
for (i = 0; i < nin; i++) {
- if (buf[i] == quit[*s]) {
+ if ((quit || kbs) &&
+ (!quit || buf[i] != quit[*s]) &&
+ (!kbs || buf[i] != kbs[*k])) {
+ const char *prefix;
+ int plen;
+
+ if (quit && kbs) {
+ prefix = (*s >= *k) ? quit : kbs;
+ plen = (*s >= *k) ? *s : *k;
+ } else if (quit) {
+ prefix = quit;
+ plen = *s;
+ } else {
+ prefix = kbs;
+ plen = *k;
+ }
+
+ if (plen > i && kwboot_write(out, prefix, plen - i) < 0)
+ return -1;
+ }
+
+ if (quit && buf[i] == quit[*s]) {
(*s)++;
if (!quit[*s]) {
- nin = i - *s;
+ nin = (i > *s) ? (i - *s) : 0;
break;
}
- } else {
- if (*s > i && kwboot_write(out, quit, *s - i) < 0)
- return -1;
+ } else if (quit) {
*s = 0;
}
+
+ if (kbs && buf[i] == kbs[*k]) {
+ (*k)++;
+ if (!kbs[*k]) {
+ if (i > *k + noff &&
+ kwboot_write(out, buf + noff, i - *k - noff) < 0)
+ return -1;
+ /*
+ * Replace backspace key by '\b' (0x08)
+ * byte which is the only recognized
+ * backspace byte by Marvell BootROM.
+ */
+ if (write(out, "\x08", 1) < 0)
+ return -1;
+ noff = i + 1;
+ *k = 0;
+ }
+ } else if (kbs) {
+ *k = 0;
+ }
}
- if (i == nin)
- nin -= *s;
+ if (i == nin) {
+ i = 0;
+ if (quit && i < *s)
+ i = *s;
+ if (kbs && i < *k)
+ i = *k;
+ nin -= (nin > i) ? i : nin;
+ }
}
- if (kwboot_write(out, buf, nin) < 0)
+ if (nin > noff && kwboot_write(out, buf + noff, nin - noff) < 0)
return -1;
return 0;
@@ -1220,7 +1494,8 @@
static int
kwboot_terminal(int tty)
{
- int rc, in, s;
+ int rc, in, s, k;
+ const char *kbs = NULL;
const char *quit = "\34c";
struct termios otio, tio;
@@ -1239,6 +1514,33 @@
goto out;
}
+ /*
+ * Get sequence for backspace key used by the current
+ * terminal. Every occurrence of this sequence will be
+ * replaced by '\b' byte which is the only recognized
+ * backspace byte by Marvell BootROM.
+ *
+ * Note that we cannot read this sequence from termios
+ * c_cc[VERASE] as VERASE is valid only when ICANON is
+ * set in termios c_lflag, which is not case for us.
+ *
+ * Also most terminals do not set termios c_cc[VERASE]
+ * as c_cc[VERASE] can specify only one-byte sequence
+ * and instead let applications to read (possible
+ * multi-byte) sequence for backspace key from "kbs"
+ * terminfo database based on $TERM env variable.
+ *
+ * So read "kbs" from terminfo database via tigetstr()
+ * call after successful setupterm(). Most terminals
+ * use byte 0x7F for backspace key, so replacement with
+ * '\b' is required.
+ */
+ if (setupterm(NULL, STDOUT_FILENO, &rc) == 0) {
+ kbs = tigetstr("kbs");
+ if (kbs == (char *)-1)
+ kbs = NULL;
+ }
+
kwboot_printv("[Type Ctrl-%c + %c to quit]\r\n",
quit[0] | 0100, quit[1]);
} else
@@ -1246,6 +1548,7 @@
rc = 0;
s = 0;
+ k = 0;
do {
fd_set rfds;
@@ -1265,13 +1568,13 @@
break;
if (FD_ISSET(tty, &rfds)) {
- rc = kwboot_term_pipe(tty, STDOUT_FILENO, NULL, NULL);
+ rc = kwboot_term_pipe(tty, STDOUT_FILENO, NULL, NULL, NULL, NULL);
if (rc)
break;
}
if (in >= 0 && FD_ISSET(in, &rfds)) {
- rc = kwboot_term_pipe(in, tty, quit, &s);
+ rc = kwboot_term_pipe(in, tty, quit, &s, kbs, &k);
if (rc)
break;
}
@@ -1708,16 +2011,16 @@
kwboot_usage(FILE *stream, char *progname)
{
fprintf(stream,
- "Usage: %s [OPTIONS] [-b <image> | -D <image> ] [-B <baud> ] <TTY>\n",
+ "Usage: %s [OPTIONS] [-b <image> | -D <image> | -b | -d ] [-B <baud> ] [-t] <TTY>\n",
progname);
fprintf(stream, "\n");
fprintf(stream,
- " -b <image>: boot <image> with preamble (Kirkwood, Armada 370/XP)\n");
+ " -b <image>: boot <image> with preamble (Kirkwood, Avanta, Armada 370/XP/375/38x/39x)\n");
fprintf(stream,
" -D <image>: boot <image> without preamble (Dove)\n");
- fprintf(stream, " -d: enter debug mode\n");
+ fprintf(stream, " -b: enter xmodem boot mode\n");
+ fprintf(stream, " -d: enter console debug mode\n");
fprintf(stream, " -a: use timings for Armada XP\n");
- fprintf(stream, " -q <req-delay>: use specific request-delay\n");
fprintf(stream, " -s <resp-timeo>: use specific response-timeout\n");
fprintf(stream,
" -o <block-timeo>: use specific xmodem block timeout\n");
@@ -1733,8 +2036,8 @@
{
const char *ttypath, *imgpath;
int rv, rc, tty, term;
- void *bootmsg;
- void *debugmsg;
+ int bootmsg;
+ int debugmsg;
void *img;
size_t size;
size_t after_img_rsv;
@@ -1744,8 +2047,8 @@
rv = 1;
tty = -1;
- bootmsg = NULL;
- debugmsg = NULL;
+ bootmsg = 0;
+ debugmsg = 0;
imgpath = NULL;
img = NULL;
term = 0;
@@ -1767,7 +2070,7 @@
case 'b':
if (imgpath || bootmsg || debugmsg)
goto usage;
- bootmsg = kwboot_msg_boot;
+ bootmsg = 1;
if (prev_optind == optind)
goto usage;
if (optind < argc - 1 && argv[optind] && argv[optind][0] != '-')
@@ -1777,14 +2080,14 @@
case 'D':
if (imgpath || bootmsg || debugmsg)
goto usage;
- bootmsg = NULL;
+ bootmsg = 0;
imgpath = optarg;
break;
case 'd':
if (imgpath || bootmsg || debugmsg)
goto usage;
- debugmsg = kwboot_msg_debug;
+ debugmsg = 1;
break;
case 'p':
@@ -1796,12 +2099,11 @@
break;
case 'a':
- msg_req_delay = KWBOOT_MSG_REQ_DELAY_AXP;
msg_rsp_timeo = KWBOOT_MSG_RSP_TIMEO_AXP;
break;
case 'q':
- msg_req_delay = atoi(optarg);
+ /* nop, for backward compatibility */
break;
case 's':
@@ -1866,17 +2168,13 @@
}
if (debugmsg) {
- rc = kwboot_debugmsg(tty, debugmsg);
- if (rc) {
- perror("debugmsg");
+ rc = kwboot_debugmsg(tty);
+ if (rc)
goto out;
- }
} else if (bootmsg) {
- rc = kwboot_bootmsg(tty, bootmsg);
- if (rc) {
- perror("bootmsg");
+ rc = kwboot_bootmsg(tty);
+ if (rc)
goto out;
- }
}
if (img) {
diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
index f7590e4..c118335 100644
--- a/tools/mkeficapsule.c
+++ b/tools/mkeficapsule.c
@@ -212,8 +212,6 @@
ret = read_bin_file(ctx->key_file, &key.data, &file_size);
if (ret < 0)
return -1;
- if (ret < 0)
- return -1;
if (file_size > UINT_MAX)
return -1;
key.size = file_size;
diff --git a/tools/mkimage.c b/tools/mkimage.c
index c8f4ecd..74bd072 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -82,8 +82,9 @@
static void usage(const char *msg)
{
fprintf(stderr, "Error: %s\n", msg);
- fprintf(stderr, "Usage: %s -l image\n"
- " -l ==> list image header information\n",
+ fprintf(stderr, "Usage: %s [-T type] -l image\n"
+ " -l ==> list image header information\n"
+ " -T ==> parse image file as 'type'\n",
params.cmdname);
fprintf(stderr,
" %s [-x] -A arch -O os -T type -C comp -a addr -e ep -n name -d data_file[:data_file...] image\n"
@@ -329,7 +330,7 @@
params.datafile = datafile;
else if (!params.datafile)
usage("Missing data file for auto-FIT (use -d)");
- } else if (type != IH_TYPE_INVALID) {
+ } else if (params.lflag || type != IH_TYPE_INVALID) {
if (type == IH_TYPE_SCRIPT && !params.datafile)
usage("Missing data file for script (use -d)");
params.type = type;
@@ -358,7 +359,7 @@
/* set tparams as per input type_id */
tparams = imagetool_get_type(params.type);
- if (tparams == NULL) {
+ if (tparams == NULL && !params.lflag) {
fprintf (stderr, "%s: unsupported type %s\n",
params.cmdname, genimg_get_type_name(params.type));
exit (EXIT_FAILURE);
@@ -368,18 +369,23 @@
* check the passed arguments parameters meets the requirements
* as per image type to be generated/listed
*/
- if (tparams->check_params)
+ if (tparams && tparams->check_params)
if (tparams->check_params (¶ms))
usage("Bad parameters for image type");
if (!params.eflag) {
params.ep = params.addr;
/* If XIP, entry point must be after the U-Boot header */
- if (params.xflag)
+ if (params.xflag && tparams)
params.ep += tparams->header_size;
}
if (params.fflag){
+ if (!tparams) {
+ fprintf(stderr, "%s: Missing FIT support\n",
+ params.cmdname);
+ exit (EXIT_FAILURE);
+ }
if (tparams->fflag_handle)
/*
* in some cases, some additional processing needs
@@ -390,7 +396,7 @@
retval = tparams->fflag_handle(¶ms);
if (retval != EXIT_SUCCESS)
- exit (retval);
+ usage("Bad parameters for FIT image type");
}
if (params.lflag || params.fflag) {
@@ -436,7 +442,7 @@
params.cmdname, params.imagefile);
exit (EXIT_FAILURE);
#endif
- } else if (sbuf.st_size < (off_t)tparams->header_size) {
+ } else if (tparams && sbuf.st_size < (off_t)tparams->header_size) {
fprintf (stderr,
"%s: Bad size: \"%s\" is not valid image: size %llu < %u\n",
params.cmdname, params.imagefile,
@@ -455,21 +461,12 @@
exit (EXIT_FAILURE);
}
- if (params.fflag) {
- /*
- * Verifies the header format based on the expected header for image
- * type in tparams
- */
- retval = imagetool_verify_print_header_by_type(ptr, &sbuf,
- tparams, ¶ms);
- } else {
- /**
- * When listing the image, we are not given the image type. Simply check all
- * image types to find one that matches our header
- */
- retval = imagetool_verify_print_header(ptr, &sbuf,
- tparams, ¶ms);
- }
+ /*
+ * Verifies the header format based on the expected header for image
+ * type in tparams. If tparams is NULL simply check all image types
+ * to find one that matches our header.
+ */
+ retval = imagetool_verify_print_header(ptr, &sbuf, tparams, ¶ms);
(void) munmap((void *)ptr, sbuf.st_size);
(void) close (ifd);
diff --git a/tools/pblimage.c b/tools/pblimage.c
index 3c823e9..bd639c2 100644
--- a/tools/pblimage.c
+++ b/tools/pblimage.c
@@ -230,19 +230,25 @@
struct image_tool_params *params)
{
struct pbl_header *pbl_hdr = (struct pbl_header *) ptr;
+ uint32_t rcwheader;
+
+ if (params->arch == IH_ARCH_ARM)
+ rcwheader = RCW_ARM_HEADER;
+ else
+ rcwheader = RCW_PPC_HEADER;
/* Only a few checks can be done: search for magic numbers */
if (ENDIANNESS == 'l') {
if (pbl_hdr->preamble != reverse_byte(RCW_PREAMBLE))
return -FDT_ERR_BADSTRUCTURE;
- if (pbl_hdr->rcwheader != reverse_byte(RCW_HEADER))
+ if (pbl_hdr->rcwheader != reverse_byte(rcwheader))
return -FDT_ERR_BADSTRUCTURE;
} else {
if (pbl_hdr->preamble != RCW_PREAMBLE)
return -FDT_ERR_BADSTRUCTURE;
- if (pbl_hdr->rcwheader != RCW_HEADER)
+ if (pbl_hdr->rcwheader != rcwheader)
return -FDT_ERR_BADSTRUCTURE;
}
return 0;
diff --git a/tools/pblimage.h b/tools/pblimage.h
index 81c5492..0222e80 100644
--- a/tools/pblimage.h
+++ b/tools/pblimage.h
@@ -8,7 +8,8 @@
#define RCW_BYTES 64
#define RCW_PREAMBLE 0xaa55aa55
-#define RCW_HEADER 0x010e0100
+#define RCW_ARM_HEADER 0x01ee0100
+#define RCW_PPC_HEADER 0x010e0100
struct pbl_header {
uint32_t preamble;