summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.mailmap23
-rw-r--r--MAINTAINERS15
-rw-r--r--Makefile4
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/cpu/arm926ejs/sunxi/fel_utils.S4
-rw-r--r--arch/arm/dts/armada-3720-turris-mox.dts7
-rw-r--r--arch/arm/dts/armada-37xx.dtsi2
-rw-r--r--arch/arm/dts/fsl-ls1028a-kontron-sl28-u-boot.dtsi128
-rw-r--r--arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi25
-rw-r--r--arch/arm/dts/sama7g5ek.dts25
-rw-r--r--arch/arm/include/asm/arch-sunxi/gpio.h1
-rw-r--r--arch/arm/include/asm/arch-sunxi/spl.h9
-rw-r--r--arch/arm/mach-k3/am6_init.c3
-rw-r--r--arch/arm/mach-mvebu/armada3700/cpu.c81
-rw-r--r--arch/arm/mach-sunxi/Kconfig5
-rw-r--r--arch/arm/mach-sunxi/board.c64
-rw-r--r--arch/arm/mach-sunxi/spl_spi_sunxi.c24
-rw-r--r--arch/x86/include/asm/intel_gnvs.h8
-rw-r--r--board/advantech/som-db5800-som-6867/.gitignore6
-rw-r--r--board/alliedtelesis/x530/x530.c1
-rw-r--r--board/congatec/conga-qeval20-qa3-e3845/.gitignore6
-rw-r--r--board/coreboot/coreboot/MAINTAINERS4
-rw-r--r--board/intel/bayleybay/.gitignore6
-rw-r--r--board/intel/edison/.gitignore6
-rw-r--r--board/intel/galileo/.gitignore6
-rw-r--r--board/intel/minnowmax/.gitignore6
-rw-r--r--board/kontron/sl28/sl28.c59
-rw-r--r--board/solidrun/clearfog/clearfog.c1
-rw-r--r--board/sunxi/board.c51
-rw-r--r--board/ti/am65x/evm.c26
-rw-r--r--board/ti/j721e/evm.c28
-rw-r--r--cmd/cls.c10
-rw-r--r--cmd/pwm.c2
-rw-r--r--configs/j721e_evm_a72_defconfig1
-rw-r--r--configs/j721e_hs_evm_a72_defconfig1
-rw-r--r--configs/kontron_sl28_defconfig13
-rw-r--r--configs/libretech_all_h3_it_h5_defconfig2
-rw-r--r--configs/libretech_all_h5_cc_h5_defconfig2
-rw-r--r--configs/licheepi_nano_defconfig2
-rw-r--r--configs/oceanic_5205_5inmfd_defconfig1
-rw-r--r--configs/orangepi_pc2_defconfig2
-rw-r--r--configs/orangepi_r1_defconfig2
-rw-r--r--configs/orangepi_win_defconfig2
-rw-r--r--configs/orangepi_zero2_defconfig2
-rw-r--r--configs/orangepi_zero_defconfig2
-rw-r--r--configs/pine64-lts_defconfig2
-rw-r--r--configs/pine_h64_defconfig2
-rw-r--r--configs/pinecube_defconfig2
-rw-r--r--configs/sopine_baseboard_defconfig1
-rw-r--r--configs/tbs2910_defconfig1
-rw-r--r--configs/turris_omnia_defconfig1
-rw-r--r--configs/vexpress_aemv8a_semi_defconfig2
-rw-r--r--doc/board/kontron/sl28.rst66
-rw-r--r--doc/board/sifive/unmatched.rst2
-rw-r--r--doc/build/gcc.rst11
-rw-r--r--doc/kwboot.1105
-rw-r--r--drivers/gpio/Kconfig6
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/sl28cpld-gpio.c165
-rw-r--r--drivers/misc/Kconfig8
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/sl28cpld.c105
-rw-r--r--drivers/mmc/rockchip_sdhci.c76
-rw-r--r--drivers/mtd/spi/spi-nor-ids.c2
-rw-r--r--drivers/pci/pci_mvebu.c133
-rw-r--r--drivers/phy/cadence/phy-cadence-sierra.c59
-rw-r--r--drivers/phy/nop-phy.c12
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-37xx.c6
-rw-r--r--drivers/rtc/armada38x.c2
-rw-r--r--drivers/serial/serial-uclass.c3
-rw-r--r--drivers/spi/Kconfig6
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/cadence_qspi.c14
-rw-r--r--drivers/spi/cadence_qspi.h2
-rw-r--r--drivers/spi/designware_spi.c2
-rw-r--r--drivers/spi/iproc_qspi.c576
-rw-r--r--drivers/watchdog/Kconfig7
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/armada-37xx-wdt.c17
-rw-r--r--drivers/watchdog/rti_wdt.c14
-rw-r--r--drivers/watchdog/sl28cpld-wdt.c109
-rw-r--r--drivers/watchdog/wdt-uclass.c7
-rw-r--r--env/Kconfig7
-rw-r--r--include/configs/lx2160a_common.h34
-rw-r--r--include/configs/ti_armv7_common.h2
-rw-r--r--include/efi_loader.h2
-rw-r--r--include/sl28cpld.h16
-rw-r--r--lib/efi_loader/efi_boottime.c14
-rw-r--r--lib/efi_loader/efi_image_loader.c2
-rw-r--r--lib/rsa/rsa-sign.c8
-rw-r--r--tools/Makefile3
-rw-r--r--tools/kwboot.c500
-rw-r--r--tools/mkimage.c7
-rw-r--r--tools/pblimage.c10
-rw-r--r--tools/pblimage.h3
95 files changed, 2237 insertions, 581 deletions
diff --git a/.mailmap b/.mailmap
index b36ae66719..1f88ea953c 100644
--- a/.mailmap
+++ b/.mailmap
@@ -22,11 +22,13 @@ Andreas Bießmann <andreas@biessmann.org>
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 @@ Jagan Teki <jagannadha.sutradharudu-teki@xilinx.com>
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 @@ Ricardo Ribalda <ricardo@ribalda.com> <ricardo.ribalda@gmail.com>
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 7012cc2b86..5011a54e61 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1171,6 +1171,13 @@ S: Maintained
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
@@ -1329,6 +1336,14 @@ F: include/virtio*.h
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 9ef34ca4b7..06572ac07e 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
VERSION = 2022
PATCHLEVEL = 04
SUBLEVEL =
-EXTRAVERSION = -rc3
+EXTRAVERSION = -rc4
NAME =
# *DOCUMENTATION*
@@ -1412,7 +1412,7 @@ MKIMAGEFLAGS_u-boot-spl.kwb = -n $(KWD_CONFIG_FILE) \
$(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
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 403156bec9..474ce4a555 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1075,6 +1075,8 @@ config ARCH_SUNXI
select DM_ETH
select DM_GPIO
select DM_I2C if I2C
+ select DM_SPI if SPI
+ select DM_SPI_FLASH if SPI
select DM_KEYBOARD
select DM_MMC if MMC
select DM_SCSI if SCSI
diff --git a/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S b/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S
index 08be7ed11a..25924033c6 100644
--- a/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S
+++ b/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S
@@ -25,9 +25,9 @@ ENTRY(return_to_fel)
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/armada-3720-turris-mox.dts b/arch/arm/dts/armada-3720-turris-mox.dts
index 1fc4a30d03..595b4b5abb 100644
--- a/arch/arm/dts/armada-3720-turris-mox.dts
+++ b/arch/arm/dts/armada-3720-turris-mox.dts
@@ -139,7 +139,9 @@
/*
* U-Boot port for Turris Mox has a bug which always expects that "ranges" DT property
* contains exactly 2 ranges with 3 (child) address cells, 2 (parent) address cells and
- * 2 size cells and also expects that the second range starts at 16 MB offset. If these
+ * 2 size cells and also expects that the second range starts at 16 MB offset. Also it
+ * expects that first range uses same address for PCI (child) and CPU (parent) cells (so
+ * no remapping) and that this address is the lowest from all specified ranges. If these
* conditions are not met then U-Boot crashes during loading kernel DTB file. PCIe address
* space is 128 MB long, so the best split between MEM and IO is to use fixed 16 MB window
* for IO and the rest 112 MB (64+32+16) for MEM. Controller supports 32-bit IO mapping.
@@ -148,6 +150,9 @@
* https://source.denx.de/u-boot/u-boot/-/commit/cb2ddb291ee6fcbddd6d8f4ff49089dfe580f5d7
* https://source.denx.de/u-boot/u-boot/-/commit/c64ac3b3185aeb3846297ad7391fc6df8ecd73bf
* https://source.denx.de/u-boot/u-boot/-/commit/4a82fca8e330157081fc132a591ebd99ba02ee33
+ * Bug related to requirement of same child and parent addresses for first range is fixed
+ * in U-Boot version 2022.04 by following commit:
+ * https://source.denx.de/u-boot/u-boot/-/commit/1fd54253bca7d43d046bba4853fe5fafd034bc17
*/
#address-cells = <3>;
#size-cells = <2>;
diff --git a/arch/arm/dts/armada-37xx.dtsi b/arch/arm/dts/armada-37xx.dtsi
index 9fa6457fac..0bb4f60763 100644
--- a/arch/arm/dts/armada-37xx.dtsi
+++ b/arch/arm/dts/armada-37xx.dtsi
@@ -499,7 +499,7 @@
* (totaling 127 MiB) for MEM.
*/
ranges = <0x82000000 0 0xe8000000 0 0xe8000000 0 0x07f00000 /* Port 0 MEM */
- 0x81000000 0 0xeff00000 0 0xeff00000 0 0x00100000>; /* Port 0 IO*/
+ 0x81000000 0 0x00000000 0 0xeff00000 0 0x00100000>; /* Port 0 IO */
interrupt-map-mask = <0 0 0 7>;
interrupt-map = <0 0 0 1 &pcie_intc 0>,
<0 0 0 2 &pcie_intc 1>,
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 d4b833284e..2dcb3c2a58 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";
-
- conf-1 {
- description = "fsl-ls1028a-kontron-sl28";
- 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";
- };
+ default = "@config-DEFAULT-SEQ";
- conf-5 {
- description = "fsl-ls1028a-kontron-sl28-var4";
+ @config-SEQ {
+ description = "NAME";
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 286e25f379..d80c5501d2 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 6adb044258..ac6f23f64e 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 7f7eb0517c..edd0fbf49f 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -160,6 +160,7 @@ enum sunxi_gpio_number {
#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 58cdf806d9..b543d24e5a 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-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c
index ffb7aaded2..8a6b1de764 100644
--- a/arch/arm/mach-k3/am6_init.c
+++ b/arch/arm/mach-k3/am6_init.c
@@ -251,7 +251,8 @@ void board_init_f(ulong dummy)
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 23492f49da..52b5109b73 100644
--- a/arch/arm/mach-mvebu/armada3700/cpu.c
+++ b/arch/arm/mach-mvebu/armada3700/cpu.c
@@ -316,8 +316,8 @@ static int fdt_setprop_inplace_u32_partial(void *blob, int node,
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 @@ int a3700_fdt_fix_pcie_regions(void *blob)
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;
+
+ /* CPU addresses on Armada 37xx always use 2 cells */
+ if (cpu_cells != 2)
+ return -EINVAL;
+
+ 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 first child address (in last cell) */
- fix_offset = base - fdt32_to_cpu(ranges[2]);
+ /* Calculate fixup offset from the lowest (first) CPU address */
+ fix_offset = base - lowest_cpu_addr;
- /* If fixup offset is zero then there is nothing to fix */
+ /* 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 205fe3c9d3..73da6b8f61 100644
--- a/arch/arm/mach-sunxi/Kconfig
+++ b/arch/arm/mach-sunxi/Kconfig
@@ -332,9 +332,6 @@ config MACH_SUN9I
config MACH_SUN50I
bool "sun50i (Allwinner A64)"
select ARM64
- select SPI
- select DM_SPI if SPI
- select DM_SPI_FLASH
select PHY_SUN4I_USB
select SUN6I_PRCM
select SUNXI_DE2
@@ -1038,7 +1035,7 @@ config SPL_STACK_R_ADDR
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 57078f7a7b..0071de19ff 100644
--- a/arch/arm/mach-sunxi/board.c
+++ b/arch/arm/mach-sunxi/board.c
@@ -191,12 +191,48 @@ SPL_LOAD_IMAGE_METHOD("FEL", 0, BOOT_DEVICE_BOARD, spl_board_load_image);
#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 @@ unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
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 910e805016..734c165e5d 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 @@ static uintptr_t spi0_base_address(void)
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 @@ static void spi0_enable_clock(void)
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 @@ static void spi0_disable_clock(void)
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 @@ static void spi0_init(void)
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/arch/x86/include/asm/intel_gnvs.h b/arch/x86/include/asm/intel_gnvs.h
index fc743dc928..0b69530edb 100644
--- a/arch/x86/include/asm/intel_gnvs.h
+++ b/arch/x86/include/asm/intel_gnvs.h
@@ -47,7 +47,13 @@ enum {
BINF_RW_B = 2
};
-enum {
+/**
+ * enum cros_fw_type_t - Used to indicate Chromium OS firmware type
+ *
+ * Chromium OS uses a region of the GNVS starting at offset 0x100 to store
+ * various bits of information, including the type of firmware being booted
+ */
+enum cros_fw_type_t {
FIRMWARE_TYPE_AUTO_DETECT = -1,
FIRMWARE_TYPE_RECOVERY = 0,
FIRMWARE_TYPE_NORMAL = 1,
diff --git a/board/advantech/som-db5800-som-6867/.gitignore b/board/advantech/som-db5800-som-6867/.gitignore
index 6eb8a5481a..39e46ba0ae 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/alliedtelesis/x530/x530.c b/board/alliedtelesis/x530/x530.c
index 8b31045a07..c0ec2afa30 100644
--- a/board/alliedtelesis/x530/x530.c
+++ b/board/alliedtelesis/x530/x530.c
@@ -73,6 +73,7 @@ static struct mv_ddr_topology_map board_topology_map = {
{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 6eb8a5481a..39e46ba0ae 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/coreboot/coreboot/MAINTAINERS b/board/coreboot/coreboot/MAINTAINERS
index a05673bb0b..ee12d32ce7 100644
--- a/board/coreboot/coreboot/MAINTAINERS
+++ b/board/coreboot/coreboot/MAINTAINERS
@@ -2,12 +2,12 @@ COREBOOT BOARD
M: Simon Glass <sjg@chromium.org>
S: Maintained
F: board/coreboot/coreboot/
-F: include/configs/chromebook_link.h
+F: include/configs/coreboot.h
F: configs/coreboot_defconfig
COREBOOT64 BOARD
M: Simon Glass <sjg@chromium.org>
S: Maintained
F: board/coreboot/coreboot/
-F: include/configs/chromebook_link.h
+F: include/configs/coreboot.h
F: configs/coreboot64_defconfig
diff --git a/board/intel/bayleybay/.gitignore b/board/intel/bayleybay/.gitignore
index 6eb8a5481a..39e46ba0ae 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/edison/.gitignore b/board/intel/edison/.gitignore
index 6eb8a5481a..39e46ba0ae 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/galileo/.gitignore b/board/intel/galileo/.gitignore
index 6eb8a5481a..39e46ba0ae 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/minnowmax/.gitignore b/board/intel/minnowmax/.gitignore
index 6eb8a5481a..39e46ba0ae 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/kontron/sl28/sl28.c b/board/kontron/sl28/sl28.c
index e84b356918..3c48a9141d 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 @@ int board_eth_init(struct bd_info *bis)
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 c920cf8d6b..03adb591d8 100644
--- a/board/solidrun/clearfog/clearfog.c
+++ b/board/solidrun/clearfog/clearfog.c
@@ -147,6 +147,7 @@ static struct mv_ddr_topology_map board_topology_map = {
{0}, /* timing parameters */
{ {0} }, /* electrical configuration */
{0,}, /* electrical parameters */
+ 0, /* ODT configuration */
0x3, /* clock enable mask */
};
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 82c52b28f8..a096159047 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -171,21 +171,56 @@ void i2c_init_board(void)
#endif
}
-#if defined(CONFIG_ENV_IS_IN_MMC) && defined(CONFIG_ENV_IS_IN_FAT)
+/*
+ * Try to use the environment from the boot source first.
+ * For MMC, this means a FAT partition on the boot device (SD or eMMC).
+ * If the raw MMC environment is also enabled, this is tried next.
+ * SPI flash falls back to FAT (on SD card).
+ */
enum env_location env_get_location(enum env_operation op, int prio)
{
- switch (prio) {
- case 0:
- return ENVL_FAT;
+ enum env_location boot_loc = ENVL_FAT;
- case 1:
- return ENVL_MMC;
+ gd->env_load_prio = prio;
+ switch (sunxi_get_boot_device()) {
+ case BOOT_DEVICE_MMC1:
+ case BOOT_DEVICE_MMC2:
+ boot_loc = ENVL_FAT;
+ break;
+ case BOOT_DEVICE_NAND:
+ if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND))
+ boot_loc = ENVL_NAND;
+ break;
+ case BOOT_DEVICE_SPI:
+ if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
+ boot_loc = ENVL_SPI_FLASH;
+ break;
+ case BOOT_DEVICE_BOARD:
+ break;
default:
- return ENVL_UNKNOWN;
+ break;
+ }
+
+ /* Always try to access the environment on the boot device first. */
+ if (prio == 0)
+ return boot_loc;
+
+ if (prio == 1) {
+ switch (boot_loc) {
+ case ENVL_SPI_FLASH:
+ return ENVL_FAT;
+ case ENVL_FAT:
+ if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC))
+ return ENVL_MMC;
+ break;
+ default:
+ break;
+ }
}
+
+ return ENVL_UNKNOWN;
}
-#endif
#ifdef CONFIG_DM_MMC
static void mmc_pinmux_setup(int sdc);
diff --git a/board/ti/am65x/evm.c b/board/ti/am65x/evm.c
index fbe33cbea5..7182a8cad1 100644
--- a/board/ti/am65x/evm.c
+++ b/board/ti/am65x/evm.c
@@ -129,6 +129,7 @@ int ft_board_setup(void *blob, struct bd_info *bd)
}
#endif
+#ifdef CONFIG_TI_I2C_BOARD_DETECT
int do_board_detect(void)
{
int ret;
@@ -353,23 +354,26 @@ static int probe_daughtercards(void)
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/board/ti/j721e/evm.c b/board/ti/j721e/evm.c
index f479197e72..e6ff54c065 100644
--- a/board/ti/j721e/evm.c
+++ b/board/ti/j721e/evm.c
@@ -397,36 +397,34 @@ void configure_serdes_torrent(void)
void configure_serdes_sierra(void)
{
- struct udevice *dev, *lnk_dev;
- struct phy serdes;
+ struct udevice *dev, *link_dev;
+ struct phy link;
int ret, count, i;
+ int link_count = 0;
if (!IS_ENABLED(CONFIG_PHY_CADENCE_SIERRA))
return;
- ret = uclass_get_device_by_driver(UCLASS_PHY,
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
DM_DRIVER_GET(sierra_phy_provider),
&dev);
if (ret)
printf("Sierra init failed:%d\n", ret);
- serdes.dev = dev;
- serdes.id = 0;
-
count = device_get_child_count(dev);
for (i = 0; i < count; i++) {
- ret = device_get_child(dev, i, &lnk_dev);
+ ret = device_get_child(dev, i, &link_dev);
if (ret)
printf("probe of sierra child node %d failed\n", i);
- }
+ if (link_dev->driver->id == UCLASS_PHY) {
+ link.dev = link_dev;
+ link.id = link_count++;
- ret = generic_phy_init(&serdes);
- if (ret)
- printf("phy_init failed!!\n");
-
- ret = generic_phy_power_on(&serdes);
- if (ret)
- printf("phy_power_on failed !!\n");
+ ret = generic_phy_power_on(&link);
+ if (ret)
+ printf("phy_power_on failed !!\n");
+ }
+ }
}
#ifdef CONFIG_BOARD_LATE_INIT
diff --git a/cmd/cls.c b/cmd/cls.c
index eab4e6993b..bdeb49786d 100644
--- a/cmd/cls.c
+++ b/cmd/cls.c
@@ -11,17 +11,23 @@
#include <lcd.h>
#include <video.h>
+#define CSI "\x1b["
+
static int do_video_clear(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
-#if defined(CONFIG_DM_VIDEO)
- struct udevice *dev;
+ __maybe_unused struct udevice *dev;
+ /* Send clear screen and home */
+ printf(CSI "2J" CSI "1;1H");
+#if defined(CONFIG_DM_VIDEO)
+#if !defined(CONFIG_VIDEO_ANSI)
if (uclass_first_device_err(UCLASS_VIDEO, &dev))
return CMD_RET_FAILURE;
if (video_clear(dev))
return CMD_RET_FAILURE;
+#endif
#elif defined(CONFIG_CFB_CONSOLE)
video_clear();
#elif defined(CONFIG_LCD)
diff --git a/cmd/pwm.c b/cmd/pwm.c
index 7947e61aee..7e82955239 100644
--- a/cmd/pwm.c
+++ b/cmd/pwm.c
@@ -111,5 +111,5 @@ U_BOOT_CMD(pwm, 6, 0, do_pwm,
"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/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig
index 7929e22269..d5181954a8 100644
--- a/configs/j721e_evm_a72_defconfig
+++ b/configs/j721e_evm_a72_defconfig
@@ -193,3 +193,4 @@ CONFIG_UFS=y
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 c37c20a91b..6850b99603 100644
--- a/configs/j721e_hs_evm_a72_defconfig
+++ b/configs/j721e_hs_evm_a72_defconfig
@@ -162,3 +162,4 @@ CONFIG_UFS=y
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 b61276cf1d..cf8aedfdfd 100644
--- a/configs/kontron_sl28_defconfig
+++ b/configs/kontron_sl28_defconfig
@@ -42,23 +42,23 @@ CONFIG_CMD_GREPENV=y
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_DDR_ECC=y
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=y
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/libretech_all_h3_it_h5_defconfig b/configs/libretech_all_h3_it_h5_defconfig
index 7f0e0be50b..cb7ffb4d7d 100644
--- a/configs/libretech_all_h3_it_h5_defconfig
+++ b/configs/libretech_all_h3_it_h5_defconfig
@@ -7,9 +7,7 @@ CONFIG_DRAM_CLK=672
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_SPL_SPI_SUNXI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH_XMC=y
CONFIG_SPI=y
-CONFIG_DM_SPI=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
diff --git a/configs/libretech_all_h5_cc_h5_defconfig b/configs/libretech_all_h5_cc_h5_defconfig
index 25bfe52b32..c3aa4b1061 100644
--- a/configs/libretech_all_h5_cc_h5_defconfig
+++ b/configs/libretech_all_h5_cc_h5_defconfig
@@ -7,10 +7,8 @@ CONFIG_DRAM_CLK=672
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_SPL_SPI_SUNXI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
-CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH_XMC=y
CONFIG_SUN8I_EMAC=y
CONFIG_SPI=y
-CONFIG_DM_SPI=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
diff --git a/configs/licheepi_nano_defconfig b/configs/licheepi_nano_defconfig
index 2ac0ef4285..67b7b85c49 100644
--- a/configs/licheepi_nano_defconfig
+++ b/configs/licheepi_nano_defconfig
@@ -9,3 +9,5 @@ CONFIG_MACH_SUNIV=y
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/oceanic_5205_5inmfd_defconfig b/configs/oceanic_5205_5inmfd_defconfig
index 9ba115c97d..7ce63ba665 100644
--- a/configs/oceanic_5205_5inmfd_defconfig
+++ b/configs/oceanic_5205_5inmfd_defconfig
@@ -11,5 +11,6 @@ CONFIG_MMC0_CD_PIN=""
CONFIG_SPL_SPI_SUNXI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SUN8I_EMAC=y
+CONFIG_SPI=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
diff --git a/configs/orangepi_pc2_defconfig b/configs/orangepi_pc2_defconfig
index 2eaddcf684..777af8c60e 100644
--- a/configs/orangepi_pc2_defconfig
+++ b/configs/orangepi_pc2_defconfig
@@ -11,9 +11,11 @@ CONFIG_SPL_SPI_SUNXI=y
CONFIG_SPL_I2C=y
CONFIG_SPL_SYS_I2C_LEGACY=y
CONFIG_SYS_I2C_MVTWSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SUN8I_EMAC=y
CONFIG_SY8106A_POWER=y
CONFIG_SY8106A_VOUT1_VOLT=1100
+CONFIG_SPI=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_MUSB_GADGET=y
diff --git a/configs/orangepi_r1_defconfig b/configs/orangepi_r1_defconfig
index 745451c4bf..4496aa4a45 100644
--- a/configs/orangepi_r1_defconfig
+++ b/configs/orangepi_r1_defconfig
@@ -8,6 +8,8 @@ CONFIG_DRAM_CLK=624
CONFIG_SPL_SPI_SUNXI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_CONSOLE_MUX=y
+CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SUN8I_EMAC=y
+CONFIG_SPI=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
diff --git a/configs/orangepi_win_defconfig b/configs/orangepi_win_defconfig
index 8c2179ba8b..3b78ad7e52 100644
--- a/configs/orangepi_win_defconfig
+++ b/configs/orangepi_win_defconfig
@@ -7,7 +7,9 @@ CONFIG_RESERVE_ALLWINNER_BOOT0_HEADER=y
CONFIG_MACPWR="PD14"
CONFIG_SPL_SPI_SUNXI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPI_FLASH_WINBOND=y
CONFIG_PHY_REALTEK=y
CONFIG_SUN8I_EMAC=y
+CONFIG_SPI=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
diff --git a/configs/orangepi_zero2_defconfig b/configs/orangepi_zero2_defconfig
index 22563c864f..54faf6aba2 100644
--- a/configs/orangepi_zero2_defconfig
+++ b/configs/orangepi_zero2_defconfig
@@ -15,5 +15,7 @@ CONFIG_SPL_SYS_I2C_LEGACY=y
CONFIG_SYS_I2C_MVTWSI=y
CONFIG_SYS_I2C_SLAVE=0x7f
CONFIG_SYS_I2C_SPEED=400000
+CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_PHY_REALTEK=y
CONFIG_SUN8I_EMAC=y
+CONFIG_SPI=y
diff --git a/configs/orangepi_zero_defconfig b/configs/orangepi_zero_defconfig
index 332cd4739e..2dc69d2994 100644
--- a/configs/orangepi_zero_defconfig
+++ b/configs/orangepi_zero_defconfig
@@ -8,6 +8,8 @@ CONFIG_DRAM_CLK=624
CONFIG_SPL_SPI_SUNXI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_CONSOLE_MUX=y
+CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SUN8I_EMAC=y
+CONFIG_SPI=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
diff --git a/configs/pine64-lts_defconfig b/configs/pine64-lts_defconfig
index 6209e68e2d..45a9e77e0e 100644
--- a/configs/pine64-lts_defconfig
+++ b/configs/pine64-lts_defconfig
@@ -10,6 +10,8 @@ CONFIG_MMC0_CD_PIN=""
CONFIG_MMC_SUNXI_SLOT_EXTRA=2
CONFIG_SPL_SPI_SUNXI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SUN8I_EMAC=y
+CONFIG_SPI=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
diff --git a/configs/pine_h64_defconfig b/configs/pine_h64_defconfig
index 1928509dd7..1e730dd9fa 100644
--- a/configs/pine_h64_defconfig
+++ b/configs/pine_h64_defconfig
@@ -11,8 +11,10 @@ CONFIG_USB3_VBUS_PIN="PL5"
CONFIG_SPL_SPI_SUNXI=y
# CONFIG_PSCI_RESET is not set
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SUN8I_EMAC=y
CONFIG_PHY_SUN50I_USB3=y
+CONFIG_SPI=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_EHCI_HCD=y
diff --git a/configs/pinecube_defconfig b/configs/pinecube_defconfig
index 0c71d59418..e779663a0d 100644
--- a/configs/pinecube_defconfig
+++ b/configs/pinecube_defconfig
@@ -12,8 +12,10 @@ CONFIG_SPL_SYS_I2C_LEGACY=y
CONFIG_SYS_I2C_MVTWSI=y
CONFIG_SYS_I2C_SLAVE=0x7f
CONFIG_SYS_I2C_SPEED=400000
+CONFIG_SPI_FLASH_WINBOND=y
# CONFIG_NETDEVICES is not set
CONFIG_AXP209_POWER=y
CONFIG_AXP_DCDC2_VOLT=1250
CONFIG_AXP_DCDC3_VOLT=3300
CONFIG_CONS_INDEX=3
+CONFIG_SPI=y
diff --git a/configs/sopine_baseboard_defconfig b/configs/sopine_baseboard_defconfig
index 0093076dc5..982f7b0b67 100644
--- a/configs/sopine_baseboard_defconfig
+++ b/configs/sopine_baseboard_defconfig
@@ -13,5 +13,6 @@ CONFIG_SPL_SPI_SUNXI=y
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SUN8I_EMAC=y
+CONFIG_SPI=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_OHCI_HCD=y
diff --git a/configs/tbs2910_defconfig b/configs/tbs2910_defconfig
index e1278f2e70..8a33160564 100644
--- a/configs/tbs2910_defconfig
+++ b/configs/tbs2910_defconfig
@@ -14,6 +14,7 @@ CONFIG_DEFAULT_DEVICE_TREE="imx6q-tbs2910"
CONFIG_PRE_CON_BUF_ADDR=0x7c000000
CONFIG_CMD_HDMIDETECT=y
CONFIG_AHCI=y
+CONFIG_LTO=y
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_BOOTDELAY=3
CONFIG_USE_BOOTCOMMAND=y
diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig
index 280dd55f00..5b1fdbfb2d 100644
--- a/configs/turris_omnia_defconfig
+++ b/configs/turris_omnia_defconfig
@@ -93,3 +93,4 @@ CONFIG_USB_XHCI_HCD=y
CONFIG_USB_EHCI_HCD=y
CONFIG_WDT=y
CONFIG_WDT_ORION=y
+CONFIG_EXT4_WRITE=y
diff --git a/configs/vexpress_aemv8a_semi_defconfig b/configs/vexpress_aemv8a_semi_defconfig
index d55e560189..50715e27fc 100644
--- a/configs/vexpress_aemv8a_semi_defconfig
+++ b/configs/vexpress_aemv8a_semi_defconfig
@@ -17,7 +17,7 @@ CONFIG_ANDROID_BOOT_IMAGE=y
CONFIG_BOOTDELAY=1
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAMA0 earlycon=pl011,0x1c090000 debug user_debug=31 loglevel=9"
-CONFIG_BOOTCOMMAND="if smhload ${boot_name} ${boot_addr_r}; then set bootargs; abootimg addr ${boot_addr_r}; abootimg get dtb --index=0 fdt_addr_r; bootm ${boot_addr_r} ${boot_addr_r} ${fdt_addr_r}; else; set fdt_high 0xffffffffffffffff; set initrd_high 0xffffffffffffffff; smhload ${kernel_name} ${kernel_addr}; smhload ${fdtfile} ${fdt_addr_r}; smhload ${ramdisk_name} ${ramdisk_addr_r} ramdisk_end; fdt addr ${fdt_addr_r}; fdt resize; fdt chosen ${ramdisk_addr_r} ${ramdisk_end}; booti $kernel_addr - $fdt_addr_r; fi"
+CONFIG_BOOTCOMMAND="if smhload ${boot_name} ${boot_addr_r}; then setenv bootargs; abootimg addr ${boot_addr_r}; abootimg get dtb --index=0 fdt_addr_r; bootm ${boot_addr_r} ${boot_addr_r} ${fdt_addr_r}; else; setenv fdt_high 0xffffffffffffffff; setenv initrd_high 0xffffffffffffffff; smhload ${kernel_name} ${kernel_addr_r}; smhload ${fdtfile} ${fdt_addr_r}; smhload ${ramdisk_name} ${ramdisk_addr_r} ramdisk_end; fdt addr ${fdt_addr_r}; fdt resize; fdt chosen ${ramdisk_addr_r} ${ramdisk_end}; booti $kernel_addr_r - $fdt_addr_r; fi"
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_SYS_PROMPT="VExpress64# "
diff --git a/doc/board/kontron/sl28.rst b/doc/board/kontron/sl28.rst
index c7b18bed10..44435d90c6 100644
--- a/doc/board/kontron/sl28.rst
+++ b/doc/board/kontron/sl28.rst
@@ -23,34 +23,17 @@ Copy u-boot.rom to a TFTP server.
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 @@ Afterward you can copy this file to your ESP into the /EFI/UpdateCapsule/
folder. On the next EFI boot this will automatically update your
bootloader.
-Useful I2C tricks
------------------
+Builtin watchdog
+----------------
+
+The builtin watchdog will supervise the bootloader startup. If anything
+goes wrong it will reset the board and boot into the failsafe bootloader.
+
+Once the bootloader is started successfully, it will disable the watchdog
+timer.
-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.
+wdt command flags
+^^^^^^^^^^^^^^^^^
-- reset into failsafe bootloader::
+The `wdt start` as well as the `wdt expire` command take a flags argument.
+The supported bitmask is as follows.
- > i2c mw 4a 5.1 0; i2c mw 4a 6.1 6b; i2c mw 4a 4.1 42
+| Bit | Description |
+| --- | ----------------------------- |
+| 0 | Enable failsafe mode |
+| 1 | Lock the control register |
+| 2 | Disable board reset |
+| 3 | Enable WDT_TIME_OUT# line |
-- read board management controller version::
+For example, you can use `wdt expire 1` to issue a reset and boot into the
+failsafe bootloader.
+
+Disable the builtin watchdog
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- > i2c md 4a 3.1 1
+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/board/sifive/unmatched.rst b/doc/board/sifive/unmatched.rst
index 24a889991c..a99442277b 100644
--- a/doc/board/sifive/unmatched.rst
+++ b/doc/board/sifive/unmatched.rst
@@ -560,7 +560,7 @@ Write U-boot SPL and U-boot to their partitions.
.. code-block:: none
- dd if=u-boot-spl.bin of=/dev/mtdblock0 bs=4096 seek=5 conv=sync
+ dd if=spl/u-boot-spl.bin of=/dev/mtdblock0 bs=4096 seek=5 conv=sync
dd if=u-boot.itb of=/dev/mtdblock0 bs=4096 seek=261 conv=sync
Power off the board.
diff --git a/doc/build/gcc.rst b/doc/build/gcc.rst
index b883cf73ee..470a7aa349 100644
--- a/doc/build/gcc.rst
+++ b/doc/build/gcc.rst
@@ -25,11 +25,12 @@ Depending on the build targets further packages maybe needed
sudo apt-get install bc bison build-essential coccinelle \
device-tree-compiler dfu-util efitools flex gdisk graphviz imagemagick \
- liblz4-tool libguestfs-tools libncurses-dev libpython3-dev libsdl2-dev \
- libssl-dev lz4 lzma lzma-alone openssl pkg-config python3 \
- python3-coverage python3-pkg-resources python3-pycryptodome \
- python3-pyelftools python3-pytest python3-sphinxcontrib.apidoc \
- python3-sphinx-rtd-theme python3-virtualenv swig
+ liblz4-tool libgnutls28-dev libguestfs-tools libncurses-dev \
+ libpython3-dev libsdl2-dev libssl-dev lz4 lzma lzma-alone openssl \
+ pkg-config python3 python3-coverage python3-pkg-resources \
+ python3-pycryptodome python3-pyelftools python3-pytest \
+ python3-sphinxcontrib.apidoc python3-sphinx-rtd-theme python3-virtualenv \
+ swig
SUSE based
~~~~~~~~~~
diff --git a/doc/kwboot.1 b/doc/kwboot.1
index acdea891d9..f555ff26a2 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 @@ kwboot \- Boot Marvell Kirkwood (and others 32-bit) SoCs over a serial link.
.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 @@ example U-Boot SPL does this). In such a case, this output is also
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 @@ in the image prior upload, to "UART boot" type. This is now done by
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 @@ Tested values for \fIbaudrate\fP for Armada 38x include: 115200,
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/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index be64303d7f..12972cdb4e 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -552,4 +552,10 @@ config ZYNQMP_GPIO_MODEPIN
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 720297952c..44f015397f 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -71,4 +71,5 @@ obj-$(CONFIG_NX_GPIO) += nx_gpio.o
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 0000000000..700fc3df29
--- /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 0ade3e32b0..7029bb7b5c 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -512,4 +512,12 @@ config ESM_PMIC
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 bca7b24e99..f22eff601a 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -82,3 +82,4 @@ obj-$(CONFIG_MICROCHIP_FLEXCOM) += microchip_flexcom.o
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 0000000000..01ef1c6178
--- /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/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c
index 278473899c..b91df05de4 100644
--- a/drivers/mmc/rockchip_sdhci.c
+++ b/drivers/mmc/rockchip_sdhci.c
@@ -90,9 +90,33 @@ struct rockchip_sdhc {
};
struct sdhci_data {
- int (*emmc_set_clock)(struct sdhci_host *host, unsigned int clock);
int (*emmc_phy_init)(struct udevice *dev);
int (*get_phy)(struct udevice *dev);
+
+ /**
+ * set_control_reg() - Set SDHCI control registers
+ *
+ * This is the set_control_reg() SDHCI operation that should be
+ * used for the hardware this driver data is associated with.
+ * Normally, this is used to set up control registers for
+ * voltage level and UHS speed mode.
+ *
+ * @host: SDHCI host structure
+ */
+ void (*set_control_reg)(struct sdhci_host *host);
+
+ /**
+ * set_ios_post() - Host specific hook after set_ios() calls
+ *
+ * This is the set_ios_post() SDHCI operation that should be
+ * used for the hardware this driver data is associated with.
+ * Normally, this is a hook that is called after sdhci_set_ios()
+ * that does any necessary host-specific configuration.
+ *
+ * @host: SDHCI host structure
+ * Return: 0 if successful, -ve on error
+ */
+ int (*set_ios_post)(struct sdhci_host *host);
};
static int rk3399_emmc_phy_init(struct udevice *dev)
@@ -182,15 +206,28 @@ static int rk3399_emmc_get_phy(struct udevice *dev)
return 0;
}
-static int rk3399_sdhci_emmc_set_clock(struct sdhci_host *host, unsigned int clock)
+static void rk3399_sdhci_set_control_reg(struct sdhci_host *host)
{
struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
+ struct mmc *mmc = host->mmc;
+ uint clock = mmc->tran_speed;
int cycle_phy = host->clock != clock && clock > EMMC_MIN_FREQ;
if (cycle_phy)
rk3399_emmc_phy_power_off(priv->phy);
- sdhci_set_clock(host->mmc, clock);
+ sdhci_set_control_reg(host);
+};
+
+static int rk3399_sdhci_set_ios_post(struct sdhci_host *host)
+{
+ struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
+ struct mmc *mmc = host->mmc;
+ uint clock = mmc->tran_speed;
+ int cycle_phy = host->clock != clock && clock > EMMC_MIN_FREQ;
+
+ if (!clock)
+ clock = mmc->clock;
if (cycle_phy)
rk3399_emmc_phy_power_on(priv->phy, clock);
@@ -269,10 +306,8 @@ static int rk3568_emmc_get_phy(struct udevice *dev)
return 0;
}
-static int rockchip_sdhci_set_ios_post(struct sdhci_host *host)
+static int rk3568_sdhci_set_ios_post(struct sdhci_host *host)
{
- struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
- struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
struct mmc *mmc = host->mmc;
uint clock = mmc->tran_speed;
u32 reg;
@@ -280,8 +315,7 @@ static int rockchip_sdhci_set_ios_post(struct sdhci_host *host)
if (!clock)
clock = mmc->clock;
- if (data->emmc_set_clock)
- data->emmc_set_clock(host, clock);
+ rk3568_sdhci_emmc_set_clock(host, clock);
if (mmc->selected_mode == MMC_HS_400 || mmc->selected_mode == MMC_HS_400_ES) {
reg = sdhci_readw(host, SDHCI_HOST_CONTROL2);
@@ -295,6 +329,26 @@ static int rockchip_sdhci_set_ios_post(struct sdhci_host *host)
return 0;
}
+static void rockchip_sdhci_set_control_reg(struct sdhci_host *host)
+{
+ struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
+ struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
+
+ if (data->set_control_reg)
+ data->set_control_reg(host);
+}
+
+static int rockchip_sdhci_set_ios_post(struct sdhci_host *host)
+{
+ struct rockchip_sdhc *priv = container_of(host, struct rockchip_sdhc, host);
+ struct sdhci_data *data = (struct sdhci_data *)dev_get_driver_data(priv->dev);
+
+ if (data->set_ios_post)
+ return data->set_ios_post(host);
+
+ return 0;
+}
+
static int rockchip_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
{
struct sdhci_host *host = dev_get_priv(mmc->dev);
@@ -358,6 +412,7 @@ static int rockchip_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
static struct sdhci_ops rockchip_sdhci_ops = {
.set_ios_post = rockchip_sdhci_set_ios_post,
.platform_execute_tuning = &rockchip_sdhci_execute_tuning,
+ .set_control_reg = rockchip_sdhci_set_control_reg,
};
static int rockchip_sdhci_probe(struct udevice *dev)
@@ -436,15 +491,16 @@ static int rockchip_sdhci_bind(struct udevice *dev)
}
static const struct sdhci_data rk3399_data = {
- .emmc_set_clock = rk3399_sdhci_emmc_set_clock,
.get_phy = rk3399_emmc_get_phy,
.emmc_phy_init = rk3399_emmc_phy_init,
+ .set_control_reg = rk3399_sdhci_set_control_reg,
+ .set_ios_post = rk3399_sdhci_set_ios_post,
};
static const struct sdhci_data rk3568_data = {
- .emmc_set_clock = rk3568_sdhci_emmc_set_clock,
.get_phy = rk3568_emmc_get_phy,
.emmc_phy_init = rk3568_emmc_phy_init,
+ .set_ios_post = rk3568_sdhci_set_ios_post,
};
static const struct udevice_id sdhci_ids[] = {
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index b551ebd75e..763bab04c6 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -119,7 +119,7 @@ const struct flash_info spi_nor_ids[] = {
},
{
INFO("gd25lq128", 0xc86018, 0, 64 * 1024, 256,
- SECT_4K | SPI_NOR_DUAL_READ |
+ SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
},
{
diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c
index 5a0a59a8b9..f07669374d 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 @@ struct mvebu_pcie {
u32 lane;
bool is_x4;
int devfn;
- u32 lane_mask;
int sec_busno;
char name[16];
unsigned int mem_target;
@@ -90,8 +77,8 @@ struct mvebu_pcie {
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 @@ static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie *pcie, int busno)
{
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 @@ static int mvebu_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
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 @@ static int mvebu_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
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 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie *pcie)
/* 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 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie *pcie)
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 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie *pcie)
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 @@ static void mvebu_pcie_setup_link(struct mvebu_pcie *pcie)
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 @@ static void mvebu_pcie_setup_link(struct mvebu_pcie *pcie)
* 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 @@ static int mvebu_pcie_probe(struct udevice *dev)
* 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 @@ static int mvebu_pcie_probe(struct udevice *dev)
* 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/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c
index d95d4b432a..fc5044fd5d 100644
--- a/drivers/phy/cadence/phy-cadence-sierra.c
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
@@ -358,26 +358,10 @@ static inline int cdns_reset_deassert(struct reset_control *rst)
return 0;
}
-static inline struct cdns_sierra_inst *phy_get_drvdata(struct phy *phy)
+static int cdns_sierra_link_init(struct phy *gphy)
{
- struct cdns_sierra_phy *sp = dev_get_priv(phy->dev);
- int index;
-
- if (phy->id >= SIERRA_MAX_LANES)
- return NULL;
-
- for (index = 0; index < sp->nsubnodes; index++) {
- if (phy->id == sp->phys[index]->mlane)
- return sp->phys[index];
- }
-
- return NULL;
-}
-
-static int cdns_sierra_phy_init(struct phy *gphy)
-{
- struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
- struct cdns_sierra_phy *phy = dev_get_priv(gphy->dev);
+ struct cdns_sierra_inst *ins = dev_get_priv(gphy->dev);
+ struct cdns_sierra_phy *phy = dev_get_priv(gphy->dev->parent);
struct cdns_sierra_data *init_data = phy->init_data;
struct cdns_sierra_vals *pma_cmn_vals, *pma_ln_vals;
enum cdns_sierra_phy_type phy_type = ins->phy_type;
@@ -443,10 +427,11 @@ static int cdns_sierra_phy_init(struct phy *gphy)
return 0;
}
-static int cdns_sierra_phy_on(struct phy *gphy)
+static int cdns_sierra_link_on(struct phy *gphy)
{
- struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
- struct cdns_sierra_phy *sp = dev_get_priv(gphy->dev);
+ struct cdns_sierra_inst *ins = dev_get_priv(gphy->dev);
+ struct cdns_sierra_phy *sp = dev_get_priv(gphy->dev->parent);
+
struct udevice *dev = gphy->dev;
u32 val;
int ret;
@@ -503,16 +488,16 @@ static int cdns_sierra_phy_on(struct phy *gphy)
return ret;
}
-static int cdns_sierra_phy_off(struct phy *gphy)
+static int cdns_sierra_link_off(struct phy *gphy)
{
- struct cdns_sierra_inst *ins = phy_get_drvdata(gphy);
+ struct cdns_sierra_inst *ins = dev_get_priv(gphy->dev);
return reset_assert_bulk(ins->lnk_rst);
}
-static int cdns_sierra_phy_reset(struct phy *gphy)
+static int cdns_sierra_link_reset(struct phy *gphy)
{
- struct cdns_sierra_phy *sp = dev_get_priv(gphy->dev);
+ struct cdns_sierra_phy *sp = dev_get_priv(gphy->dev->parent);
reset_control_assert(sp->phy_rst);
reset_control_deassert(sp->phy_rst);
@@ -520,10 +505,10 @@ static int cdns_sierra_phy_reset(struct phy *gphy)
};
static const struct phy_ops ops = {
- .init = cdns_sierra_phy_init,
- .power_on = cdns_sierra_phy_on,
- .power_off = cdns_sierra_phy_off,
- .reset = cdns_sierra_phy_reset,
+ .init = cdns_sierra_link_init,
+ .power_on = cdns_sierra_link_on,
+ .power_off = cdns_sierra_link_off,
+ .reset = cdns_sierra_link_reset,
};
struct cdns_sierra_pll_mux_sel {
@@ -580,7 +565,7 @@ static const struct clk_ops cdns_sierra_pll_mux_ops = {
.set_parent = cdns_sierra_pll_mux_set_parent,
};
-int cdns_sierra_pll_mux_probe(struct udevice *dev)
+static int cdns_sierra_pll_mux_probe(struct udevice *dev)
{
struct cdns_sierra_pll_mux *priv = dev_get_priv(dev);
struct cdns_sierra_phy *sp = dev_get_priv(dev->parent);
@@ -1012,9 +997,8 @@ static int cdns_sierra_phy_get_resets(struct cdns_sierra_phy *sp,
return 0;
}
-static int cdns_sierra_bind_link_nodes(struct cdns_sierra_phy *sp)
+static int cdns_sierra_phy_bind(struct udevice *dev)
{
- struct udevice *dev = sp->dev;
struct driver *link_drv;
ofnode child;
int rc;
@@ -1079,6 +1063,7 @@ U_BOOT_DRIVER(sierra_phy_link) = {
.name = "sierra_phy_link",
.id = UCLASS_PHY,
.probe = cdns_sierra_link_probe,
+ .ops = &ops,
.priv_auto = sizeof(struct cdns_sierra_inst),
};
@@ -1141,10 +1126,6 @@ static int cdns_sierra_phy_probe(struct udevice *dev)
}
sp->autoconf = dev_read_bool(dev, "cdns,autoconf");
- /* Binding link nodes as children to serdes */
- ret = cdns_sierra_bind_link_nodes(sp);
- if (ret)
- goto clk_disable;
dev_info(dev, "sierra probed\n");
return 0;
@@ -1971,10 +1952,10 @@ static const struct udevice_id cdns_sierra_id_table[] = {
U_BOOT_DRIVER(sierra_phy_provider) = {
.name = "cdns,sierra",
- .id = UCLASS_PHY,
+ .id = UCLASS_MISC,
.of_match = cdns_sierra_id_table,
.probe = cdns_sierra_phy_probe,
.remove = cdns_sierra_phy_remove,
- .ops = &ops,
+ .bind = cdns_sierra_phy_bind,
.priv_auto = sizeof(struct cdns_sierra_phy),
};
diff --git a/drivers/phy/nop-phy.c b/drivers/phy/nop-phy.c
index e2ee6e9206..d0904f4f07 100644
--- a/drivers/phy/nop-phy.c
+++ b/drivers/phy/nop-phy.c
@@ -45,11 +45,13 @@ static int nop_phy_init(struct phy *phy)
#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/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
index 1cf1f06f10..e76ef153e6 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -162,11 +162,11 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = {
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/rtc/armada38x.c b/drivers/rtc/armada38x.c
index 2d264acf77..2af64e3912 100644
--- a/drivers/rtc/armada38x.c
+++ b/drivers/rtc/armada38x.c
@@ -121,7 +121,7 @@ static int armada38x_rtc_reset(struct udevice *dev)
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 362cedd955..f30f352bd7 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -66,7 +66,8 @@ static int serial_check_stdout(const void *blob, struct udevice **devp)
*/
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/spi/Kconfig b/drivers/spi/Kconfig
index 0a6a85f9c4..423a757141 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -185,6 +185,12 @@ config ICH_SPI
access the SPI NOR flash on platforms embedding this Intel
ICH IP core.
+config IPROC_QSPI
+ bool "Broadcom iProc QSPI Flash Controller driver"
+ help
+ Enable Broadcom iProc QSPI Flash Controller driver.
+ This driver can be used to access the SPI NOR flash.
+
config KIRKWOOD_SPI
bool "Marvell Kirkwood SPI Driver"
help
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index bea746f3e3..7f43f843ca 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_FSL_DSPI) += fsl_dspi.o
obj-$(CONFIG_FSL_ESPI) += fsl_espi.o
obj-$(CONFIG_SYNQUACER_SPI) += spi-synquacer.o
obj-$(CONFIG_ICH_SPI) += ich.o
+obj-$(CONFIG_IPROC_QSPI) += iproc_qspi.o
obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
obj-$(CONFIG_MESON_SPIFC) += meson_spifc.o
obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index d1b3808c4d..db680618ee 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -201,11 +201,9 @@ static int cadence_spi_probe(struct udevice *bus)
}
}
- ret = reset_get_bulk(bus, &priv->resets);
- if (ret)
- dev_warn(bus, "Can't get reset: %d\n", ret);
- else
- reset_deassert_bulk(&priv->resets);
+ priv->resets = devm_reset_bulk_get_optional(bus);
+ if (priv->resets)
+ reset_deassert_bulk(priv->resets);
if (!priv->qspi_is_init) {
cadence_qspi_apb_controller_init(plat);
@@ -220,8 +218,12 @@ static int cadence_spi_probe(struct udevice *bus)
static int cadence_spi_remove(struct udevice *dev)
{
struct cadence_spi_priv *priv = dev_get_priv(dev);
+ int ret = 0;
+
+ if (priv->resets)
+ ret = reset_release_bulk(priv->resets);
- return reset_release_bulk(&priv->resets);
+ return ret;
}
static int cadence_spi_set_mode(struct udevice *bus, uint mode)
diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h
index 49b401168f..19345cac5a 100644
--- a/drivers/spi/cadence_qspi.h
+++ b/drivers/spi/cadence_qspi.h
@@ -56,7 +56,7 @@ struct cadence_spi_priv {
unsigned int qspi_calibrated_cs;
unsigned int previous_hz;
- struct reset_ctl_bulk resets;
+ struct reset_ctl_bulk *resets;
};
/* Functions call declaration */
diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c
index 742121140d..fc22f540fe 100644
--- a/drivers/spi/designware_spi.c
+++ b/drivers/spi/designware_spi.c
@@ -572,7 +572,7 @@ static int dw_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
int pos, i, ret = 0;
struct udevice *bus = slave->dev->parent;
struct dw_spi_priv *priv = dev_get_priv(bus);
- u8 op_len = sizeof(op->cmd.opcode) + op->addr.nbytes + op->dummy.nbytes;
+ u8 op_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes;
u8 op_buf[op_len];
u32 cr0;
diff --git a/drivers/spi/iproc_qspi.c b/drivers/spi/iproc_qspi.c
new file mode 100644
index 0000000000..b5c274314b
--- /dev/null
+++ b/drivers/spi/iproc_qspi.c
@@ -0,0 +1,576 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020-2021 Broadcom
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <spi.h>
+#include <spi-mem.h>
+#include <asm/io.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/iopoll.h>
+#include <linux/log2.h>
+
+/* Delay required to change the mode of operation */
+#define BUSY_DELAY_US 1
+#define BUSY_TIMEOUT_US 200000
+#define DWORD_ALIGNED(a) (!(((ulong)(a)) & 3))
+
+/* Chip attributes */
+#define QSPI_AXI_CLK 175000000
+#define SPBR_MIN 8U
+#define SPBR_MAX 255U
+#define NUM_CDRAM 16U
+
+#define CDRAM_PCS0 2
+#define CDRAM_CONT BIT(7)
+#define CDRAM_BITS_EN BIT(6)
+#define CDRAM_QUAD_MODE BIT(8)
+#define CDRAM_RBIT_INPUT BIT(10)
+#define MSPI_SPE BIT(6)
+#define MSPI_CONT_AFTER_CMD BIT(7)
+#define MSPI_MSTR BIT(7)
+
+/* Register fields */
+#define MSPI_SPCR0_MSB_BITS_8 0x00000020
+#define BSPI_RAF_CONTROL_START_MASK 0x00000001
+#define BSPI_RAF_STATUS_SESSION_BUSY_MASK 0x00000001
+#define BSPI_RAF_STATUS_FIFO_EMPTY_MASK 0x00000002
+#define BSPI_STRAP_OVERRIDE_DATA_QUAD_SHIFT 3
+#define BSPI_STRAP_OVERRIDE_4BYTE_SHIFT 2
+#define BSPI_STRAP_OVERRIDE_DATA_DUAL_SHIFT 1
+#define BSPI_STRAP_OVERRIDE_SHIFT 0
+#define BSPI_BPC_DATA_SHIFT 0
+#define BSPI_BPC_MODE_SHIFT 8
+#define BSPI_BPC_ADDR_SHIFT 16
+#define BSPI_BPC_CMD_SHIFT 24
+#define BSPI_BPP_ADDR_SHIFT 16
+
+/* MSPI registers */
+#define MSPI_SPCR0_LSB_REG 0x000
+#define MSPI_SPCR0_MSB_REG 0x004
+#define MSPI_SPCR1_LSB_REG 0x008
+#define MSPI_SPCR1_MSB_REG 0x00c
+#define MSPI_NEWQP_REG 0x010
+#define MSPI_ENDQP_REG 0x014
+#define MSPI_SPCR2_REG 0x018
+#define MSPI_STATUS_REG 0x020
+#define MSPI_CPTQP_REG 0x024
+#define MSPI_TX_REG 0x040
+#define MSPI_RX_REG 0x0c0
+#define MSPI_CDRAM_REG 0x140
+#define MSPI_WRITE_LOCK_REG 0x180
+#define MSPI_DISABLE_FLUSH_GEN_REG 0x184
+
+/* BSPI registers */
+#define BSPI_REVISION_ID_REG 0x000
+#define BSPI_SCRATCH_REG 0x004
+#define BSPI_MAST_N_BOOT_CTRL_REG 0x008
+#define BSPI_BUSY_STATUS_REG 0x00c
+#define BSPI_INTR_STATUS_REG 0x010
+#define BSPI_B0_STATUS_REG 0x014
+#define BSPI_B0_CTRL_REG 0x018
+#define BSPI_B1_STATUS_REG 0x01c
+#define BSPI_B1_CTRL_REG 0x020
+#define BSPI_STRAP_OVERRIDE_CTRL_REG 0x024
+#define BSPI_FLEX_MODE_ENABLE_REG 0x028
+#define BSPI_BITS_PER_CYCLE_REG 0x02C
+#define BSPI_BITS_PER_PHASE_REG 0x030
+#define BSPI_CMD_AND_MODE_BYTE_REG 0x034
+#define BSPI_FLASH_UPPER_ADDR_BYTE_REG 0x038
+#define BSPI_XOR_VALUE_REG 0x03C
+#define BSPI_XOR_ENABLE_REG 0x040
+#define BSPI_PIO_MODE_ENABLE_REG 0x044
+#define BSPI_PIO_IODIR_REG 0x048
+#define BSPI_PIO_DATA_REG 0x04C
+
+/* RAF registers */
+#define BSPI_RAF_START_ADDRESS_REG 0x00
+#define BSPI_RAF_NUM_WORDS_REG 0x04
+#define BSPI_RAF_CTRL_REG 0x08
+#define BSPI_RAF_FULLNESS_REG 0x0C
+#define BSPI_RAF_WATERMARK_REG 0x10
+#define BSPI_RAF_STATUS_REG 0x14
+#define BSPI_RAF_READ_DATA_REG 0x18
+#define BSPI_RAF_WORD_CNT_REG 0x1C
+#define BSPI_RAF_CURR_ADDR_REG 0x20
+
+#define XFER_DUAL BIT(30)
+#define XFER_QUAD BIT(31)
+
+#define FLUSH_BIT BIT(0)
+#define MAST_N_BOOT_BIT BIT(0)
+#define WRITE_LOCK_BIT BIT(0)
+
+#define CEIL(m, n) (((m) + (n) - 1) / (n))
+#define UPPER_BYTE_MASK 0xFF000000
+#define SIZE_16MB 0x001000000
+
+/*
+ * struct bcmspi_priv - qspi private structure
+ *
+ * @bspi_addr: bspi read address
+ * @bspi_4byte_addr: bspi 4 byte address mode
+ * @mspi: mspi registers block address
+ * @bspi: bspi registers block address
+ * @bspi_raf: bspi raf registers block address
+ */
+struct bcmspi_priv {
+ u32 bspi_addr;
+ bool bspi_4byte_addr;
+ fdt_addr_t mspi;
+ fdt_addr_t bspi;
+ fdt_addr_t bspi_raf;
+};
+
+/* BSPI mode */
+
+static void bspi_flush_prefetch_buffers(struct bcmspi_priv *priv)
+{
+ writel(0, priv->bspi + BSPI_B0_CTRL_REG);
+ writel(0, priv->bspi + BSPI_B1_CTRL_REG);
+ writel(FLUSH_BIT, priv->bspi + BSPI_B0_CTRL_REG);
+ writel(FLUSH_BIT, priv->bspi + BSPI_B1_CTRL_REG);
+}
+
+static int bspi_enable(struct bcmspi_priv *priv)
+{
+ /* Disable write lock */
+ writel(0, priv->mspi + MSPI_WRITE_LOCK_REG);
+ /* Flush prefetch buffers */
+ bspi_flush_prefetch_buffers(priv);
+ /* Switch to BSPI */
+ writel(0, priv->bspi + BSPI_MAST_N_BOOT_CTRL_REG);
+
+ return 0;
+}
+
+static int bspi_disable(struct bcmspi_priv *priv)
+{
+ int ret;
+ uint val;
+
+ if ((readl(priv->bspi + BSPI_MAST_N_BOOT_CTRL_REG) & 1) == 0) {
+ ret = readl_poll_timeout(priv->bspi + BSPI_BUSY_STATUS_REG, val, !(val & 1),
+ BUSY_TIMEOUT_US);
+ if (ret) {
+ printf("%s: Failed to disable bspi, device busy\n", __func__);
+ return ret;
+ }
+
+ /* Switch to MSPI */
+ writel(MAST_N_BOOT_BIT, priv->bspi + BSPI_MAST_N_BOOT_CTRL_REG);
+ udelay(BUSY_DELAY_US);
+
+ val = readl(priv->bspi + BSPI_MAST_N_BOOT_CTRL_REG);
+ if (!(val & 1)) {
+ printf("%s: Failed to enable mspi\n", __func__);
+ return -EBUSY;
+ }
+ }
+
+ /* Enable write lock */
+ writel(WRITE_LOCK_BIT, priv->mspi + MSPI_WRITE_LOCK_REG);
+
+ return 0;
+}
+
+static int bspi_read_via_raf(struct bcmspi_priv *priv, u8 *rx, uint bytes)
+{
+ u32 status;
+ uint words;
+ int aligned;
+ int ret;
+
+ /*
+ * Flush data from the previous session (unlikely)
+ * Read outstanding bits in the poll condition to empty FIFO
+ */
+ ret = readl_poll_timeout(priv->bspi_raf + BSPI_RAF_STATUS_REG,
+ status,
+ (!readl(priv->bspi_raf + BSPI_RAF_READ_DATA_REG) &&
+ status & BSPI_RAF_STATUS_FIFO_EMPTY_MASK) &&
+ !(status & BSPI_RAF_STATUS_SESSION_BUSY_MASK),
+ BUSY_TIMEOUT_US);
+ if (ret) {
+ printf("%s: Failed to flush fifo\n", __func__);
+ return ret;
+ }
+
+ /* Transfer is in words */
+ words = CEIL(bytes, 4);
+
+ /* Setup hardware */
+ if (priv->bspi_4byte_addr) {
+ u32 val = priv->bspi_addr & UPPER_BYTE_MASK;
+
+ if (val != readl(priv->bspi + BSPI_FLASH_UPPER_ADDR_BYTE_REG)) {
+ writel(val, priv->bspi + BSPI_FLASH_UPPER_ADDR_BYTE_REG);
+ bspi_flush_prefetch_buffers(priv);
+ }
+ }
+
+ writel(priv->bspi_addr & ~UPPER_BYTE_MASK, priv->bspi_raf + BSPI_RAF_START_ADDRESS_REG);
+ writel(words, priv->bspi_raf + BSPI_RAF_NUM_WORDS_REG);
+ writel(0, priv->bspi_raf + BSPI_RAF_WATERMARK_REG);
+
+ /* Start reading */
+ writel(BSPI_RAF_CONTROL_START_MASK, priv->bspi_raf + BSPI_RAF_CTRL_REG);
+ aligned = DWORD_ALIGNED(rx);
+ while (bytes) {
+ status = readl(priv->bspi_raf + BSPI_RAF_STATUS_REG);
+ if (!(status & BSPI_RAF_STATUS_FIFO_EMPTY_MASK)) {
+ /* RAF is LE only, convert data to host endianness */
+ u32 data = le32_to_cpu(readl(priv->bspi_raf + BSPI_RAF_READ_DATA_REG));
+
+ /* Check if we can use the whole word */
+ if (aligned && bytes >= 4) {
+ *(u32 *)rx = data;
+ rx += 4;
+ bytes -= 4;
+ } else {
+ uint chunk = min(bytes, 4U);
+
+ /* Read out bytes one by one */
+ while (chunk) {
+ *rx++ = (u8)data;
+ data >>= 8;
+ chunk--;
+ bytes--;
+ }
+ }
+
+ continue;
+ }
+ if (!(status & BSPI_RAF_STATUS_SESSION_BUSY_MASK)) {
+ /* FIFO is empty and the session is done */
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int bspi_read(struct bcmspi_priv *priv, u8 *rx, uint bytes)
+{
+ int ret;
+
+ /* Transfer data */
+ while (bytes > 0) {
+ /* Special handing since RAF cannot go across 16MB boundary */
+ uint trans = bytes;
+ /* Divide into multiple transfers if it goes across the 16MB boundary */
+ if (priv->bspi_4byte_addr && (priv->bspi_addr >> 24) !=
+ ((priv->bspi_addr + bytes) >> 24))
+ trans = SIZE_16MB - (priv->bspi_addr & ~UPPER_BYTE_MASK);
+
+ ret = bspi_read_via_raf(priv, rx, trans);
+ if (ret)
+ return ret;
+
+ priv->bspi_addr += trans;
+ rx += trans;
+ bytes -= trans;
+ }
+
+ bspi_flush_prefetch_buffers(priv);
+ return 0;
+}
+
+static void bspi_set_flex_mode(struct bcmspi_priv *priv, const struct spi_mem_op *op)
+{
+ int bpp = (op->dummy.nbytes * 8) / op->dummy.buswidth;
+ int cmd = op->cmd.opcode;
+ int bpc = ilog2(op->data.buswidth) << BSPI_BPC_DATA_SHIFT |
+ ilog2(op->addr.buswidth) << BSPI_BPC_ADDR_SHIFT |
+ ilog2(op->cmd.buswidth) << BSPI_BPC_CMD_SHIFT;
+ int so = BIT(BSPI_STRAP_OVERRIDE_SHIFT) |
+ (op->data.buswidth > 1) << BSPI_STRAP_OVERRIDE_DATA_DUAL_SHIFT |
+ (op->addr.nbytes > 3) << BSPI_STRAP_OVERRIDE_4BYTE_SHIFT |
+ (op->data.buswidth > 3) << BSPI_STRAP_OVERRIDE_DATA_QUAD_SHIFT;
+
+ /* Disable flex mode first */
+ writel(0, priv->bspi + BSPI_FLEX_MODE_ENABLE_REG);
+
+ /* Configure single, dual or quad mode */
+ writel(bpc, priv->bspi + BSPI_BITS_PER_CYCLE_REG);
+
+ /* Opcode */
+ writel(cmd, priv->bspi + BSPI_CMD_AND_MODE_BYTE_REG);
+
+ /* Count of dummy cycles */
+ writel(bpp, priv->bspi + BSPI_BITS_PER_PHASE_REG);
+
+ /* Enable 4-byte address */
+ if (priv->bspi_4byte_addr) {
+ setbits_le32(priv->bspi + BSPI_BITS_PER_PHASE_REG, BIT(BSPI_BPP_ADDR_SHIFT));
+ } else {
+ clrbits_le32(priv->bspi + BSPI_BITS_PER_PHASE_REG, BIT(BSPI_BPP_ADDR_SHIFT));
+ writel(0, priv->bspi + BSPI_FLASH_UPPER_ADDR_BYTE_REG);
+ }
+
+ /* Enable flex mode to take effect */
+ writel(1, priv->bspi + BSPI_FLEX_MODE_ENABLE_REG);
+
+ /* Flush prefetch buffers since 32MB window BSPI could be used */
+ bspi_flush_prefetch_buffers(priv);
+
+ /* Override the strap settings */
+ writel(so, priv->bspi + BSPI_STRAP_OVERRIDE_CTRL_REG);
+}
+
+static int bspi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
+{
+ struct udevice *bus = dev_get_parent(slave->dev);
+ struct bcmspi_priv *priv = dev_get_priv(bus);
+ int ret = -ENOTSUPP;
+
+ /* BSPI read */
+ if (op->data.dir == SPI_MEM_DATA_IN &&
+ op->data.nbytes && op->addr.nbytes) {
+ priv->bspi_4byte_addr = (op->addr.nbytes > 3);
+ priv->bspi_addr = op->addr.val;
+ bspi_set_flex_mode(priv, op);
+ ret = bspi_read(priv, op->data.buf.in, op->data.nbytes);
+ }
+
+ return ret;
+}
+
+static const struct spi_controller_mem_ops bspi_mem_ops = {
+ .exec_op = bspi_exec_op,
+};
+
+/* MSPI mode */
+
+static int mspi_exec(struct bcmspi_priv *priv, uint bytes, const u8 *tx, u8 *rx, ulong flags)
+{
+ u32 cdr = CDRAM_PCS0 | CDRAM_CONT;
+ bool use_16bits = !(bytes & 1);
+
+ if (flags & XFER_QUAD) {
+ cdr |= CDRAM_QUAD_MODE;
+
+ if (!tx)
+ cdr |= CDRAM_RBIT_INPUT;
+ }
+
+ while (bytes) {
+ uint chunk;
+ uint queues;
+ uint i;
+ uint val;
+ int ret;
+
+ if (use_16bits) {
+ chunk = min(bytes, NUM_CDRAM * 2);
+ queues = (chunk + 1) / 2;
+ bytes -= chunk;
+
+ /* Fill CDRAMs */
+ for (i = 0; i < queues; i++)
+ writel(cdr | CDRAM_BITS_EN, priv->mspi + MSPI_CDRAM_REG + 4 * i);
+
+ /* Fill TXRAMs */
+ for (i = 0; i < chunk; i++)
+ writel(tx ? tx[i] : 0xff, priv->mspi + MSPI_TX_REG + 4 * i);
+ } else {
+ /* Determine how many bytes to process this time */
+ chunk = min(bytes, NUM_CDRAM);
+ queues = chunk;
+ bytes -= chunk;
+
+ /* Fill CDRAMs and TXRAMS */
+ for (i = 0; i < chunk; i++) {
+ writel(cdr, priv->mspi + MSPI_CDRAM_REG + 4 * i);
+ writel(tx ? tx[i] : 0xff, priv->mspi + MSPI_TX_REG + 8 * i);
+ }
+ }
+
+ /* Setup queue pointers */
+ writel(0, priv->mspi + MSPI_NEWQP_REG);
+ writel(queues - 1, priv->mspi + MSPI_ENDQP_REG);
+
+ /* Deassert CS if requested and it's the last transfer */
+ if (bytes == 0 && (flags & SPI_XFER_END))
+ clrbits_le32(priv->mspi + MSPI_CDRAM_REG + ((queues - 1) << 2), CDRAM_CONT);
+
+ /* Kick off */
+ writel(0, priv->mspi + MSPI_STATUS_REG);
+ if (bytes == 0 && (flags & SPI_XFER_END))
+ writel(MSPI_SPE, priv->mspi + MSPI_SPCR2_REG);
+ else
+ writel(MSPI_SPE | MSPI_CONT_AFTER_CMD,
+ priv->mspi + MSPI_SPCR2_REG);
+
+ ret = readl_poll_timeout(priv->mspi + MSPI_STATUS_REG, val, (val & 1),
+ BUSY_TIMEOUT_US);
+ if (ret) {
+ printf("%s: Failed to disable bspi, device busy\n", __func__);
+ return ret;
+ }
+
+ /* Read data out */
+ if (rx) {
+ if (use_16bits) {
+ for (i = 0; i < chunk; i++)
+ rx[i] = readl(priv->mspi + MSPI_RX_REG + 4 * i) & 0xff;
+ } else {
+ for (i = 0; i < chunk; i++)
+ rx[i] = readl(priv->mspi + MSPI_RX_REG + 8 * i + 4) & 0xff;
+ }
+ }
+
+ /* Advance pointers */
+ if (tx)
+ tx += chunk;
+ if (rx)
+ rx += chunk;
+ }
+
+ return 0;
+}
+
+static int mspi_xfer(struct udevice *dev, uint bitlen, const void *dout, void *din, ulong flags)
+{
+ struct udevice *bus = dev_get_parent(dev);
+ struct bcmspi_priv *priv = dev_get_priv(bus);
+ uint bytes;
+ int ret = 0;
+
+ /* we can only transfer multiples of 8 bits */
+ if (bitlen % 8)
+ return -EPROTONOSUPPORT;
+
+ bytes = bitlen / 8;
+
+ if (flags & SPI_XFER_BEGIN) {
+ /* Switch to MSPI */
+ ret = bspi_disable(priv);
+ if (ret)
+ return ret;
+ }
+
+ /* MSPI: Transfer */
+ if (bytes)
+ ret = mspi_exec(priv, bytes, dout, din, flags);
+
+ if (flags & SPI_XFER_END) {
+ /* Switch back to BSPI */
+ ret = bspi_enable(priv);
+ if (ret)
+ return ret;
+ }
+
+ return ret;
+}
+
+/* iProc interface */
+
+static int iproc_qspi_set_speed(struct udevice *bus, uint speed)
+{
+ struct bcmspi_priv *priv = dev_get_priv(bus);
+ uint spbr;
+
+ /* MSPI: SCK configuration */
+ spbr = (QSPI_AXI_CLK - 1) / (2 * speed) + 1;
+ writel(max(min(spbr, SPBR_MAX), SPBR_MIN), priv->mspi + MSPI_SPCR0_LSB_REG);
+
+ return 0;
+}
+
+static int iproc_qspi_set_mode(struct udevice *bus, uint mode)
+{
+ struct bcmspi_priv *priv = dev_get_priv(bus);
+
+ /* MSPI: set master bit and mode */
+ writel(MSPI_MSTR /* Master */ | (mode & 3), priv->mspi + MSPI_SPCR0_MSB_REG);
+
+ return 0;
+}
+
+static int iproc_qspi_claim_bus(struct udevice *dev)
+{
+ /* Nothing to do */
+ return 0;
+}
+
+static int iproc_qspi_release_bus(struct udevice *dev)
+{
+ struct udevice *bus = dev_get_parent(dev);
+ struct bcmspi_priv *priv = dev_get_priv(bus);
+
+ /* Make sure no operation is in progress */
+ writel(0, priv->mspi + MSPI_SPCR2_REG);
+ udelay(BUSY_DELAY_US);
+
+ return 0;
+}
+
+static int iproc_qspi_of_to_plat(struct udevice *bus)
+{
+ struct bcmspi_priv *priv = dev_get_priv(bus);
+
+ priv->bspi = dev_read_addr_name(bus, "bspi");
+ if (IS_ERR((void *)priv->bspi)) {
+ printf("%s: Failed to get bspi base address\n", __func__);
+ return PTR_ERR((void *)priv->bspi);
+ }
+
+ priv->bspi_raf = dev_read_addr_name(bus, "bspi_raf");
+ if (IS_ERR((void *)priv->bspi_raf)) {
+ printf("%s: Failed to get bspi_raf base address\n", __func__);
+ return PTR_ERR((void *)priv->bspi_raf);
+ }
+
+ priv->mspi = dev_read_addr_name(bus, "mspi");
+ if (IS_ERR((void *)priv->mspi)) {
+ printf("%s: Failed to get mspi base address\n", __func__);
+ return PTR_ERR((void *)priv->mspi);
+ }
+
+ return 0;
+}
+
+static int iproc_qspi_probe(struct udevice *bus)
+{
+ struct bcmspi_priv *priv = dev_get_priv(bus);
+
+ /* configure mspi */
+ writel(0, priv->mspi + MSPI_SPCR1_LSB_REG);
+ writel(0, priv->mspi + MSPI_SPCR1_MSB_REG);
+ writel(0, priv->mspi + MSPI_NEWQP_REG);
+ writel(0, priv->mspi + MSPI_ENDQP_REG);
+ writel(0, priv->mspi + MSPI_SPCR2_REG);
+
+ /* configure bspi */
+ bspi_enable(priv);
+
+ return 0;
+}
+
+static const struct dm_spi_ops iproc_qspi_ops = {
+ .claim_bus = iproc_qspi_claim_bus,
+ .release_bus = iproc_qspi_release_bus,
+ .xfer = mspi_xfer,
+ .set_speed = iproc_qspi_set_speed,
+ .set_mode = iproc_qspi_set_mode,
+ .mem_ops = &bspi_mem_ops,
+};
+
+static const struct udevice_id iproc_qspi_ids[] = {
+ { .compatible = "brcm,iproc-qspi" },
+ { }
+};
+
+U_BOOT_DRIVER(iproc_qspi) = {
+ .name = "iproc_qspi",
+ .id = UCLASS_SPI,
+ .of_match = iproc_qspi_ids,
+ .ops = &iproc_qspi_ops,
+ .of_to_plat = iproc_qspi_of_to_plat,
+ .priv_auto = sizeof(struct bcmspi_priv),
+ .probe = iproc_qspi_probe,
+};
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 1f3ca99f9a..5b614cfa6e 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -267,6 +267,13 @@ config WDT_SBSA
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 6d2b3822c0..a35bd559f5 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_WDT_OCTEONTX) += octeontx_wdt.o
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 2e119b9b5a..bacebbc792 100644
--- a/drivers/watchdog/armada-37xx-wdt.c
+++ b/drivers/watchdog/armada-37xx-wdt.c
@@ -58,13 +58,11 @@ static void counter_disable(struct a37xx_wdt *priv, int id)
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 @@ static int init_counter(struct a37xx_wdt *priv, int id, u32 mode, u32 trig_src)
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_expire_now(struct udevice *dev, ulong flags)
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 253286d349..8d93f19b98 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 @@ static int rti_wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags)
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 @@ static int rti_wdt_probe(struct udevice *dev)
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 0000000000..af5a6b1a28
--- /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 6d0f473867..dbf556467d 100644
--- a/drivers/watchdog/wdt-uclass.c
+++ b/drivers/watchdog/wdt-uclass.c
@@ -36,6 +36,8 @@ struct wdt_priv {
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 @@ static void init_watchdog_dev(struct udevice *dev)
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 @@ static int wdt_pre_probe(struct udevice *dev)
* 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/env/Kconfig b/env/Kconfig
index 20f395f544..443f2f7dd4 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -320,6 +320,7 @@ config ENV_IS_IN_SPI_FLASH
default y if NORTHBRIDGE_INTEL_IVYBRIDGE
default y if INTEL_QUARK
default y if INTEL_QUEENSBAY
+ default y if ARCH_SUNXI
help
Define this if you have a SPI Flash memory device which you
want to use for the environment.
@@ -536,7 +537,7 @@ config ENV_OFFSET
ENV_IS_IN_SPI_FLASH
default 0x3f8000 if ARCH_ROCKCHIP && ENV_IS_IN_MMC
default 0x140000 if ARCH_ROCKCHIP && ENV_IS_IN_SPI_FLASH
- default 0x88000 if ARCH_SUNXI
+ default 0xF0000 if ARCH_SUNXI
default 0xE0000 if ARCH_ZYNQ
default 0x1E00000 if ARCH_ZYNQMP
default 0x7F40000 if ARCH_VERSAL
@@ -559,7 +560,8 @@ config ENV_OFFSET_REDUND
config ENV_SIZE
hex "Environment Size"
default 0x40000 if ENV_IS_IN_SPI_FLASH && ARCH_ZYNQMP
- default 0x20000 if ARCH_SUNXI || ARCH_ZYNQ || ARCH_OMAP2PLUS || ARCH_AT91
+ default 0x20000 if ARCH_ZYNQ || ARCH_OMAP2PLUS || ARCH_AT91
+ default 0x10000 if ARCH_SUNXI
default 0x8000 if ARCH_ROCKCHIP && ENV_IS_IN_MMC
default 0x2000 if ARCH_ROCKCHIP && ENV_IS_IN_SPI_FLASH
default 0x8000 if ARCH_ZYNQMP || ARCH_VERSAL
@@ -575,6 +577,7 @@ config ENV_SECT_SIZE
default 0x40000 if ARCH_ZYNQMP || ARCH_VERSAL
default 0x20000 if ARCH_ZYNQ || ARCH_OMAP2PLUS || ARCH_AT91
default 0x20000 if MICROBLAZE && ENV_IS_IN_SPI_FLASH
+ default 0x10000 if ARCH_SUNXI && ENV_IS_IN_SPI_FLASH
help
Size of the sector containing the environment.
diff --git a/include/configs/lx2160a_common.h b/include/configs/lx2160a_common.h
index c407fa8ba1..469989a97d 100644
--- a/include/configs/lx2160a_common.h
+++ b/include/configs/lx2160a_common.h
@@ -243,12 +243,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 9733707009..7483bc821d 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/efi_loader.h b/include/efi_loader.h
index e390d323a9..110d8ae79c 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -342,7 +342,7 @@ struct efi_open_protocol_info_item {
*/
struct efi_handler {
struct list_head link;
- const efi_guid_t *guid;
+ const efi_guid_t guid;
void *protocol_interface;
struct list_head open_infos;
};
diff --git a/include/sl28cpld.h b/include/sl28cpld.h
new file mode 100644
index 0000000000..9a7c6de31f
--- /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_boottime.c b/lib/efi_loader/efi_boottime.c
index 82128ac1d5..d0f3e05e70 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -552,7 +552,7 @@ efi_status_t efi_search_protocol(const efi_handle_t handle,
struct efi_handler *protocol;
protocol = list_entry(lhandle, struct efi_handler, link);
- if (!guidcmp(protocol->guid, protocol_guid)) {
+ if (!guidcmp(&protocol->guid, protocol_guid)) {
if (handler)
*handler = protocol;
return EFI_SUCCESS;
@@ -604,7 +604,7 @@ efi_status_t efi_remove_all_protocols(const efi_handle_t handle)
list_for_each_entry_safe(protocol, pos, &efiobj->protocols, link) {
efi_status_t ret;
- ret = efi_remove_protocol(handle, protocol->guid,
+ ret = efi_remove_protocol(handle, &protocol->guid,
protocol->protocol_interface);
if (ret != EFI_SUCCESS)
return ret;
@@ -1131,7 +1131,7 @@ efi_status_t efi_add_protocol(const efi_handle_t handle,
handler = calloc(1, sizeof(struct efi_handler));
if (!handler)
return EFI_OUT_OF_RESOURCES;
- handler->guid = protocol;
+ memcpy((void *)&handler->guid, protocol, sizeof(efi_guid_t));
handler->protocol_interface = protocol_interface;
INIT_LIST_HEAD(&handler->open_infos);
list_add_tail(&handler->link, &efiobj->protocols);
@@ -1227,7 +1227,7 @@ static efi_status_t efi_get_drivers(efi_handle_t handle,
/* Count all driver associations */
list_for_each_entry(handler, &handle->protocols, link) {
- if (protocol && guidcmp(handler->guid, protocol))
+ if (protocol && guidcmp(&handler->guid, protocol))
continue;
list_for_each_entry(item, &handler->open_infos, link) {
if (item->info.attributes &
@@ -1249,7 +1249,7 @@ static efi_status_t efi_get_drivers(efi_handle_t handle,
return EFI_OUT_OF_RESOURCES;
/* Collect unique driver handles */
list_for_each_entry(handler, &handle->protocols, link) {
- if (protocol && guidcmp(handler->guid, protocol))
+ if (protocol && guidcmp(&handler->guid, protocol))
continue;
list_for_each_entry(item, &handler->open_infos, link) {
if (item->info.attributes &
@@ -2446,7 +2446,7 @@ static efi_status_t EFIAPI efi_protocols_per_handle(
protocol = list_entry(protocol_handle,
struct efi_handler, link);
- (*protocol_buffer)[j] = (void *)protocol->guid;
+ (*protocol_buffer)[j] = (void *)&protocol->guid;
++j;
}
}
@@ -3094,7 +3094,7 @@ close_next:
(efi_handle_t)image_obj)
continue;
r = EFI_CALL(efi_close_protocol
- (efiobj, protocol->guid,
+ (efiobj, &protocol->guid,
info->info.agent_handle,
info->info.controller_handle
));
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index 5df35939f7..9611398885 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -91,7 +91,7 @@ void efi_print_image_infos(void *pc)
list_for_each_entry(efiobj, &efi_obj_list, link) {
list_for_each_entry(handler, &efiobj->protocols, link) {
- if (!guidcmp(handler->guid, &efi_guid_loaded_image)) {
+ if (!guidcmp(&handler->guid, &efi_guid_loaded_image)) {
efi_print_image_info(
(struct efi_loaded_image_obj *)efiobj,
handler->protocol_interface, pc);
diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c
index 3e7b798289..b2a21199e4 100644
--- a/lib/rsa/rsa-sign.c
+++ b/lib/rsa/rsa-sign.c
@@ -383,12 +383,11 @@ static int rsa_sign_with_key(EVP_PKEY *pkey, struct padding_algo *padding_algo,
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 @@ static int rsa_sign_with_key(EVP_PKEY *pkey, struct padding_algo *padding_algo,
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 @@ static int rsa_sign_with_key(EVP_PKEY *pkey, struct padding_algo *padding_algo,
return 0;
err_sign:
- EVP_MD_CTX_destroy(context);
+ EVP_MD_CTX_free(context);
err_create:
free(sig);
err_alloc:
diff --git a/tools/Makefile b/tools/Makefile
index 5409ff2879..60231c728c 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -196,6 +196,9 @@ hostprogs-$(CONFIG_EXYNOS5250) += mkexynosspl
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/kwboot.c b/tools/kwboot.c
index 68c0ef1f1b..9f2dd2de4e 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 @@ static unsigned char kwboot_msg_debug[] = {
};
/* 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 const char kwb_baud_magic[16] = "$baudratechange";
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 @@ out:
return rc;
}
+static void *
+kwboot_msg_write_handler(void *arg)
+{
+ int tty = *(int *)((void **)arg)[0];
+ const void *msg = ((void **)arg)[1];
+ int rsp_timeo = msg_rsp_timeo;
+ int i, dummy_oldtype;
+
+ /* allow to cancel this thread at any time */
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &dummy_oldtype);
+
+ 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);
+ }
+}
+
static int
-kwboot_bootmsg(int tty, void *msg)
+kwboot_msg_start_thread(pthread_t *thread, int *tty, void *msg)
{
- struct kwboot_block block;
+ void *arg[2];
int rc;
- char c;
- int count;
- if (msg == NULL)
- kwboot_printv("Please reboot the target into UART boot mode...");
- else
- kwboot_printv("Sending boot message. Please reboot the target...");
+ arg[0] = tty;
+ arg[1] = msg;
+ rc = pthread_create(thread, NULL, kwboot_msg_write_handler, arg);
+ if (rc) {
+ errno = rc;
+ return -1;
+ }
- do {
- rc = tcflush(tty, TCIOFLUSH);
- if (rc)
- break;
+ return 0;
+}
- for (count = 0; count < 128; count++) {
- rc = kwboot_tty_send(tty, msg, 8, 0);
- if (rc) {
- usleep(msg_req_delay * 1000);
- continue;
- }
- }
+static int
+kwboot_msg_stop_thread(pthread_t thread)
+{
+ int rc;
- rc = kwboot_tty_recv(tty, &c, 1, msg_rsp_timeo);
+ 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 @@ kwboot_bootmsg(int tty, void *msg)
*/
/* 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 @@ kwboot_bootmsg(int tty, void *msg)
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;
- kwboot_printv("Sending debug message. Please reboot the target...");
+ /* flush input and output queue */
+ tcflush(tty, TCIOFLUSH);
- do {
- char buf[16];
+ rc = kwboot_msg_start_thread(&write_thread, &tty, kwboot_msg_debug);
+ if (rc) {
+ perror("Failed to start write thread");
+ return rc;
+ }
- rc = tcflush(tty, TCIOFLUSH);
- if (rc)
- break;
+ kwboot_printv("Sending debug message. Please reboot the target...");
+ kwboot_spinner();
- 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 @@ kwboot_xmodem(int tty, const void *_img, size_t size, int baudrate)
}
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 @@ kwboot_term_pipe(int in, int out, const char *quit, int *s)
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 @@ kwboot_terminal(int tty)
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 @@ kwboot_terminal(int tty)
rc = 0;
s = 0;
+ k = 0;
do {
fd_set rfds;
@@ -1265,13 +1568,13 @@ kwboot_terminal(int tty)
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 @@ static void
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 @@ main(int argc, char **argv)
{
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 @@ main(int argc, char **argv)
rv = 1;
tty = -1;
- bootmsg = NULL;
- debugmsg = NULL;
+ bootmsg = 0;
+ debugmsg = 0;
imgpath = NULL;
img = NULL;
term = 0;
@@ -1767,24 +2070,25 @@ main(int argc, char **argv)
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] != '-')
+ /* Option -b could have optional argument which specify image path */
+ if (optind < argc && argv[optind] && argv[optind][0] != '-')
imgpath = argv[optind++];
break;
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 +2100,11 @@ main(int argc, char **argv)
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':
@@ -1826,17 +2129,44 @@ main(int argc, char **argv)
if (!bootmsg && !term && !debugmsg && !imgpath)
goto usage;
- ttypath = argv[optind++];
+ /*
+ * If there is no remaining argument but optional imgpath was parsed
+ * then it means that optional imgpath was eaten by getopt parser.
+ * Reassing imgpath to required ttypath argument.
+ */
+ if (optind == argc && imgpath) {
+ ttypath = imgpath;
+ imgpath = NULL;
+ } else if (optind + 1 == argc) {
+ ttypath = argv[optind];
+ } else {
+ goto usage;
+ }
- if (optind != argc)
+ /* boot and debug message use baudrate 115200 */
+ if (((bootmsg && !imgpath) || debugmsg) && baudrate != 115200) {
+ fprintf(stderr, "Baudrate other than 115200 cannot be used for this operation.\n");
goto usage;
+ }
- tty = kwboot_open_tty(ttypath, imgpath ? 115200 : baudrate);
+ tty = kwboot_open_tty(ttypath, baudrate);
if (tty < 0) {
perror(ttypath);
goto out;
}
+ /*
+ * initial baudrate for image transfer is always 115200,
+ * the change to different baudrate is done only after the header is sent
+ */
+ if (imgpath && baudrate != 115200) {
+ rc = kwboot_tty_change_baudrate(tty, 115200);
+ if (rc) {
+ perror(ttypath);
+ goto out;
+ }
+ }
+
if (baudrate == 115200)
/* do not change baudrate during Xmodem to the same value */
baudrate = 0;
@@ -1866,17 +2196,13 @@ main(int argc, char **argv)
}
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/mkimage.c b/tools/mkimage.c
index 760145119d..74bd072832 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -381,6 +381,11 @@ int main(int argc, char **argv)
}
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
@@ -391,7 +396,7 @@ int main(int argc, char **argv)
retval = tparams->fflag_handle(&params);
if (retval != EXIT_SUCCESS)
- exit (retval);
+ usage("Bad parameters for FIT image type");
}
if (params.lflag || params.fflag) {
diff --git a/tools/pblimage.c b/tools/pblimage.c
index 3c823e96cf..bd639c276f 100644
--- a/tools/pblimage.c
+++ b/tools/pblimage.c
@@ -230,19 +230,25 @@ static int pblimage_verify_header(unsigned char *ptr, int image_size,
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 81c5492926..0222e8067b 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;