From 1926a6d63420a831d7d2e91ea0a22a9f36b22d5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philip=20M=C3=BCller?= <philm@manjaro.org> Date: Fri, 11 Mar 2022 10:04:43 +0100 Subject: [PATCH] [pkg-upd] 2022.04rc3+git+589c659-1 --- ...659035a44a683b087fd75fe0b7667f7be7f5.patch | 4694 +++++++++++++++++ ...ci-Add-HS400-Enhanced-Strobe-support.patch | 0 ...k-power-on-and-init-counts-in-uclass.patch | 430 -- ...ci-Fix-RK3399-eMMC-PHY-power-cycling.patch | 0 ...0-Enhanced-Strobe-support-for-RK3399.patch | 0 ...0-Enhanced-Strobe-support-for-RK3568.patch | 0 ...mc-sdhci-allow-disabling-sdma-in-spl.patch | 0 PKGBUILD | 30 +- boot.txt | 2 +- 9 files changed, 4713 insertions(+), 443 deletions(-) create mode 100644 1000-upstream-589c659035a44a683b087fd75fe0b7667f7be7f5.patch rename 2002-mmc-sdhci-Add-HS400-Enhanced-Strobe-support.patch => 2001-mmc-sdhci-Add-HS400-Enhanced-Strobe-support.patch (100%) delete mode 100644 2001-phy-Track-power-on-and-init-counts-in-uclass.patch rename 2003-rockchip-sdhci-Fix-RK3399-eMMC-PHY-power-cycling.patch => 2002-rockchip-sdhci-Fix-RK3399-eMMC-PHY-power-cycling.patch (100%) rename 2004-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3399.patch => 2003-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3399.patch (100%) rename 2005-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3568.patch => 2004-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3568.patch (100%) rename 2006-mmc-sdhci-allow-disabling-sdma-in-spl.patch => 2005-mmc-sdhci-allow-disabling-sdma-in-spl.patch (100%) diff --git a/1000-upstream-589c659035a44a683b087fd75fe0b7667f7be7f5.patch b/1000-upstream-589c659035a44a683b087fd75fe0b7667f7be7f5.patch new file mode 100644 index 0000000..eab647b --- /dev/null +++ b/1000-upstream-589c659035a44a683b087fd75fe0b7667f7be7f5.patch @@ -0,0 +1,4694 @@ +From 17a9f3f53d644d025a1a9e6d3a61fc71adf8b9d8 Mon Sep 17 00:00:00 2001 +From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Date: Fri, 28 Jan 2022 13:10:10 +0200 +Subject: [PATCH 01/53] ARM: dts: at91: sama7g5ek: disable slew rate for GMACs + non MDIO pins + +Non GMAC's MDIO pins should have slew rate disabled for R(G)MII modes. Set +them accordingly in DT. + +Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Tested-by: Eugen Hristev <eugen.hristev@microchip.com> +Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com> +--- + arch/arm/dts/sama7g5ek.dts | 25 +++++++++++++++++++------ + 1 file changed, 19 insertions(+), 6 deletions(-) + +diff --git a/arch/arm/dts/sama7g5ek.dts b/arch/arm/dts/sama7g5ek.dts +index 6adb0442581..ac6f23f64e0 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; + }; + +From 42595eb7067c6c076e1c98213438be727f883fe2 Mon Sep 17 00:00:00 2001 +From: Michael Walle <michael@walle.cc> +Date: Fri, 25 Feb 2022 18:06:24 +0530 +Subject: [PATCH 02/53] misc: add sl28cpld base driver + +Add a multi-function device driver which will probe its children and +provides methods to access the device. + +Signed-off-by: Michael Walle <michael@walle.cc> +[Rebased] +Signed-off-by: Priyanka Jain <priyanka.jain@nxp.com> +--- + MAINTAINERS | 5 ++ + drivers/misc/Kconfig | 8 +++ + drivers/misc/Makefile | 1 + + drivers/misc/sl28cpld.c | 105 ++++++++++++++++++++++++++++++++++++++++ + include/sl28cpld.h | 14 ++++++ + 5 files changed, 133 insertions(+) + create mode 100644 drivers/misc/sl28cpld.c + create mode 100644 include/sl28cpld.h + +diff --git a/MAINTAINERS b/MAINTAINERS +index fb171e0c687..8b3870ff964 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -1161,6 +1161,11 @@ 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/misc/sl28cpld.c ++ + SPI + M: Jagan Teki <jagan@amarulasolutions.com> + S: Maintained +diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig +index 0ade3e32b0e..7029bb7b5c5 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 bca7b24e99a..f22eff601a1 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 00000000000..01ef1c6178f +--- /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/include/sl28cpld.h b/include/sl28cpld.h +new file mode 100644 +index 00000000000..d116607cfb1 +--- /dev/null ++++ b/include/sl28cpld.h +@@ -0,0 +1,14 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (c) 2021 Michael Walle <michael@walle.cc> ++ */ ++ ++#ifndef __SL28CPLD_H ++#define __SL28CPLD_H ++ ++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 + +From f606c9a8959728f7df539e182fb799d3ccc92cc6 Mon Sep 17 00:00:00 2001 +From: Michael Walle <michael@walle.cc> +Date: Mon, 15 Nov 2021 23:45:43 +0100 +Subject: [PATCH 03/53] watchdog: add sl28cpld watchdog driver + +The watchdog timer is part of the sl28cpld management controller. The +watchdog timer usually supervises the bootloader boot-up and if it bites +the failsafe bootloader will be activated. Apart from that it supports +the usual board level reset and one SMARC speciality: driving the +WDT_TIMEOUT# signal. + +Signed-off-by: Michael Walle <michael@walle.cc> +Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com> +--- + MAINTAINERS | 1 + + doc/board/kontron/sl28.rst | 53 +++++++++++----- + drivers/watchdog/Kconfig | 7 ++ + drivers/watchdog/Makefile | 1 + + drivers/watchdog/sl28cpld-wdt.c | 109 ++++++++++++++++++++++++++++++++ + 5 files changed, 154 insertions(+), 17 deletions(-) + create mode 100644 drivers/watchdog/sl28cpld-wdt.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 8b3870ff964..989ea41e2c3 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -1165,6 +1165,7 @@ SL28CLPD + M: Michael Walle <michael@walle.cc> + S: Maintained + F: drivers/misc/sl28cpld.c ++F: drivers/watchdog/sl28cpld-wdt.c + + SPI + M: Jagan Teki <jagan@amarulasolutions.com> +diff --git a/doc/board/kontron/sl28.rst b/doc/board/kontron/sl28.rst +index c7b18bed10c..c2cdc5e4241 100644 +--- a/doc/board/kontron/sl28.rst ++++ b/doc/board/kontron/sl28.rst +@@ -35,23 +35,6 @@ 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 +- +- + Update image + ------------ + +@@ -82,6 +65,42 @@ u-boot (yet). But you can use the i2c command to access it. + > i2c md 4a 3.1 1 + + ++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. ++ ++wdt command flags ++^^^^^^^^^^^^^^^^^ ++ ++The `wdt start` as well as the `wdt expire` command take a flags argument. ++The supported bitmask is as follows. ++ ++| Bit | Description | ++| --- | ----------------------------- | ++| 0 | Enable failsafe mode | ++| 1 | Lock the control register | ++| 2 | Disable board reset | ++| 3 | Enable WDT_TIME_OUT# line | ++ ++For example, you can use `wdt expire 1` to issue a reset and boot into the ++failsafe bootloader. ++ ++Disable the builtin watchdog ++^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ++ ++If for some reason, this isn't a desired behavior, the watchdog can also ++be configured to not be enabled on board reset. It's configuration is saved ++in the non-volatile board configuration bits. To change these you can use ++the `sl28 nvm` command. ++ ++For more information on the non-volatile board configuration bits, see the ++following section. ++ + Non-volatile Board Configuration Bits + ------------------------------------- + +diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig +index cabac290539..f90f0ca02bc 100644 +--- a/drivers/watchdog/Kconfig ++++ b/drivers/watchdog/Kconfig +@@ -266,6 +266,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 6d2b3822c06..a35bd559f51 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/sl28cpld-wdt.c b/drivers/watchdog/sl28cpld-wdt.c +new file mode 100644 +index 00000000000..af5a6b1a28a +--- /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, ++}; + +From 07d6cb93781d47a8cb94c63b6419c68923b6f09d Mon Sep 17 00:00:00 2001 +From: Michael Walle <michael@walle.cc> +Date: Fri, 25 Feb 2022 18:10:24 +0530 +Subject: [PATCH 04/53] gpio: add sl28cpld driver + +The gpio block is part of the sl28cpld sl28cpld management controller. +There are three different flavors: the usual input and output where the +direction is configurable, but also input only and output only variants. + +Signed-off-by: Michael Walle <michael@walle.cc> +[Rebased] +Signed-off-by: Priyanka Jain <priyanka.jain@nxp.com> +--- + MAINTAINERS | 1 + + drivers/gpio/Kconfig | 6 ++ + drivers/gpio/Makefile | 1 + + drivers/gpio/sl28cpld-gpio.c | 165 +++++++++++++++++++++++++++++++++++ + 4 files changed, 173 insertions(+) + create mode 100644 drivers/gpio/sl28cpld-gpio.c + +diff --git a/MAINTAINERS b/MAINTAINERS +index 989ea41e2c3..0f39bc6bc92 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -1164,6 +1164,7 @@ 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 + +diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig +index 8d0e47c67d9..522dfc195ec 100644 +--- a/drivers/gpio/Kconfig ++++ b/drivers/gpio/Kconfig +@@ -544,4 +544,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 63e9be6034f..33f7d41b7db 100644 +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -70,4 +70,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 00000000000..700fc3df298 +--- /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, ++}; + +From fea51613222edba814d33a21d9485463cf3988f3 Mon Sep 17 00:00:00 2001 +From: Michael Walle <michael@walle.cc> +Date: Mon, 15 Nov 2021 23:45:45 +0100 +Subject: [PATCH 05/53] board: sl28: fix DRAM pretty print + +The current console output is: + +DRAM: 4 GiB +DDR 4 GiB (DDR3, 32-bit, CL=11, ECC on) + +The size is printed twice and we can save one line of console output if +we join both lines. The new output is as follows: + +DRAM: 4 GiB (DDR3, 32-bit, CL=11, ECC on) + +Signed-off-by: Michael Walle <michael@walle.cc> +Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com> +--- + board/kontron/sl28/sl28.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/board/kontron/sl28/sl28.c b/board/kontron/sl28/sl28.c +index e84b3569186..a4ee8a1ef3e 100644 +--- a/board/kontron/sl28/sl28.c ++++ b/board/kontron/sl28/sl28.c +@@ -47,8 +47,6 @@ int checkboard(void) + + 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); + } + + +From d36b683a0f4d9cd22aded61595b771c88203f3ab Mon Sep 17 00:00:00 2001 +From: Michael Walle <michael@walle.cc> +Date: Mon, 15 Nov 2021 23:45:46 +0100 +Subject: [PATCH 06/53] board: sl28: print CPLD version on bootup + +Most of the time it is very useful to have the version of the board +management controller. Now that we have a driver, print it during +startup. + +Signed-off-by: Michael Walle <michael@walle.cc> +Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com> +--- + board/kontron/sl28/sl28.c | 28 ++++++++++++++++++++++++++++ + include/sl28cpld.h | 2 ++ + 2 files changed, 30 insertions(+) + +diff --git a/board/kontron/sl28/sl28.c b/board/kontron/sl28/sl28.c +index a4ee8a1ef3e..9cde48e61ef 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> +@@ -15,6 +16,7 @@ + #include <fsl_immap.h> + #include <netdev.h> + ++#include <sl28cpld.h> + #include <fdtdec.h> + #include <miiphy.h> + +@@ -39,9 +41,35 @@ 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; + } + +diff --git a/include/sl28cpld.h b/include/sl28cpld.h +index d116607cfb1..9a7c6de31f5 100644 +--- a/include/sl28cpld.h ++++ b/include/sl28cpld.h +@@ -6,6 +6,8 @@ + #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, + +From 34502f7aa343c58c9b4a7206e9fd44e3b89b4dea Mon Sep 17 00:00:00 2001 +From: Michael Walle <michael@walle.cc> +Date: Mon, 15 Nov 2021 23:45:47 +0100 +Subject: [PATCH 07/53] board: sl28: enable sl28cpld support + +Enable the GPIO and watchdog driver. Don't start the watchdog +automatically, though. + +Signed-off-by: Michael Walle <michael@walle.cc> +Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com> +--- + configs/kontron_sl28_defconfig | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/configs/kontron_sl28_defconfig b/configs/kontron_sl28_defconfig +index b61276cf1dd..a0c0c3c6a19 100644 +--- a/configs/kontron_sl28_defconfig ++++ b/configs/kontron_sl28_defconfig +@@ -42,12 +42,14 @@ 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 +@@ -69,8 +71,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 +106,10 @@ 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_OF_LIBFDT_ASSUME_MASK=0x0 + CONFIG_OF_LIBFDT_OVERLAY=y + CONFIG_EFI_SET_TIME=y + +From 2ba8a446ceece208c5926b623ddfd66bd163ff27 Mon Sep 17 00:00:00 2001 +From: Michael Walle <michael@walle.cc> +Date: Mon, 15 Nov 2021 23:45:48 +0100 +Subject: [PATCH 08/53] board: sl28: enable SoC watchdog support + +The SoC provides two additional watchdogs integrated in the SoC. Enable +support for these. + +Signed-off-by: Michael Walle <michael@walle.cc> +Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com> +--- + configs/kontron_sl28_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/configs/kontron_sl28_defconfig b/configs/kontron_sl28_defconfig +index a0c0c3c6a19..a4d9254815a 100644 +--- a/configs/kontron_sl28_defconfig ++++ b/configs/kontron_sl28_defconfig +@@ -110,6 +110,7 @@ CONFIG_USB_GADGET_DOWNLOAD=y + # 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 + +From 453d1711d22c4bccd48848a8450aa95cbc5008cc Mon Sep 17 00:00:00 2001 +From: Michael Walle <michael@walle.cc> +Date: Mon, 15 Nov 2021 23:45:49 +0100 +Subject: [PATCH 09/53] board: sl28: disable recovery watchdog + +This board has an internal watchdog which supervises the board startup. +Although, the initial state of the watchdog is configurable, it is +enabled by default. In board_late_init(), which means almost everything +worked as expected, disable the watchdog. + +Signed-off-by: Michael Walle <michael@walle.cc> +Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com> +--- + board/kontron/sl28/sl28.c | 29 +++++++++++++++++++++++++++++ + doc/board/kontron/sl28.rst | 12 ++++++------ + 2 files changed, 35 insertions(+), 6 deletions(-) + +diff --git a/board/kontron/sl28/sl28.c b/board/kontron/sl28/sl28.c +index 9cde48e61ef..3c48a9141d0 100644 +--- a/board/kontron/sl28/sl28.c ++++ b/board/kontron/sl28/sl28.c +@@ -15,6 +15,7 @@ + #include <asm/arch/soc.h> + #include <fsl_immap.h> + #include <netdev.h> ++#include <wdt.h> + + #include <sl28cpld.h> + #include <fdtdec.h> +@@ -73,6 +74,34 @@ int checkboard(void) + 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) + { + print_ddr_info(0); +diff --git a/doc/board/kontron/sl28.rst b/doc/board/kontron/sl28.rst +index c2cdc5e4241..04483e1e573 100644 +--- a/doc/board/kontron/sl28.rst ++++ b/doc/board/kontron/sl28.rst +@@ -23,17 +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. ++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 + ------------ + +From 2810da7c80ad7d25ef987d65bcaad2479f1df30e Mon Sep 17 00:00:00 2001 +From: Michael Walle <michael@walle.cc> +Date: Mon, 15 Nov 2021 23:45:50 +0100 +Subject: [PATCH 10/53] board: sl28: remove "Useful I2C tricks" section from + docs + +They are no longer needed, because we now have proper driver support for +the sl28cpld management controller. + +Signed-off-by: Michael Walle <michael@walle.cc> +Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com> +--- + doc/board/kontron/sl28.rst | 15 --------------- + 1 file changed, 15 deletions(-) + +diff --git a/doc/board/kontron/sl28.rst b/doc/board/kontron/sl28.rst +index 04483e1e573..44435d90c62 100644 +--- a/doc/board/kontron/sl28.rst ++++ b/doc/board/kontron/sl28.rst +@@ -50,21 +50,6 @@ 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 +------------------ +- +-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. +- +-- reset into failsafe bootloader:: +- +- > i2c mw 4a 5.1 0; i2c mw 4a 6.1 6b; i2c mw 4a 4.1 42 +- +-- read board management controller version:: +- +- > i2c md 4a 3.1 1 +- +- + Builtin watchdog + ---------------- + + +From 62ba0e5df6e81f0a45b589273c043d451986767c Mon Sep 17 00:00:00 2001 +From: Michael Walle <michael@walle.cc> +Date: Fri, 25 Feb 2022 18:18:40 +0530 +Subject: [PATCH 11/53] board: sl28: disable random MAC address generation + +Nowadays, u-boot (when CONFIG_NET_RANDOM_ETHADDR is set) will set +enetaddr to a random value if not set and then pass the randomly +generated MAC address to linux. + +This is bad for the following reasons: + (1) it makes it impossible for linux to detect this error + (2) linux won't trigger any fallback mechanism for the case where + it didn't find any valid MAC address + (3) a saveenv will store this randomly generated MAC address in the + environment + +Probably, the user will also be unaware that something is wrong. He will +just get different MAC addresses on each reboot, asking himself why this +is the case. + +As this board usually have a serial port, the user can just fix this by +setting the MAC address manually in the environment. Also disable the +netconsole just in case, because it cannot be guaranteed that it will +work in any case. After all, this was just a convenience option, because +the bootloader - right now - doesn't have the ability to read the MAC +address, which is stored in the OTP. But it is far more important to +have a clear view of whats wrong with a board and that means we can no +longer use this Kconfig option. + +Signed-off-by: Michael Walle <michael@walle.cc> +[Rebased] +Signed-off-by: Priyanka Jain <priyanka.jain@nxp.com> +--- + configs/kontron_sl28_defconfig | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/configs/kontron_sl28_defconfig b/configs/kontron_sl28_defconfig +index a4d9254815a..b743c2ba9e7 100644 +--- a/configs/kontron_sl28_defconfig ++++ b/configs/kontron_sl28_defconfig +@@ -59,8 +59,6 @@ CONFIG_OF_LIST="" + 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 + +From 554a85313bc7bb50704c2a8d6f4857037aea2426 Mon Sep 17 00:00:00 2001 +From: Michael Walle <michael@walle.cc> +Date: Fri, 25 Feb 2022 18:21:56 +0530 +Subject: [PATCH 12/53] board: sl28: use fit image generator + +Simplify the binman config and fdt nodes by using the "@..-SEQ" +substitutions and CONFIG_OF_LIST. + +Signed-off-by: Michael Walle <michael@walle.cc> +[Rebased] +Signed-off-by: Priyanka Jain <priyanka.jain@nxp.com> +--- + .../dts/fsl-ls1028a-kontron-sl28-u-boot.dtsi | 128 ++---------------- + configs/kontron_sl28_defconfig | 2 +- + 2 files changed, 10 insertions(+), 120 deletions(-) + +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 d4b833284e2..2dcb3c2a58f 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/configs/kontron_sl28_defconfig b/configs/kontron_sl28_defconfig +index b743c2ba9e7..cf8aedfdfd7 100644 +--- a/configs/kontron_sl28_defconfig ++++ b/configs/kontron_sl28_defconfig +@@ -55,7 +55,7 @@ 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 + +From 453db6056850e1ac1be0a12df72fcf3bd5f61bd3 Mon Sep 17 00:00:00 2001 +From: Daniel Klauer <daniel.klauer@gin.de> +Date: Wed, 9 Feb 2022 15:53:41 +0100 +Subject: [PATCH 13/53] lx2160a: Fix distroboot device list for configs without + USB/SCSI/etc + +The BOOT_TARGET_DEVICES list for distro_bootcmd was hard-coded to assume +that all boot devices are available/enabled in the configuration, +thus ignoring the actual config settings. The config_distro_bootcmd.h +header file specifically has compile-time checks to detect such problems. + +To allow disabling USB, SCSI, etc. in custom lx2160a board configs, +make it depend on the config settings and use only the enabled features. + +Signed-off-by: Daniel Klauer <daniel.klauer@gin.de> +Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com> +--- + include/configs/lx2160a_common.h | 34 +++++++++++++++++++++++++++----- + 1 file changed, 29 insertions(+), 5 deletions(-) + +diff --git a/include/configs/lx2160a_common.h b/include/configs/lx2160a_common.h +index e31f8d087f7..4f4b5713dc7 100644 +--- a/include/configs/lx2160a_common.h ++++ b/include/configs/lx2160a_common.h +@@ -244,12 +244,36 @@ + "run distro_bootcmd;run sd2_bootcmd;" \ + "env exists secureboot && esbc_halt;" + ++#ifdef CONFIG_CMD_USB ++#define BOOT_TARGET_DEVICES_USB(func) func(USB, usb, 0) ++#else ++#define BOOT_TARGET_DEVICES_USB(func) ++#endif ++ ++#ifdef CONFIG_MMC ++#define BOOT_TARGET_DEVICES_MMC(func, instance) func(MMC, mmc, instance) ++#else ++#define BOOT_TARGET_DEVICES_MMC(func) ++#endif ++ ++#ifdef CONFIG_SCSI ++#define BOOT_TARGET_DEVICES_SCSI(func) func(SCSI, scsi, 0) ++#else ++#define BOOT_TARGET_DEVICES_SCSI(func) ++#endif ++ ++#ifdef CONFIG_CMD_DHCP ++#define BOOT_TARGET_DEVICES_DHCP(func) func(DHCP, dhcp, na) ++#else ++#define BOOT_TARGET_DEVICES_DHCP(func) ++#endif ++ + #define BOOT_TARGET_DEVICES(func) \ +- func(USB, usb, 0) \ +- func(MMC, mmc, 0) \ +- func(MMC, mmc, 1) \ +- func(SCSI, scsi, 0) \ +- func(DHCP, dhcp, na) ++ BOOT_TARGET_DEVICES_USB(func) \ ++ BOOT_TARGET_DEVICES_MMC(func, 0) \ ++ BOOT_TARGET_DEVICES_MMC(func, 1) \ ++ BOOT_TARGET_DEVICES_SCSI(func) \ ++ BOOT_TARGET_DEVICES_DHCP(func) + #include <config_distro_bootcmd.h> + + #endif /* __LX2_COMMON_H */ + +From 2058967d2fe8f93142d774bc47241d80894027d5 Mon Sep 17 00:00:00 2001 +From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com> +Date: Thu, 17 Feb 2022 11:51:36 +0800 +Subject: [PATCH 14/53] tools: pblimage: fix image header verification function + +The Layerscape platforms have different RCW header value from FSL +PowerPC platforms, the current image header verification callback +is only working on PowerPC, it will fail on Layerscape, this patch +is to fix this issue. + +This is a historical problem and exposed by the following patch: +http://patchwork.ozlabs.org/project/uboot/patch/20220114173443.9877-1-pali@kernel.org + +Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com> +Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com> +--- + Makefile | 2 +- + tools/pblimage.c | 10 ++++++++-- + tools/pblimage.h | 3 ++- + 3 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/Makefile b/Makefile +index 66d9e78cc77..4d9cda7f305 100644 +--- a/Makefile ++++ b/Makefile +@@ -1411,7 +1411,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/tools/pblimage.c b/tools/pblimage.c +index 3c823e96cf1..bd639c276f9 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 81c5492926b..0222e8067b4 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; + +From a41b88ec02ea1dbf4e5e6e895625a5fee96097c5 Mon Sep 17 00:00:00 2001 +From: Tim Harvey <tharvey@gateworks.com> +Date: Mon, 28 Feb 2022 14:53:21 -0800 +Subject: [PATCH 15/53] phy: nop-phy: Fix phy reset if no reset-gpio defined + +Ensure there is a valid reset-gpio defined before using it. + +Fixes: f9852acdce02 ("phy: nop-phy: Fix enabling reset") +Cc: Adam Ford <aford173@gmail.com> +Signed-off-by: Tim Harvey <tharvey@gateworks.com> +--- + drivers/phy/nop-phy.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/drivers/phy/nop-phy.c b/drivers/phy/nop-phy.c +index e2ee6e92068..d0904f4f075 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; + +From a08b04b5c75a7e9122dfc733c66b978aa0afe4ba Mon Sep 17 00:00:00 2001 +From: Jesse Taube <mr.bossman075@gmail.com> +Date: Fri, 11 Feb 2022 19:32:33 -0500 +Subject: [PATCH 16/53] mach-sunxi: Add boot device detection for SUNIV/F1C100s + +In contrast to other Allwinner SoCs the F1C100s BROM does not store a +boot source indicator in the eGON header in SRAM. This leaves the SPL +guessing where we were exactly booted from, and for instance trying +the SD card first, even though we booted from SPI flash. + +By inspecting the BROM code and by experimentation, Samuel found that the +top of the BROM stack contains unique pointers for each of the boot +sources, which we can use as a boot source indicator. + +This patch removes the existing board_boot_order bodge and replace it +with a proper boot source indication function. + +The only caveat is that this only works in the SPL, as the SPL header +gets overwritten with the exception vectors, once U-Boot proper takes +over. Always return MMC0 as the boot source, when called from U-Boot +proper, as a placeholder for now, until we find another way. + +Signed-off-by: Jesse Taube <Mr.Bossman075@gmail.com> +Suggested-by: Samuel Holland <samuel@sholland.org> +Reviewed-by: Andre Przywara <andre.przywara@arm.com> +Signed-off-by: Andre Przywara <andre.przywara@arm.com> +--- + arch/arm/include/asm/arch-sunxi/spl.h | 9 ++++ + arch/arm/mach-sunxi/board.c | 64 ++++++++++++++++----------- + 2 files changed, 46 insertions(+), 27 deletions(-) + +diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h +index 58cdf806d9a..b543d24e5a0 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-sunxi/board.c b/arch/arm/mach-sunxi/board.c +index 57078f7a7b2..0071de19ffd 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) + { + +From 0dcdaff8b88e996de5d9c91141084cbfcfb01be6 Mon Sep 17 00:00:00 2001 +From: Jesse Taube <mr.bossman075@gmail.com> +Date: Fri, 11 Feb 2022 19:32:34 -0500 +Subject: [PATCH 17/53] mach-sunxi: Add SPL SPI boot for SUNIV + +The SUNIV SoCs come with a sun6i-style SPI controller at the base address +of sun4i SPI controller. The module clock of the SPI controller is +missing which leaves us running directly from the AHB clock, which is +set to 200MHz. + +Signed-off-by: Icenowy Zheng <icenowy@aosc.io> +[Icenowy: Original implementation] +Signed-off-by: Jesse Taube <Mr.Bossman075@gmail.com> +[Jesse: adaptation to Upstream U-Boot] +Reviewed-by: Andre Przywara <andre.przywara@arm.com> +Signed-off-by: Andre Przywara <andre.przywara@arm.com> +--- + arch/arm/include/asm/arch-sunxi/gpio.h | 1 + + arch/arm/mach-sunxi/spl_spi_sunxi.c | 24 +++++++++++++++++------- + 2 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h +index 7f7eb0517cf..edd0fbf49fe 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/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c +index 910e8050161..734c165e5d2 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(); + +From 640f2f3bf1d6320274b17192a1ab9d8030211302 Mon Sep 17 00:00:00 2001 +From: Jesse Taube <mr.bossman075@gmail.com> +Date: Fri, 11 Feb 2022 19:32:35 -0500 +Subject: [PATCH 18/53] mach-sunxi: Enable SPI boot for SUNIV and licheepi nano + +Enable SPI boot in SPL on SUNIV architecture and use +it in the licheepi nano that uses the F1C100s. + +Signed-off-by: Jesse Taube <Mr.Bossman075@gmail.com> +Reviewed-by: Andre Przywara <andre.przywara@arm.com> +Signed-off-by: Andre Przywara <andre.przywara@arm.com> +--- + arch/arm/mach-sunxi/Kconfig | 2 +- + configs/licheepi_nano_defconfig | 1 + + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig +index 205fe3c9d3c..d1c60d24082 100644 +--- a/arch/arm/mach-sunxi/Kconfig ++++ b/arch/arm/mach-sunxi/Kconfig +@@ -1038,7 +1038,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/configs/licheepi_nano_defconfig b/configs/licheepi_nano_defconfig +index 2ac0ef42856..9fd1dcc9958 100644 +--- a/configs/licheepi_nano_defconfig ++++ b/configs/licheepi_nano_defconfig +@@ -9,3 +9,4 @@ CONFIG_MACH_SUNIV=y + CONFIG_DRAM_CLK=156 + CONFIG_DRAM_ZQ=0 + # CONFIG_VIDEO_SUNXI is not set ++CONFIG_SPL_SPI_SUNXI=y + +From c21f3d45711135179b4abbdc9462109a41060df6 Mon Sep 17 00:00:00 2001 +From: Andre Przywara <andre.przywara@arm.com> +Date: Tue, 1 Mar 2022 12:21:58 +0000 +Subject: [PATCH 19/53] sunxi: f1c100s: Fix FEL registers restore + +Commit 88998f777531 ("arm: arm926ej-s: Add sunxi code") introduced +the ARM926 version of the code to save and restore some FEL state, to +be able to return to the BROM FEL code after the SPL has run. + +However during review a change was made, that happened to mess up the +register restore part, so SCTLR and CPSR ended up with the wrong values, +breaking return to FEL. + +Use the same offset that we actually save those registers to, to make +FEL booting actually work on the Lichee Pi Nano. + +Signed-off-by: Andre Przywara <andre.przywara@arm.com> +--- + arch/arm/cpu/arm926ejs/sunxi/fel_utils.S | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S b/arch/arm/cpu/arm926ejs/sunxi/fel_utils.S +index 08be7ed11aa..25924033c63 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) + +From cfcf1952c11e6ffcbbf88eb63c49edca2acf1d5e Mon Sep 17 00:00:00 2001 +From: Andre Przywara <andre.przywara@arm.com> +Date: Wed, 2 Mar 2022 01:30:55 +0000 +Subject: [PATCH 20/53] sunxi: f1c100s: Drop SYSRESET to enable reset + functionality + +The F1C100s DT contains the wrong compatible string for the watchdog, +which breaks reset functionality. +Updating the DT goes via the Linux tree, but to allow reset +functionality meanwhile (useful for development!), disable SYSRESET for +now, to let the old-fashioned watchdog driver kick in and provide the +reset_cpu() implementation. + +Signed-off-by: Andre Przywara <andre.przywara@arm.com> +--- + configs/licheepi_nano_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/configs/licheepi_nano_defconfig b/configs/licheepi_nano_defconfig +index 9fd1dcc9958..67b7b85c491 100644 +--- a/configs/licheepi_nano_defconfig ++++ b/configs/licheepi_nano_defconfig +@@ -10,3 +10,4 @@ CONFIG_DRAM_CLK=156 + CONFIG_DRAM_ZQ=0 + # CONFIG_VIDEO_SUNXI is not set + CONFIG_SPL_SPI_SUNXI=y ++# CONFIG_SYSRESET is not set + +From 7938b3be7cedcfe54e891c86e4297b0dccde0f9f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Fri, 18 Feb 2022 12:24:13 +0100 +Subject: [PATCH 21/53] tools: kwboot: Fix quitting terminal +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Sometimes kwboot after quitting terminal prints error message: + + terminal: Bad address + +This is caused by trying to call write() syscall with count of (size_t)-1 +bytes. + +When quit sequence is split into more read() calls then number of input +bytes (nin) at the end of cycle can underflow and be negative. Fix it. + +Fixes: de7514046ea5 ("tools: kwboot: Fix detection of quit esc sequence") +Signed-off-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Stefan Roese <sr@denx.de> +--- + tools/kwboot.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/kwboot.c b/tools/kwboot.c +index 68c0ef1f1b0..2d2d545d825 100644 +--- a/tools/kwboot.c ++++ b/tools/kwboot.c +@@ -1197,7 +1197,7 @@ kwboot_term_pipe(int in, int out, const char *quit, int *s) + if (buf[i] == quit[*s]) { + (*s)++; + if (!quit[*s]) { +- nin = i - *s; ++ nin = (i > *s) ? (i - *s) : 0; + break; + } + } else { +@@ -1208,7 +1208,7 @@ kwboot_term_pipe(int in, int out, const char *quit, int *s) + } + + if (i == nin) +- nin -= *s; ++ nin -= (nin > *s) ? *s : nin; + } + + if (kwboot_write(out, buf, nin) < 0) + +From 68285176a9552ba264878cdc6c7daccb5806b569 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Fri, 18 Feb 2022 12:25:22 +0100 +Subject: [PATCH 22/53] pci: pci_mvebu: Remove unused SELECT and lane_mask +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Macro SELECT() is unused and struct mvebu_pcie field lane_mask is unused +too. Remove them. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Marek Behún <marek.behun@nic.cz> +Reviewed-by: Stefan Roese <sr@denx.de> +--- + drivers/pci/pci_mvebu.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c +index 5a0a59a8b9e..16fe54fd366 100644 +--- a/drivers/pci/pci_mvebu.c ++++ b/drivers/pci/pci_mvebu.c +@@ -30,8 +30,6 @@ + #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 +@@ -77,7 +75,6 @@ struct mvebu_pcie { + u32 lane; + bool is_x4; + int devfn; +- u32 lane_mask; + int sec_busno; + char name[16]; + unsigned int mem_target; + +From fc27e5df637dd4c954b67dd1415b9af144718a9e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Fri, 18 Feb 2022 12:25:23 +0100 +Subject: [PATCH 23/53] pci: pci_mvebu: Cleanup macro names +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use "MVPCIE_" prefix instead of generic "PCIE_" prefix for pci_mvebu.c +specific macros. Define offset macros for Root Port registers and use +standard register macros from pci.h when accessing Root Port registers. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Marek Behún <marek.behun@nic.cz> +Reviewed-by: Stefan Roese <sr@denx.de> +--- + drivers/pci/pci_mvebu.c | 130 +++++++++++++++++++--------------------- + 1 file changed, 60 insertions(+), 70 deletions(-) + +diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c +index 16fe54fd366..f07669374d7 100644 +--- a/drivers/pci/pci_mvebu.c ++++ b/drivers/pci/pci_mvebu.c +@@ -30,35 +30,25 @@ + #include <linux/sizes.h> + + /* PCIe unit register offsets */ +-#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 +@@ -87,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) +@@ -112,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) +@@ -195,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; +@@ -286,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; +@@ -321,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; +@@ -342,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; + } +@@ -357,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 */ +@@ -403,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 +@@ -414,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) +@@ -440,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 +@@ -448,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 + +From 7f59ed68728e732062f4fb0c1e8940f5bf550ded Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <marek.behun@nic.cz> +Date: Fri, 18 Feb 2022 17:46:25 +0100 +Subject: [PATCH 24/53] arm: mvebu: turris_omnia: Enable ext4 write support in + defconfig +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Enable ext4 write support in Turris Omnia's defconfig. Some users find +it useful. + +Signed-off-by: Marek Behún <marek.behun@nic.cz> +Reviewed-by: Stefan Roese <sr@denx.de> +--- + configs/turris_omnia_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig +index 280dd55f001..5b1fdbfb2d3 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 + +From 1fd54253bca7d43d046bba4853fe5fafd034bc17 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Wed, 23 Feb 2022 13:52:32 +0100 +Subject: [PATCH 25/53] arm: a37xx: pci: Fix a3700_fdt_fix_pcie_regions() + function again +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The a3700_fdt_fix_pcie_regions() function still computes nonsense. + +It computes the fixup offset from the PCI address taken from the first +row of the "ranges" array, which means that: +- PCI address must equal CPU address (otherwise the computed fix offset + will be wrong), +- the first row must contain the lowest address. + +This is the case for the default device-tree, which is why we didn't +notice it. + +It also adds the fixup offset to all PCI and CPU addresses, which is +wrong. + +Instead: +1) The fixup offset must be computed from the CPU address, not PCI + address. + +2) The fixup offset must be computed from the row containing the lowest + CPU address, which is not necessarily contained in the first row. + +3) The PCI address - the address to which the PCIe controller remaps the + address space as seen from the point of view of the PCIe device - + must be fixed by the fix offset in the same way as the CPU address + only in the special case when the CPU adn PCI addresses are the same. + Same addresses means that remapping is disabled, and thus if we + change the CPU address, we need also to change the PCI address so + that the remapping is still disabled afterwards. + +Consider an example: + The ranges entries contain: + PCI address CPU address + 70000000 EA000000 + E9000000 E9000000 + EB000000 EB000000 + + By default CPU PCIe window is at: E8000000 - F0000000 + Consider the case when TF-A moves it to: F2000000 - FA000000 + + Until now the function would take the PCI address of the first entry: + 70000000, and the new base, F2000000, to compute the fix offset: + F2000000 - 70000000 = 82000000, and then add 8200000 to all addresses, + resulting in + PCI address CPU address + F2000000 6C000000 + 6B000000 6B000000 + 6D000000 6D000000 + which is complete nonsense - none of the CPU addresses is in the + requested window. + + Now it will take the lowest CPU address, which is in second row, + E9000000, and compute the fix offset F2000000 - E9000000 = 09000000, + and then add it to all CPU addresses and those PCI addresses which + equal to their corresponding CPU addresses, resulting in + PCI address CPU address + 70000000 F3000000 + F2000000 F2000000 + F4000000 F4000000 + where all of the CPU addresses are in the needed window. + +Fixes: 4a82fca8e330 ("arm: a37xx: pci: Fix a3700_fdt_fix_pcie_regions() function") +Signed-off-by: Pali Rohár <pali@kernel.org> +Signed-off-by: Marek Behún <marek.behun@nic.cz> +Reviewed-by: Stefan Roese <sr@denx.de> +--- + arch/arm/mach-mvebu/armada3700/cpu.c | 81 +++++++++++++++++++--------- + 1 file changed, 55 insertions(+), 26 deletions(-) + +diff --git a/arch/arm/mach-mvebu/armada3700/cpu.c b/arch/arm/mach-mvebu/armada3700/cpu.c +index 23492f49dae..52b5109b735 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; + } + +From 2454de2c34531941756d259771fd0266ea2d5d0b Mon Sep 17 00:00:00 2001 +From: Francois Berder <fberder@outlook.fr> +Date: Mon, 28 Feb 2022 10:31:45 +0100 +Subject: [PATCH 26/53] drivers: rtc: fix null pointer access in + armada38x_rtc_reset + +Replace null pointer by pointer to device registers when calling +armada38x_rtc_write. + +Signed-off-by: Francois Berder <fberder@outlook.fr> +Reviewed-by: Stefan Roese <sr@denx.de> +--- + drivers/rtc/armada38x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/rtc/armada38x.c b/drivers/rtc/armada38x.c +index 2d264acf779..2af64e39122 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; + +From 87724d5c905be4fb5eeed0e31384664721db4098 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <marek.behun@nic.cz> +Date: Mon, 28 Feb 2022 15:59:37 +0100 +Subject: [PATCH 27/53] arm64: a37xx: pinctrl: Fix PWM pins indexes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 5534fb4f4833 ("arm64: a37xx: pinctrl: Correct PWM pins +definitions") introduced bogus definitions os PWM pins: all 4 pins have +index 11, instead of having indexes 11, 12, 13, 14. + +Fix this. + +Signed-off-by: Marek Behún <marek.behun@nic.cz> +Reviewed-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Stefan Roese <sr@denx.de> +--- + drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +index 1cf1f06f101..e76ef153e60 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"), + +From 0a6f0297c677946907b7ba34d34995fe03055aad Mon Sep 17 00:00:00 2001 +From: Chris Packham <judge.packham@gmail.com> +Date: Tue, 1 Mar 2022 13:53:23 +1300 +Subject: [PATCH 28/53] ARM: mvebu: x530: clearfog: Add ODT configuration + +Commit 369e532691e0 ("ddr: marvell: a38x: allow board specific ODT +configuration") added the odt_config member to struct +mv_ddr_topology_map ahead of the clk_enable and ck_delay members. This +means that any boards that configured either of clk_enable or ck_delay +needed to have their board topology updated. This affects the x530 and +clearfog boards. Other A38x boards don't touch any of the trailing +members of mv_ddr_topology_map so don't need updating. + +Fixes: 369e532691e0 ("ddr: marvell: a38x: allow board specific ODT configuration") +Signed-off-by: Chris Packham <judge.packham@gmail.com> +Acked-by: Baruch Siach <baruch@tkos.co.il> +Reviewed-by: Stefan Roese <sr@denx.de> +--- + board/alliedtelesis/x530/x530.c | 1 + + board/solidrun/clearfog/clearfog.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/board/alliedtelesis/x530/x530.c b/board/alliedtelesis/x530/x530.c +index 8b31045a074..c0ec2afa301 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/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c +index c920cf8d6b5..03adb591d82 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 */ + }; + + +From d8865f8677c6dd43109e22bfbb85a3cd6bf6aca1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Wed, 2 Mar 2022 11:49:18 +0100 +Subject: [PATCH 29/53] tools: kwboot: Check for return value of + kwboot_tty_send() and tcflush() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Failure of kwboot_tty_send() and tcflush() functions is fatal, it does not +make sense to continue. So return error back to the caller like in other +places where are called these functions. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Stefan Roese <sr@denx.de> +Tested-by: Stefan Roese <sr@denx.de> +--- + tools/kwboot.c | 30 +++++++++++++++++++----------- + 1 file changed, 19 insertions(+), 11 deletions(-) + +diff --git a/tools/kwboot.c b/tools/kwboot.c +index 2d2d545d825..5a7c53ce892 100644 +--- a/tools/kwboot.c ++++ b/tools/kwboot.c +@@ -740,10 +740,8 @@ kwboot_bootmsg(int tty, void *msg) + + for (count = 0; count < 128; count++) { + rc = kwboot_tty_send(tty, msg, 8, 0); +- if (rc) { +- usleep(msg_req_delay * 1000); +- continue; +- } ++ if (rc) ++ break; + } + + rc = kwboot_tty_recv(tty, &c, 1, msg_rsp_timeo); +@@ -772,11 +770,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,7 +791,11 @@ 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; + } +@@ -805,10 +815,8 @@ kwboot_debugmsg(int tty, void *msg) + break; + + rc = kwboot_tty_send(tty, msg, 8, 0); +- if (rc) { +- usleep(msg_req_delay * 1000); +- continue; +- } ++ if (rc) ++ break; + + rc = kwboot_tty_recv(tty, buf, 16, msg_rsp_timeo); + + +From 132016e2706affdd9e150c4e34fd2d1f5bd05749 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Wed, 2 Mar 2022 11:49:19 +0100 +Subject: [PATCH 30/53] tools: kwboot: Remove msg_req_delay +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Variable msg_req_delay is set but never used. So completely remove it. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Stefan Roese <sr@denx.de> +Tested-by: Stefan Roese <sr@denx.de> +--- + tools/kwboot.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/tools/kwboot.c b/tools/kwboot.c +index 5a7c53ce892..4dfb1038b4f 100644 +--- a/tools/kwboot.c ++++ b/tools/kwboot.c +@@ -48,11 +48,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 +283,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; + +@@ -1725,7 +1722,6 @@ kwboot_usage(FILE *stream, char *progname) + " -D <image>: boot <image> without preamble (Dove)\n"); + fprintf(stream, " -d: enter 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"); +@@ -1804,12 +1800,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': + +From c1d911f15f81a09126f52fac3e78e2eb6cfd224b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Wed, 2 Mar 2022 11:49:20 +0100 +Subject: [PATCH 31/53] tools: kwboot: Cleanup bootmsg and debugmsg variables +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Function kwboot_debugmsg() is always called with kwboot_msg_debug as msg +and function kwboot_bootmsg() with kwboot_msg_debug as msg. Function +kwboot_bootmsg() is never called with NULL msg. + +Simplify, cleanup and remove dead code. + +No functional change. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Stefan Roese <sr@denx.de> +Tested-by: Stefan Roese <sr@denx.de> +--- + tools/kwboot.c | 31 ++++++++++++++----------------- + 1 file changed, 14 insertions(+), 17 deletions(-) + +diff --git a/tools/kwboot.c b/tools/kwboot.c +index 4dfb1038b4f..4e2acb52458 100644 +--- a/tools/kwboot.c ++++ b/tools/kwboot.c +@@ -718,17 +718,14 @@ kwboot_open_tty(const char *path, int baudrate) + } + + static int +-kwboot_bootmsg(int tty, void *msg) ++kwboot_bootmsg(int tty) + { + struct kwboot_block block; + 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..."); ++ kwboot_printv("Sending boot message. Please reboot the target..."); + + do { + rc = tcflush(tty, TCIOFLUSH); +@@ -736,7 +733,7 @@ kwboot_bootmsg(int tty, void *msg) + break; + + for (count = 0; count < 128; count++) { +- rc = kwboot_tty_send(tty, msg, 8, 0); ++ rc = kwboot_tty_send(tty, kwboot_msg_boot, sizeof(kwboot_msg_boot), 0); + if (rc) + break; + } +@@ -798,7 +795,7 @@ kwboot_bootmsg(int tty, void *msg) + } + + static int +-kwboot_debugmsg(int tty, void *msg) ++kwboot_debugmsg(int tty) + { + int rc; + +@@ -811,7 +808,7 @@ kwboot_debugmsg(int tty, void *msg) + if (rc) + break; + +- rc = kwboot_tty_send(tty, msg, 8, 0); ++ rc = kwboot_tty_send(tty, kwboot_msg_debug, sizeof(kwboot_msg_debug), 0); + if (rc) + break; + +@@ -1737,8 +1734,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; +@@ -1748,8 +1745,8 @@ main(int argc, char **argv) + + rv = 1; + tty = -1; +- bootmsg = NULL; +- debugmsg = NULL; ++ bootmsg = 0; ++ debugmsg = 0; + imgpath = NULL; + img = NULL; + term = 0; +@@ -1771,7 +1768,7 @@ 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] != '-') +@@ -1781,14 +1778,14 @@ main(int argc, char **argv) + 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': +@@ -1869,13 +1866,13 @@ main(int argc, char **argv) + } + + if (debugmsg) { +- rc = kwboot_debugmsg(tty, debugmsg); ++ rc = kwboot_debugmsg(tty); + if (rc) { + perror("debugmsg"); + goto out; + } + } else if (bootmsg) { +- rc = kwboot_bootmsg(tty, bootmsg); ++ rc = kwboot_bootmsg(tty); + if (rc) { + perror("bootmsg"); + goto out; + +From 913866af6c97c37bbdb8165c32d8046b8ec2c5e1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Wed, 2 Mar 2022 11:49:21 +0100 +Subject: [PATCH 32/53] tools: kwboot: Use separate thread for sending boot + message pattern +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +After BootROM successfully detects boot message pattern on UART it waits +until host stop sending data on UART. For example Armada 385 BootROM +requires that host does not send anything on UART at least 24 ms. If host +is still sending something then BootROM waits (possibly infinitely). + +BootROM successfully detects boot message pattern if it receives it in +small period of time after power on. + +So to ensure that host put BootROM into UART boot mode, host must send +continuous stream of boot message pattern with a small gap (for A385 at +least 24 ms) after series of pattern. But this gap cannot be too often or +too long to ensure that it does not cover whole BootROM time window when it +is detecting for boot message pattern. + +Therefore it is needed to do following steps in cycle without any delay: +1. send series of boot message pattern over UART +2. wait until kernel transmit all data +3. sleep small period of time + +At the same time, host needs to monitor input queue, data received on the +UART and checking if it contains NAK byte by which BootROM informs that +xmodem transfer is ready. + +But it is not possible to wait until kernel transmit all data on UART and +at the same time in the one process to also wait for input data. This is +limitation of POSIX tty API and also by linux kernel that it does not +provide asynchronous function for waiting until all data are transmitted. +There is only synchronous variant tcdrain(). + +So to correctly implement this handshake on systems with linux kernel, it +is needed to use tcdrain() in separate thread. + +Implement sending of boot message pattern in one thread and reading of +reply in the main thread. Use pthread library for threads. + +This change makes UART booting on Armada 385 more reliable. It is possible +to start kwboot and power on board after minute and kwboot correctly put +board into UART boot mode. + +Old implementation without separate thread has an issue that it read just +one byte from UART input queue and then it send 128 message pattern to the +output queue. If some noise was on UART then kwboot was not able to read +BootROM response as its input queue was just overflowed and kwboot was +sending more data than receiving. + +This change basically fixed above issue too. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Stefan Roese <sr@denx.de> +Tested-by: Stefan Roese <sr@denx.de> +--- + tools/Makefile | 3 ++ + tools/kwboot.c | 120 +++++++++++++++++++++++++++++++++++++++++-------- + 2 files changed, 104 insertions(+), 19 deletions(-) + +diff --git a/tools/Makefile b/tools/Makefile +index 5409ff2879c..f8fb9fe09ee 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 ++ + ifdtool-objs := $(LIBFDT_OBJS) ifdtool.o + hostprogs-$(CONFIG_X86) += ifdtool + +diff --git a/tools/kwboot.c b/tools/kwboot.c +index 4e2acb52458..9fd90b9bec7 100644 +--- a/tools/kwboot.c ++++ b/tools/kwboot.c +@@ -28,6 +28,7 @@ + #include <stdint.h> + #include <time.h> + #include <sys/stat.h> ++#include <pthread.h> + + #ifdef __linux__ + #include "termios_linux.h" +@@ -717,37 +718,120 @@ kwboot_open_tty(const char *path, int baudrate) + 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_msg_start_thread(pthread_t *thread, int *tty, void *msg) ++{ ++ void *arg[2]; ++ int rc; ++ ++ arg[0] = tty; ++ arg[1] = msg; ++ rc = pthread_create(thread, NULL, kwboot_msg_write_handler, arg); ++ if (rc) { ++ errno = rc; ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int ++kwboot_msg_stop_thread(pthread_t thread) ++{ ++ int rc; ++ ++ rc = pthread_cancel(thread); ++ if (rc) { ++ errno = rc; ++ return -1; ++ } ++ ++ rc = pthread_join(thread, NULL); ++ if (rc) { ++ errno = rc; ++ return -1; ++ } ++ ++ return 0; ++} ++ + static int + kwboot_bootmsg(int tty) + { + struct kwboot_block block; +- int rc; ++ pthread_t write_thread; ++ int rc, err; + char c; +- int count; +- +- kwboot_printv("Sending boot message. Please reboot the target..."); + +- do { +- rc = tcflush(tty, TCIOFLUSH); +- if (rc) +- break; ++ /* flush input and output queue */ ++ tcflush(tty, TCIOFLUSH); + +- for (count = 0; count < 128; count++) { +- rc = kwboot_tty_send(tty, kwboot_msg_boot, sizeof(kwboot_msg_boot), 0); +- if (rc) +- break; +- } ++ rc = kwboot_msg_start_thread(&write_thread, &tty, kwboot_msg_boot); ++ if (rc) { ++ perror("Failed to start write thread"); ++ return rc; ++ } + +- rc = kwboot_tty_recv(tty, &c, 1, msg_rsp_timeo); ++ 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 +@@ -1873,10 +1957,8 @@ main(int argc, char **argv) + } + } else if (bootmsg) { + rc = kwboot_bootmsg(tty); +- if (rc) { +- perror("bootmsg"); ++ if (rc) + goto out; +- } + } + + if (img) { + +From 93976af58926626077eca8b7bbd1aa592649ec01 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Wed, 2 Mar 2022 11:49:22 +0100 +Subject: [PATCH 33/53] tools: kwboot: Fix sending and processing debug message + pattern (-d option) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +-d option is currently broken. In most cases BootROM does not detect this +message pattern. For sending debug message pattern it is needed to do same +steps as for boot message pattern. + +Implement sending debug message pattern via same separate thread like it is +for boot message pattern. + +Checking if BootROM entered into UART debug mode is different than +detecting UART boot mode. When in boot mode, BootROM sends xmodem NAK +bytes. When in debug mode, BootROM activates console echo and reply back +every written byte (extept \r\n which is interpreted as executing command +and \b which is interpreting as removing the last sent byte). + +So in kwboot, check that BootROM send back at least 4 debug message +patterns as a echo reply for debug message patterns which kwboot is sending +in the loop. + +Then there is another observation, if host writes too many bytes (as +command) then BootROM command line buffer may overflow after trying to +execute such long command. To workaround this overflow, it is enough to +remove bytes from the input line buffer by sending 3 \b bytes for every +sent character. So do it. + +With this change, it is possbile to enter into the UART debug mode with +kwboot -d option. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Stefan Roese <sr@denx.de> +Tested-by: Stefan Roese <sr@denx.de> +--- + tools/kwboot.c | 139 +++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 123 insertions(+), 16 deletions(-) + +diff --git a/tools/kwboot.c b/tools/kwboot.c +index 9fd90b9bec7..3ab49e74bb6 100644 +--- a/tools/kwboot.c ++++ b/tools/kwboot.c +@@ -881,30 +881,139 @@ kwboot_bootmsg(int tty) + static int + 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, kwboot_msg_debug, sizeof(kwboot_msg_debug), 0); +- if (rc) ++ 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 +@@ -1951,10 +2060,8 @@ main(int argc, char **argv) + + if (debugmsg) { + rc = kwboot_debugmsg(tty); +- if (rc) { +- perror("debugmsg"); ++ if (rc) + goto out; +- } + } else if (bootmsg) { + rc = kwboot_bootmsg(tty); + if (rc) + +From e8d26e8276358fcd1c2fe28293d3b4c82a735731 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Wed, 2 Mar 2022 11:49:23 +0100 +Subject: [PATCH 34/53] tools: kwboot: Add support for backspace key in mini + terminal +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Marvell BootROM recognize only '\b' byte as backspace. Use terminfo +for retrieving current backspace sequence and replace any occurrence of +backspace sequence by the '\b' byte. + +Reading terminfo database is possible via tigetstr() function from system +library libtinfo.so.*. So link kwboot with -ltinfo. + +Normally terminfo functions are in <term.h> system header file. But this +header file conflicts with U-Boot "termios_linux.h" header file. So declare +terminfo functions manually. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Stefan Roese <sr@denx.de> +Tested-by: Stefan Roese <sr@denx.de> +--- + tools/Makefile | 2 +- + tools/kwboot.c | 109 +++++++++++++++++++++++++++++++++++++++++++------ + 2 files changed, 97 insertions(+), 14 deletions(-) + +diff --git a/tools/Makefile b/tools/Makefile +index f8fb9fe09ee..60231c728ce 100644 +--- a/tools/Makefile ++++ b/tools/Makefile +@@ -197,7 +197,7 @@ hostprogs-$(CONFIG_EXYNOS5420) += mkexynosspl + HOSTCFLAGS_mkexynosspl.o := -pedantic + + HOSTCFLAGS_kwboot.o += -pthread +-HOSTLDLIBS_kwboot += -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 3ab49e74bb6..26cfe6dea6a 100644 +--- a/tools/kwboot.c ++++ b/tools/kwboot.c +@@ -36,6 +36,13 @@ + #include <termios.h> + #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 + */ +@@ -1376,37 +1383,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) ? (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 -= (nin > *s) ? *s : nin; ++ 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; +@@ -1415,7 +1469,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; + +@@ -1434,6 +1489,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 +@@ -1441,6 +1523,7 @@ kwboot_terminal(int tty) + + rc = 0; + s = 0; ++ k = 0; + + do { + fd_set rfds; +@@ -1460,13 +1543,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; + } + +From bdc4dbaefe98890cc7ec7b6aa2d4e85b086527cd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Wed, 2 Mar 2022 11:49:24 +0100 +Subject: [PATCH 35/53] tools: kwboot: Update usage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add all supported Armada SoCs and document -b and -d options in usage. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Stefan Roese <sr@denx.de> +Tested-by: Stefan Roese <sr@denx.de> +--- + tools/kwboot.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/tools/kwboot.c b/tools/kwboot.c +index 26cfe6dea6a..11aca00bf1e 100644 +--- a/tools/kwboot.c ++++ b/tools/kwboot.c +@@ -1986,14 +1986,15 @@ 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, 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, " -s <resp-timeo>: use specific response-timeout\n"); + fprintf(stream, + +From 787fcf5c004d3e4e9fd4b8b6e092bcfe73714cbb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Wed, 2 Mar 2022 11:49:25 +0100 +Subject: [PATCH 36/53] tools: kwboot: Update manpage +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Document -D, -b, -d, -q and -s options. + +Add common examples how to use kwboot. + +Add information about Armada 38x BootROM bug for debug console mode and how +to workaround it. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Stefan Roese <sr@denx.de> +Tested-by: Stefan Roese <sr@denx.de> +--- + doc/kwboot.1 | 103 +++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 99 insertions(+), 4 deletions(-) + +diff --git a/doc/kwboot.1 b/doc/kwboot.1 +index acdea891d9f..bda049bde56 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. +@@ -47,6 +47,48 @@ code in it's header which may also print some output via UART (for + 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. +@@ -55,13 +97,33 @@ In the past, when this option was used, the program patched the header + 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" + + +From 0b5909d3afaff4fe552cb01de3cb6e537e8bfece Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Wed, 2 Mar 2022 11:49:26 +0100 +Subject: [PATCH 37/53] tools: kwboot: Update doc about Avanta +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Testes proved that current kwboot version supports also Avanta SoCs. +It looks like that Avanta SoCs are using same kwbimage format as Armada. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Tested-by: Tony Dinh <mibodhi@gmail.com> +Reviewed-by: Stefan Roese <sr@denx.de> +Tested-by: Stefan Roese <sr@denx.de> +--- + doc/kwboot.1 | 2 +- + tools/kwboot.c | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/doc/kwboot.1 b/doc/kwboot.1 +index bda049bde56..f555ff26a25 100644 +--- a/doc/kwboot.1 ++++ b/doc/kwboot.1 +@@ -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 +diff --git a/tools/kwboot.c b/tools/kwboot.c +index 11aca00bf1e..cd1879246a8 100644 +--- a/tools/kwboot.c ++++ b/tools/kwboot.c +@@ -1,7 +1,7 @@ + /* + * 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> +@@ -1990,7 +1990,7 @@ kwboot_usage(FILE *stream, char *progname) + progname); + fprintf(stream, "\n"); + fprintf(stream, +- " -b <image>: boot <image> with preamble (Kirkwood, Armada 370/XP/375/38x/39x)\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, " -b: enter xmodem boot mode\n"); + +From f4fa962fcdbd69589021a096f1af0690fe884279 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Wed, 2 Mar 2022 11:49:27 +0100 +Subject: [PATCH 38/53] tools: kwboot: Update references with public links +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Public documents about BootROM of some Marvell SoCs are available in the +public Web Archive. Put this information into source code. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Stefan Roese <sr@denx.de> +Tested-by: Stefan Roese <sr@denx.de> +--- + tools/kwboot.c | 31 ++++++++++++++++++++++++++++--- + 1 file changed, 28 insertions(+), 3 deletions(-) + +diff --git a/tools/kwboot.c b/tools/kwboot.c +index cd1879246a8..69d1be0f482 100644 +--- a/tools/kwboot.c ++++ b/tools/kwboot.c +@@ -7,9 +7,34 @@ + * (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" + +From 4ff9a8c33c5f2514ee6e66788259399b6626f6b5 Mon Sep 17 00:00:00 2001 +From: Romain Naour <romain.naour@smile.fr> +Date: Thu, 10 Feb 2022 23:13:36 +0100 +Subject: [PATCH 39/53] configs: ti: use standard configuration nodes naming + +Currently, any u-boot bootloader for ti armv7 platforms using +DEFAULT_FIT_TI_ARGS to boot with a fitimage (boot_fit = 1) +doesn't boot when built with Yocto Poky (openembedded-core). + + ## Loading kernel from FIT Image at 90000000 ... + Could not find configuration node + ERROR: can't get kernel image! + +Arago forked the kernel-fitimage class [1] and altered the +configuration nodes naming while adding the OPTEE support by +using FITIMAGE_CONF_BY_NAME by default [2]. + +The "upstream" kernel-fitimage class from openembedded-core still +add the "conf-" prefix for each configuration nodes [3]. + +The ITS file format (from doc/uImage.FIT/source_file_format.txt) +is not really accurate with the expected naming of these nodes. +But in practice the "conf-" prefix is widely used. + +When the FIT image support has been added for ti armv7 platforms +the naming from Arago has been used [3]. Fix this issue by adding +the prefix expected by the ITS file generated by kernel-fitimage +class from openembedded-core. + +[1] http://arago-project.org/git/meta-arago.git?p=meta-arago.git;a=commitdiff;h=719ab1b2098bcdc59c249e3529fa82cb1b9130e6 +[2] http://arago-project.org/git/meta-arago.git?p=meta-arago.git;a=commitdiff;h=f23f2876a0cda89241d031bb7ba0b4256ed90035 +[3] https://git.openembedded.org/openembedded-core/tree/meta/classes/kernel-fitimage.bbclass?h=yocto-3.1.13#n290 +[3] 1e93cc8473e4fe018aececc8ed3bf8fc2b3ff561 + +Signed-off-by: Romain Naour <romain.naour@smile.fr> +Cc: Tom Rini <trini@konsulko.com> +Reviewed-by: Denys Dmytriyenko <denys@konsulko.com> +--- + include/configs/ti_armv7_common.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/configs/ti_armv7_common.h b/include/configs/ti_armv7_common.h +index 97337070092..7483bc821d3 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, + +From f7fbe547d99729cfa36238ba1629c26589834867 Mon Sep 17 00:00:00 2001 +From: Christian Gmeiner <christian.gmeiner@gmail.com> +Date: Tue, 15 Feb 2022 07:47:55 +0100 +Subject: [PATCH 40/53] arm: mach-k3: am6_init: Use CONFIG_TI_I2C_BOARD_DETECT + +We only want to call do_board_detect() if CONFIG_TI_I2C_BOARD_DETECT +is set. Same as done for am64. + +This makes it possible to add a custom am65 based board design to +U-Boot that does not use this board detection mechanism. + +Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com> +--- + arch/arm/mach-k3/am6_init.c | 3 ++- + board/ti/am65x/evm.c | 26 +++++++++++++++----------- + 2 files changed, 17 insertions(+), 12 deletions(-) + +diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c +index ffb7aaded2e..8a6b1de7641 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/board/ti/am65x/evm.c b/board/ti/am65x/evm.c +index fbe33cbea55..7182a8cad1a 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; + } + +From 4403e1a31cca73d516c2302e2950ddc8ea7d0c37 Mon Sep 17 00:00:00 2001 +From: Aswath Govindraju <a-govindraju@ti.com> +Date: Wed, 16 Feb 2022 11:27:24 +0530 +Subject: [PATCH 41/53] configs: j721e_*_evm_a72_defconfig: Enable config for + setting mmc speed mode + +Enable config for setting mmc speed mode from U-Boot command line. + +Signed-off-by: Aswath Govindraju <a-govindraju@ti.com> +--- + configs/j721e_evm_a72_defconfig | 1 + + configs/j721e_hs_evm_a72_defconfig | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig +index b843a84415b..60c96f89613 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 ae184b03587..6479f9baff0 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 + +From 39834ccdd43f492c61c0d8b4db55988b1f47a4dc Mon Sep 17 00:00:00 2001 +From: Jan Kiszka <jan.kiszka@siemens.com> +Date: Wed, 16 Feb 2022 09:06:49 +0100 +Subject: [PATCH 42/53] arm: dts: iot2050: Add cfg register space for ringacc + and udmap + +Recent unrelated fixes (9876ae7db6da) revealed that we were missing bits +from 2af181b53e28 in the IOT2050 dt. Add them, but only for main U-Boot. +SPL loads from QSPI only, thus cannot use DMA. + +Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> +--- + .../dts/k3-am65-iot2050-common-u-boot.dtsi | 25 ++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +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 286e25f3794..d80c5501d2f 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 { + +From 55fd1c442e747338604ef0075a4a888a40399ddc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?S=C3=A9bastien=20Szymanski?= + <sebastien.szymanski@armadeus.com> +Date: Fri, 25 Feb 2022 14:48:54 +0100 +Subject: [PATCH 43/53] cmd: pwm: fix typo 'eisable' -> 'disable' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixed misspelled 'disable' in help text. + +Signed-off-by: Sébastien Szymanski <sebastien.szymanski@armadeus.com> +--- + cmd/pwm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cmd/pwm.c b/cmd/pwm.c +index 7947e61aeed..7e82955239f 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"); + +From 5017f9b595da6e5c8f064a43fc6cd42cb62c082a Mon Sep 17 00:00:00 2001 +From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> +Date: Tue, 1 Mar 2022 08:53:56 +0100 +Subject: [PATCH 44/53] mkimage: error handling for FIT image + +If parameter -F is given but FIT support is missing, a NULL pointer might +dereferenced (Coverity CID 350249). + +If incorrect parameters are given, provide a message and show usage. + +Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> +--- + tools/mkimage.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/tools/mkimage.c b/tools/mkimage.c +index 760145119dc..74bd072832c 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(¶ms); + + if (retval != EXIT_SUCCESS) +- exit (retval); ++ usage("Bad parameters for FIT image type"); + } + + if (params.lflag || params.fflag) { + +From 4fa4227cdd14020bb6d588293f3cb8591aeebfa0 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Tue, 1 Mar 2022 12:43:32 +0100 +Subject: [PATCH 45/53] .mailmap: Record all address for main U-Boot + contributor + +Based on looking at top contributors it was seen that top statistics from +top contributors don't include all contributions from different email +addresses. That's why I checked all top contributors are checked it. + +git shortlog -n $START..$END -e -s + +The patch is adding mapping for Bin Meng, Marek Vasut, Masahiro Yamada, +Michal Simek, Tom Rini, Wolfgang Denk. +And also use mapping for Stefan Roese and Wolfgang Denk to be properly +counted. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +Acked-by: Bin Meng <bmeng.cn@gmail.com> +Reviewed-by: Stefan Roese <sr@denx.de> +--- + .mailmap | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/.mailmap b/.mailmap +index b36ae66719e..36fc1164a2b 100644 +--- a/.mailmap ++++ b/.mailmap +@@ -22,6 +22,7 @@ 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> +@@ -35,7 +36,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 +56,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> + +From 9b5ad4f5da756939eac4123fc347af533eeb339e Mon Sep 17 00:00:00 2001 +From: Yann Droneaud <ydroneaud@opteya.com> +Date: Tue, 1 Mar 2022 16:12:34 +0100 +Subject: [PATCH 46/53] lib: rsa: use actual OpenSSL 1.1.0 EVP MD API + +Since OpenSSL 1.1.0, EVP_MD_CTX_create() is EVP_MD_CTX_new() + EVP_MD_CTX_destroy() is EVP_MD_CTX_free() + EVP_MD_CTX_init() is EVP_MD_CTX_reset() + +As there's no need to reset a newly created EVP_MD_CTX, moreover +EVP_DigestSignInit() does the reset, thus call to EVP_MD_CTX_init() +can be dropped. +As there's no need to reset an EVP_MD_CTX before it's destroyed, +as it will be reset by EVP_MD_CTX_free(), call to EVP_MD_CTX_reset() +is not needed and can be dropped. + +Signed-off-by: Yann Droneaud <ydroneaud@opteya.com> +--- + lib/rsa/rsa-sign.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/lib/rsa/rsa-sign.c b/lib/rsa/rsa-sign.c +index 3e7b7982890..b2a21199e48 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: + +From a12366a807a8fbba67b6da6e842e8296af60aba0 Mon Sep 17 00:00:00 2001 +From: Stefan Roese <sr@denx.de> +Date: Thu, 13 Jan 2022 16:57:31 +0100 +Subject: [PATCH 47/53] MAINTAINERS: Add watchdog maintainers entry + +I've been handling "inofficially" the watchdog related patches for a few +years now. Let's make this official and add a tree for it and also add +myself here in the MAINTAINERS file. + +Signed-off-by: Stefan Roese <sr@denx.de> +Cc: Tom Rini <trini@konsulko.com> +Cc: Harald Seiler <hws@denx.de> +Reviewed-by: Tom Rini <trini@konsulko.com> +--- + MAINTAINERS | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/MAINTAINERS b/MAINTAINERS +index 0f39bc6bc92..82fc49e31d4 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -1326,6 +1326,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> + +From a12492ebbc88dab74b1d6e27d8194a56eb1fbbff Mon Sep 17 00:00:00 2001 +From: Philippe Reynes <philippe.reynes@softathome.com> +Date: Thu, 10 Feb 2022 18:17:54 +0100 +Subject: [PATCH 48/53] drivers: watchdog: wdt-uclass.c: add a property u-boot, + noautostart + +Since commit 492ee6b8d0e7 ("watchdog: wdt-uclass.c: handle all DM +watchdogs in watchdog_reset()"), all the watchdog are started when +the config WATCHDOG_AUTOSTART. + +To avoid a binary choice none/all, a property u-boot,noautostart +may be added in the watchdog node of the u-boot device tree to not +autostart this watchdog. + +Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com> +Reviewed-by: Simon Glass <sjg@chromium.org> +Reviewed-by: Stefan Roese <sr@denx.de> +--- + drivers/watchdog/wdt-uclass.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c +index 6d0f4738676..dbf556467d3 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. + +From 65066773a3e4c3f1dfc5eac8400ca7a7268e4fb7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali@kernel.org> +Date: Wed, 23 Feb 2022 14:21:40 +0100 +Subject: [PATCH 49/53] watchdog: armada_37xx: Probe driver also when watchdog + is already running +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If Armada 37xx watchdog is started before U-Boot then CNTR_CTRL_ACTIVE bit +is set, U-Boot armada-37xx-wdt.c driver fails to initialize and so U-Boot +is unable to use or kick this watchdog. + +Do not check for CNTR_CTRL_ACTIVE bit and always initialize watchdog. Same +behavior is implemented in Linux kernel driver. + +This change allows to activate watchdog in firmware which loads U-Boot. + +Signed-off-by: Pali Rohár <pali@kernel.org> +Reviewed-by: Marek Behún <marek.behun@nic.cz> +Reviewed-by: Stefan Roese <sr@denx.de> +--- + drivers/watchdog/armada-37xx-wdt.c | 17 +++-------------- + 1 file changed, 3 insertions(+), 14 deletions(-) + +diff --git a/drivers/watchdog/armada-37xx-wdt.c b/drivers/watchdog/armada-37xx-wdt.c +index 2e119b9b5aa..bacebbc7926 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; + + +From 817e153fe546c2da9df8e8affc94d12036815659 Mon Sep 17 00:00:00 2001 +From: Jan Kiszka <jan.kiszka@siemens.com> +Date: Tue, 8 Mar 2022 07:25:50 +0100 +Subject: [PATCH 50/53] watchdog: rti_wdt: Add 10% safety margin to clock + frequency + +When running against RC_OSC_32k, the watchdog may suffer from running +faster than expected, expiring earlier. The Linux kernel adds a 10% +margin to the timeout calculation by slowing down the read clock rate +accordingly. Do the same here, also to have comparable preset values +for both drivers. + +Along this, fix the name of the local var holding to frequency - in Hz, +not kHz. + +Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> +Signed-off-by: Stefan Roese <sr@denx.de> +--- + drivers/watchdog/rti_wdt.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c +index 253286d349b..8d93f19b984 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; + } + +From 45eb35c1979e928a2b086b090be86ac249114e62 Mon Sep 17 00:00:00 2001 +From: Michal Simek <michal.simek@xilinx.com> +Date: Mon, 7 Mar 2022 08:41:21 +0100 +Subject: [PATCH 51/53] .mailmap: Fix Heinrich's xypron.glpk@gmx.de record + +There is one issue with Heinrich xypron.glpk@gmx.de <xypron.glpk@gmx.de> +record which should be specifically grouped with his name. + +Signed-off-by: Michal Simek <michal.simek@xilinx.com> +--- + .mailmap | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.mailmap b/.mailmap +index 36fc1164a2b..1f88ea953ce 100644 +--- a/.mailmap ++++ b/.mailmap +@@ -28,6 +28,7 @@ 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> + +From c12f9d2e5496489c22aa265725cc71697d2de0cb Mon Sep 17 00:00:00 2001 +From: Mark Kettenis <kettenis@openbsd.org> +Date: Mon, 21 Feb 2022 22:17:37 +0100 +Subject: [PATCH 52/53] drivers: serial: Make sure we really return a serial + device + +The stdout-path property in the device tree does not necessarily +point at a serial device. On machines such as the Apple M1 laptops +where the serial port isn't easy to access and users expect to see +console output on the integrated display stdout-path may point at +the device tree node for the framebuffer for example. + +If stdout-path does not point at a node for a serial device, the +serial_check_stdout() will not find a bound device and will drop +down into code that attempts to use lists_bind_fdt() to bind a +device anyway. However, that fallback code does not check that +the uclass of the device is UCLASS_SERIAL. So if stdout-path points +at the framebuffer instead of the serial device it will return a +UCLASS_VIDEO device. Since the code that calls this function +expects the returned device to be a UCLASS_SERIAL device, U-Boot +will crash as soon as it attempts to send output to the console. + +Add a check here to verify that the uclass of the bound device +really is UCLASS_SERIAL. If it isn't, serial_check_stdout() will +return an error and serial_find_console_or_panic() will use the +serial device with sequence number 0 as the console and all is fine. + +Signed-off-by: Mark Kettenis <kettenis@openbsd.org> +Reviewed-by: Simon Glass <sjg@chromium.org> +--- + drivers/serial/serial-uclass.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c +index 362cedd9552..f30f352bd7a 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; + } + + +From b38fbddbaa3dca0a190f9655f753e72405290431 Mon Sep 17 00:00:00 2001 +From: Philippe Reynes <philippe.reynes@softathome.com> +Date: Tue, 8 Mar 2022 10:37:19 +0100 +Subject: [PATCH 53/53] board: .gitignore: replace dsdt.c by dsdt_generated.c + +Since commit 5d94cbd1dca7 ("scripts: Makefile.lib: generate +dsdt_generated.c instead of dsdt.c"), the file generated +is named dsdt_generated.c instead of dsdt.c. +So all files .gitignore referencing dsdt.c should be +upated with dsdt_generated.c. + +Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com> +Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de> +--- + board/advantech/som-db5800-som-6867/.gitignore | 6 +++--- + board/congatec/conga-qeval20-qa3-e3845/.gitignore | 6 +++--- + board/intel/bayleybay/.gitignore | 6 +++--- + board/intel/edison/.gitignore | 6 +++--- + board/intel/galileo/.gitignore | 6 +++--- + board/intel/minnowmax/.gitignore | 6 +++--- + 6 files changed, 18 insertions(+), 18 deletions(-) + +diff --git a/board/advantech/som-db5800-som-6867/.gitignore b/board/advantech/som-db5800-som-6867/.gitignore +index 6eb8a5481ab..39e46ba0ae7 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/congatec/conga-qeval20-qa3-e3845/.gitignore b/board/congatec/conga-qeval20-qa3-e3845/.gitignore +index 6eb8a5481ab..39e46ba0ae7 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/intel/bayleybay/.gitignore b/board/intel/bayleybay/.gitignore +index 6eb8a5481ab..39e46ba0ae7 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 6eb8a5481ab..39e46ba0ae7 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 6eb8a5481ab..39e46ba0ae7 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 6eb8a5481ab..39e46ba0ae7 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/2002-mmc-sdhci-Add-HS400-Enhanced-Strobe-support.patch b/2001-mmc-sdhci-Add-HS400-Enhanced-Strobe-support.patch similarity index 100% rename from 2002-mmc-sdhci-Add-HS400-Enhanced-Strobe-support.patch rename to 2001-mmc-sdhci-Add-HS400-Enhanced-Strobe-support.patch diff --git a/2001-phy-Track-power-on-and-init-counts-in-uclass.patch b/2001-phy-Track-power-on-and-init-counts-in-uclass.patch deleted file mode 100644 index d0283bc..0000000 --- a/2001-phy-Track-power-on-and-init-counts-in-uclass.patch +++ /dev/null @@ -1,430 +0,0 @@ -From 226fce6108fe364e35f3eb9a84ff1a7ec93727ce Mon Sep 17 00:00:00 2001 -From: Alper Nebi Yasak <alpernebiyasak@gmail.com> -Date: Thu, 30 Dec 2021 22:36:51 +0300 -Subject: [PATCH] phy: Track power-on and init counts in uclass - -On boards using the RK3399 SoC, the USB OHCI and EHCI controllers share -the same PHY device instance. While these controllers are being stopped -they both attempt to power-off and deinitialize it, but trying to -power-off the deinitialized PHY device results in a hang. This usually -happens just before booting an OS, and can be explicitly triggered by -running "usb start; usb stop" in the U-Boot shell. - -Implement a uclass-wide counting mechanism for PHY initialization and -power state change requests, so that we don't power-off/deinitialize a -PHY instance until all of its users want it done. The Allwinner A10 USB -PHY driver does this counting in-driver, remove those parts in favour of -this in-uclass implementation. - -The sandbox PHY operations test needs some changes since the uclass will -no longer call into the drivers for actions matching its tracked state -(e.g. powering-off a powered-off PHY). Update that test, and add a new -one which simulates multiple users of a single PHY. - -The major complication here is that PHY handles aren't deduplicated per -instance, so the obvious idea of putting the counts in the PHY handles -don't immediately work. It seems possible to bind a child udevice per -PHY instance to the PHY provider and deduplicate the handles in each -child's uclass-private areas, like in the CLK framework. An alternative -approach could be to use those bound child udevices themselves as the -PHY handles. Instead, to avoid the architectural changes those would -require, this patch solves things by dynamically allocating a list of -structs (one per instance) in the provider's uclass-private area. - -Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com> -Reviewed-by: Simon Glass <sjg@chromium.org> -Tested-by: Peter Robinson <pbrobinson@gmail.com> - Rock960 ---- - drivers/phy/allwinner/phy-sun4i-usb.c | 9 -- - drivers/phy/phy-uclass.c | 137 ++++++++++++++++++++++++++ - test/dm/phy.c | 83 +++++++++++++++- - 3 files changed, 215 insertions(+), 14 deletions(-) - -diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c -index ab2a5d17fc..86c589a65f 100644 ---- a/drivers/phy/allwinner/phy-sun4i-usb.c -+++ b/drivers/phy/allwinner/phy-sun4i-usb.c -@@ -125,7 +125,6 @@ struct sun4i_usb_phy_info { - - struct sun4i_usb_phy_plat { - void __iomem *pmu; -- int power_on_count; - int gpio_vbus; - int gpio_vbus_det; - int gpio_id_det; -@@ -225,10 +224,6 @@ static int sun4i_usb_phy_power_on(struct phy *phy) - initial_usb_scan_delay = 0; - } - -- usb_phy->power_on_count++; -- if (usb_phy->power_on_count != 1) -- return 0; -- - if (usb_phy->gpio_vbus >= 0) - gpio_set_value(usb_phy->gpio_vbus, SUNXI_GPIO_PULL_UP); - -@@ -240,10 +235,6 @@ static int sun4i_usb_phy_power_off(struct phy *phy) - struct sun4i_usb_phy_data *data = dev_get_priv(phy->dev); - struct sun4i_usb_phy_plat *usb_phy = &data->usb_phy[phy->id]; - -- usb_phy->power_on_count--; -- if (usb_phy->power_on_count != 0) -- return 0; -- - if (usb_phy->gpio_vbus >= 0) - gpio_set_value(usb_phy->gpio_vbus, SUNXI_GPIO_PULL_DISABLE); - -diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c -index 706e9fdf3a..49e2ec25c2 100644 ---- a/drivers/phy/phy-uclass.c -+++ b/drivers/phy/phy-uclass.c -@@ -11,12 +11,96 @@ - #include <dm/device_compat.h> - #include <dm/devres.h> - #include <generic-phy.h> -+#include <linux/list.h> -+ -+/** -+ * struct phy_counts - Init and power-on counts of a single PHY port -+ * -+ * This structure is used to keep track of PHY initialization and power -+ * state change requests, so that we don't power off and deinitialize a -+ * PHY instance until all of its users want it done. Otherwise, multiple -+ * consumers using the same PHY port can cause problems (e.g. one might -+ * call power_off() after another's exit() and hang indefinitely). -+ * -+ * @id: The PHY ID within a PHY provider -+ * @power_on_count: Times generic_phy_power_on() was called for this ID -+ * without a matching generic_phy_power_off() afterwards -+ * @init_count: Times generic_phy_init() was called for this ID -+ * without a matching generic_phy_exit() afterwards -+ * @list: Handle for a linked list of these structures corresponding to -+ * ports of the same PHY provider -+ */ -+struct phy_counts { -+ unsigned long id; -+ int power_on_count; -+ int init_count; -+ struct list_head list; -+}; - - static inline struct phy_ops *phy_dev_ops(struct udevice *dev) - { - return (struct phy_ops *)dev->driver->ops; - } - -+static struct phy_counts *phy_get_counts(struct phy *phy) -+{ -+ struct list_head *uc_priv; -+ struct phy_counts *counts; -+ -+ if (!generic_phy_valid(phy)) -+ return NULL; -+ -+ uc_priv = dev_get_uclass_priv(phy->dev); -+ list_for_each_entry(counts, uc_priv, list) -+ if (counts->id == phy->id) -+ return counts; -+ -+ return NULL; -+} -+ -+static int phy_alloc_counts(struct phy *phy) -+{ -+ struct list_head *uc_priv; -+ struct phy_counts *counts; -+ -+ if (!generic_phy_valid(phy)) -+ return 0; -+ if (phy_get_counts(phy)) -+ return 0; -+ -+ uc_priv = dev_get_uclass_priv(phy->dev); -+ counts = kzalloc(sizeof(*counts), GFP_KERNEL); -+ if (!counts) -+ return -ENOMEM; -+ -+ counts->id = phy->id; -+ counts->power_on_count = 0; -+ counts->init_count = 0; -+ list_add(&counts->list, uc_priv); -+ -+ return 0; -+} -+ -+static int phy_uclass_pre_probe(struct udevice *dev) -+{ -+ struct list_head *uc_priv = dev_get_uclass_priv(dev); -+ -+ INIT_LIST_HEAD(uc_priv); -+ -+ return 0; -+} -+ -+static int phy_uclass_pre_remove(struct udevice *dev) -+{ -+ struct list_head *uc_priv = dev_get_uclass_priv(dev); -+ struct phy_counts *counts, *next; -+ -+ list_for_each_entry_safe(counts, next, uc_priv, list) -+ kfree(counts); -+ -+ return 0; -+} -+ - static int generic_phy_xlate_offs_flags(struct phy *phy, - struct ofnode_phandle_args *args) - { -@@ -88,6 +172,12 @@ int generic_phy_get_by_index_nodev(ofnode node, int index, struct phy *phy) - goto err; - } - -+ ret = phy_alloc_counts(phy); -+ if (ret) { -+ debug("phy_alloc_counts() failed: %d\n", ret); -+ goto err; -+ } -+ - return 0; - - err: -@@ -118,6 +208,7 @@ int generic_phy_get_by_name(struct udevice *dev, const char *phy_name, - - int generic_phy_init(struct phy *phy) - { -+ struct phy_counts *counts; - struct phy_ops const *ops; - int ret; - -@@ -126,10 +217,19 @@ int generic_phy_init(struct phy *phy) - ops = phy_dev_ops(phy->dev); - if (!ops->init) - return 0; -+ -+ counts = phy_get_counts(phy); -+ if (counts->init_count > 0) { -+ counts->init_count++; -+ return 0; -+ } -+ - ret = ops->init(phy); - if (ret) - dev_err(phy->dev, "PHY: Failed to init %s: %d.\n", - phy->dev->name, ret); -+ else -+ counts->init_count = 1; - - return ret; - } -@@ -154,6 +254,7 @@ int generic_phy_reset(struct phy *phy) - - int generic_phy_exit(struct phy *phy) - { -+ struct phy_counts *counts; - struct phy_ops const *ops; - int ret; - -@@ -162,16 +263,28 @@ int generic_phy_exit(struct phy *phy) - ops = phy_dev_ops(phy->dev); - if (!ops->exit) - return 0; -+ -+ counts = phy_get_counts(phy); -+ if (counts->init_count == 0) -+ return 0; -+ if (counts->init_count > 1) { -+ counts->init_count--; -+ return 0; -+ } -+ - ret = ops->exit(phy); - if (ret) - dev_err(phy->dev, "PHY: Failed to exit %s: %d.\n", - phy->dev->name, ret); -+ else -+ counts->init_count = 0; - - return ret; - } - - int generic_phy_power_on(struct phy *phy) - { -+ struct phy_counts *counts; - struct phy_ops const *ops; - int ret; - -@@ -180,16 +293,26 @@ int generic_phy_power_on(struct phy *phy) - ops = phy_dev_ops(phy->dev); - if (!ops->power_on) - return 0; -+ -+ counts = phy_get_counts(phy); -+ if (counts->power_on_count > 0) { -+ counts->power_on_count++; -+ return 0; -+ } -+ - ret = ops->power_on(phy); - if (ret) - dev_err(phy->dev, "PHY: Failed to power on %s: %d.\n", - phy->dev->name, ret); -+ else -+ counts->power_on_count = 1; - - return ret; - } - - int generic_phy_power_off(struct phy *phy) - { -+ struct phy_counts *counts; - struct phy_ops const *ops; - int ret; - -@@ -198,10 +321,21 @@ int generic_phy_power_off(struct phy *phy) - ops = phy_dev_ops(phy->dev); - if (!ops->power_off) - return 0; -+ -+ counts = phy_get_counts(phy); -+ if (counts->power_on_count == 0) -+ return 0; -+ if (counts->power_on_count > 1) { -+ counts->power_on_count--; -+ return 0; -+ } -+ - ret = ops->power_off(phy); - if (ret) - dev_err(phy->dev, "PHY: Failed to power off %s: %d.\n", - phy->dev->name, ret); -+ else -+ counts->power_on_count = 0; - - return ret; - } -@@ -316,4 +450,7 @@ int generic_phy_power_off_bulk(struct phy_bulk *bulk) - UCLASS_DRIVER(phy) = { - .id = UCLASS_PHY, - .name = "phy", -+ .pre_probe = phy_uclass_pre_probe, -+ .pre_remove = phy_uclass_pre_remove, -+ .per_device_auto = sizeof(struct list_head), - }; -diff --git a/test/dm/phy.c b/test/dm/phy.c -index ecbd47bf12..df4c73fc70 100644 ---- a/test/dm/phy.c -+++ b/test/dm/phy.c -@@ -79,12 +79,15 @@ static int dm_test_phy_ops(struct unit_test_state *uts) - ut_assertok(generic_phy_power_off(&phy1)); - - /* -- * test operations after exit(). -- * The sandbox phy driver does not allow it. -+ * Test power_on() failure after exit(). -+ * The sandbox phy driver does not allow power-on/off after -+ * exit, but the uclass counts power-on/init calls and skips -+ * calling the driver's ops when e.g. powering off an already -+ * powered-off phy. - */ - ut_assertok(generic_phy_exit(&phy1)); - ut_assert(generic_phy_power_on(&phy1) != 0); -- ut_assert(generic_phy_power_off(&phy1) != 0); -+ ut_assertok(generic_phy_power_off(&phy1)); - - /* - * test normal operations again (after re-init) -@@ -99,6 +102,17 @@ static int dm_test_phy_ops(struct unit_test_state *uts) - */ - ut_assertok(generic_phy_reset(&phy1)); - -+ /* -+ * Test power_off() failure after exit(). -+ * For this we need to call exit() while the phy is powered-on, -+ * so that the uclass actually calls the driver's power-off() -+ * and reports the resulting failure. -+ */ -+ ut_assertok(generic_phy_power_on(&phy1)); -+ ut_assertok(generic_phy_exit(&phy1)); -+ ut_assert(generic_phy_power_off(&phy1) != 0); -+ ut_assertok(generic_phy_power_on(&phy1)); -+ - /* PHY2 has a known problem with power off */ - ut_assertok(generic_phy_init(&phy2)); - ut_assertok(generic_phy_power_on(&phy2)); -@@ -106,8 +120,8 @@ static int dm_test_phy_ops(struct unit_test_state *uts) - - /* PHY3 has a known problem with power off and power on */ - ut_assertok(generic_phy_init(&phy3)); -- ut_asserteq(-EIO, generic_phy_power_off(&phy3)); -- ut_asserteq(-EIO, generic_phy_power_off(&phy3)); -+ ut_asserteq(-EIO, generic_phy_power_on(&phy3)); -+ ut_assertok(generic_phy_power_off(&phy3)); - - return 0; - } -@@ -145,3 +159,62 @@ static int dm_test_phy_bulk(struct unit_test_state *uts) - return 0; - } - DM_TEST(dm_test_phy_bulk, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); -+ -+static int dm_test_phy_multi_exit(struct unit_test_state *uts) -+{ -+ struct phy phy1_method1; -+ struct phy phy1_method2; -+ struct phy phy1_method3; -+ struct udevice *parent; -+ -+ /* Get the same phy instance in 3 different ways. */ -+ ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS, -+ "gen_phy_user", &parent)); -+ ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method1)); -+ ut_asserteq(0, phy1_method1.id); -+ ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method2)); -+ ut_asserteq(0, phy1_method2.id); -+ ut_asserteq_ptr(phy1_method1.dev, phy1_method1.dev); -+ -+ ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS, -+ "gen_phy_user1", &parent)); -+ ut_assertok(generic_phy_get_by_name(parent, "phy1", &phy1_method3)); -+ ut_asserteq(0, phy1_method3.id); -+ ut_asserteq_ptr(phy1_method1.dev, phy1_method3.dev); -+ -+ /* -+ * Test using the same PHY from different handles. -+ * In non-test code these could be in different drivers. -+ */ -+ -+ /* -+ * These must only call the driver's ops at the first init() -+ * and power_on(). -+ */ -+ ut_assertok(generic_phy_init(&phy1_method1)); -+ ut_assertok(generic_phy_init(&phy1_method2)); -+ ut_assertok(generic_phy_power_on(&phy1_method1)); -+ ut_assertok(generic_phy_power_on(&phy1_method2)); -+ ut_assertok(generic_phy_init(&phy1_method3)); -+ ut_assertok(generic_phy_power_on(&phy1_method3)); -+ -+ /* -+ * These must not call the driver's ops as other handles still -+ * want the PHY powered-on and initialized. -+ */ -+ ut_assertok(generic_phy_power_off(&phy1_method3)); -+ ut_assertok(generic_phy_exit(&phy1_method3)); -+ -+ /* -+ * We would get an error here if the generic_phy_exit() above -+ * actually called the driver's exit(), as the sandbox driver -+ * doesn't allow power-off() after exit(). -+ */ -+ ut_assertok(generic_phy_power_off(&phy1_method1)); -+ ut_assertok(generic_phy_power_off(&phy1_method2)); -+ ut_assertok(generic_phy_exit(&phy1_method1)); -+ ut_assertok(generic_phy_exit(&phy1_method2)); -+ -+ return 0; -+} -+DM_TEST(dm_test_phy_multi_exit, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); --- -2.33.1 - diff --git a/2003-rockchip-sdhci-Fix-RK3399-eMMC-PHY-power-cycling.patch b/2002-rockchip-sdhci-Fix-RK3399-eMMC-PHY-power-cycling.patch similarity index 100% rename from 2003-rockchip-sdhci-Fix-RK3399-eMMC-PHY-power-cycling.patch rename to 2002-rockchip-sdhci-Fix-RK3399-eMMC-PHY-power-cycling.patch diff --git a/2004-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3399.patch b/2003-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3399.patch similarity index 100% rename from 2004-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3399.patch rename to 2003-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3399.patch diff --git a/2005-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3568.patch b/2004-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3568.patch similarity index 100% rename from 2005-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3568.patch rename to 2004-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3568.patch diff --git a/2006-mmc-sdhci-allow-disabling-sdma-in-spl.patch b/2005-mmc-sdhci-allow-disabling-sdma-in-spl.patch similarity index 100% rename from 2006-mmc-sdhci-allow-disabling-sdma-in-spl.patch rename to 2005-mmc-sdhci-allow-disabling-sdma-in-spl.patch diff --git a/PKGBUILD b/PKGBUILD index ebb9f25..9a2afe7 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -5,13 +5,14 @@ # Contributor: Dragan Simic <dsimic@buserror.io> pkgname=uboot-pinephonepro -pkgver=2022.01 -pkgrel=0.2 +pkgver=2022.04rc3 +pkgrel=1 epoch=4 _tfaver=2.6 +_commit=589c659035a44a683b087fd75fe0b7667f7be7f5 pkgdesc="U-Boot for Pine64 PinePhone Pro" arch=('aarch64') -url='https://git.sr.ht/~martijnbraam/u-boot' +url='https://source.denx.de/u-boot/u-boot' license=('GPL') makedepends=('git' 'arm-none-eabi-gcc' 'dtc' 'bc') depends=('uboot-tools') @@ -25,30 +26,30 @@ source=("ftp://ftp.denx.de/pub/u-boot/u-boot-${pkgver/rc/-rc}.tar.bz2" "ppp-prepare-fstab.service" "ppp-uboot-flash" "ppp-uboot-mkscr" + "1000-upstream-${_commit}.patch::https://github.com/u-boot/u-boot/compare/v${pkgver/rc/-rc}...${_commit}.patch" "1001-Correct-boot-order-to-be-USB-SD-eMMC.patch" "1002-rockchip-Add-initial-support-for-the-PinePhone-Pro.patch" #"1003-Configure-USB-power-settings-for-PinePhone-Pro.patch" "1004-mtd-spi-nor-ids-Add-GigaDevice-GD25LQ128E-entry.patch" - "2001-phy-Track-power-on-and-init-counts-in-uclass.patch" - "2002-mmc-sdhci-Add-HS400-Enhanced-Strobe-support.patch" - "2003-rockchip-sdhci-Fix-RK3399-eMMC-PHY-power-cycling.patch" - "2004-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3399.patch" - "2005-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3568.patch" - "2006-mmc-sdhci-allow-disabling-sdma-in-spl.patch" + "2001-mmc-sdhci-Add-HS400-Enhanced-Strobe-support.patch" + "2002-rockchip-sdhci-Fix-RK3399-eMMC-PHY-power-cycling.patch" + "2003-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3399.patch" + "2004-rockchip-sdhci-Add-HS400-Enhanced-Strobe-support-for-RK3568.patch" + "2005-mmc-sdhci-allow-disabling-sdma-in-spl.patch" "3001-pinephone-pro-Remove-cargo-culted-iodomain-config.patch" "3002-pine64-pinephonePro-SPI-support.patch") -sha256sums=('81b4543227db228c03f8a1bf5ddbc813b0bb8f6555ce46064ef721a6fc680413' +sha256sums=('4731da5228dc35827a9d9ebc8f541b01aa6af36c27be24e10aff06e596bee2de' '4e59f02ccb042d5d18c89c849701b96e6cf4b788709564405354b5d313d173f7' - '4e356b3868c0c1ac061c2c15c7ba80c627e1743214680409f418f9b4c00eb3f7' + '12311da7e1a8d7bf19ddf78568e58da0888b0ca89e937aecccae4d896d20b7e2' 'de7e36cdc7ed2fb5abb9155c97f87926361aa5be87d794c9016776160f3430ec' 'e55fb02dfb6213eabbb899b468dc5f68d36a11c05feda4c14e80282415222fea' '6265fb9d3bc84bf1217383b52587b1d5a36372d88a824932586a802a502f62ba' '05eaccb2e8ea1eba3e86a4e7fcf12fd232195b5018c049ddf36e5a82a968cc24' + '527e061dba87b9a080517c27407bfaf883753cf2ddd2e302dbdaf6dca6888ecc' '017d33aac55f8a5ed22170c97b4792ba755a4dad04f6c0cdd85119bbc81e87b3' '7c3d76f4bee0e54900142043241248072e334387065212141e1f600afe0aafba' #'b750ba47843defafd8be1cc2615983c93e9cde5a4f5a7b55308a6f00f3fe6611' '1c9cc403f527733b9ef093505c147074ac5afa881380d65ae3819f2bad75c8cd' - 'feb6ed9924f1b8f76066002cf3e414592e9ac8977f8e7aca8adc0c3d8bdb687f' '68ff1130b396cf106ee16fd2e697fc61eb6fb3e873d78551b8247de73386ed1e' 'ee52b4374f159e648b6b21e40b399804c763bb3ddde60b016fcd6e0da8135f2f' '17e4adb43ac13a1297b5df8e1b7d3d03b555f5b5bc2085647e105cbd0897a238' @@ -118,6 +119,11 @@ build() { update_config 'CONFIG_IDENT_STRING' '" Manjaro Linux ARM"' update_config 'CONFIG_BOOTDELAY' '0' + # Try a couple of SPI tweaks; if actually needed, these options + # will be propely moved to a PinePhone Pro configuration patch later + update_config 'CONFIG_SPL_DM_SEQ_ALIAS' 'y' + update_config 'CONFIG_SF_DEFAULT_BUS' '1' + # Disable DMA for eMMC, to make suspend/resume work; this option # will be propely moved to a PinePhone Pro configuration patch later update_config 'CONFIG_SPL_MMC_SDHCI_SDMA' 'n' diff --git a/boot.txt b/boot.txt index 60e610a..909b741 100644 --- a/boot.txt +++ b/boot.txt @@ -19,7 +19,7 @@ gpio set 154 part uuid ${devtype} ${devnum}:1 uuid_boot part uuid ${devtype} ${devnum}:2 uuid_root -setenv bootargs loglevel=4 console=tty0 console=${console} earlycon=uart8250,mmio32,0xff1a0000 consoleblank=0 boot=PARTUUID=${uuid_boot} root=PARTUUID=${uuid_root} rw rootwait quiet audit=0 bootsplash.bootfile=bootsplash-themes/manjaro/bootsplash +setenv bootargs loglevel=4 console=ttyS2,1500000 console=tty0 earlycon=uart8250,mmio32,0xff1a0000 consoleblank=0 boot=PARTUUID=${uuid_boot} root=PARTUUID=${uuid_root} rw rootwait quiet audit=0 bootsplash.bootfile=bootsplash-themes/manjaro/bootsplash if load ${devtype} ${devnum}:${distro_bootpart} ${kernel_addr_r} /Image; then gpio clear 105 -- GitLab