diff options
342 files changed, 6003 insertions, 1269 deletions
@@ -1,9 +1,9 @@ # SPDX-License-Identifier: GPL-2.0+ VERSION = 2024 -PATCHLEVEL = 01 +PATCHLEVEL = 04 SUBLEVEL = -EXTRAVERSION = +EXTRAVERSION = -rc1 NAME = # *DOCUMENTATION* diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index abd7c6c79a8..59e4d4d949a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1160,14 +1160,14 @@ config ARCH_SUNXI select SPL_SEPARATE_BSS if SPL select SPL_STACK_R if SPL select SPL_SYS_MALLOC_SIMPLE if SPL - select SPL_SYS_THUMB_BUILD if !ARM64 + select SPL_SYS_THUMB_BUILD if SPL && !ARM64 select SUNXI_GPIO select SYS_NS16550 select SYS_THUMB_BUILD if !ARM64 select USB if DISTRO_DEFAULTS select USB_KEYBOARD if DISTRO_DEFAULTS && USB_HOST select USB_STORAGE if DISTRO_DEFAULTS && USB_HOST - select SPL_USE_TINY_PRINTF + select SPL_USE_TINY_PRINTF if SPL select USE_PREBOOT select SYS_RELOC_GD_ENV_ADDR imply BOARD_LATE_INIT diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index b5c588c3363..50f35e3db3f 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -838,6 +838,7 @@ dtb-$(CONFIG_MACH_SUN50I_H6) += \ dtb-$(CONFIG_MACH_SUN50I_H616) += \ sun50i-h616-orangepi-zero2.dtb \ sun50i-h618-orangepi-zero3.dtb \ + sun50i-h618-transpeed-8k618-t.dtb \ sun50i-h616-x96-mate.dtb dtb-$(CONFIG_MACH_SUN50I) += \ sun50i-a64-amarula-relic.dtb \ diff --git a/arch/arm/dts/sama5d2.dtsi b/arch/arm/dts/sama5d2.dtsi index 819564fdd5b..7b62fffb4ff 100644 --- a/arch/arm/dts/sama5d2.dtsi +++ b/arch/arm/dts/sama5d2.dtsi @@ -34,6 +34,15 @@ #size-cells = <1>; bootph-all; + nfc_sram: sram@100000 { + compatible = "mmio-sram"; + no-memory-wc; + reg = <0x00100000 0x2400>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x00100000 0x2400>; + }; + usb1: ohci@400000 { compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00400000 0x100000>; @@ -50,6 +59,32 @@ status = "disabled"; }; + ebi: ebi@10000000 { + compatible = "atmel,sama5d3-ebi"; + #address-cells = <2>; + #size-cells = <1>; + atmel,smc = <&hsmc>; + reg = <0x10000000 0x10000000 + 0x60000000 0x30000000>; + ranges = <0x0 0x0 0x10000000 0x10000000 + 0x1 0x0 0x60000000 0x10000000 + 0x2 0x0 0x70000000 0x10000000 + 0x3 0x0 0x80000000 0x10000000>; + clocks = <&h32ck>; + status = "disabled"; + + nand_controller: nand-controller { + compatible = "atmel,sama5d3-nand-controller"; + atmel,nfc-sram = <&nfc_sram>; + atmel,nfc-io = <&nfc_io>; + ecc-engine = <&pmecc>; + #address-cells = <2>; + #size-cells = <1>; + ranges; + status = "disabled"; + }; + }; + sdmmc0: sdio-host@a0000000 { compatible = "atmel,sama5d2-sdhci"; reg = <0xa0000000 0x300>; @@ -66,6 +101,11 @@ status = "disabled"; }; + nfc_io: nfc-io@c0000000 { + compatible = "atmel,sama5d3-nfc-io", "syscon"; + reg = <0xc0000000 0x8000000>; + }; + apb { compatible = "simple-bus"; #address-cells = <1>; @@ -79,7 +119,7 @@ status = "disabled"; }; - pmc: pmc@f0014000 { + pmc: clock-controller@f0014000 { compatible = "atmel,sama5d2-pmc", "syscon"; reg = <0xf0014000 0x160>; #address-cells = <1>; @@ -657,6 +697,22 @@ }; }; + hsmc: hsmc@f8014000 { + compatible = "atmel,sama5d2-smc", "syscon", "simple-mfd"; + reg = <0xf8014000 0x1000>; + interrupts = <17 IRQ_TYPE_LEVEL_HIGH 6>; + clocks = <&hsmc_clk>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + pmecc: ecc-engine@f8014070 { + compatible = "atmel,sama5d2-pmecc"; + reg = <0xf8014070 0x490>, + <0xf8014500 0x200>; + }; + }; + uart0: serial@f801c000 { compatible = "atmel,at91sam9260-usart"; reg = <0xf801c000 0x100>; @@ -698,13 +754,18 @@ status = "disabled"; }; - rstc@f8048000 { + sfr: sfr@f8030000 { + compatible = "atmel,sama5d2-sfr", "syscon"; + reg = <0xf8030000 0x98>; + }; + + reset_controller: reset-controller@f8048000 { compatible = "atmel,sama5d3-rstc"; reg = <0xf8048000 0x10>; clocks = <&clk32k>; }; - shdwc@f8048010 { + shutdown_controller: poweroff@f8048010 { compatible = "atmel,sama5d2-shdwc"; reg = <0xf8048010 0x10>; clocks = <&clk32k>; @@ -719,18 +780,13 @@ clocks = <&h32ck>; }; - watchdog@f8048040 { + watchdog: watchdog@f8048040 { compatible = "atmel,sama5d4-wdt"; reg = <0xf8048040 0x10>; clocks = <&clk32k>; status = "disabled"; }; - sfr: sfr@f8030000 { - compatible = "atmel,sama5d2-sfr", "syscon"; - reg = <0xf8030000 0x98>; - }; - sckc@f8048050 { compatible = "atmel,at91sam9x5-sckc"; reg = <0xf8048050 0x4>; diff --git a/arch/arm/dts/sun50i-h616-bigtreetech-cb1-manta.dts b/arch/arm/dts/sun50i-h616-bigtreetech-cb1-manta.dts new file mode 100644 index 00000000000..dbce61b355d --- /dev/null +++ b/arch/arm/dts/sun50i-h616-bigtreetech-cb1-manta.dts @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: (GPL-2.0+ or MIT) +/* + * Copyright (C) 2023 Martin Botka <martin.botka@somainline.org>. + */ + +/dts-v1/; + +#include "sun50i-h616-bigtreetech-cb1.dtsi" + +/ { + model = "BigTreeTech CB1"; + compatible = "bigtreetech,cb1-manta", "bigtreetech,cb1", "allwinner,sun50i-h616"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&ehci1 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_ph_pins>; + status = "okay"; +}; diff --git a/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dtsi b/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dtsi new file mode 100644 index 00000000000..1fed2b46cfe --- /dev/null +++ b/arch/arm/dts/sun50i-h616-bigtreetech-cb1.dtsi @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: (GPL-2.0+ or MIT) +/* + * Copyright (C) 2023 Martin Botka <martin.botka@somainline.org>. + */ + +/dts-v1/; + +#include "sun50i-h616.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/leds/common.h> + +/ { + aliases { + ethernet0 = &rtl8189ftv; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + function = LED_FUNCTION_STATUS; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pio 7 5 GPIO_ACTIVE_HIGH>; /* PH5 */ + }; + }; + + reg_vcc5v: regulator-vcc5v { + /* board wide 5V supply from carrier boards */ + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_vcc33_wifi: vcc33-wifi { + compatible = "regulator-fixed"; + regulator-name = "vcc33-wifi"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + vin-supply = <®_vcc5v>; + }; + + reg_vcc_wifi_io: vcc-wifi-io { + compatible = "regulator-fixed"; + regulator-name = "vcc-wifi-io"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + vin-supply = <®_vcc33_wifi>; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + clocks = <&rtc 1>; + clock-names = "ext_clock"; + reset-gpios = <&pio 6 18 GPIO_ACTIVE_LOW>; /* PG18 */ + post-power-on-delay-ms = <200>; + }; +}; + +&mmc0 { + vmmc-supply = <®_dldo1>; + /* Card detection pin is not connected */ + broken-cd; + bus-width = <4>; + status = "okay"; +}; + +&mmc1 { + vmmc-supply = <®_vcc33_wifi>; + vqmmc-supply = <®_vcc_wifi_io>; + mmc-pwrseq = <&wifi_pwrseq>; + bus-width = <4>; + non-removable; + mmc-ddr-1_8v; + status = "okay"; + + rtl8189ftv: wifi@1 { + reg = <1>; + }; +}; + +&r_i2c { + status = "okay"; + + axp313a: pmic@36 { + compatible = "x-powers,axp313a"; + reg = <0x36>; + interrupt-controller; + #interrupt-cells = <1>; + + regulators{ + reg_dcdc1: dcdc1 { + regulator-name = "vdd-gpu-sys"; + regulator-min-microvolt = <810000>; + regulator-max-microvolt = <990000>; + regulator-always-on; + }; + + reg_dcdc2: dcdc2 { + regulator-name = "vdd-cpu"; + regulator-min-microvolt = <810000>; + regulator-max-microvolt = <1100000>; + regulator-ramp-delay = <200>; + regulator-always-on; + }; + + reg_dcdc3: dcdc3 { + regulator-name = "vcc-dram"; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1500000>; + regulator-always-on; + }; + + reg_aldo1: aldo1 { + regulator-name = "vcc-1v8-pll"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + reg_dldo1: dldo1 { + regulator-name = "vcc-3v3-io"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + }; +}; + +&usbphy { + status = "okay"; +}; diff --git a/arch/arm/dts/sun50i-h616-bigtreetech-pi.dts b/arch/arm/dts/sun50i-h616-bigtreetech-pi.dts new file mode 100644 index 00000000000..832f08b2b26 --- /dev/null +++ b/arch/arm/dts/sun50i-h616-bigtreetech-pi.dts @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: (GPL-2.0+ or MIT) +/* + * Copyright (C) 2023 Martin Botka <martin@biqu3d.com>. + */ + +/dts-v1/; + +#include "sun50i-h616-bigtreetech-cb1.dtsi" + +/ { + model = "BigTreeTech Pi"; + compatible = "bigtreetech,pi", "allwinner,sun50i-h616"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&ehci2 { + status = "okay"; +}; + +&ehci3 { + status = "okay"; +}; + +&ir { + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&ohci2 { + status = "okay"; +}; + +&ohci3 { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_ph_pins>; + status = "okay"; +}; diff --git a/arch/arm/dts/sun50i-h616.dtsi b/arch/arm/dts/sun50i-h616.dtsi index 74aed0d232a..d549d277d97 100644 --- a/arch/arm/dts/sun50i-h616.dtsi +++ b/arch/arm/dts/sun50i-h616.dtsi @@ -133,6 +133,13 @@ #reset-cells = <1>; }; + sid: efuse@3006000 { + compatible = "allwinner,sun50i-h616-sid", "allwinner,sun50i-a64-sid"; + reg = <0x03006000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + }; + watchdog: watchdog@30090a0 { compatible = "allwinner,sun50i-h616-wdt", "allwinner,sun6i-a31-wdt"; diff --git a/arch/arm/dts/sun50i-h618-orangepi-zero2w.dts b/arch/arm/dts/sun50i-h618-orangepi-zero2w.dts new file mode 100644 index 00000000000..21ca1977055 --- /dev/null +++ b/arch/arm/dts/sun50i-h618-orangepi-zero2w.dts @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2023 Arm Ltd. + */ + +/dts-v1/; + +#include "sun50i-h616.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/leds/common.h> + +/ { + model = "OrangePi Zero 2W"; + compatible = "xunlong,orangepi-zero2w", "allwinner,sun50i-h618"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + function = LED_FUNCTION_STATUS; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pio 2 13 GPIO_ACTIVE_HIGH>; /* PC13 */ + }; + }; + + reg_vcc5v: vcc5v { + /* board wide 5V supply directly from the USB-C socket */ + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_vcc3v3: vcc3v3 { + /* SY8089 DC/DC converter */ + compatible = "regulator-fixed"; + regulator-name = "vcc-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <®_vcc5v>; + regulator-always-on; + }; +}; + +&ehci1 { + status = "okay"; +}; + +/* USB 2 & 3 are on the FPC connector (or the exansion board) */ + +&mmc0 { + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ + bus-width = <4>; + vmmc-supply = <®_vcc3v3>; + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&pio { + vcc-pc-supply = <®_dldo1>; + vcc-pf-supply = <®_dldo1>; /* internally via VCC-IO */ + vcc-pg-supply = <®_aldo1>; + vcc-ph-supply = <®_dldo1>; /* internally via VCC-IO */ + vcc-pi-supply = <®_dldo1>; +}; + +&r_i2c { + status = "okay"; + + axp313: pmic@36 { + compatible = "x-powers,axp313a"; + reg = <0x36>; + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&pio>; + interrupts = <2 9 IRQ_TYPE_LEVEL_LOW>; /* PC9 */ + + vin1-supply = <®_vcc5v>; + vin2-supply = <®_vcc5v>; + vin3-supply = <®_vcc5v>; + + regulators { + /* Supplies VCC-PLL and DRAM */ + reg_aldo1: aldo1 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc1v8"; + }; + + /* Supplies VCC-IO, so needs to be always on. */ + reg_dldo1: dldo1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc3v3"; + }; + + reg_dcdc1: dcdc1 { + regulator-always-on; + regulator-min-microvolt = <810000>; + regulator-max-microvolt = <990000>; + regulator-name = "vdd-gpu-sys"; + }; + + reg_dcdc2: dcdc2 { + regulator-always-on; + regulator-min-microvolt = <810000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpu"; + }; + + reg_dcdc3: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-dram"; + }; + }; + }; +}; + +&spi0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>, <&spi0_cs0_pin>; + + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_ph_pins>; + status = "okay"; +}; + +&usbotg { + /* + * PHY0 pins are connected to a USB-C socket, but a role switch + * is not implemented: both CC pins are pulled to GND. + * The VBUS pins power the device, so a fixed peripheral mode + * is the best choice. + * The board can be powered via GPIOs, in this case port0 *can* + * act as a host (with a cable/adapter ignoring CC), as VBUS is + * then provided by the GPIOs. Any user of this setup would + * need to adjust the DT accordingly: dr_mode set to "host", + * enabling OHCI0 and EHCI0. + */ + dr_mode = "peripheral"; + status = "okay"; +}; + +&usbphy { + usb1_vbus-supply = <®_vcc5v>; + status = "okay"; +}; diff --git a/arch/arm/dts/sun50i-h618-transpeed-8k618-t.dts b/arch/arm/dts/sun50i-h618-transpeed-8k618-t.dts new file mode 100644 index 00000000000..8ea1fd41aeb --- /dev/null +++ b/arch/arm/dts/sun50i-h618-transpeed-8k618-t.dts @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2023 Arm Ltd. + */ + +/dts-v1/; + +#include "sun50i-h616.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> + +/ { + model = "Transpeed 8K618-T"; + compatible = "transpeed,8k618-t", "allwinner,sun50i-h618"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + reg_vcc5v: vcc5v { + /* board wide 5V supply directly from the DC input */ + compatible = "regulator-fixed"; + regulator-name = "vcc-5v"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + reg_vcc3v3: vcc3v3 { + /* discrete 3.3V regulator */ + compatible = "regulator-fixed"; + regulator-name = "vcc-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&ir { + status = "okay"; +}; + +&mmc0 { + vmmc-supply = <®_dldo1>; + cd-gpios = <&pio 8 16 GPIO_ACTIVE_LOW>; /* PI16 */ + bus-width = <4>; + status = "okay"; +}; + +&mmc2 { + vmmc-supply = <®_dldo1>; + vqmmc-supply = <®_aldo1>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&r_i2c { + status = "okay"; + + axp313: pmic@36 { + compatible = "x-powers,axp313a"; + reg = <0x36>; + #interrupt-cells = <1>; + interrupt-controller; + + vin1-supply = <®_vcc5v>; + vin2-supply = <®_vcc5v>; + vin3-supply = <®_vcc5v>; + + regulators { + reg_aldo1: aldo1 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-1v8-pll"; + }; + + reg_dldo1: dldo1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-3v3-io-mmc"; + }; + + reg_dcdc1: dcdc1 { + regulator-always-on; + regulator-min-microvolt = <810000>; + regulator-max-microvolt = <990000>; + regulator-name = "vdd-gpu-sys"; + }; + + reg_dcdc2: dcdc2 { + regulator-always-on; + regulator-min-microvolt = <810000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vdd-cpu"; + }; + + reg_dcdc3: dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1360000>; + regulator-max-microvolt = <1360000>; + regulator-name = "vdd-dram"; + }; + }; + }; +}; + +&pio { + vcc-pc-supply = <®_aldo1>; + vcc-pg-supply = <®_dldo1>; + vcc-ph-supply = <®_dldo1>; + vcc-pi-supply = <®_dldo1>; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_ph_pins>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>, <&uart1_rts_cts_pins>; + uart-has-rtscts; + status = "okay"; +}; + +&usbotg { + dr_mode = "host"; /* USB A type receptable */ + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; diff --git a/arch/arm/dts/sun8i-r40.dtsi b/arch/arm/dts/sun8i-r40.dtsi index 4ef26d8f534..a5b1f1e3900 100644 --- a/arch/arm/dts/sun8i-r40.dtsi +++ b/arch/arm/dts/sun8i-r40.dtsi @@ -338,6 +338,8 @@ resets = <&ccu RST_BUS_VE>; interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; allwinner,sram = <&ve_sram 1>; + interconnects = <&mbus 4>; + interconnect-names = "dma-mem"; }; mmc0: mmc@1c0f000 { diff --git a/arch/arm/dts/sun8i-v3s-anbernic-rg-nano.dts b/arch/arm/dts/sun8i-v3s-anbernic-rg-nano.dts new file mode 100644 index 00000000000..f34dfdf1566 --- /dev/null +++ b/arch/arm/dts/sun8i-v3s-anbernic-rg-nano.dts @@ -0,0 +1,276 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; +#include <dt-bindings/input/linux-event-codes.h> +#include "sun8i-v3s.dtsi" +#include "sunxi-common-regulators.dtsi" + +/ { + model = "Anbernic RG Nano"; + compatible = "anbernic,rg-nano", "allwinner,sun8i-v3s"; + + aliases { + rtc0 = &pcf8563; + rtc1 = &rtc; + serial0 = &uart0; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + brightness-levels = <0 1 2 3 8 14 21 32 46 60 80 100>; + default-brightness-level = <11>; + power-supply = <®_vcc5v0>; + pwms = <&pwm 0 40000 1>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio_keys: gpio-keys { + compatible = "gpio-keys"; + + button-a { + gpios = <&gpio_expander 12 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "BTN-A"; + linux,code = <BTN_EAST>; + }; + + button-b { + gpios = <&gpio_expander 14 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "BTN-B"; + linux,code = <BTN_SOUTH>; + }; + + button-down { + gpios = <&gpio_expander 1 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "DPAD-DOWN"; + linux,code = <BTN_DPAD_DOWN>; + }; + + button-left { + gpios = <&gpio_expander 4 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "DPAD-LEFT"; + linux,code = <BTN_DPAD_LEFT>; + }; + + button-right { + gpios = <&gpio_expander 0 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "DPAD-RIGHT"; + linux,code = <BTN_DPAD_RIGHT>; + }; + + button-se { + gpios = <&gpio_expander 7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "BTN-SELECT"; + linux,code = <BTN_SELECT>; + }; + + button-st { + gpios = <&gpio_expander 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "BTN-START"; + linux,code = <BTN_START>; + }; + + button-tl { + gpios = <&gpio_expander 2 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "BTN-L"; + linux,code = <BTN_TL>; + }; + + button-tr { + gpios = <&gpio_expander 15 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "BTN-R"; + linux,code = <BTN_TR>; + }; + + button-up { + gpios = <&gpio_expander 3 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "DPAD-UP"; + linux,code = <BTN_DPAD_UP>; + }; + + button-x { + gpios = <&gpio_expander 11 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "BTN-X"; + linux,code = <BTN_NORTH>; + }; + + button-y { + gpios = <&gpio_expander 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + label = "BTN-Y"; + linux,code = <BTN_WEST>; + }; + }; +}; + +&codec { + allwinner,audio-routing = "Speaker", "HP", + "MIC1", "Mic", + "Mic", "HBIAS"; + allwinner,pa-gpios = <&pio 5 6 (GPIO_ACTIVE_HIGH | GPIO_PULL_UP)>; /* PF6 */ + status = "okay"; +}; + +&ehci { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + gpio_expander: gpio@20 { + compatible = "nxp,pcal6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&pio>; + interrupts = <1 3 IRQ_TYPE_EDGE_BOTH>; /* PB3/EINT3 */ + vcc-supply = <®_vcc3v3>; + }; + + axp209: pmic@34 { + reg = <0x34>; + interrupt-parent = <&pio>; + interrupts = <1 5 IRQ_TYPE_EDGE_FALLING>; /* PB5/EINT5 */ + }; + + pcf8563: rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; +}; + +#include "axp209.dtsi" + +&battery_power_supply { + status = "okay"; +}; + +&mmc0 { + broken-cd; + bus-width = <4>; + disable-wp; + vmmc-supply = <®_vcc3v3>; + vqmmc-supply = <®_vcc3v3>; + status = "okay"; +}; + +&ohci { + status = "okay"; +}; + +&pio { + vcc-pb-supply = <®_vcc3v3>; + vcc-pc-supply = <®_vcc3v3>; + vcc-pf-supply = <®_vcc3v3>; + vcc-pg-supply = <®_vcc3v3>; + + spi0_no_miso_pins: spi0-no-miso-pins { + pins = "PC1", "PC2", "PC3"; + function = "spi0"; + }; +}; + +&pwm { + pinctrl-0 = <&pwm0_pin>; + pinctrl-names = "default"; + status = "okay"; +}; + +/* DCDC2 wired into vdd-cpu, vdd-sys, and vdd-ephy. */ +®_dcdc2 { + regulator-always-on; + regulator-max-microvolt = <1250000>; + regulator-min-microvolt = <1250000>; + regulator-name = "vdd-cpu"; +}; + +/* DCDC3 wired into every 3.3v input that isn't the RTC. */ +®_dcdc3 { + regulator-always-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc-io"; +}; + +/* LDO1 wired into RTC, voltage is hard-wired at 3.3v. */ +®_ldo1 { + regulator-always-on; + regulator-name = "vcc-rtc"; +}; + +/* LDO2 wired into VCC-PLL and audio codec. */ +®_ldo2 { + regulator-always-on; + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <3000000>; + regulator-name = "vcc-pll"; +}; + +/* LDO3, LDO4, and LDO5 unused. */ +®_ldo3 { + status = "disabled"; +}; + +®_ldo4 { + status = "disabled"; +}; + +/* RTC uses internal oscillator */ +&rtc { + /delete-property/ clocks; +}; + +&spi0 { + pinctrl-0 = <&spi0_no_miso_pins>; + pinctrl-names = "default"; + status = "okay"; + + display@0 { + compatible = "saef,sftc154b", "panel-mipi-dbi-spi"; + reg = <0>; + backlight = <&backlight>; + dc-gpios = <&pio 2 0 GPIO_ACTIVE_HIGH>; /* PC0 */ + reset-gpios = <&pio 1 2 GPIO_ACTIVE_HIGH>; /* PB2 */ + spi-max-frequency = <100000000>; + + height-mm = <39>; + width-mm = <39>; + + /* Set hb-porch to compensate for non-visible area */ + panel-timing { + hactive = <240>; + vactive = <240>; + hback-porch = <80>; + vback-porch = <0>; + clock-frequency = <0>; + hfront-porch = <0>; + hsync-len = <0>; + vfront-porch = <0>; + vsync-len = <0>; + }; + }; +}; + +&uart0 { + pinctrl-0 = <&uart0_pb_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usb_power_supply { + status = "okay"; +}; + +&usbphy { + usb0_id_det-gpios = <&pio 6 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; /* PG5 */ + status = "okay"; +}; diff --git a/arch/arm/dts/sun8i-v3s.dtsi b/arch/arm/dts/sun8i-v3s.dtsi index 3b9a282c274..e8a04476b77 100644 --- a/arch/arm/dts/sun8i-v3s.dtsi +++ b/arch/arm/dts/sun8i-v3s.dtsi @@ -319,6 +319,29 @@ #phy-cells = <1>; }; + ehci: usb@1c1a000 { + compatible = "allwinner,sun8i-v3s-ehci", "generic-ehci"; + reg = <0x01c1a000 0x100>; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>; + resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>; + phys = <&usbphy 0>; + phy-names = "usb"; + status = "disabled"; + }; + + ohci: usb@1c1a400 { + compatible = "allwinner,sun8i-v3s-ohci", "generic-ohci"; + reg = <0x01c1a400 0x100>; + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&ccu CLK_BUS_EHCI0>, <&ccu CLK_BUS_OHCI0>, + <&ccu CLK_USB_OHCI0>; + resets = <&ccu RST_BUS_EHCI0>, <&ccu RST_BUS_OHCI0>; + phys = <&usbphy 0>; + phy-names = "usb"; + status = "disabled"; + }; + ccu: clock@1c20000 { compatible = "allwinner,sun8i-v3s-ccu"; reg = <0x01c20000 0x400>; @@ -414,6 +437,18 @@ bias-pull-up; }; + /omit-if-no-ref/ + pwm0_pin: pwm0-pin { + pins = "PB4"; + function = "pwm0"; + }; + + /omit-if-no-ref/ + pwm1_pin: pwm1-pin { + pins = "PB5"; + function = "pwm1"; + }; + spi0_pins: spi0-pins { pins = "PC0", "PC1", "PC2", "PC3"; function = "spi0"; diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi index a0c8abb7033..0909a67883e 100644 --- a/arch/arm/dts/sunxi-u-boot.dtsi +++ b/arch/arm/dts/sunxi-u-boot.dtsi @@ -1,13 +1,9 @@ #include <config.h> -#ifdef CONFIG_MACH_SUN50I_H6 -#define BL31_ADDR 0x104000 -#define SCP_ADDR 0x114000 -#elif defined(CONFIG_MACH_SUN50I_H616) -#define BL31_ADDR 0x40000000 +#ifdef CONFIG_ARM64 +#define ARCH "arm64" #else -#define BL31_ADDR 0x44000 -#define SCP_ADDR 0x50000 +#define ARCH "arm" #endif / { @@ -44,47 +40,52 @@ filename = "spl/sunxi-spl.bin"; }; -#ifdef CONFIG_ARM64 +#ifdef CONFIG_SPL_LOAD_FIT fit { - description = "Configuration to load ATF before U-Boot"; + description = "Configuration to load U-Boot and firmware"; #address-cells = <1>; fit,fdt-list = "of-list"; images { uboot { - description = "U-Boot (64-bit)"; + description = "U-Boot"; type = "standalone"; os = "u-boot"; - arch = "arm64"; + arch = ARCH; compression = "none"; load = <CONFIG_TEXT_BASE>; +#if CONFIG_SUNXI_BL31_BASE == 0 + entry = <CONFIG_TEXT_BASE>; +#endif u-boot-nodtb { }; }; +#if CONFIG_SUNXI_BL31_BASE atf { description = "ARM Trusted Firmware"; type = "firmware"; os = "arm-trusted-firmware"; - arch = "arm64"; + arch = ARCH; compression = "none"; - load = <BL31_ADDR>; - entry = <BL31_ADDR>; + load = <CONFIG_SUNXI_BL31_BASE>; + entry = <CONFIG_SUNXI_BL31_BASE>; atf-bl31 { filename = "bl31.bin"; missing-msg = "atf-bl31-sunxi"; }; }; +#endif -#ifdef SCP_ADDR +#if CONFIG_SUNXI_SCP_BASE scp { description = "SCP firmware"; type = "firmware"; arch = "or1k"; compression = "none"; - load = <SCP_ADDR>; + load = <CONFIG_SUNXI_SCP_BASE>; scp { filename = "scp.bin"; @@ -105,11 +106,15 @@ @config-SEQ { description = "NAME"; +#if CONFIG_SUNXI_BL31_BASE firmware = "atf"; -#ifndef SCP_ADDR - loadables = "uboot"; #else + firmware = "uboot"; +#endif +#if CONFIG_SUNXI_SCP_BASE loadables = "scp", "uboot"; +#else + loadables = "uboot"; #endif fdt = "fdt-SEQ"; }; diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index 3daee2f574a..f023a4cfd93 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -36,58 +36,20 @@ #define SUNXI_SRAMC_BASE 0x01c00000 #define SUNXI_DRAMC_BASE 0x01c01000 -#define SUNXI_DMA_BASE 0x01c02000 #define SUNXI_NFC_BASE 0x01c03000 -#define SUNXI_TS_BASE 0x01c04000 -#define SUNXI_SPI0_BASE 0x01c05000 -#define SUNXI_SPI1_BASE 0x01c06000 -#define SUNXI_MS_BASE 0x01c07000 -#define SUNXI_TVD_BASE 0x01c08000 -#define SUNXI_CSI0_BASE 0x01c09000 #ifndef CONFIG_MACH_SUNXI_H3_H5 #define SUNXI_TVE0_BASE 0x01c0a000 #endif -#define SUNXI_EMAC_BASE 0x01c0b000 #define SUNXI_LCD0_BASE 0x01c0C000 #define SUNXI_LCD1_BASE 0x01c0d000 -#define SUNXI_VE_BASE 0x01c0e000 #define SUNXI_MMC0_BASE 0x01c0f000 #define SUNXI_MMC1_BASE 0x01c10000 #define SUNXI_MMC2_BASE 0x01c11000 #define SUNXI_MMC3_BASE 0x01c12000 -#ifdef CONFIG_SUNXI_GEN_SUN4I -#define SUNXI_USB0_BASE 0x01c13000 -#define SUNXI_USB1_BASE 0x01c14000 -#endif #define SUNXI_SS_BASE 0x01c15000 #if !defined(CONFIG_MACH_SUNXI_H3_H5) && !defined(CONFIG_MACH_SUN50I) #define SUNXI_HDMI_BASE 0x01c16000 #endif -#define SUNXI_SPI2_BASE 0x01c17000 -#define SUNXI_SATA_BASE 0x01c18000 -#ifdef CONFIG_SUNXI_GEN_SUN4I -#define SUNXI_PATA_BASE 0x01c19000 -#define SUNXI_ACE_BASE 0x01c1a000 -#define SUNXI_TVE1_BASE 0x01c1b000 -#define SUNXI_USB2_BASE 0x01c1c000 -#endif -#ifdef CONFIG_SUNXI_GEN_SUN6I -#if defined(CONFIG_MACH_SUNXI_H3_H5) || defined(CONFIG_MACH_SUN50I) -#define SUNXI_USBPHY_BASE 0x01c19000 -#define SUNXI_USB0_BASE SUNXI_USBPHY_BASE -#define SUNXI_USB1_BASE 0x01c1a000 -#define SUNXI_USB2_BASE 0x01c1b000 -#define SUNXI_USB3_BASE 0x01c1c000 -#define SUNXI_USB4_BASE 0x01c1d000 -#else -#define SUNXI_USB0_BASE 0x01c19000 -#define SUNXI_USB1_BASE 0x01c1a000 -#define SUNXI_USB2_BASE 0x01c1b000 -#endif -#endif -#define SUNXI_CSI1_BASE 0x01c1d000 -#define SUNXI_TZASC_BASE 0x01c1e000 -#define SUNXI_SPI3_BASE 0x01c1f000 #define SUNXI_CCM_BASE 0x01c20000 #define SUNXI_INTC_BASE 0x01c20400 @@ -177,8 +139,6 @@ defined(CONFIG_MACH_SUN50I) #else #define SUNXI_TVE0_BASE 0x01e40000 #endif -#define SUNXI_MP_BASE 0x01e80000 -#define SUNXI_AVG_BASE 0x01ea0000 #if defined(CONFIG_MACH_SUNXI_H3_H5) || defined(CONFIG_MACH_SUN50I) #define SUNXI_HDMI_BASE 0x01ee0000 @@ -197,13 +157,6 @@ defined(CONFIG_MACH_SUN50I) #define SUN6I_P2WI_BASE 0x01f03400 #define SUNXI_RSB_BASE 0x01f03400 -/* CoreSight Debug Module */ -#define SUNXI_CSDM_BASE 0x3f500000 - -#define SUNXI_DDRII_DDRIII_BASE 0x40000000 /* 2 GiB */ - -#define SUNXI_BROM_BASE 0xffff0000 /* 32 kiB */ - #define SUNXI_CPU_CFG (SUNXI_TIMER_BASE + 0x13c) /* SS bonding ids used for cpu identification */ diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h index 15ee092d358..8a3f465545a 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun50i_h6.h @@ -7,25 +7,14 @@ #ifndef _SUNXI_CPU_SUN50I_H6_H #define _SUNXI_CPU_SUN50I_H6_H -#define SUNXI_SRAM_A1_BASE CONFIG_SUNXI_SRAM_ADDRESS -#define SUNXI_SRAM_C_BASE 0x00028000 -#define SUNXI_SRAM_A2_BASE 0x00100000 - -#define SUNXI_DE3_BASE 0x01000000 -#define SUNXI_SS_BASE 0x01904000 -#define SUNXI_EMCE_BASE 0x01905000 - #define SUNXI_SRAMC_BASE 0x03000000 #define SUNXI_CCM_BASE 0x03001000 -#define SUNXI_DMA_BASE 0x03002000 /* SID address space starts at 0x03006000, but e-fuse is at offset 0x200 */ #define SUNXI_SIDC_BASE 0x03006000 #define SUNXI_SID_BASE 0x03006200 #define SUNXI_TIMER_BASE 0x03009000 -#define SUNXI_PSI_BASE 0x0300C000 #define SUNXI_GIC400_BASE 0x03020000 -#define SUNXI_IOMMU_BASE 0x030F0000 #ifdef CONFIG_MACH_SUN50I_H6 #define SUNXI_DRAM_COM_BASE 0x04002000 @@ -46,18 +35,8 @@ #define SUNXI_TWI1_BASE 0x05002400 #define SUNXI_TWI2_BASE 0x05002800 #define SUNXI_TWI3_BASE 0x05002C00 -#define SUNXI_SPI0_BASE 0x05010000 -#define SUNXI_SPI1_BASE 0x05011000 -#define SUNXI_GMAC_BASE 0x05020000 -#define SUNXI_USB0_BASE 0x05100000 -#define SUNXI_XHCI_BASE 0x05200000 -#define SUNXI_USB3_BASE 0x05311000 -#define SUNXI_PCIE_BASE 0x05400000 #define SUNXI_HDMI_BASE 0x06000000 -#define SUNXI_TCON_TOP_BASE 0x06510000 -#define SUNXI_TCON_LCD0_BASE 0x06511000 -#define SUNXI_TCON_TV0_BASE 0x06515000 #define SUNXI_RTC_BASE 0x07000000 #define SUNXI_R_CPUCFG_BASE 0x07000400 diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h index 2bf2675d5c1..73de4707c16 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun9i.h @@ -20,7 +20,6 @@ /* AHB0 Module */ #define SUNXI_NFC_BASE (REGS_AHB0_BASE + 0x3000) -#define SUNXI_TSC_BASE (REGS_AHB0_BASE + 0x4000) #define SUNXI_GTBUS_BASE (REGS_AHB0_BASE + 0x9000) /* SID address space starts at 0x01ce000, but e-fuse is at offset 0x200 */ @@ -32,14 +31,7 @@ #define SUNXI_MMC3_BASE (REGS_AHB0_BASE + 0x12000) #define SUNXI_MMC_COMMON_BASE (REGS_AHB0_BASE + 0x13000) -#define SUNXI_SPI0_BASE (REGS_AHB0_BASE + 0x1A000) -#define SUNXI_SPI1_BASE (REGS_AHB0_BASE + 0x1B000) -#define SUNXI_SPI2_BASE (REGS_AHB0_BASE + 0x1C000) -#define SUNXI_SPI3_BASE (REGS_AHB0_BASE + 0x1D000) - #define SUNXI_GIC400_BASE (REGS_AHB0_BASE + 0x40000) -#define SUNXI_ARMA9_GIC_BASE (REGS_AHB0_BASE + 0x41000) -#define SUNXI_ARMA9_CPUIF_BASE (REGS_AHB0_BASE + 0x42000) #define SUNXI_DRAM_COM_BASE (REGS_AHB0_BASE + 0x62000) #define SUNXI_DRAM_CTL0_BASE (REGS_AHB0_BASE + 0x63000) @@ -47,59 +39,26 @@ #define SUNXI_DRAM_PHY0_BASE (REGS_AHB0_BASE + 0x65000) #define SUNXI_DRAM_PHY1_BASE (REGS_AHB0_BASE + 0x66000) -/* AHB1 Module */ -#define SUNXI_DMA_BASE (REGS_AHB1_BASE + 0x002000) -#define SUNXI_USBOTG_BASE (REGS_AHB1_BASE + 0x100000) -#define SUNXI_USBEHCI0_BASE (REGS_AHB1_BASE + 0x200000) -#define SUNXI_USBEHCI1_BASE (REGS_AHB1_BASE + 0x201000) -#define SUNXI_USBEHCI2_BASE (REGS_AHB1_BASE + 0x202000) - -/* AHB2 Module */ -#define SUNXI_DE_SYS_BASE (REGS_AHB2_BASE + 0x000000) -#define SUNXI_DISP_SYS_BASE (REGS_AHB2_BASE + 0x010000) #define SUNXI_DE_FE0_BASE (REGS_AHB2_BASE + 0x100000) -#define SUNXI_DE_FE1_BASE (REGS_AHB2_BASE + 0x140000) -#define SUNXI_DE_FE2_BASE (REGS_AHB2_BASE + 0x180000) - #define SUNXI_DE_BE0_BASE (REGS_AHB2_BASE + 0x200000) -#define SUNXI_DE_BE1_BASE (REGS_AHB2_BASE + 0x240000) -#define SUNXI_DE_BE2_BASE (REGS_AHB2_BASE + 0x280000) - -#define SUNXI_DE_DEU0_BASE (REGS_AHB2_BASE + 0x300000) -#define SUNXI_DE_DEU1_BASE (REGS_AHB2_BASE + 0x340000) -#define SUNXI_DE_DRC0_BASE (REGS_AHB2_BASE + 0x400000) -#define SUNXI_DE_DRC1_BASE (REGS_AHB2_BASE + 0x440000) - #define SUNXI_LCD0_BASE (REGS_AHB2_BASE + 0xC00000) #define SUNXI_LCD1_BASE (REGS_AHB2_BASE + 0xC10000) #define SUNXI_LCD2_BASE (REGS_AHB2_BASE + 0xC20000) -#define SUNXI_MIPI_DSI0_BASE (REGS_AHB2_BASE + 0xC40000) -/* Also seen as SUNXI_MIPI_DSI0_DPHY_BASE 0x01ca1000 */ -#define SUNXI_MIPI_DSI0_DPHY_BASE (REGS_AHB2_BASE + 0xC40100) #define SUNXI_HDMI_BASE (REGS_AHB2_BASE + 0xD00000) /* APB0 Module */ #define SUNXI_CCM_BASE (REGS_APB0_BASE + 0x0000) -#define SUNXI_CCMMODULE_BASE (REGS_APB0_BASE + 0x0400) #define SUNXI_TIMER_BASE (REGS_APB0_BASE + 0x0C00) #define SUNXI_PWM_BASE (REGS_APB0_BASE + 0x1400) -#define SUNXI_LRADC_BASE (REGS_APB0_BASE + 0x1800) /* APB1 Module */ #define SUNXI_TWI0_BASE (REGS_APB1_BASE + 0x2800) #define SUNXI_TWI1_BASE (REGS_APB1_BASE + 0x2C00) -#define SUNXI_TWI2_BASE (REGS_APB1_BASE + 0x3000) -#define SUNXI_TWI3_BASE (REGS_APB1_BASE + 0x3400) -#define SUNXI_TWI4_BASE (REGS_APB1_BASE + 0x3800) /* RCPUS Module */ #define SUNXI_PRCM_BASE (REGS_RCPUS_BASE + 0x1400) #define SUNXI_RSB_BASE (REGS_RCPUS_BASE + 0x3400) -/* Misc. */ -#define SUNXI_BROM_BASE 0xFFFF0000 /* 32K */ -#define SUNXI_CPU_CFG (SUNXI_TIMER_BASE + 0x13c) - #ifndef __ASSEMBLY__ void sunxi_board_init(void); void sunxi_reset(void); diff --git a/arch/arm/mach-bcm283x/include/mach/base.h b/arch/arm/mach-bcm283x/include/mach/base.h index 4ccaf69693d..6de99e7ea12 100644 --- a/arch/arm/mach-bcm283x/include/mach/base.h +++ b/arch/arm/mach-bcm283x/include/mach/base.h @@ -6,7 +6,10 @@ #ifndef _BCM283x_BASE_H_ #define _BCM283x_BASE_H_ -extern unsigned long rpi_bcm283x_base; +extern unsigned long rpi_mbox_base; +extern unsigned long rpi_timer_base; +extern unsigned long rpi_sdhci_base; +extern unsigned long rpi_wdog_base; #ifdef CONFIG_ARMV7_LPAE #ifdef CONFIG_TARGET_RPI_4_32B diff --git a/arch/arm/mach-bcm283x/include/mach/mbox.h b/arch/arm/mach-bcm283x/include/mach/mbox.h index 490664f878f..35d4e2f0754 100644 --- a/arch/arm/mach-bcm283x/include/mach/mbox.h +++ b/arch/arm/mach-bcm283x/include/mach/mbox.h @@ -38,8 +38,7 @@ /* Raw mailbox HW */ -#define BCM2835_MBOX_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \ - rpi_bcm283x_base + 0x0000b880; }) +#define BCM2835_MBOX_PHYSADDR rpi_mbox_base struct bcm2835_mbox_regs { u32 read; diff --git a/arch/arm/mach-bcm283x/include/mach/sdhci.h b/arch/arm/mach-bcm283x/include/mach/sdhci.h index 73236906870..e837c679c46 100644 --- a/arch/arm/mach-bcm283x/include/mach/sdhci.h +++ b/arch/arm/mach-bcm283x/include/mach/sdhci.h @@ -8,8 +8,7 @@ #include <asm/arch/base.h> -#define BCM2835_SDHCI_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \ - rpi_bcm283x_base + 0x00300000; }) +#define BCM2835_SDHCI_PHYSADDR rpi_sdhci_base int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq); diff --git a/arch/arm/mach-bcm283x/include/mach/timer.h b/arch/arm/mach-bcm283x/include/mach/timer.h index 5567dbd7f3d..60500a256d0 100644 --- a/arch/arm/mach-bcm283x/include/mach/timer.h +++ b/arch/arm/mach-bcm283x/include/mach/timer.h @@ -11,8 +11,7 @@ #include <linux/bug.h> #endif -#define BCM2835_TIMER_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \ - rpi_bcm283x_base + 0x00003000; }) +#define BCM2835_TIMER_PHYSADDR rpi_timer_base #define BCM2835_TIMER_CS_M3 (1 << 3) #define BCM2835_TIMER_CS_M2 (1 << 2) diff --git a/arch/arm/mach-bcm283x/include/mach/wdog.h b/arch/arm/mach-bcm283x/include/mach/wdog.h index 99426667205..b9505606749 100644 --- a/arch/arm/mach-bcm283x/include/mach/wdog.h +++ b/arch/arm/mach-bcm283x/include/mach/wdog.h @@ -8,8 +8,7 @@ #include <asm/arch/base.h> -#define BCM2835_WDOG_PHYSADDR ({ BUG_ON(!rpi_bcm283x_base); \ - rpi_bcm283x_base + 0x00100000; }) +#define BCM2835_WDOG_PHYSADDR rpi_wdog_base struct bcm2835_wdog_regs { u32 unknown0[7]; diff --git a/arch/arm/mach-bcm283x/init.c b/arch/arm/mach-bcm283x/init.c index 7265faf6cec..016bc1eb412 100644 --- a/arch/arm/mach-bcm283x/init.c +++ b/arch/arm/mach-bcm283x/init.c @@ -68,6 +68,36 @@ static struct mm_region bcm2711_mem_map[MEM_MAP_MAX_ENTRIES] = { } }; +static struct mm_region bcm2712_mem_map[MEM_MAP_MAX_ENTRIES] = { + { + /* First 1GB of DRAM */ + .virt = 0x00000000UL, + .phys = 0x00000000UL, + .size = 0x40000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + /* Beginning of AXI bus where uSD controller lives */ + .virt = 0x1000000000UL, + .phys = 0x1000000000UL, + .size = 0x0002000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* SoC bus */ + .virt = 0x107c000000UL, + .phys = 0x107c000000UL, + .size = 0x0004000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* List terminator */ + 0, + } +}; + struct mm_region *mem_map = bcm283x_mem_map; /* @@ -78,6 +108,7 @@ static const struct udevice_id board_ids[] = { { .compatible = "brcm,bcm2837", .data = (ulong)&bcm283x_mem_map}, { .compatible = "brcm,bcm2838", .data = (ulong)&bcm2711_mem_map}, { .compatible = "brcm,bcm2711", .data = (ulong)&bcm2711_mem_map}, + { .compatible = "brcm,bcm2712", .data = (ulong)&bcm2712_mem_map}, { }, }; @@ -115,7 +146,11 @@ static void rpi_update_mem_map(void) static void rpi_update_mem_map(void) {} #endif -unsigned long rpi_bcm283x_base = 0x3f000000; +/* Default bcm283x devices addresses */ +unsigned long rpi_mbox_base = 0x3f00b880; +unsigned long rpi_sdhci_base = 0x3f300000; +unsigned long rpi_wdog_base = 0x3f100000; +unsigned long rpi_timer_base = 0x3f003000; int arch_cpu_init(void) { @@ -126,22 +161,45 @@ int arch_cpu_init(void) int mach_cpu_init(void) { - int ret, soc_offset; + int ret, soc, offset; u64 io_base, size; rpi_update_mem_map(); /* Get IO base from device tree */ - soc_offset = fdt_path_offset(gd->fdt_blob, "/soc"); - if (soc_offset < 0) - return soc_offset; + soc = fdt_path_offset(gd->fdt_blob, "/soc"); + if (soc < 0) + return soc; - ret = fdt_read_range((void *)gd->fdt_blob, soc_offset, 0, NULL, - &io_base, &size); + ret = fdt_read_range((void *)gd->fdt_blob, soc, 0, NULL, + &io_base, &size); if (ret) return ret; - rpi_bcm283x_base = io_base; + rpi_mbox_base = io_base + 0x00b880; + rpi_sdhci_base = io_base + 0x300000; + rpi_wdog_base = io_base + 0x100000; + rpi_timer_base = io_base + 0x003000; + + offset = fdt_node_offset_by_compatible(gd->fdt_blob, soc, + "brcm,bcm2835-mbox"); + if (offset > soc) + rpi_mbox_base = fdt_get_base_address(gd->fdt_blob, offset); + + offset = fdt_node_offset_by_compatible(gd->fdt_blob, soc, + "brcm,bcm2835-sdhci"); + if (offset > soc) + rpi_sdhci_base = fdt_get_base_address(gd->fdt_blob, offset); + + offset = fdt_node_offset_by_compatible(gd->fdt_blob, soc, + "brcm,bcm2835-system-timer"); + if (offset > soc) + rpi_timer_base = fdt_get_base_address(gd->fdt_blob, offset); + + offset = fdt_node_offset_by_compatible(gd->fdt_blob, soc, + "brcm,bcm2712-pm"); + if (offset > soc) + rpi_wdog_base = fdt_get_base_address(gd->fdt_blob, offset); return 0; } diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index d5db805c62b..f411366778f 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -525,19 +525,26 @@ void remove_fwl_configs(struct fwl_data *fwl_data, size_t fwl_data_size) void spl_enable_cache(void) { #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) - phys_addr_t ram_top = CFG_SYS_SDRAM_BASE; + gd->ram_top = CFG_SYS_SDRAM_BASE; + int ret = 0; dram_init(); /* reserve TLB table */ gd->arch.tlb_size = PGTABLE_SIZE; - ram_top += get_effective_memsize(); + gd->ram_top += get_effective_memsize(); /* keep ram_top in the 32-bit address space */ - if (ram_top >= 0x100000000) - ram_top = (phys_addr_t) 0x100000000; + if (gd->ram_top >= 0x100000000) + gd->ram_top = (phys_addr_t)0x100000000; - gd->arch.tlb_addr = ram_top - gd->arch.tlb_size; + gd->relocaddr = gd->ram_top; + + ret = spl_reserve_video_from_ram_top(); + if (ret) + panic("Failed to reserve framebuffer memory (%d)\n", ret); + + gd->arch.tlb_addr = gd->relocaddr - gd->arch.tlb_size; gd->arch.tlb_addr &= ~(0x10000 - 1); debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr, gd->arch.tlb_addr + gd->arch.tlb_size); diff --git a/arch/arm/mach-meson/board-info.c b/arch/arm/mach-meson/board-info.c index 95a29da0722..d51d9b8f064 100644 --- a/arch/arm/mach-meson/board-info.c +++ b/arch/arm/mach-meson/board-info.c @@ -126,13 +126,6 @@ static const char *socinfo_to_soc_id(u32 socinfo) return "Unknown"; } -static void print_board_model(void) -{ - const char *model; - model = fdt_getprop(gd->fdt_blob, 0, "model", NULL); - printf("Model: %s\n", model ? model : "Unknown"); -} - static unsigned int get_socinfo(void) { struct regmap *regmap; @@ -172,9 +165,6 @@ int checkboard(void) { unsigned int socinfo; - /* print board information */ - print_board_model(); - socinfo = get_socinfo(); if (!socinfo) return 0; diff --git a/arch/arm/mach-rockchip/rk3288/rk3288.c b/arch/arm/mach-rockchip/rk3288/rk3288.c index 26c7e41cd89..d9f782e342b 100644 --- a/arch/arm/mach-rockchip/rk3288/rk3288.c +++ b/arch/arm/mach-rockchip/rk3288/rk3288.c @@ -184,8 +184,6 @@ static int do_clock(struct cmd_tbl *cmdtp, int flag, int argc, rate = clk_get_rate(&clk); printf("%s: %lu\n", clks[i].name, rate); - - clk_free(&clk); } return 0; diff --git a/arch/arm/mach-socfpga/clock_manager_agilex.c b/arch/arm/mach-socfpga/clock_manager_agilex.c index e035c09aaef..28f593b60e6 100644 --- a/arch/arm/mach-socfpga/clock_manager_agilex.c +++ b/arch/arm/mach-socfpga/clock_manager_agilex.c @@ -37,8 +37,6 @@ static ulong cm_get_rate_dm(u32 id) rate = clk_get_rate(&clk); - clk_free(&clk); - if ((rate == (unsigned long)-ENOSYS) || (rate == (unsigned long)-ENXIO) || (rate == (unsigned long)-EIO)) { diff --git a/arch/arm/mach-socfpga/clock_manager_arria10.c b/arch/arm/mach-socfpga/clock_manager_arria10.c index b48a2b47bcd..8ab18f6b725 100644 --- a/arch/arm/mach-socfpga/clock_manager_arria10.c +++ b/arch/arm/mach-socfpga/clock_manager_arria10.c @@ -962,7 +962,6 @@ static u32 cm_get_rate_dm(char *name) struct uclass *uc; struct udevice *dev = NULL; struct clk clk = { 0 }; - ulong rate; int ret; /* Device addresses start at 1 */ @@ -982,11 +981,7 @@ static u32 cm_get_rate_dm(char *name) if (ret) return 0; - rate = clk_get_rate(&clk); - - clk_free(&clk); - - return rate; + return clk_get_rate(&clk); } static u32 cm_get_rate_dm_khz(char *name) diff --git a/arch/arm/mach-socfpga/clock_manager_n5x.c b/arch/arm/mach-socfpga/clock_manager_n5x.c index 4f098533e7c..0ed480de670 100644 --- a/arch/arm/mach-socfpga/clock_manager_n5x.c +++ b/arch/arm/mach-socfpga/clock_manager_n5x.c @@ -36,8 +36,6 @@ static ulong cm_get_rate_dm(u32 id) rate = clk_get_rate(&clk); - clk_free(&clk); - if ((rate == (unsigned long)-ENXIO) || (rate == (unsigned long)-EIO)) { debug("%s id %u: clk_get_rate err: %ld\n", diff --git a/arch/arm/mach-sunxi/Kconfig b/arch/arm/mach-sunxi/Kconfig index a4a8d8e9445..fe89aec6b9a 100644 --- a/arch/arm/mach-sunxi/Kconfig +++ b/arch/arm/mach-sunxi/Kconfig @@ -161,6 +161,23 @@ config SUNXI_RVBAR_ALTERNATIVE for all other SoCs, so the content of the SRAM_VER_REG becomes irrelevant there, and we can use the same code. +config SUNXI_BL31_BASE + hex + default 0x00044000 if MACH_SUN50I || MACH_SUN50I_H5 + default 0x00104000 if MACH_SUN50I_H6 + default 0x40000000 if MACH_SUN50I_H616 + default 0x0 + help + Address where BL31 (TF-A) is loaded, or zero if BL31 is not used. + +config SUNXI_SCP_BASE + hex + default 0x00050000 if MACH_SUN50I || MACH_SUN50I_H5 + default 0x00114000 if MACH_SUN50I_H6 + default 0x0 + help + Address where SCP firmware is loaded, or zero if it is not used. + config SUNXI_A64_TIMER_ERRATUM bool @@ -182,7 +199,7 @@ config SUNXI_GEN_SUN6I config SUN50I_GEN_H6 bool select FIT - select SPL_LOAD_FIT + select SPL_LOAD_FIT if SPL select MMC_SUNXI_HAS_NEW_MODE select SUPPORT_SPL ---help--- @@ -272,7 +289,7 @@ config MACH_SUN6I select ARCH_SUPPORT_PSCI select SPL_ARMV7_SET_CORTEX_SMPEN select DRAM_SUN6I - select SPL_I2C + select SPL_I2C if SPL select SUN6I_PRCM select SUNXI_GEN_SUN6I select SUPPORT_SPL @@ -300,7 +317,7 @@ config MACH_SUN8I_A23 select CPU_V7_HAS_VIRT select ARCH_SUPPORT_PSCI select DRAM_SUN8I_A23 - select SPL_I2C + select SPL_I2C if SPL select SUNXI_GEN_SUN6I select SUPPORT_SPL select SYS_I2C_SUN8I_RSB @@ -313,7 +330,7 @@ config MACH_SUN8I_A33 select CPU_V7_HAS_VIRT select ARCH_SUPPORT_PSCI select DRAM_SUN8I_A33 - select SPL_I2C + select SPL_I2C if SPL select SUNXI_GEN_SUN6I select SUPPORT_SPL select SYS_I2C_SUN8I_RSB @@ -323,7 +340,7 @@ config MACH_SUN8I_A83T bool "sun8i (Allwinner A83T)" select CPU_V7A select DRAM_SUN8I_A83T - select SPL_I2C + select SPL_I2C if SPL select SUNXI_GEN_SUN6I select MMC_SUNXI_HAS_NEW_MODE select MMC_SUNXI_HAS_MODE_SWITCH @@ -382,7 +399,7 @@ config MACH_SUN9I select CPU_V7A select SPL_ARMV7_SET_CORTEX_SMPEN select DRAM_SUN9I - select SPL_I2C + select SPL_I2C if SPL select SUN6I_PRCM select SUNXI_GEN_SUN6I select SUPPORT_SPL @@ -398,7 +415,7 @@ config MACH_SUN50I select SUNXI_DRAM_DW select SUNXI_DRAM_DW_32BIT select FIT - select SPL_LOAD_FIT + select SPL_LOAD_FIT if SPL select SUNXI_A64_TIMER_ERRATUM config MACH_SUN50I_H5 @@ -407,7 +424,7 @@ config MACH_SUN50I_H5 select MACH_SUNXI_H3_H5 select MMC_SUNXI_HAS_NEW_MODE select FIT - select SPL_LOAD_FIT + select SPL_LOAD_FIT if SPL config MACH_SUN50I_H6 bool "sun50i (Allwinner H6)" diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 11a49418225..f4dbb2a740b 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -9,7 +9,6 @@ * Some init for sunxi platform. */ -#include <common.h> #include <cpu_func.h> #include <init.h> #include <log.h> diff --git a/arch/arm/mach-sunxi/clock.c b/arch/arm/mach-sunxi/clock.c index da3a0eb0584..b6c68c94f67 100644 --- a/arch/arm/mach-sunxi/clock.c +++ b/arch/arm/mach-sunxi/clock.c @@ -7,7 +7,6 @@ * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net> */ -#include <common.h> #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch/prcm.h> diff --git a/arch/arm/mach-sunxi/clock_sun4i.c b/arch/arm/mach-sunxi/clock_sun4i.c index 471609764d2..8f1d1b65f00 100644 --- a/arch/arm/mach-sunxi/clock_sun4i.c +++ b/arch/arm/mach-sunxi/clock_sun4i.c @@ -9,7 +9,6 @@ * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net> */ -#include <common.h> #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch/sys_proto.h> diff --git a/arch/arm/mach-sunxi/clock_sun50i_h6.c b/arch/arm/mach-sunxi/clock_sun50i_h6.c index bea91c78bc5..dac3663e1be 100644 --- a/arch/arm/mach-sunxi/clock_sun50i_h6.c +++ b/arch/arm/mach-sunxi/clock_sun50i_h6.c @@ -1,4 +1,3 @@ -#include <common.h> #include <asm/io.h> #include <asm/arch/cpu.h> #include <asm/arch/clock.h> diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c index 6bd75a15f6d..aad9df282ec 100644 --- a/arch/arm/mach-sunxi/clock_sun6i.c +++ b/arch/arm/mach-sunxi/clock_sun6i.c @@ -9,7 +9,6 @@ * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net> */ -#include <common.h> #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch/prcm.h> diff --git a/arch/arm/mach-sunxi/clock_sun8i_a83t.c b/arch/arm/mach-sunxi/clock_sun8i_a83t.c index 31e4281529a..198fe9dbd73 100644 --- a/arch/arm/mach-sunxi/clock_sun8i_a83t.c +++ b/arch/arm/mach-sunxi/clock_sun8i_a83t.c @@ -9,7 +9,6 @@ * (C) Copyright 2015 Vishnu Patekar <vishnupatekar0510@gmail.com> */ -#include <common.h> #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch/prcm.h> diff --git a/arch/arm/mach-sunxi/clock_sun9i.c b/arch/arm/mach-sunxi/clock_sun9i.c index 8ba4802f3b3..edaff9a28ce 100644 --- a/arch/arm/mach-sunxi/clock_sun9i.c +++ b/arch/arm/mach-sunxi/clock_sun9i.c @@ -9,7 +9,6 @@ * Philipp Tomsich <philipp.tomsich@theobroma-systems.com> */ -#include <common.h> #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch/prcm.h> diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c index 7fecc3b88dd..310dca06e57 100644 --- a/arch/arm/mach-sunxi/cpu_info.c +++ b/arch/arm/mach-sunxi/cpu_info.c @@ -5,7 +5,6 @@ * Tom Cubie <tangliang@allwinnertech.com> */ -#include <common.h> #include <init.h> #include <asm/io.h> #include <asm/arch/cpu.h> diff --git a/arch/arm/mach-sunxi/dram_helpers.c b/arch/arm/mach-sunxi/dram_helpers.c index cdf2750f1c5..4a867df7af8 100644 --- a/arch/arm/mach-sunxi/dram_helpers.c +++ b/arch/arm/mach-sunxi/dram_helpers.c @@ -5,8 +5,9 @@ * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com> */ -#include <common.h> +#include <config.h> #include <time.h> +#include <vsprintf.h> #include <asm/barriers.h> #include <asm/io.h> #include <asm/arch/dram.h> diff --git a/arch/arm/mach-sunxi/dram_sun4i.c b/arch/arm/mach-sunxi/dram_sun4i.c index 80a6c4bc0fd..2cce381c9df 100644 --- a/arch/arm/mach-sunxi/dram_sun4i.c +++ b/arch/arm/mach-sunxi/dram_sun4i.c @@ -20,7 +20,6 @@ * rather undocumented and full of magic. */ -#include <common.h> #include <init.h> #include <asm/io.h> #include <asm/arch/clock.h> diff --git a/arch/arm/mach-sunxi/dram_sun50i_h6.c b/arch/arm/mach-sunxi/dram_sun50i_h6.c index 62bc2a0231e..e7862bd06ea 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h6.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h6.c @@ -5,7 +5,6 @@ * (C) Copyright 2017 Icenowy Zheng <icenowy@aosc.io> * */ -#include <common.h> #include <init.h> #include <log.h> #include <asm/io.h> diff --git a/arch/arm/mach-sunxi/dram_sun50i_h616.c b/arch/arm/mach-sunxi/dram_sun50i_h616.c index e62d5711d0f..37c139e0eea 100644 --- a/arch/arm/mach-sunxi/dram_sun50i_h616.c +++ b/arch/arm/mach-sunxi/dram_sun50i_h616.c @@ -12,7 +12,6 @@ * (C) Copyright 2020 Jernej Skrabec <jernej.skrabec@siol.net> * */ -#include <common.h> #include <init.h> #include <log.h> #include <asm/io.h> diff --git a/arch/arm/mach-sunxi/dram_sun6i.c b/arch/arm/mach-sunxi/dram_sun6i.c index 0590110d4ac..c023845908f 100644 --- a/arch/arm/mach-sunxi/dram_sun6i.c +++ b/arch/arm/mach-sunxi/dram_sun6i.c @@ -9,7 +9,6 @@ * * (C) Copyright 2014 Hans de Goede <hdegoede@redhat.com> */ -#include <common.h> #include <errno.h> #include <init.h> #include <asm/io.h> diff --git a/arch/arm/mach-sunxi/dram_sun8i_a23.c b/arch/arm/mach-sunxi/dram_sun8i_a23.c index 056cb03efb1..1c3c6d8126e 100644 --- a/arch/arm/mach-sunxi/dram_sun8i_a23.c +++ b/arch/arm/mach-sunxi/dram_sun8i_a23.c @@ -19,7 +19,6 @@ * This may be used as a (possible) reference for future work / cleanups. */ -#include <common.h> #include <errno.h> #include <init.h> #include <asm/io.h> diff --git a/arch/arm/mach-sunxi/dram_sun8i_a33.c b/arch/arm/mach-sunxi/dram_sun8i_a33.c index 367b74061ed..0d08b6a424e 100644 --- a/arch/arm/mach-sunxi/dram_sun8i_a33.c +++ b/arch/arm/mach-sunxi/dram_sun8i_a33.c @@ -7,7 +7,6 @@ * (C) Copyright 2015 Vishnu Patekar <vishnupatekar0510@gmail.com> * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com> */ -#include <common.h> #include <errno.h> #include <init.h> #include <asm/io.h> diff --git a/arch/arm/mach-sunxi/dram_sun8i_a83t.c b/arch/arm/mach-sunxi/dram_sun8i_a83t.c index a3f833dd341..ef833321e37 100644 --- a/arch/arm/mach-sunxi/dram_sun8i_a83t.c +++ b/arch/arm/mach-sunxi/dram_sun8i_a83t.c @@ -7,7 +7,6 @@ * (C) Copyright 2015 Vishnu Patekar <vishnupatekar0510@gmail.com> * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com> */ -#include <common.h> #include <errno.h> #include <init.h> #include <asm/io.h> diff --git a/arch/arm/mach-sunxi/dram_sun9i.c b/arch/arm/mach-sunxi/dram_sun9i.c index 14be212e891..002b6df39d5 100644 --- a/arch/arm/mach-sunxi/dram_sun9i.c +++ b/arch/arm/mach-sunxi/dram_sun9i.c @@ -10,7 +10,6 @@ * Philipp Tomsich <philipp.tomsich@theobroma-systems.com> */ -#include <common.h> #include <dm.h> #include <errno.h> #include <init.h> diff --git a/arch/arm/mach-sunxi/dram_suniv.c b/arch/arm/mach-sunxi/dram_suniv.c index 9e583e18553..640f872ad4c 100644 --- a/arch/arm/mach-sunxi/dram_suniv.c +++ b/arch/arm/mach-sunxi/dram_suniv.c @@ -9,7 +9,7 @@ * Copyright(c) 2007-2018 Jianjun Jiang <8192542@qq.com> */ -#include <common.h> +#include <config.h> #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch/dram.h> diff --git a/arch/arm/mach-sunxi/dram_sunxi_dw.c b/arch/arm/mach-sunxi/dram_sunxi_dw.c index daef051d0c8..3bfcc632119 100644 --- a/arch/arm/mach-sunxi/dram_sunxi_dw.c +++ b/arch/arm/mach-sunxi/dram_sunxi_dw.c @@ -8,7 +8,6 @@ * (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com> * (C) Copyright 2015 Jens Kuske <jenskuske@gmail.com> */ -#include <common.h> #include <init.h> #include <log.h> #include <asm/io.h> diff --git a/arch/arm/mach-sunxi/gtbus_sun9i.c b/arch/arm/mach-sunxi/gtbus_sun9i.c index 5624621b500..a058fea6bef 100644 --- a/arch/arm/mach-sunxi/gtbus_sun9i.c +++ b/arch/arm/mach-sunxi/gtbus_sun9i.c @@ -6,7 +6,6 @@ * Philipp Tomsich <philipp.tomsich@theobroma-systems.com> */ -#include <common.h> #include <asm/io.h> #include <asm/arch/cpu.h> #include <asm/arch/gtbus_sun9i.h> diff --git a/arch/arm/mach-sunxi/pmic_bus.c b/arch/arm/mach-sunxi/pmic_bus.c index 8e7625fe057..87df312725c 100644 --- a/arch/arm/mach-sunxi/pmic_bus.c +++ b/arch/arm/mach-sunxi/pmic_bus.c @@ -9,7 +9,6 @@ */ #include <axp_pmic.h> -#include <common.h> #include <dm.h> #include <asm/arch/p2wi.h> #include <asm/arch/rsb.h> diff --git a/arch/arm/mach-sunxi/prcm.c b/arch/arm/mach-sunxi/prcm.c index 71a2e44918e..ef7c46eab3b 100644 --- a/arch/arm/mach-sunxi/prcm.c +++ b/arch/arm/mach-sunxi/prcm.c @@ -13,7 +13,6 @@ * Tom Cubie <tangliang@allwinnertech.com> */ -#include <common.h> #include <errno.h> #include <asm/io.h> #include <asm/arch/cpu.h> diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c index 267cb0b1aba..72faa7171c1 100644 --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c @@ -3,7 +3,6 @@ * Copyright (C) 2016 Siarhei Siamashka <siarhei.siamashka@gmail.com> */ -#include <common.h> #include <image.h> #include <log.h> #include <spl.h> diff --git a/arch/arm/mach-sunxi/timer.c b/arch/arm/mach-sunxi/timer.c index 9a6f6c06d8c..1bbfad5e520 100644 --- a/arch/arm/mach-sunxi/timer.c +++ b/arch/arm/mach-sunxi/timer.c @@ -5,7 +5,6 @@ * Tom Cubie <tangliang@allwinnertech.com> */ -#include <common.h> #include <init.h> #include <time.h> #include <asm/global_data.h> diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c index e6a67326dd4..5e1ba8d43ed 100644 --- a/arch/arm/mach-zynq/clk.c +++ b/arch/arm/mach-zynq/clk.c @@ -44,8 +44,6 @@ int set_cpu_clk_info(void) gd->bd->bi_arm_freq = rate; gd->cpu_clk = clk_get_rate(&clk); } - - clk_free(&clk); } gd->bd->bi_dsp_freq = 0; diff --git a/arch/mips/mach-pic32/cpu.c b/arch/mips/mach-pic32/cpu.c index 3181a946a27..668adbbda62 100644 --- a/arch/mips/mach-pic32/cpu.c +++ b/arch/mips/mach-pic32/cpu.c @@ -30,7 +30,6 @@ static ulong rate(int id) int ret; struct udevice *dev; struct clk clk; - ulong rate; ret = uclass_get_device(UCLASS_CLK, 0, &dev); if (ret) { @@ -43,11 +42,7 @@ static ulong rate(int id) if (ret < 0) return ret; - rate = clk_get_rate(&clk); - - clk_free(&clk); - - return rate; + return clk_get_rate(&clk); } static ulong clk_get_cpu_rate(void) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 67126d96af8..ac52c5e6daf 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -14,6 +14,9 @@ config TARGET_ANDES_AE350 config TARGET_MICROCHIP_ICICLE bool "Support Microchip PolarFire-SoC Icicle Board" +config TARGET_MILKV_DUO + bool "Support Milk-v Duo Board" + config TARGET_OPENPITON_RISCV64 bool "Support RISC-V cores on OpenPiton SoC" @@ -83,6 +86,7 @@ source "board/openpiton/riscv64/Kconfig" source "board/sifive/unleashed/Kconfig" source "board/sifive/unmatched/Kconfig" source "board/sipeed/maix/Kconfig" +source "board/sophgo/milkv_duo/Kconfig" source "board/starfive/visionfive2/Kconfig" source "board/thead/th1520_lpi4a/Kconfig" source "board/xilinx/mbv/Kconfig" diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk index 9cf2aef0a41..9f16dda92a0 100644 --- a/arch/riscv/config.mk +++ b/arch/riscv/config.mk @@ -25,7 +25,7 @@ EFI_LDS := elf_riscv64_efi.lds PLATFORM_ELFFLAGS += -B riscv -O elf64-littleriscv endif -PLATFORM_CPPFLAGS += -ffixed-gp -fpic +PLATFORM_CPPFLAGS += -ffixed-x3 -fpic PLATFORM_RELFLAGS += -fno-common -ffunction-sections -fdata-sections LDFLAGS_u-boot += --gc-sections -static -pie diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile index b05bb5607f0..17cda483e12 100644 --- a/arch/riscv/dts/Makefile +++ b/arch/riscv/dts/Makefile @@ -2,6 +2,7 @@ dtb-$(CONFIG_TARGET_ANDES_AE350) += ae350_32.dtb ae350_64.dtb dtb-$(CONFIG_TARGET_MICROCHIP_ICICLE) += mpfs-icicle-kit.dtb +dtb-$(CONFIG_TARGET_MILKV_DUO) += cv1800b-milkv-duo.dtb dtb-$(CONFIG_TARGET_QEMU_VIRT) += qemu-virt32.dtb qemu-virt64.dtb dtb-$(CONFIG_TARGET_OPENPITON_RISCV64) += openpiton-riscv64.dtb dtb-$(CONFIG_TARGET_SIFIVE_UNLEASHED) += hifive-unleashed-a00.dtb diff --git a/arch/riscv/dts/cv1800b-milkv-duo.dts b/arch/riscv/dts/cv1800b-milkv-duo.dts new file mode 100644 index 00000000000..3af9e34b3bc --- /dev/null +++ b/arch/riscv/dts/cv1800b-milkv-duo.dts @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org> + */ + +/dts-v1/; + +#include "cv1800b.dtsi" + +/ { + model = "Milk-V Duo"; + compatible = "milkv,duo", "sophgo,cv1800b"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + serial4 = &uart4; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x3f40000>; + }; +}; + +&osc { + clock-frequency = <25000000>; +}; + +&uart0 { + status = "okay"; +}; diff --git a/arch/riscv/dts/cv1800b.dtsi b/arch/riscv/dts/cv1800b.dtsi new file mode 100644 index 00000000000..165e9e320a8 --- /dev/null +++ b/arch/riscv/dts/cv1800b.dtsi @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org> + */ + +#include "cv18xx.dtsi" + +/ { + compatible = "sophgo,cv1800b"; +}; + +&plic { + compatible = "sophgo,cv1800b-plic", "thead,c900-plic"; +}; + +&clint { + compatible = "sophgo,cv1800b-clint", "thead,c900-clint"; +}; diff --git a/arch/riscv/dts/cv18xx.dtsi b/arch/riscv/dts/cv18xx.dtsi new file mode 100644 index 00000000000..2d6f4a4b1e5 --- /dev/null +++ b/arch/riscv/dts/cv18xx.dtsi @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2023 Jisheng Zhang <jszhang@kernel.org> + * Copyright (C) 2023 Inochi Amaoto <inochiama@outlook.com> + */ + +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + #address-cells = <1>; + #size-cells = <1>; + + cpus: cpus { + #address-cells = <1>; + #size-cells = <0>; + timebase-frequency = <25000000>; + + cpu0: cpu@0 { + compatible = "thead,c906", "riscv"; + device_type = "cpu"; + reg = <0>; + d-cache-block-size = <64>; + d-cache-sets = <512>; + d-cache-size = <65536>; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <32768>; + mmu-type = "riscv,sv39"; + riscv,isa = "rv64imafdc"; + riscv,isa-base = "rv64i"; + riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "zicntr", "zicsr", + "zifencei", "zihpm"; + + cpu0_intc: interrupt-controller { + compatible = "riscv,cpu-intc"; + interrupt-controller; + #interrupt-cells = <1>; + }; + }; + }; + + osc: oscillator { + compatible = "fixed-clock"; + clock-output-names = "osc_25m"; + #clock-cells = <0>; + }; + + soc { + compatible = "simple-bus"; + interrupt-parent = <&plic>; + #address-cells = <1>; + #size-cells = <1>; + dma-noncoherent; + ranges; + + gpio0: gpio@3020000 { + compatible = "snps,dw-apb-gpio"; + reg = <0x3020000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + porta: gpio-controller@0 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + reg = <0>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <60 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + + gpio1: gpio@3021000 { + compatible = "snps,dw-apb-gpio"; + reg = <0x3021000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + portb: gpio-controller@0 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + reg = <0>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <61 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + + gpio2: gpio@3022000 { + compatible = "snps,dw-apb-gpio"; + reg = <0x3022000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + portc: gpio-controller@0 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + reg = <0>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <62 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + + gpio3: gpio@3023000 { + compatible = "snps,dw-apb-gpio"; + reg = <0x3023000 0x1000>; + #address-cells = <1>; + #size-cells = <0>; + + portd: gpio-controller@0 { + compatible = "snps,dw-apb-gpio-port"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + reg = <0>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <63 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + + uart0: serial@4140000 { + compatible = "snps,dw-apb-uart"; + reg = <0x04140000 0x100>; + interrupts = <44 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&osc>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart1: serial@4150000 { + compatible = "snps,dw-apb-uart"; + reg = <0x04150000 0x100>; + interrupts = <45 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&osc>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart2: serial@4160000 { + compatible = "snps,dw-apb-uart"; + reg = <0x04160000 0x100>; + interrupts = <46 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&osc>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart3: serial@4170000 { + compatible = "snps,dw-apb-uart"; + reg = <0x04170000 0x100>; + interrupts = <47 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&osc>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart4: serial@41c0000 { + compatible = "snps,dw-apb-uart"; + reg = <0x041c0000 0x100>; + interrupts = <48 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&osc>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + plic: interrupt-controller@70000000 { + reg = <0x70000000 0x4000000>; + interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + riscv,ndev = <101>; + }; + + clint: timer@74000000 { + reg = <0x74000000 0x10000>; + interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>; + }; + }; +}; diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi index e94f9fe826a..f2c6bec9298 100644 --- a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi +++ b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi @@ -127,6 +127,11 @@ pinctrl-0 = <&i2c5_pins>; status = "okay"; + pmic@36 { + compatible = "x-powers,axp15060"; + reg = <0x36>; + }; + eeprom@50 { compatible = "atmel,24c04"; reg = <0x50>; diff --git a/arch/riscv/dts/jh7110.dtsi b/arch/riscv/dts/jh7110.dtsi index 6d2675d6cea..2cdc683d49b 100644 --- a/arch/riscv/dts/jh7110.dtsi +++ b/arch/riscv/dts/jh7110.dtsi @@ -473,6 +473,12 @@ status = "disabled"; }; + power-controller@17030000 { + compatible = "starfive,jh7110-pmu"; + reg = <0x0 0x17030000 0x0 0x10000>; + interrupts = <111>; + }; + qspi: spi@13010000 { compatible = "cdns,qspi-nor"; reg = <0x0 0x13010000 0x0 0x10000 diff --git a/arch/riscv/include/asm/arch-fu740/eeprom.h b/arch/riscv/include/asm/arch-fu740/eeprom.h new file mode 100644 index 00000000000..aaa02c6d2bb --- /dev/null +++ b/arch/riscv/include/asm/arch-fu740/eeprom.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2024 SiFive, Inc. + * + * Zong Li <zong.li@sifve.com> + */ + +#ifndef _ASM_RISCV_EEPROM_H +#define _ASM_RISCV_EEPROM_H + +#define PCB_REVISION_REV3 0x3 + +u8 get_pcb_revision_from_eeprom(void); + +#endif /* _ASM_RISCV_EEPROM_H */ diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index bf4c9af6220..d1113f3d703 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -33,6 +33,7 @@ enum sbi_ext_id { SBI_EXT_CPPC = 0x43505043, SBI_EXT_NACL = 0x4E41434C, SBI_EXT_STA = 0x535441, + SBI_EXT_DBTR = 0x44425452, }; enum sbi_ext_base_fid { diff --git a/arch/riscv/lib/crt0_riscv_efi.S b/arch/riscv/lib/crt0_riscv_efi.S index 793eefdd883..46b08552371 100644 --- a/arch/riscv/lib/crt0_riscv_efi.S +++ b/arch/riscv/lib/crt0_riscv_efi.S @@ -53,7 +53,7 @@ pe_header: .long IMAGE_NT_SIGNATURE /* 'PE' */ coff_header: .short PE_MACHINE /* RISC-V 64/32-bit */ - .short 2 /* nr_sections */ + .short 3 /* nr_sections */ .long 0 /* TimeDateStamp */ .long 0 /* PointerToSymbolTable */ .long 0 /* NumberOfSymbols */ @@ -144,18 +144,37 @@ section_table: .byte 0 .byte 0 .byte 0 /* end of 0 padding of section name */ - .long _edata - _start /* VirtualSize */ + .long _etext - _start /* VirtualSize */ .long _start - ImageBase /* VirtualAddress */ - .long _edata - _start /* SizeOfRawData */ + .long _etext - _start /* SizeOfRawData */ .long _start - ImageBase /* PointerToRawData */ + .long 0 /* PointerToRelocations (0 for executables) */ + .long 0 /* PointerToLineNumbers (0 for executables) */ + .short 0 /* NumberOfRelocations (0 for executables) */ + .short 0 /* NumberOfLineNumbers (0 for executables) */ + /* Characteristics (section flags) */ + .long (IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_EXECUTE | \ + IMAGE_SCN_CNT_CODE) + + .ascii ".data" + .byte 0 + .byte 0 + .byte 0 /* end of 0 padding of section name */ + .long _edata - _data /* VirtualSize */ + .long _data - ImageBase /* VirtualAddress */ + .long _edata - _data /* SizeOfRawData */ + .long _data - ImageBase /* PointerToRawData */ + .long 0 /* PointerToRelocations */ + .long 0 /* PointerToLineNumbers */ + .short 0 /* NumberOfRelocations */ + .short 0 /* NumberOfLineNumbers */ + /* Characteristics (section flags) */ + .long (IMAGE_SCN_MEM_WRITE | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_CNT_INITIALIZED_DATA) - .long 0 /* PointerToRelocations (0 for executables) */ - .long 0 /* PointerToLineNumbers (0 for executables) */ - .short 0 /* NumberOfRelocations (0 for executables) */ - .short 0 /* NumberOfLineNumbers (0 for executables) */ - .long 0xe0500020 /* Characteristics (section flags) */ - - .align 9 + .align 12 _start: addi sp, sp, -(SIZE_LONG * 3) SAVE_LONG(a0, 0) diff --git a/arch/riscv/lib/elf_riscv32_efi.lds b/arch/riscv/lib/elf_riscv32_efi.lds index c3e0d20d577..7b9bd7b7f15 100644 --- a/arch/riscv/lib/elf_riscv32_efi.lds +++ b/arch/riscv/lib/elf_riscv32_efi.lds @@ -1,14 +1,18 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: BSD-2-Clause */ /* * U-Boot riscv32 EFI linker script * - * SPDX-License-Identifier: BSD-2-Clause - * * Modified from arch/arm/lib/elf_aarch64_efi.lds */ OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") OUTPUT_ARCH(riscv) + +PHDRS +{ + data PT_LOAD FLAGS(3); /* SHF_WRITE | SHF_ALLOC */ +} + ENTRY(_start) SECTIONS { @@ -20,11 +24,17 @@ SECTIONS *(.gnu.linkonce.t.*) *(.srodata) *(.rodata*) + . = ALIGN(16); + *(.dynamic); . = ALIGN(512); } + .rela.dyn : { *(.rela.dyn) } + .rela.plt : { *(.rela.plt) } + .rela.got : { *(.rela.got) } + .rela.data : { *(.rela.data) *(.rela.data*) } _etext = .; _text_size = . - _text; - .dynamic : { *(.dynamic) } + . = ALIGN(4096); .data : { _data = .; *(.sdata) @@ -49,12 +59,8 @@ SECTIONS . = ALIGN(512); _bss_end = .; _edata = .; - } - .rela.dyn : { *(.rela.dyn) } - .rela.plt : { *(.rela.plt) } - .rela.got : { *(.rela.got) } - .rela.data : { *(.rela.data) *(.rela.data*) } - _data_size = . - _etext; + } :data + _data_size = _edata - _data; . = ALIGN(4096); .dynsym : { *(.dynsym) } diff --git a/arch/riscv/lib/elf_riscv64_efi.lds b/arch/riscv/lib/elf_riscv64_efi.lds index ecb91395486..d0b4f3d1d64 100644 --- a/arch/riscv/lib/elf_riscv64_efi.lds +++ b/arch/riscv/lib/elf_riscv64_efi.lds @@ -1,14 +1,18 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ +/* SPDX-License-Identifier: BSD-2-Clause */ /* * U-Boot riscv64 EFI linker script * - * SPDX-License-Identifier: BSD-2-Clause - * * Modified from arch/arm/lib/elf_aarch64_efi.lds */ OUTPUT_FORMAT("elf64-littleriscv", "elf64-littleriscv", "elf64-littleriscv") OUTPUT_ARCH(riscv) + +PHDRS +{ + data PT_LOAD FLAGS(3); /* SHF_WRITE | SHF_ALLOC */ +} + ENTRY(_start) SECTIONS { @@ -20,11 +24,17 @@ SECTIONS *(.gnu.linkonce.t.*) *(.srodata) *(.rodata*) + . = ALIGN(16); + *(.dynamic); . = ALIGN(512); } + .rela.dyn : { *(.rela.dyn) } + .rela.plt : { *(.rela.plt) } + .rela.got : { *(.rela.got) } + .rela.data : { *(.rela.data) *(.rela.data*) } _etext = .; _text_size = . - _text; - .dynamic : { *(.dynamic) } + . = ALIGN(4096); .data : { _data = .; *(.sdata) @@ -49,12 +59,8 @@ SECTIONS . = ALIGN(512); _bss_end = .; _edata = .; - } - .rela.dyn : { *(.rela.dyn) } - .rela.plt : { *(.rela.plt) } - .rela.got : { *(.rela.got) } - .rela.data : { *(.rela.data) *(.rela.data*) } - _data_size = . - _etext; + } :data + _data_size = _edata - _data; . = ALIGN(4096); .dynsym : { *(.dynsym) } diff --git a/arch/sandbox/include/asm/clk.h b/arch/sandbox/include/asm/clk.h index d4e04ad1486..37fe49c7fcf 100644 --- a/arch/sandbox/include/asm/clk.h +++ b/arch/sandbox/include/asm/clk.h @@ -182,14 +182,6 @@ int sandbox_clk_test_disable(struct udevice *dev, int id); */ int sandbox_clk_test_disable_bulk(struct udevice *dev); /** - * sandbox_clk_test_free - Ask the sandbox clock test device to free its - * clocks. - * - * @dev: The sandbox clock test (client) device. - * @return: 0 if OK, or a negative error code. - */ -int sandbox_clk_test_free(struct udevice *dev); -/** * sandbox_clk_test_release_bulk - Ask the sandbox clock test device to release * all clocks in it's clock bulk struct. * diff --git a/board/AndesTech/ae350/ae350.c b/board/AndesTech/ae350/ae350.c index 4e53fee5d23..62b93b4ecba 100644 --- a/board/AndesTech/ae350/ae350.c +++ b/board/AndesTech/ae350/ae350.c @@ -21,8 +21,6 @@ #include <fdtdec.h> #include <dm.h> #include <spl.h> -#include <mapmem.h> -#include <hang.h> DECLARE_GLOBAL_DATA_PTR; @@ -51,29 +49,6 @@ int misc_init_r(void) } #endif -#if CONFIG_IS_ENABLED(LOAD_FIT) || CONFIG_IS_ENABLED(LOAD_FIT_FULL) -#define ANDES_SPL_FDT_ADDR (CONFIG_TEXT_BASE - 0x100000) -void spl_perform_fixups(struct spl_image_info *spl_image) -{ - /* - * Originally, u-boot-spl will place DTB directly after the kernel, - * but the size of the kernel did not include the BSS section, which - * means u-boot-spl will place the DTB in the kernel BSS section - * causing the DTB to be cleared by kernel BSS initializtion. - * Moving DTB in front of the kernel can avoid the error. - */ - if (ANDES_SPL_FDT_ADDR < 0) { - printf("%s: CONFIG_TEXT_BASE needs to be larger than 0x100000\n", - __func__); - hang(); - } - - memcpy((void *)ANDES_SPL_FDT_ADDR, spl_image->fdt_addr, - fdt_totalsize(spl_image->fdt_addr)); - spl_image->fdt_addr = map_sysmem(ANDES_SPL_FDT_ADDR, 0); -} -#endif - int board_init(void) { gd->bd->bi_boot_params = PHYS_SDRAM_0 + 0x400; diff --git a/board/microchip/pic32mzda/pic32mzda.c b/board/microchip/pic32mzda/pic32mzda.c index e7337deea7f..3c2203d2202 100644 --- a/board/microchip/pic32mzda/pic32mzda.c +++ b/board/microchip/pic32mzda/pic32mzda.c @@ -36,8 +36,6 @@ int checkboard(void) rate = clk_get_rate(&clk); printf("CPU Speed: %lu MHz\n", rate / 1000000); - clk_free(&clk); - return 0; } #endif diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index cd823ad7465..2851ebc9853 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -171,6 +171,11 @@ static const struct rpi_model rpi_models_new_scheme[] = { DTB_DIR "bcm2711-rpi-cm4.dtb", true, }, + [0x17] = { + "5 Model B", + DTB_DIR "bcm2712-rpi-5-b.dtb", + true, + }, }; static const struct rpi_model rpi_models_old_scheme[] = { @@ -429,15 +434,27 @@ static void get_board_revision(void) int ret; const struct rpi_model *models; uint32_t models_count; + ofnode node; BCM2835_MBOX_INIT_HDR(msg); BCM2835_MBOX_INIT_TAG(&msg->get_board_rev, GET_BOARD_REV); ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg->hdr); if (ret) { - printf("bcm2835: Could not query board revision\n"); /* Ignore error; not critical */ - return; + node = ofnode_path("/system"); + if (!ofnode_valid(node)) { + printf("bcm2835: Could not find /system node\n"); + return; + } + + ret = ofnode_read_u32(node, "linux,revision", &revision); + if (ret) { + printf("bcm2835: Could not find linux,revision\n"); + return; + } + } else { + revision = msg->get_board_rev.body.resp.rev; } /* @@ -451,7 +468,6 @@ static void get_board_revision(void) * http://www.raspberrypi.org/forums/viewtopic.php?f=63&t=98367&start=250 * http://www.raspberrypi.org/forums/viewtopic.php?f=31&t=20594 */ - revision = msg->get_board_rev.body.resp.rev; if (revision & 0x800000) { rev_scheme = 1; rev_type = (revision >> 4) & 0xff; diff --git a/board/renesas/alt/alt.c b/board/renesas/alt/alt.c index 85fbaf0b28b..be77cade01b 100644 --- a/board/renesas/alt/alt.c +++ b/board/renesas/alt/alt.c @@ -5,7 +5,6 @@ * Copyright (C) 2014, 2015 Renesas Electronics Corporation */ -#include <common.h> #include <cpu_func.h> #include <env.h> #include <hang.h> diff --git a/board/renesas/alt/alt_spl.c b/board/renesas/alt/alt_spl.c index cdaa04e4f4c..fc9dac55e6a 100644 --- a/board/renesas/alt/alt_spl.c +++ b/board/renesas/alt/alt_spl.c @@ -5,7 +5,6 @@ * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com> */ -#include <common.h> #include <cpu_func.h> #include <init.h> #include <malloc.h> diff --git a/board/renesas/alt/qos.c b/board/renesas/alt/qos.c index 2f657505ceb..38dfa647e81 100644 --- a/board/renesas/alt/qos.c +++ b/board/renesas/alt/qos.c @@ -6,7 +6,6 @@ * */ -#include <common.h> #include <asm/processor.h> #include <asm/mach-types.h> #include <asm/io.h> diff --git a/board/renesas/blanche/blanche.c b/board/renesas/blanche/blanche.c index 8e1ae29e221..c6ecea2afcf 100644 --- a/board/renesas/blanche/blanche.c +++ b/board/renesas/blanche/blanche.c @@ -6,7 +6,6 @@ * Copyright (C) 2016 Renesas Electronics Corporation */ -#include <common.h> #include <cpu_func.h> #include <init.h> #include <net.h> diff --git a/board/renesas/blanche/qos.c b/board/renesas/blanche/qos.c index e3ad83ee0c2..3134b36a443 100644 --- a/board/renesas/blanche/qos.c +++ b/board/renesas/blanche/qos.c @@ -5,7 +5,6 @@ * Copyright (C) 2016 Renesas Electronics Corporation */ -#include <common.h> #include <asm/processor.h> #include <asm/mach-types.h> #include <asm/io.h> diff --git a/board/renesas/draak/draak.c b/board/renesas/draak/draak.c index 1ed72d34a74..06a3a832984 100644 --- a/board/renesas/draak/draak.c +++ b/board/renesas/draak/draak.c @@ -6,7 +6,6 @@ * Copyright (C) 2017 Marek Vasut <marek.vasut+renesas@gmail.com> */ -#include <common.h> #include <cpu_func.h> #include <hang.h> #include <init.h> diff --git a/board/renesas/falcon/falcon.c b/board/renesas/falcon/falcon.c index 0aa0f1afcbf..cd86bb3108c 100644 --- a/board/renesas/falcon/falcon.c +++ b/board/renesas/falcon/falcon.c @@ -6,7 +6,6 @@ * Copyright (C) 2020 Renesas Electronics Corp. */ -#include <common.h> #include <asm/arch/rmobile.h> #include <asm/arch/sys_proto.h> #include <asm/global_data.h> @@ -15,6 +14,7 @@ #include <asm/processor.h> #include <linux/errno.h> #include <asm/system.h> +#include <asm/u-boot.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/board/renesas/gose/gose.c b/board/renesas/gose/gose.c index 2d1435acff6..6edbdac3ded 100644 --- a/board/renesas/gose/gose.c +++ b/board/renesas/gose/gose.c @@ -5,7 +5,6 @@ * Copyright (C) 2014 Renesas Electronics Corporation */ -#include <common.h> #include <clock_legacy.h> #include <cpu_func.h> #include <env.h> diff --git a/board/renesas/gose/gose_spl.c b/board/renesas/gose/gose_spl.c index c0bf7204439..87126a0fc15 100644 --- a/board/renesas/gose/gose_spl.c +++ b/board/renesas/gose/gose_spl.c @@ -5,7 +5,6 @@ * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com> */ -#include <common.h> #include <cpu_func.h> #include <init.h> #include <malloc.h> diff --git a/board/renesas/gose/qos.c b/board/renesas/gose/qos.c index 1c4ebfc6a8a..9944df76759 100644 --- a/board/renesas/gose/qos.c +++ b/board/renesas/gose/qos.c @@ -6,7 +6,6 @@ * Copyright (C) 2014 Renesas Electronics Corporation */ -#include <common.h> #include <asm/processor.h> #include <asm/mach-types.h> #include <asm/io.h> diff --git a/board/renesas/grpeach/grpeach.c b/board/renesas/grpeach/grpeach.c index f609e4f0728..c475c3f50ab 100644 --- a/board/renesas/grpeach/grpeach.c +++ b/board/renesas/grpeach/grpeach.c @@ -4,12 +4,13 @@ * Copyright (C) Chris Brandt */ -#include <common.h> #include <cpu_func.h> +#include <errno.h> #include <init.h> #include <asm/global_data.h> #include <asm/io.h> #include <asm/arch/sys_proto.h> +#include <asm/u-boot.h> #define RZA1_WDT_BASE 0xfcfe0000 #define WTCSR 0x00 diff --git a/board/renesas/koelsch/koelsch.c b/board/renesas/koelsch/koelsch.c index c3ebcd3e39f..ee5597ad3d9 100644 --- a/board/renesas/koelsch/koelsch.c +++ b/board/renesas/koelsch/koelsch.c @@ -6,7 +6,6 @@ * */ -#include <common.h> #include <clock_legacy.h> #include <cpu_func.h> #include <env.h> diff --git a/board/renesas/koelsch/koelsch_spl.c b/board/renesas/koelsch/koelsch_spl.c index b377f707158..7581920f577 100644 --- a/board/renesas/koelsch/koelsch_spl.c +++ b/board/renesas/koelsch/koelsch_spl.c @@ -5,7 +5,6 @@ * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com> */ -#include <common.h> #include <cpu_func.h> #include <init.h> #include <malloc.h> diff --git a/board/renesas/koelsch/qos.c b/board/renesas/koelsch/qos.c index f884e5fe650..70cd117ba6b 100644 --- a/board/renesas/koelsch/qos.c +++ b/board/renesas/koelsch/qos.c @@ -6,7 +6,6 @@ * */ -#include <common.h> #include <asm/processor.h> #include <asm/mach-types.h> #include <asm/io.h> diff --git a/board/renesas/lager/lager.c b/board/renesas/lager/lager.c index 1437875cfa7..0daad0b1e6d 100644 --- a/board/renesas/lager/lager.c +++ b/board/renesas/lager/lager.c @@ -7,7 +7,6 @@ * Copyright (C) 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> */ -#include <common.h> #include <clock_legacy.h> #include <cpu_func.h> #include <env.h> diff --git a/board/renesas/lager/lager_spl.c b/board/renesas/lager/lager_spl.c index d3d397e8f0a..df3e240599a 100644 --- a/board/renesas/lager/lager_spl.c +++ b/board/renesas/lager/lager_spl.c @@ -5,7 +5,6 @@ * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com> */ -#include <common.h> #include <cpu_func.h> #include <init.h> #include <malloc.h> diff --git a/board/renesas/lager/qos.c b/board/renesas/lager/qos.c index f01ca2fac71..ddc831c0c21 100644 --- a/board/renesas/lager/qos.c +++ b/board/renesas/lager/qos.c @@ -5,7 +5,6 @@ * Copyright (C) 2013,2014 Renesas Electronics Corporation */ -#include <common.h> #include <asm/processor.h> #include <asm/mach-types.h> #include <asm/io.h> diff --git a/board/renesas/porter/porter.c b/board/renesas/porter/porter.c index db1fb4b035f..2e6051addb1 100644 --- a/board/renesas/porter/porter.c +++ b/board/renesas/porter/porter.c @@ -6,7 +6,6 @@ * Copyright (C) 2015 Cogent Embedded, Inc. */ -#include <common.h> #include <clock_legacy.h> #include <cpu_func.h> #include <env.h> diff --git a/board/renesas/porter/porter_spl.c b/board/renesas/porter/porter_spl.c index 8595770c364..039fc7b719e 100644 --- a/board/renesas/porter/porter_spl.c +++ b/board/renesas/porter/porter_spl.c @@ -5,7 +5,6 @@ * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com> */ -#include <common.h> #include <cpu_func.h> #include <init.h> #include <malloc.h> diff --git a/board/renesas/porter/qos.c b/board/renesas/porter/qos.c index bca54f7f74c..e4d8f3dfafe 100644 --- a/board/renesas/porter/qos.c +++ b/board/renesas/porter/qos.c @@ -7,7 +7,6 @@ * */ -#include <common.h> #include <asm/processor.h> #include <asm/mach-types.h> #include <asm/io.h> diff --git a/board/renesas/r2dplus/r2dplus.c b/board/renesas/r2dplus/r2dplus.c index 4b9959a4326..78b8cb4ac34 100644 --- a/board/renesas/r2dplus/r2dplus.c +++ b/board/renesas/r2dplus/r2dplus.c @@ -4,7 +4,6 @@ * Nobuhiro Iwamatsu <iwamatsu@nigauri.org> */ -#include <common.h> #include <ide.h> #include <init.h> #include <net.h> diff --git a/board/renesas/rcar-common/common.c b/board/renesas/rcar-common/common.c index ed3f093bf3c..66eb6a2002c 100644 --- a/board/renesas/rcar-common/common.c +++ b/board/renesas/rcar-common/common.c @@ -7,7 +7,6 @@ * Copyright (C) 2015 Nobuhiro Iwamatsu <iwamatsu@nigauri.org> */ -#include <common.h> #include <dm.h> #include <fdt_support.h> #include <hang.h> diff --git a/board/renesas/rcar-common/gen3-spl.c b/board/renesas/rcar-common/gen3-spl.c index b02a946a21d..44a20cef2df 100644 --- a/board/renesas/rcar-common/gen3-spl.c +++ b/board/renesas/rcar-common/gen3-spl.c @@ -5,7 +5,6 @@ * Copyright (C) 2019 Marek Vasut <marek.vasut@gmail.com> */ -#include <common.h> #include <cpu_func.h> #include <image.h> #include <init.h> diff --git a/board/renesas/rcar-common/v3-common.c b/board/renesas/rcar-common/v3-common.c index 7c6202ea499..26c589d03e9 100644 --- a/board/renesas/rcar-common/v3-common.c +++ b/board/renesas/rcar-common/v3-common.c @@ -3,8 +3,8 @@ * Copyright (C) 2017-2023 Marek Vasut <marek.vasut+renesas@mailbox.org> */ -#include <common.h> #include <clock_legacy.h> +#include <asm/arch/rmobile.h> #include <asm/io.h> #define CPGWPR 0xE6150900 diff --git a/board/renesas/salvator-x/salvator-x.c b/board/renesas/salvator-x/salvator-x.c index 939b48ee300..d8312ddb8a9 100644 --- a/board/renesas/salvator-x/salvator-x.c +++ b/board/renesas/salvator-x/salvator-x.c @@ -7,7 +7,6 @@ * Copyright (C) 2015 Nobuhiro Iwamatsu <iwamatsu@nigauri.org> */ -#include <common.h> #include <cpu_func.h> #include <image.h> #include <init.h> diff --git a/board/renesas/silk/qos.c b/board/renesas/silk/qos.c index 43a29898657..bdd76461b6a 100644 --- a/board/renesas/silk/qos.c +++ b/board/renesas/silk/qos.c @@ -7,7 +7,6 @@ * */ -#include <common.h> #include <asm/processor.h> #include <asm/mach-types.h> #include <asm/io.h> diff --git a/board/renesas/silk/silk.c b/board/renesas/silk/silk.c index 6ecebfe814d..18ff7591228 100644 --- a/board/renesas/silk/silk.c +++ b/board/renesas/silk/silk.c @@ -6,7 +6,6 @@ * Copyright (C) 2015 Cogent Embedded, Inc. */ -#include <common.h> #include <cpu_func.h> #include <env.h> #include <hang.h> diff --git a/board/renesas/silk/silk_spl.c b/board/renesas/silk/silk_spl.c index afb9f85ffc2..b899442c25a 100644 --- a/board/renesas/silk/silk_spl.c +++ b/board/renesas/silk/silk_spl.c @@ -5,7 +5,6 @@ * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com> */ -#include <common.h> #include <cpu_func.h> #include <init.h> #include <malloc.h> diff --git a/board/renesas/spider/spider.c b/board/renesas/spider/spider.c index fd83a72229e..1eb75a6397f 100644 --- a/board/renesas/spider/spider.c +++ b/board/renesas/spider/spider.c @@ -6,7 +6,6 @@ * Copyright (C) 2021 Renesas Electronics Corp. */ -#include <common.h> #include <asm/arch/rmobile.h> #include <asm/arch/sys_proto.h> #include <asm/global_data.h> diff --git a/board/renesas/stout/cpld.c b/board/renesas/stout/cpld.c index b7c75f5aa65..f5bb549b7c0 100644 --- a/board/renesas/stout/cpld.c +++ b/board/renesas/stout/cpld.c @@ -7,7 +7,6 @@ * Copyright (C) 2015 Cogent Embedded, Inc. */ -#include <common.h> #include <command.h> #include <cpu_func.h> #include <asm/io.h> diff --git a/board/renesas/stout/qos.c b/board/renesas/stout/qos.c index c2f0b853871..9030ba7f61f 100644 --- a/board/renesas/stout/qos.c +++ b/board/renesas/stout/qos.c @@ -7,7 +7,6 @@ * Copyright (C) 2015 Cogent Embedded, Inc. */ -#include <common.h> #include <asm/processor.h> #include <asm/mach-types.h> #include <asm/io.h> diff --git a/board/renesas/stout/stout.c b/board/renesas/stout/stout.c index f069eccde97..131deac1c7a 100644 --- a/board/renesas/stout/stout.c +++ b/board/renesas/stout/stout.c @@ -8,7 +8,6 @@ * Copyright (C) 2015 Cogent Embedded, Inc. */ -#include <common.h> #include <clock_legacy.h> #include <env.h> #include <init.h> diff --git a/board/renesas/stout/stout_spl.c b/board/renesas/stout/stout_spl.c index c37c0557132..8ec02168106 100644 --- a/board/renesas/stout/stout_spl.c +++ b/board/renesas/stout/stout_spl.c @@ -5,7 +5,6 @@ * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com> */ -#include <common.h> #include <cpu_func.h> #include <init.h> #include <malloc.h> diff --git a/board/renesas/ulcb/cpld.c b/board/renesas/ulcb/cpld.c index 0c060a5323d..e72e45e3fb4 100644 --- a/board/renesas/ulcb/cpld.c +++ b/board/renesas/ulcb/cpld.c @@ -6,7 +6,6 @@ * Copyright (C) 2017 Cogent Embedded, Inc. */ -#include <common.h> #include <command.h> #include <asm/gpio.h> #include <asm/io.h> diff --git a/board/renesas/ulcb/ulcb.c b/board/renesas/ulcb/ulcb.c index 1477750f921..b2a16b03513 100644 --- a/board/renesas/ulcb/ulcb.c +++ b/board/renesas/ulcb/ulcb.c @@ -6,7 +6,6 @@ * Copyright (C) 2017 Renesas Electronics Corporation */ -#include <common.h> #include <image.h> #include <init.h> #include <malloc.h> diff --git a/board/renesas/v3hsk/cpld.c b/board/renesas/v3hsk/cpld.c index 6016f6daef9..1272aec7302 100644 --- a/board/renesas/v3hsk/cpld.c +++ b/board/renesas/v3hsk/cpld.c @@ -7,7 +7,6 @@ * */ -#include <common.h> #include <dm.h> #include <errno.h> #include <i2c.h> diff --git a/board/renesas/v3msk/cpld.c b/board/renesas/v3msk/cpld.c index aed616ac859..260755ac746 100644 --- a/board/renesas/v3msk/cpld.c +++ b/board/renesas/v3msk/cpld.c @@ -7,7 +7,6 @@ * */ -#include <common.h> #include <asm/gpio.h> #include <asm/io.h> #include <dm.h> diff --git a/board/renesas/whitehawk/whitehawk.c b/board/renesas/whitehawk/whitehawk.c index 32284b2ecc0..a72f5e0a7a5 100644 --- a/board/renesas/whitehawk/whitehawk.c +++ b/board/renesas/whitehawk/whitehawk.c @@ -6,7 +6,6 @@ * Copyright (C) 2021 Renesas Electronics Corp. */ -#include <common.h> #include <asm/arch/rmobile.h> #include <asm/arch/sys_proto.h> #include <asm/global_data.h> @@ -32,7 +31,7 @@ static void init_generic_timer(void) static void init_gic_v3(void) { - /* GIC v3 power on */ + /* GIC v3 power on */ writel(BIT(1), GICR_LPI_PWRR); /* Wait till the WAKER_CA_BIT changes to 0 */ diff --git a/board/sifive/unmatched/spl.c b/board/sifive/unmatched/spl.c index 7c0beedc083..e69bed9d99d 100644 --- a/board/sifive/unmatched/spl.c +++ b/board/sifive/unmatched/spl.c @@ -15,6 +15,29 @@ #include <asm/gpio.h> #include <asm/arch/gpio.h> #include <asm/arch/spl.h> +#include <linux/io.h> +#include <asm/arch/eeprom.h> + +struct pwm_sifive_regs { + unsigned int cfg; /* PWM configuration register */ + unsigned int pad0; /* Reserved */ + unsigned int cnt; /* PWM count register */ + unsigned int pad1; /* Reserved */ + unsigned int pwms; /* Scaled PWM count register */ + unsigned int pad2; /* Reserved */ + unsigned int pad3; /* Reserved */ + unsigned int pad4; /* Reserved */ + unsigned int cmp0; /* PWM 0 compare register */ + unsigned int cmp1; /* PWM 1 compare register */ + unsigned int cmp2; /* PWM 2 compare register */ + unsigned int cmp3; /* PWM 3 compare register */ +}; + +#define PWM0_BASE 0x10020000 +#define PWM1_BASE 0x10021000 +#define PWM_CFG_INIT 0x1000 +#define PWM_CMP_ENABLE_VAL 0x0 +#define PWM_CMP_DISABLE_VAL 0xffff #define UBRDG_RESET SIFIVE_GENERIC_GPIO_NR(0, 7) #define ULPI_RESET SIFIVE_GENERIC_GPIO_NR(0, 9) @@ -26,6 +49,33 @@ #define MODE_SELECT_SD 0xb #define MODE_SELECT_MASK GENMASK(3, 0) +void spl_pwm_device_init(void) +{ + struct pwm_sifive_regs *pwm0, *pwm1; + + pwm0 = (struct pwm_sifive_regs *)PWM0_BASE; + pwm1 = (struct pwm_sifive_regs *)PWM1_BASE; + writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp0); + + /* Set the 3-color PWM LEDs to yellow in SPL */ + writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp1); + writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp2); + writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp3); + writel(PWM_CFG_INIT, (void *)&pwm0->cfg); + + /* Turn on all the fans, (J21), (J23) and (J24), on the unmatched board */ + /* The SoC fan(J21) on the rev3 board cannot be controlled by PWM_COMP0, + * so here sets the initial value of PWM_COMP0 as DISABLE */ + if (get_pcb_revision_from_eeprom() == PCB_REVISION_REV3) + writel(PWM_CMP_DISABLE_VAL, (void *)&pwm1->cmp1); + else + writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp1); + + writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp2); + writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp3); + writel(PWM_CFG_INIT, (void *)&pwm1->cfg); +} + static inline int spl_reset_device_by_gpio(const char *label, int pin, int low_width) { int ret; @@ -90,6 +140,8 @@ int spl_board_init_f(void) goto end; } + spl_pwm_device_init(); + ret = spl_gemgxl_init(); if (ret) { debug("Gigabit ethernet PHY (VSC8541) init failed: %d\n", ret); diff --git a/board/sipeed/maix/maix.c b/board/sipeed/maix/maix.c index 79e492f0a8e..06653b5a876 100644 --- a/board/sipeed/maix/maix.c +++ b/board/sipeed/maix/maix.c @@ -32,7 +32,6 @@ static int sram_init(void) continue; ret = clk_enable(&clk); - clk_free(&clk); if (ret) return ret; } diff --git a/board/sophgo/milkv_duo/Kconfig b/board/sophgo/milkv_duo/Kconfig new file mode 100644 index 00000000000..2a458f291cc --- /dev/null +++ b/board/sophgo/milkv_duo/Kconfig @@ -0,0 +1,28 @@ +if TARGET_MILKV_DUO + +config SYS_BOARD + default "milkv_duo" + +config SYS_VENDOR + default "sophgo" + +config SYS_CPU + default "generic" + +config SYS_CONFIG_NAME + default "milkv_duo" + +config TEXT_BASE + default 0x80200000 + +config ENV_SIZE + default 0x20000 + +config ENV_SECT_SIZE + default 0x40000 + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select GENERIC_RISCV + +endif diff --git a/board/sophgo/milkv_duo/MAINTAINERS b/board/sophgo/milkv_duo/MAINTAINERS new file mode 100644 index 00000000000..651a0592f7a --- /dev/null +++ b/board/sophgo/milkv_duo/MAINTAINERS @@ -0,0 +1,6 @@ +Milk-V Duo +M: Kongyang Liu <seashell11234455@gmail.com> +S: Maintained +F: board/sophgo/milkv_duo/ +F: configs/milkv_duo_defconfig +F: doc/board/sophgo/milkv_duo.rst diff --git a/board/sophgo/milkv_duo/Makefile b/board/sophgo/milkv_duo/Makefile new file mode 100644 index 00000000000..a087013f5c6 --- /dev/null +++ b/board/sophgo/milkv_duo/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com> + +obj-y := board.o diff --git a/board/sophgo/milkv_duo/board.c b/board/sophgo/milkv_duo/board.c new file mode 100644 index 00000000000..eaa47be1739 --- /dev/null +++ b/board/sophgo/milkv_duo/board.c @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com> + */ + +int board_init(void) +{ + return 0; +} diff --git a/board/starfive/visionfive2/spl.c b/board/starfive/visionfive2/spl.c index 336f0cdfc90..1b49945d11b 100644 --- a/board/starfive/visionfive2/spl.c +++ b/board/starfive/visionfive2/spl.c @@ -45,6 +45,10 @@ static const struct starfive_vf2_pro starfive_verb[] = { {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "motorcomm,tx-clk-1000-inverted", NULL}, {"/soc/ethernet@16030000/mdio/ethernet-phy@0", + "motorcomm,rx-clk-drv-microamp", "3970"}, + {"/soc/ethernet@16030000/mdio/ethernet-phy@0", + "motorcomm,rx-data-drv-microamp", "2910"}, + {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "rx-internal-delay-ps", "1900"}, {"/soc/ethernet@16030000/mdio/ethernet-phy@0", "tx-internal-delay-ps", "1500"}, @@ -54,6 +58,10 @@ static const struct starfive_vf2_pro starfive_verb[] = { { "/soc/ethernet@16040000/mdio/ethernet-phy@1", "motorcomm,tx-clk-100-inverted", NULL}, {"/soc/ethernet@16040000/mdio/ethernet-phy@1", + "motorcomm,rx-clk-drv-microamp", "3970"}, + {"/soc/ethernet@16040000/mdio/ethernet-phy@1", + "motorcomm,rx-data-drv-microamp", "2910"}, + {"/soc/ethernet@16040000/mdio/ethernet-phy@1", "rx-internal-delay-ps", "0"}, {"/soc/ethernet@16040000/mdio/ethernet-phy@1", "tx-internal-delay-ps", "0"}, @@ -61,11 +69,13 @@ static const struct starfive_vf2_pro starfive_verb[] = { void spl_fdt_fixup_version_a(void *fdt) { + static const char compat[] = "starfive,visionfive-2-v1.2a\0starfive,jh7110"; u32 phandle; u8 i; int offset; int ret; + fdt_setprop(fdt, fdt_path_offset(fdt, "/"), "compatible", compat, sizeof(compat)); fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model", "StarFive VisionFive 2 v1.2A"); @@ -106,11 +116,13 @@ void spl_fdt_fixup_version_a(void *fdt) void spl_fdt_fixup_version_b(void *fdt) { + static const char compat[] = "starfive,visionfive-2-v1.3b\0starfive,jh7110"; u32 phandle; u8 i; int offset; int ret; + fdt_setprop(fdt, fdt_path_offset(fdt, "/"), "compatible", compat, sizeof(compat)); fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model", "StarFive VisionFive 2 v1.3B"); diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index f556857a391..a2da6a4a7a2 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -348,6 +348,11 @@ M: Chen-Yu Tsai <wens@csie.org> S: Maintained F: configs/libretech_all_h5_cc_h5_defconfig +NANOPI DUO2 BOARD +M: Chuanhong Guo <gch981213@gmail.com> +S: Maintained +F: configs/nanopi_duo2_defconfig + NANOPI-M1 BOARD M: Mylène Josserand <mylene.josserand@free-electrons.com> S: Maintained @@ -550,6 +555,11 @@ M: Maxime Ripard <mripard@kernel.org> S: Maintained F: configs/tbs_a711_defconfig +TRANSPEED 8K618-T BOARD +M: Nick Alilovic <nickalilovic@gmail.com> +S: Maintained +F: configs/transpeed-8k618-t_defconfig + WEXLER-TAB7200 BOARD M: Aleksei Mamlin <mamlinav@gmail.com> S: Maintained diff --git a/board/synopsys/hsdk/clk-lib.c b/board/synopsys/hsdk/clk-lib.c index be76d6c8f47..a9614e90800 100644 --- a/board/synopsys/hsdk/clk-lib.c +++ b/board/synopsys/hsdk/clk-lib.c @@ -56,8 +56,6 @@ int soc_clk_ctl(const char *name, ulong *rate, enum clk_ctl_ops ctl) priv_rate = clk_get_rate(&clk); - clk_free(&clk); - mhz_rate = ceil(priv_rate, HZ_IN_MHZ); if (ctl & CLK_MHZ) diff --git a/board/ti/am62x/evm.c b/board/ti/am62x/evm.c index ad939088402..88e02155ee3 100644 --- a/board/ti/am62x/evm.c +++ b/board/ti/am62x/evm.c @@ -60,27 +60,9 @@ int dram_init_banksize(void) } #if defined(CONFIG_SPL_BUILD) -static int video_setup(void) -{ - if (CONFIG_IS_ENABLED(VIDEO)) { - ulong addr; - int ret; - - addr = gd->relocaddr; - ret = video_reserve(&addr); - if (ret) - return ret; - debug("Reserving %luk for video at: %08lx\n", - ((unsigned long)gd->relocaddr - addr) >> 10, addr); - gd->relocaddr = addr; - } - - return 0; -} void spl_board_init(void) { - video_setup(); enable_caches(); if (IS_ENABLED(CONFIG_SPL_SPLASH_SCREEN) && IS_ENABLED(CONFIG_SPL_BMP)) splash_display(); diff --git a/cmd/Kconfig b/cmd/Kconfig index 06aae30df30..a86b5705174 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -232,6 +232,12 @@ config CMD_SBI help Display information about the SBI implementation. +config CMD_SMBIOS + bool "smbios" + depends on SMBIOS + help + Display the SMBIOS information. + endmenu menu "Boot commands" diff --git a/cmd/Makefile b/cmd/Makefile index e2a2b16ab25..87133cc27a8 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -168,6 +168,7 @@ obj-$(CONFIG_CMD_SETEXPR) += setexpr.o obj-$(CONFIG_CMD_SETEXPR_FMT) += printf.o obj-$(CONFIG_CMD_SPI) += spi.o obj-$(CONFIG_CMD_STRINGS) += strings.o +obj-$(CONFIG_CMD_SMBIOS) += smbios.o obj-$(CONFIG_CMD_SMC) += smccc.o obj-$(CONFIG_CMD_SYSBOOT) += sysboot.o obj-$(CONFIG_CMD_STACKPROTECTOR_TEST) += stackprot_test.o diff --git a/cmd/efidebug.c b/cmd/efidebug.c index a3a7556ea4a..a587860e2a5 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -173,15 +173,12 @@ EFI_ESRT_UPDATE_STATUS_NUM > (idx) ? efi_update_status_str[(idx)] : "error"\ static int do_efi_capsule_esrt(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]) { - struct efi_system_resource_table *esrt = NULL; + struct efi_system_resource_table *esrt; if (argc != 1) return CMD_RET_USAGE; - for (int idx = 0; idx < systab.nr_tables; idx++) - if (!guidcmp(&efi_esrt_guid, &systab.tables[idx].guid)) - esrt = (struct efi_system_resource_table *)systab.tables[idx].table; - + esrt = efi_get_configuration_table(&efi_esrt_guid); if (!esrt) { log_info("ESRT: table not present\n"); return CMD_RET_SUCCESS; diff --git a/cmd/riscv/sbi.c b/cmd/riscv/sbi.c index 940d9bc1681..9daf0e247ad 100644 --- a/cmd/riscv/sbi.c +++ b/cmd/riscv/sbi.c @@ -53,6 +53,7 @@ static struct sbi_ext extensions[] = { { SBI_EXT_CPPC, "Collaborative Processor Performance Control Extension" }, { SBI_EXT_NACL, "Nested Acceleration Extension" }, { SBI_EXT_STA, "Steal-time Accounting Extension" }, + { SBI_EXT_DBTR, "Debug Trigger Extension" }, }; static int do_sbi(struct cmd_tbl *cmdtp, int flag, int argc, diff --git a/cmd/smbios.c b/cmd/smbios.c new file mode 100644 index 00000000000..66f6b761378 --- /dev/null +++ b/cmd/smbios.c @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * The 'smbios' command displays information from the SMBIOS table. + * + * Copyright (c) 2023, Heinrich Schuchardt <heinrich.schuchardt@canonical.com> + */ + +#include <command.h> +#include <hexdump.h> +#include <mapmem.h> +#include <smbios.h> +#include <tables_csum.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +/** + * smbios_get_string() - get SMBIOS string from table + * + * @table: SMBIOS table + * @index: index of the string + * Return: address of string, may point to empty string + */ +static const char *smbios_get_string(void *table, int index) +{ + const char *str = (char *)table + + ((struct smbios_header *)table)->length; + static const char fallback[] = "Not Specified"; + + if (!index) + return fallback; + + if (!*str) + ++str; + for (--index; *str && index; --index) + str += strlen(str) + 1; + + return str; +} + +static struct smbios_header *next_table(struct smbios_header *table) +{ + const char *str; + + if (table->type == SMBIOS_END_OF_TABLE) + return NULL; + + str = smbios_get_string(table, -1); + return (struct smbios_header *)(++str); +} + +static void smbios_print_generic(struct smbios_header *table) +{ + char *str = (char *)table + table->length; + + if (CONFIG_IS_ENABLED(HEXDUMP)) { + printf("Header and Data:\n"); + print_hex_dump("\t", DUMP_PREFIX_OFFSET, 16, 1, + table, table->length, false); + } + if (*str) { + printf("Strings:\n"); + for (int index = 1; *str; ++index) { + printf("\tString %u: %s\n", index, str); + str += strlen(str) + 1; + } + } +} + +void smbios_print_str(const char *label, void *table, u8 index) +{ + printf("\t%s: %s\n", label, smbios_get_string(table, index)); +} + +static void smbios_print_type1(struct smbios_type1 *table) +{ + printf("System Information\n"); + smbios_print_str("Manufacturer", table, table->manufacturer); + smbios_print_str("Product Name", table, table->product_name); + smbios_print_str("Version", table, table->version); + smbios_print_str("Serial Number", table, table->serial_number); + if (table->length >= 0x19) { + printf("\tUUID: %pUl\n", table->uuid); + smbios_print_str("Wake Up Type", table, table->serial_number); + } + if (table->length >= 0x1b) { + smbios_print_str("Serial Number", table, table->serial_number); + smbios_print_str("SKU Number", table, table->sku_number); + } +} + +static void smbios_print_type2(struct smbios_type2 *table) +{ + u16 *handle; + + printf("Base Board Information\n"); + smbios_print_str("Manufacturer", table, table->manufacturer); + smbios_print_str("Product Name", table, table->product_name); + smbios_print_str("Version", table, table->version); + smbios_print_str("Serial Number", table, table->serial_number); + smbios_print_str("Asset Tag", table, table->asset_tag_number); + printf("\tFeature Flags: 0x%04x\n", table->feature_flags); + smbios_print_str("Chassis Location", table, table->chassis_location); + printf("\tChassis Handle: 0x%04x\n", table->chassis_handle); + smbios_print_str("Board Type", table, table->board_type); + printf("\tContained Object Handles: "); + handle = (void *)table->eos; + for (int i = 0; i < table->number_contained_objects; ++i) + printf("0x%04x ", handle[i]); + printf("\n"); +} + +static void smbios_print_type127(struct smbios_type127 *table) +{ + printf("End Of Table\n"); +} + +static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + ulong addr; + void *entry; + u32 size; + char version[12]; + struct smbios_header *table; + static const char smbios_sig[] = "_SM_"; + static const char smbios3_sig[] = "_SM3_"; + size_t count = 0; + u32 table_maximum_size; + + addr = gd_smbios_start(); + if (!addr) { + log_warning("SMBIOS not available\n"); + return CMD_RET_FAILURE; + } + entry = map_sysmem(addr, 0); + if (!memcmp(entry, smbios3_sig, sizeof(smbios3_sig) - 1)) { + struct smbios3_entry *entry3 = entry; + + table = (void *)(uintptr_t)entry3->struct_table_address; + snprintf(version, sizeof(version), "%d.%d.%d", + entry3->major_ver, entry3->minor_ver, entry3->doc_rev); + table = (void *)(uintptr_t)entry3->struct_table_address; + size = entry3->length; + table_maximum_size = entry3->table_maximum_size; + } else if (!memcmp(entry, smbios_sig, sizeof(smbios_sig) - 1)) { + struct smbios_entry *entry2 = entry; + + snprintf(version, sizeof(version), "%d.%d", + entry2->major_ver, entry2->minor_ver); + table = (void *)(uintptr_t)entry2->struct_table_address; + size = entry2->length; + table_maximum_size = entry2->struct_table_length; + } else { + log_err("Unknown SMBIOS anchor format\n"); + return CMD_RET_FAILURE; + } + if (table_compute_checksum(entry, size)) { + log_err("Invalid anchor checksum\n"); + return CMD_RET_FAILURE; + } + printf("SMBIOS %s present.\n", version); + + for (struct smbios_header *pos = table; pos; pos = next_table(pos)) + ++count; + printf("%zd structures occupying %d bytes\n", count, table_maximum_size); + printf("Table at 0x%llx\n", (unsigned long long)map_to_sysmem(table)); + + for (struct smbios_header *pos = table; pos; pos = next_table(pos)) { + printf("\nHandle 0x%04x, DMI type %d, %d bytes at 0x%llx\n", + pos->handle, pos->type, pos->length, + (unsigned long long)map_to_sysmem(pos)); + switch (pos->type) { + case 1: + smbios_print_type1((struct smbios_type1 *)pos); + break; + case 2: + smbios_print_type2((struct smbios_type2 *)pos); + break; + case 127: + smbios_print_type127((struct smbios_type127 *)pos); + break; + default: + smbios_print_generic(pos); + break; + } + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_LONGHELP(smbios, "- display SMBIOS information"); + +U_BOOT_CMD(smbios, 1, 0, do_smbios, "display SMBIOS information", + smbios_help_text); diff --git a/common/board_f.c b/common/board_f.c index d4d7d01f8f6..442b8349d08 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -403,17 +403,47 @@ __weak int arch_reserve_mmu(void) return 0; } -static int reserve_video(void) +static int reserve_video_from_videoblob(void) { if (IS_ENABLED(CONFIG_SPL_VIDEO_HANDOFF) && spl_phase() > PHASE_SPL) { struct video_handoff *ho; + int ret = 0; ho = bloblist_find(BLOBLISTT_U_BOOT_VIDEO, sizeof(*ho)); if (!ho) - return log_msg_ret("blf", -ENOENT); - video_reserve_from_bloblist(ho); - gd->relocaddr = ho->fb; - } else if (CONFIG_IS_ENABLED(VIDEO)) { + return log_msg_ret("Missing video bloblist", -ENOENT); + + ret = video_reserve_from_bloblist(ho); + if (ret) + return log_msg_ret("Invalid Video handoff info", ret); + + /* Sanity check fb from blob is before current relocaddr */ + if (likely(gd->relocaddr > (unsigned long)ho->fb)) + gd->relocaddr = ho->fb; + } + + return 0; +} + +/* + * Check if any bloblist received specifying reserved areas from previous stage and adjust + * gd->relocaddr accordingly, so that we start reserving after pre-reserved areas + * from previous stage. + * + * NOTE: + * IT is recommended that all bloblists from previous stage are reserved from ram_top + * as next stage will simply start reserving further regions after them. + */ +static int setup_relocaddr_from_bloblist(void) +{ + reserve_video_from_videoblob(); + + return 0; +} + +static int reserve_video(void) +{ + if (CONFIG_IS_ENABLED(VIDEO)) { ulong addr; int ret; @@ -923,6 +953,7 @@ static const init_fnc_t init_sequence_f[] = { reserve_pram, #endif reserve_round_4k, + setup_relocaddr_from_bloblist, arch_reserve_mmu, reserve_video, reserve_trace, diff --git a/common/spl/Kconfig b/common/spl/Kconfig index e7b84fc1fa6..8805dd33fec 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -97,8 +97,7 @@ config SPL_PAD_TO default 0x31000 if ARCH_MX6 && MX6_OCRAM_256KB default 0x11000 if ARCH_MX7 || (ARCH_MX6 && !MX6_OCRAM_256KB) default 0x10000 if ARCH_KEYSTONE - default 0x8000 if ARCH_SUNXI && !MACH_SUN50I_H616 - default 0x0 if ARCH_MTMIPS + default 0x0 if ARCH_MTMIPS || ARCH_SUNXI default TPL_MAX_SIZE if TPL_MAX_SIZE > SPL_MAX_SIZE default SPL_MAX_SIZE help @@ -585,8 +584,7 @@ config SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION config SPL_FIT_IMAGE_TINY bool "Remove functionality from SPL FIT loading to reduce size" depends on SPL_FIT - default y if MACH_SUN50I || MACH_SUN50I_H5 || SUN50I_GEN_H6 - default y if ARCH_IMX8M || ARCH_IMX9 + default y if ARCH_IMX8M || ARCH_IMX9 || ARCH_SUNXI help Enable this to reduce the size of the FIT image loading code in SPL, if space for the SPL binary is very tight. @@ -1115,7 +1113,7 @@ config SPL_OS_BOOT config SPL_PAYLOAD_ARGS_ADDR hex "Address in memory to load 'args' file for Falcon Mode to" - depends on SPL_OS_BOOT + depends on SPL_OS_BOOT || SPL_LOAD_FIT_OPENSBI_OS_BOOT default 0x88000000 if ARCH_OMAP2PLUS help Address in memory where the 'args' file, typically a device tree diff --git a/common/spl/spl.c b/common/spl/spl.c index 3ce5bfeec8b..b65c439e7aa 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -42,6 +42,7 @@ #include <fdt_support.h> #include <bootcount.h> #include <wdt.h> +#include <video.h> DECLARE_GLOBAL_DATA_PTR; DECLARE_BINMAN_MAGIC_SYM; @@ -152,6 +153,24 @@ void spl_fixup_fdt(void *fdt_blob) #endif } +int spl_reserve_video_from_ram_top(void) +{ + if (CONFIG_IS_ENABLED(VIDEO)) { + ulong addr; + int ret; + + addr = gd->ram_top; + ret = video_reserve(&addr); + if (ret) + return ret; + debug("Reserving %luk for video at: %08lx\n", + ((unsigned long)gd->relocaddr - addr) >> 10, addr); + gd->relocaddr = addr; + } + + return 0; +} + ulong spl_get_image_pos(void) { if (!CONFIG_IS_ENABLED(BINMAN_UBOOT_SYMBOLS)) diff --git a/common/spl/spl_opensbi.c b/common/spl/spl_opensbi.c index 9801d38c0b3..8127ebc946b 100644 --- a/common/spl/spl_opensbi.c +++ b/common/spl/spl_opensbi.c @@ -16,6 +16,7 @@ #include <opensbi.h> #include <linux/libfdt.h> #include <linux/printk.h> +#include <mapmem.h> DECLARE_GLOBAL_DATA_PTR; @@ -58,6 +59,20 @@ void __noreturn spl_invoke_opensbi(struct spl_image_info *spl_image) } /* + * Originally, u-boot-spl will place DTB directly after the kernel, + * but the size of the kernel did not include the BSS section, which + * means u-boot-spl will place the DTB in the kernel BSS section + * causing the DTB to be cleared by kernel BSS initializtion. + * Moving DTB in front of the kernel can avoid the error. + */ +#if CONFIG_IS_ENABLED(LOAD_FIT_OPENSBI_OS_BOOT) && \ + CONFIG_IS_ENABLED(PAYLOAD_ARGS_ADDR) + memcpy((void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR, spl_image->fdt_addr, + fdt_totalsize(spl_image->fdt_addr)); + spl_image->fdt_addr = map_sysmem(CONFIG_SPL_PAYLOAD_ARGS_ADDR, 0); +#endif + + /* * Find next os image in /fit-images * The next os image default is u-boot proper, once enable * OpenSBI OS boot mode, the OS image should be linux. diff --git a/common/splash_source.c b/common/splash_source.c index 7223a1aae78..2ce0768833d 100644 --- a/common/splash_source.c +++ b/common/splash_source.c @@ -216,7 +216,7 @@ static int splash_init_virtio(void) } } -#ifdef CONFIG_CMD_UBIFS +#if defined(CONFIG_CMD_UBIFS) && !defined(CONFIG_SPL_BUILD) static int splash_mount_ubifs(struct splash_location *location) { int res; diff --git a/configs/ae350_rv32_defconfig b/configs/ae350_rv32_defconfig index 3bfa3e9f8ed..35ad62c845d 100644 --- a/configs/ae350_rv32_defconfig +++ b/configs/ae350_rv32_defconfig @@ -23,6 +23,7 @@ CONFIG_SYS_PROMPT="RISC-V # " CONFIG_CMD_IMLS=y CONFIG_CMD_MMC=y CONFIG_CMD_SF_TEST=y +CONFIG_CMD_WDT=y # CONFIG_CMD_SETEXPR is not set CONFIG_BOOTP_PREFER_SERVERIP=y CONFIG_CMD_CACHE=y @@ -49,3 +50,6 @@ CONFIG_BAUDRATE=38400 CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_ATCSPI200_SPI=y +# CONFIG_WATCHDOG_AUTOSTART is not set +CONFIG_WDT=y +CONFIG_WDT_ATCWDT200=y diff --git a/configs/ae350_rv32_falcon_defconfig b/configs/ae350_rv32_falcon_defconfig index abf7dd4f4d7..f81471087ba 100644 --- a/configs/ae350_rv32_falcon_defconfig +++ b/configs/ae350_rv32_falcon_defconfig @@ -14,6 +14,7 @@ CONFIG_TARGET_ANDES_AE350=y CONFIG_RISCV_SMODE=y # CONFIG_AVAILABLE_HARTS is not set CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y +CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000 CONFIG_SYS_MONITOR_BASE=0x88000000 CONFIG_FIT=y CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000 diff --git a/configs/ae350_rv32_falcon_xip_defconfig b/configs/ae350_rv32_falcon_xip_defconfig index 5166ab7a938..50e164c4d25 100644 --- a/configs/ae350_rv32_falcon_xip_defconfig +++ b/configs/ae350_rv32_falcon_xip_defconfig @@ -15,6 +15,7 @@ CONFIG_TARGET_ANDES_AE350=y CONFIG_RISCV_SMODE=y CONFIG_SPL_XIP=y CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y +CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000 CONFIG_SYS_MONITOR_BASE=0x88000000 CONFIG_FIT=y CONFIG_SPL_LOAD_FIT_ADDRESS=0x80010000 diff --git a/configs/ae350_rv32_spl_defconfig b/configs/ae350_rv32_spl_defconfig index aeb50206d2c..41cd457bc3a 100644 --- a/configs/ae350_rv32_spl_defconfig +++ b/configs/ae350_rv32_spl_defconfig @@ -33,6 +33,7 @@ CONFIG_SYS_PROMPT="RISC-V # " CONFIG_CMD_IMLS=y CONFIG_CMD_MMC=y CONFIG_CMD_SF_TEST=y +CONFIG_CMD_WDT=y # CONFIG_CMD_SETEXPR is not set CONFIG_BOOTP_PREFER_SERVERIP=y CONFIG_CMD_CACHE=y @@ -58,3 +59,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_ATCSPI200_SPI=y # CONFIG_BINMAN_FDT is not set +# CONFIG_WATCHDOG_AUTOSTART is not set +CONFIG_WDT=y +CONFIG_WDT_ATCWDT200=y diff --git a/configs/ae350_rv32_spl_xip_defconfig b/configs/ae350_rv32_spl_xip_defconfig index f15ec301ce7..954e2f2de7b 100644 --- a/configs/ae350_rv32_spl_xip_defconfig +++ b/configs/ae350_rv32_spl_xip_defconfig @@ -34,6 +34,7 @@ CONFIG_SYS_PROMPT="RISC-V # " CONFIG_CMD_IMLS=y CONFIG_CMD_MMC=y CONFIG_CMD_SF_TEST=y +CONFIG_CMD_WDT=y # CONFIG_CMD_SETEXPR is not set CONFIG_BOOTP_PREFER_SERVERIP=y CONFIG_CMD_CACHE=y @@ -59,3 +60,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_ATCSPI200_SPI=y # CONFIG_BINMAN_FDT is not set +# CONFIG_WATCHDOG_AUTOSTART is not set +CONFIG_WDT=y +CONFIG_WDT_ATCWDT200=y diff --git a/configs/ae350_rv32_xip_defconfig b/configs/ae350_rv32_xip_defconfig index c40eb043c5d..95863595d2d 100644 --- a/configs/ae350_rv32_xip_defconfig +++ b/configs/ae350_rv32_xip_defconfig @@ -24,6 +24,7 @@ CONFIG_SYS_PROMPT="RISC-V # " CONFIG_CMD_IMLS=y CONFIG_CMD_MMC=y CONFIG_CMD_SF_TEST=y +CONFIG_CMD_WDT=y # CONFIG_CMD_SETEXPR is not set CONFIG_BOOTP_PREFER_SERVERIP=y CONFIG_CMD_CACHE=y @@ -50,3 +51,6 @@ CONFIG_BAUDRATE=38400 CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_ATCSPI200_SPI=y +# CONFIG_WATCHDOG_AUTOSTART is not set +CONFIG_WDT=y +CONFIG_WDT_ATCWDT200=y diff --git a/configs/ae350_rv64_defconfig b/configs/ae350_rv64_defconfig index 7ae938aeb23..988214285a4 100644 --- a/configs/ae350_rv64_defconfig +++ b/configs/ae350_rv64_defconfig @@ -23,6 +23,7 @@ CONFIG_SYS_PROMPT="RISC-V # " CONFIG_CMD_IMLS=y CONFIG_CMD_MMC=y CONFIG_CMD_SF_TEST=y +CONFIG_CMD_WDT=y # CONFIG_CMD_SETEXPR is not set CONFIG_BOOTP_PREFER_SERVERIP=y CONFIG_CMD_CACHE=y @@ -49,3 +50,6 @@ CONFIG_BAUDRATE=38400 CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_ATCSPI200_SPI=y +# CONFIG_WATCHDOG_AUTOSTART is not set +CONFIG_WDT=y +CONFIG_WDT_ATCWDT200=y diff --git a/configs/ae350_rv64_falcon_defconfig b/configs/ae350_rv64_falcon_defconfig index 12892387083..b0b7ae597e0 100644 --- a/configs/ae350_rv64_falcon_defconfig +++ b/configs/ae350_rv64_falcon_defconfig @@ -14,6 +14,7 @@ CONFIG_ARCH_RV64I=y CONFIG_RISCV_SMODE=y # CONFIG_AVAILABLE_HARTS is not set CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y +CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000 CONFIG_SYS_MONITOR_BASE=0x88000000 CONFIG_FIT=y CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000 diff --git a/configs/ae350_rv64_falcon_xip_defconfig b/configs/ae350_rv64_falcon_xip_defconfig index 18e2dafe7f3..cac315d97b4 100644 --- a/configs/ae350_rv64_falcon_xip_defconfig +++ b/configs/ae350_rv64_falcon_xip_defconfig @@ -15,6 +15,7 @@ CONFIG_ARCH_RV64I=y CONFIG_RISCV_SMODE=y CONFIG_SPL_XIP=y CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT=y +CONFIG_SPL_PAYLOAD_ARGS_ADDR=0x01700000 CONFIG_SYS_MONITOR_BASE=0x88000000 CONFIG_FIT=y CONFIG_SPL_LOAD_FIT_ADDRESS=0x80010000 diff --git a/configs/ae350_rv64_spl_defconfig b/configs/ae350_rv64_spl_defconfig index 68ac4325ab8..e9293204337 100644 --- a/configs/ae350_rv64_spl_defconfig +++ b/configs/ae350_rv64_spl_defconfig @@ -33,6 +33,7 @@ CONFIG_SYS_PROMPT="RISC-V # " CONFIG_CMD_IMLS=y CONFIG_CMD_MMC=y CONFIG_CMD_SF_TEST=y +CONFIG_CMD_WDT=y # CONFIG_CMD_SETEXPR is not set CONFIG_BOOTP_PREFER_SERVERIP=y CONFIG_CMD_CACHE=y @@ -58,3 +59,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_ATCSPI200_SPI=y # CONFIG_BINMAN_FDT is not set +# CONFIG_WATCHDOG_AUTOSTART is not set +CONFIG_WDT=y +CONFIG_WDT_ATCWDT200=y diff --git a/configs/ae350_rv64_spl_xip_defconfig b/configs/ae350_rv64_spl_xip_defconfig index 839ca335d4d..3f92643b077 100644 --- a/configs/ae350_rv64_spl_xip_defconfig +++ b/configs/ae350_rv64_spl_xip_defconfig @@ -34,6 +34,7 @@ CONFIG_SYS_PROMPT="RISC-V # " CONFIG_CMD_IMLS=y CONFIG_CMD_MMC=y CONFIG_CMD_SF_TEST=y +CONFIG_CMD_WDT=y # CONFIG_CMD_SETEXPR is not set CONFIG_BOOTP_PREFER_SERVERIP=y CONFIG_CMD_CACHE=y @@ -59,3 +60,6 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_ATCSPI200_SPI=y # CONFIG_BINMAN_FDT is not set +# CONFIG_WATCHDOG_AUTOSTART is not set +CONFIG_WDT=y +CONFIG_WDT_ATCWDT200=y diff --git a/configs/ae350_rv64_xip_defconfig b/configs/ae350_rv64_xip_defconfig index 5432b6d6d78..835f0209903 100644 --- a/configs/ae350_rv64_xip_defconfig +++ b/configs/ae350_rv64_xip_defconfig @@ -24,6 +24,7 @@ CONFIG_SYS_PROMPT="RISC-V # " CONFIG_CMD_IMLS=y CONFIG_CMD_MMC=y CONFIG_CMD_SF_TEST=y +CONFIG_CMD_WDT=y # CONFIG_CMD_SETEXPR is not set CONFIG_BOOTP_PREFER_SERVERIP=y CONFIG_CMD_CACHE=y @@ -50,3 +51,6 @@ CONFIG_BAUDRATE=38400 CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_ATCSPI200_SPI=y +# CONFIG_WATCHDOG_AUTOSTART is not set +CONFIG_WDT=y +CONFIG_WDT_ATCWDT200=y diff --git a/configs/milkv_duo_defconfig b/configs/milkv_duo_defconfig new file mode 100644 index 00000000000..9eca6abfbca --- /dev/null +++ b/configs/milkv_duo_defconfig @@ -0,0 +1,23 @@ +CONFIG_RISCV=y +CONFIG_SYS_MALLOC_LEN=0x820000 +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x82300000 +CONFIG_DEFAULT_DEVICE_TREE="cv1800b-milkv-duo" +CONFIG_IDENT_STRING="milkv_duo" +CONFIG_SYS_LOAD_ADDR=0x80080000 +CONFIG_TARGET_MILKV_DUO=y +CONFIG_ARCH_RV64I=y +CONFIG_RISCV_SMODE=y +CONFIG_FIT=y +CONFIG_SUPPORT_RAW_INITRD=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="milkv_duo# " +CONFIG_SYS_MAXARGS=64 +CONFIG_SYS_CBSIZE=512 +CONFIG_SYS_PBSIZE=544 +CONFIG_SYS_BOOTM_LEN=0x4000000 +CONFIG_ENV_OVERWRITE=y +CONFIG_SYS_NS16550=y +CONFIG_SYS_NS16550_MEM32=y diff --git a/configs/nanopi_duo2_defconfig b/configs/nanopi_duo2_defconfig new file mode 100644 index 00000000000..beb2f923be2 --- /dev/null +++ b/configs/nanopi_duo2_defconfig @@ -0,0 +1,12 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_DEFAULT_DEVICE_TREE="sun8i-h3-nanopi-duo2" +CONFIG_SPL=y +CONFIG_MACH_SUN8I_H3=y +CONFIG_DRAM_CLK=408 +# CONFIG_VIDEO_DE2 is not set +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_CONSOLE_MUX=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_MUSB_GADGET=y diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig index 5100e193be6..631d8866f62 100644 --- a/configs/qemu_arm64_defconfig +++ b/configs/qemu_arm64_defconfig @@ -27,6 +27,7 @@ CONFIG_USE_PREBOOT=y # CONFIG_DISPLAY_CPUINFO is not set # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_PCI_INIT_R=y +CONFIG_CMD_SMBIOS=y CONFIG_CMD_BOOTZ=y CONFIG_CMD_BOOTEFI_SELFTEST=y CONFIG_CMD_NVEDIT_EFI=y diff --git a/configs/rpi_arm64_defconfig b/configs/rpi_arm64_defconfig index 08bb30b1d7a..e4c4aef9a48 100644 --- a/configs/rpi_arm64_defconfig +++ b/configs/rpi_arm64_defconfig @@ -1,6 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_BCM283X=y -CONFIG_TEXT_BASE=0x00080000 +CONFIG_POSITION_INDEPENDENT=y CONFIG_TARGET_RPI_ARM64=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x7fffe30 @@ -33,6 +33,7 @@ CONFIG_BCM2835_GPIO=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_MMC_SDHCI_BCM2835=y +CONFIG_MMC_SDHCI_BCMSTB=y CONFIG_BCMGENET=y CONFIG_PCI_BRCMSTB=y CONFIG_PINCTRL=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index ea4e2c1ec39..a8df5e635b2 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -42,6 +42,7 @@ CONFIG_STACKPROTECTOR=y CONFIG_ANDROID_AB=y CONFIG_CMD_CPU=y CONFIG_CMD_LICENSE=y +CONFIG_CMD_SMBIOS=y CONFIG_CMD_BOOTM_PRE_LOAD=y CONFIG_CMD_BOOTZ=y CONFIG_BOOTM_OPENRTOS=y diff --git a/configs/starfive_visionfive2_defconfig b/configs/starfive_visionfive2_defconfig index 1b7d57bac7f..c68f3c2def5 100644 --- a/configs/starfive_visionfive2_defconfig +++ b/configs/starfive_visionfive2_defconfig @@ -77,7 +77,6 @@ CONFIG_CMD_TFTPPUT=y CONFIG_CMD_BOOTSTAGE=y CONFIG_OF_BOARD=y CONFIG_ENV_OVERWRITE=y -CONFIG_ENV_IS_NOWHERE=y CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_ENV_SECT_SIZE_AUTO=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y diff --git a/configs/transpeed-8k618-t_defconfig b/configs/transpeed-8k618-t_defconfig new file mode 100644 index 00000000000..020d3974afe --- /dev/null +++ b/configs/transpeed-8k618-t_defconfig @@ -0,0 +1,27 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_DEFAULT_DEVICE_TREE="sun50i-h618-transpeed-8k618-t" +CONFIG_SPL=y +CONFIG_DRAM_SUN50I_H616_DX_ODT=0x03030303 +CONFIG_DRAM_SUN50I_H616_DX_DRI=0x0e0e0e0e +CONFIG_DRAM_SUN50I_H616_CA_DRI=0x1f12 +CONFIG_DRAM_SUN50I_H616_TPR0=0xc0001002 +CONFIG_DRAM_SUN50I_H616_TPR10=0x2f1107 +CONFIG_DRAM_SUN50I_H616_TPR11=0xddddcccc +CONFIG_DRAM_SUN50I_H616_TPR12=0xeddc7665 +CONFIG_MACH_SUN50I_H616=y +CONFIG_SUNXI_DRAM_H616_DDR3_1333=y +CONFIG_DRAM_CLK=648 +CONFIG_MMC_SUNXI_SLOT_EXTRA=2 +CONFIG_R_I2C_ENABLE=y +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_I2C=y +CONFIG_SPL_SYS_I2C_LEGACY=y +CONFIG_SYS_I2C_MVTWSI=y +CONFIG_SYS_I2C_SLAVE=0x7f +CONFIG_SYS_I2C_SPEED=400000 +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_AXP313_POWER=y +CONFIG_AXP_DCDC3_VOLT=1360 +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_OHCI_HCD=y diff --git a/doc/board/index.rst b/doc/board/index.rst index c96e5fda281..d0f9f355d2e 100644 --- a/doc/board/index.rst +++ b/doc/board/index.rst @@ -46,6 +46,7 @@ Board-specific doc sifive/index sipeed/index socionext/index + sophgo/index st/index starfive/index ste/index diff --git a/doc/board/sophgo/index.rst b/doc/board/sophgo/index.rst new file mode 100644 index 00000000000..e097afdac64 --- /dev/null +++ b/doc/board/sophgo/index.rst @@ -0,0 +1,8 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Sophgo +====== +.. toctree:: + :maxdepth: 1 + + milkv_duo diff --git a/doc/board/sophgo/milkv_duo.rst b/doc/board/sophgo/milkv_duo.rst new file mode 100644 index 00000000000..cb2ed1ad987 --- /dev/null +++ b/doc/board/sophgo/milkv_duo.rst @@ -0,0 +1,64 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Milk-V Duo +========== + +CV1800B RISC-V SoC +------------------ +The CV1800B is a high-performance, low-power 1+1 64-bit RISC-V SoC from Sophgo. + +Mainline support +---------------- +The support for following drivers are already enabled: +1. ns16550 UART Driver. + +Building +~~~~~~~~ +1. Add the RISC-V toolchain to your PATH. +2. Setup ARCH & cross compilation environment variable: + +.. code-block:: console + + export CROSS_COMPILE=<riscv64 toolchain prefix> + cd <U-Boot-dir> + make milkv_duo_defconfig + make + +This will generate u-boot-dtb.bin + +Booting +~~~~~~~ +Currently, we rely on vendor FSBL(First Stage Boot Loader) to initialize the +clock and load the u-boot image, then bootup from it. + +Alternatively, to run u-boot-dtb.bin on top of FSBL, follow these steps: + +1. Use the vendor-provided tool to create a unified fip.bin file containing + FSBL, OpenSBI, and U-Boot. + +2. Place the generated fip.bin file into the FAT partition of the SD card. + +3. Insert the SD card into the board and power it on. + +The board will automatically execute the FSBL from the fip.bin file. +Subsequently, it will transition to OpenSBI, and finally, OpenSBI will invoke +U-Boot. + + +Sample boot log from Milk-V Duo board +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. code-block:: none + + U-Boot 2024.01-rc5-00010-g51965baa36 (Dec 28 2023 - 13:15:53 +0800)milkv_duo + + DRAM: 63.3 MiB + Core: 10 devices, 8 uclasses, devicetree: separate + Loading Environment from nowhere... OK + In: serial@4140000 + Out: serial@4140000 + Err: serial@4140000 + Net: No ethernet found. + milkv_duo# cpu detail + 0: cpu@0 rv64imafdc + ID = 0, freq = 0 Hz: L1 cache, MMU + milkv_duo# diff --git a/doc/develop/driver-model/migration.rst b/doc/develop/driver-model/migration.rst index 03fea943b29..b40a6af9d11 100644 --- a/doc/develop/driver-model/migration.rst +++ b/doc/develop/driver-model/migration.rst @@ -13,7 +13,7 @@ CONFIG_DM * Status: In progress * Deadline: 2020.01 -Starting with the 2010.01 release CONFIG_DM will be enabled for all boards. +Starting with the 2020.01 release CONFIG_DM will be enabled for all boards. This does not concern CONFIG_DM_SPL and CONFIG_DM_TPL. The conversion date for these configuration items still needs to be defined. diff --git a/doc/develop/falcon.rst b/doc/develop/falcon.rst index 8a46c0efa18..244b4ccb5c2 100644 --- a/doc/develop/falcon.rst +++ b/doc/develop/falcon.rst @@ -256,3 +256,161 @@ the following command: Falcon Mode was presented at the RMLL 2012. Slides are available at: http://schedule2012.rmll.info/IMG/pdf/LSM2012_UbootFalconMode_Babic.pdf + +Falcon Mode Boot on RISC-V +-------------------------- + +Introduction +~~~~~~~~~~~~ + +In the RISC-V environment, OpenSBI is required to enable a supervisor mode +binary to execute certain privileged operations. The typical boot sequence on +RISC-V is SPL -> OpenSBI -> U-Boot -> Linux kernel. SPL will load and start +the OpenSBI initializations, then OpenSBI will bring up the next image, U-Boot +proper. The OpenSBI binary must be prepared in advance of the U-Boot build +process and it will be packed together with U-Boot into a file called +u-boot.itb. + +The Falcon Mode on RISC-V platforms is a distinct boot sequence. Borrowing +ideas from the U-Boot Falcon Mode on ARM, it skips the U-Boot proper phase +in the normal boot process and allows OpenSBI to load and start the Linux +kernel. Its boot sequence is SPL -> OpenSBI -> Linux kernel. The OpenSBI +binary and Linux kernel binary must be prepared prior to the U-Boot build +process and they will be packed together as a FIT image named linux.itb in +this process. + +CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT enables the Falcon Mode boot on RISC-V. +This configuration setting tells OpenSBI that Linux kernel is its next OS +image and makes it load and start the kernel afterwards. + +Note that the Falcon Mode boot bypasses a lot of initializations by U-Boot. +If the Linux kernel expects hardware initializations by U-Boot, make sure to +port the relevant code to the SPL build process. + +Configuration +~~~~~~~~~~~~~ + +CONFIG_SPL_LOAD_FIT_ADDRESS + Specifies the address to load u-boot.itb in a normal boot. When the Falcon + Mode boot is enabled, it specifies the load address of linux.itb. + +CONFIG_SYS_TEXT_BASE + Specifies the address of the text section for a u-boot proper in a normal + boot. When the Falcon Mode boot is enabled, it specifies the text section + address for the Linux kernel image. + +CONFIG_SPL_PAYLOAD_ARGS_ADDR + The address in the RAM to which the FDT blob is to be moved by the SPL. + SPL places the FDT blob right after the kernel. As the kernel does not + include the BSS section in its size calculation, SPL ends up placing + the FDT blob within the BSS section of the kernel. This may cause the + FDT blob to be cleared during kernel BSS initialization. To avoid the + issue, be sure to move the FDT blob out of the kernel first. + +CONFIG_SPL_LOAD_FIT_OPENSBI_OS_BOOT + Activates the Falcon Mode boot on RISC-V. + +Example for Andes AE350 Board +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A FDT blob is required to boot the Linux kernel from the SPL. Andes AE350 +platforms generally come with a builtin dtb. To load a custom DTB, follow +these steps: + +1. Load the custom DTB to SDRAM:: + + => fatload mmc 0:1 0x20000000 user_custom.dtb + +2. Set the SPI speed:: + + => sf probe 0:0 50000000 0 + +3. Erase sectors from the SPI Flash:: + + => sf erase 0xf0000 0x10000 + +4. Write the FDT blob to the erased sectors of the Flash:: + + => sf write 0x20000000 0xf0000 0x10000 + +Console Log of AE350 Falcon Mode Boot +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + U-Boot SPL 2023.01-00031-g777ecdea66 (Oct 31 2023 - 18:41:36 +0800) + Trying to boot from RAM + + OpenSBI v1.2-51-g7304e42 + ____ _____ ____ _____ + / __ \ / ____| _ \_ _| + | | | |_ __ ___ _ __ | (___ | |_) || | + | | | | '_ \ / _ \ '_ \ \___ \| _ < | | + | |__| | |_) | __/ | | |____) | |_) || |_ + \____/| .__/ \___|_| |_|_____/|____/_____| + | | + |_| + + Platform Name : andestech,ax25 + Platform Features : medeleg + Platform HART Count : 1 + Platform IPI Device : andes_plicsw + Platform Timer Device : andes_plmt @ 60000000Hz + Platform Console Device : uart8250 + Platform HSM Device : andes_smu + Platform PMU Device : andes_pmu + Platform Reboot Device : atcwdt200 + Platform Shutdown Device : --- + Firmware Base : 0x0 + Firmware Size : 196 KB + Runtime SBI Version : 1.0 + + Domain0 Name : root + Domain0 Boot HART : 0 + Domain0 HARTs : 0* + Domain0 Region00 : 0x0000000000000000-0x000000000003ffff () + Domain0 Region01 : 0x00000000e6000000-0x00000000e60fffff (I,R) + Domain0 Region02 : 0x00000000e6400000-0x00000000e67fffff (I) + Domain0 Region03 : 0x0000000000000000-0xffffffffffffffff (R,W,X) + Domain0 Next Address : 0x0000000001800000 + Domain0 Next Arg1 : 0x0000000001700000 + Domain0 Next Mode : S-mode + Domain0 SysReset : yes + + Boot HART ID : 0 + Boot HART Domain : root + Boot HART Priv Version : v1.11 + Boot HART Base ISA : rv64imafdcx + Boot HART ISA Extensions : none + Boot HART PMP Count : 8 + Boot HART PMP Granularity : 4 + Boot HART PMP Address Bits: 31 + Boot HART MHPM Count : 4 + Boot HART MHPM Bits : 64 + Boot HART MIDELEG : 0x0000000000000222 + Boot HART MEDELEG : 0x000000000000b109 + [ 0.000000] Linux version 6.1.47-09019-g0584b09ad862-dirty + [ 0.000000] OF: fdt: Ignoring memory range 0x0 - 0x1800000 + [ 0.000000] Machine model: andestech,ax25 + [ 0.000000] earlycon: sbi0 at I/O port 0x0 (options '') + [ 0.000000] printk: bootconsole [sbi0] enabled + [ 0.000000] Disabled 4-level and 5-level paging + [ 0.000000] efi: UEFI not found. + [ 0.000000] Zone ranges: + [ 0.000000] DMA32 [mem 0x0000000001800000-0x000000003fffffff] + [ 0.000000] Normal empty + [ 0.000000] Movable zone start for each node + [ 0.000000] Early memory node ranges + [ 0.000000] node 0: [mem 0x0000000001800000-0x000000003fffffff] + [ 0.000000] Initmem setup node 0 [mem 0x0000000001800000-0x000000003fffffff] + [ 0.000000] SBI specification v1.0 detected + [ 0.000000] SBI implementation ID=0x1 Version=0x10002 + [ 0.000000] SBI TIME extension detected + [ 0.000000] SBI IPI extension detected + [ 0.000000] SBI RFENCE extension detected + [ 0.000000] SBI SRST extension detected + [ 0.000000] SBI HSM extension detected + [ 0.000000] riscv: base ISA extensions acim + [ 0.000000] riscv: ELF capabilities acim + [ 0.000000] percpu: Embedded 18 pages/cpu s35000 r8192 d30536 u73728 + [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 252500 diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst index 27733135f5e..4f18623b28e 100644 --- a/doc/develop/release_cycle.rst +++ b/doc/develop/release_cycle.rst @@ -50,8 +50,7 @@ Current Status * U-Boot v2024.01 was released on Mon 08 January 2024. -* The Merge Window for the next release (v2024.04) is **open** until the -rc1 - release on Mon 29 January 2024. +* The Merge Window for the next release (v2024.04) is **closed**. * The next branch is now **closed**. @@ -63,9 +62,9 @@ Future Releases .. The following commented out dates are for when release candidates are planned to be tagged. -.. For the next scheduled release, release candidates were made on:: +For the next scheduled release, release candidates were made on:: -.. * U-Boot v2024.01-rc1 was released on Mon 29 January 2024. +* U-Boot v2024.01-rc1 was released on Mon 29 January 2024. .. * U-Boot v2024.01-rc2 was released on Mon 12 February 2024. diff --git a/doc/develop/spl.rst b/doc/develop/spl.rst index 76e87f07c72..0a3e572310a 100644 --- a/doc/develop/spl.rst +++ b/doc/develop/spl.rst @@ -65,6 +65,15 @@ CONFIG_SPL_NAND_LOAD (drivers/mtd/nand/raw/nand_spl_load.o) CONFIG_SPL_SPI_LOAD (drivers/mtd/spi/spi_spl_load.o) CONFIG_SPL_RAM_DEVICE (common/spl/spl.c) CONFIG_SPL_WATCHDOG (drivers/watchdog/libwatchdog.o) +CONFIG_SPL_SYSCON (drivers/core/syscon-uclass.o) +CONFIG_SPL_GZIP (lib/gzip.o) +CONFIG_SPL_VIDEO (drivers/video/video-uclass.o drivers/video/vidconsole-uclass.o) +CONFIG_SPL_SPLASH_SCREEN (common/splash.o) +CONFIG_SPL_SPLASH_SOURCE (common/splash_source.o) +CONFIG_SPL_GPIO (drivers/gpio) +CONFIG_SPL_DM_GPIO (drivers/gpio/gpio-uclass.o) +CONFIG_SPL_BMP (drivers/video/bmp.o) +CONFIG_SPL_BLOBLIST (common/bloblist.o) Adding SPL-specific code ------------------------ @@ -164,3 +173,31 @@ cflow will spit out a number of warnings as it does not parse the config files and picks functions based on #ifdef. Parsing the '.i' files instead introduces another set of headaches. These warnings are not usually important to understanding the flow, however. + + +Reserving memory in SPL +----------------------- + +If memory needs to be reserved in RAM during SPL stage with the requirement that +the SPL reserved memory remains preserved across further boot stages too +then it needs to be reserved mandatorily starting from end of RAM. This is to +ensure that further stages can simply skip this region before carrying out +further reservations or updating the relocation address. + +Also out of these regions which are to be preserved across further stages of +boot, video framebuffer memory region must be reserved first starting from +end of RAM for which helper function spl_reserve_video_from_ram_top is provided +which makes sure that video memory is placed at top of reservation area with +further reservations below it. + +The corresponding information of reservation for those regions can be passed to +further boot stages using a bloblist. For e.g. the information for +framebuffer area reserved by SPL can be passed onto U-boot using +BLOBLISTT_U_BOOT_VIDEO. + +The further boot stages need to parse each of the bloblist passed from SPL stage +starting from video bloblist and skip this whole SPL reserved memory area from +end of RAM as per the bloblists received, before carrying out further +reservations or updating the relocation address. For e.g, U-boot proper uses +function "setup_relocaddr_from_bloblist" to parse the bloblists passed from +previous stage and skip the memory reserved from previous stage accordingly. diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index c739242b6a8..0389b269c01 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -193,7 +193,7 @@ on the sandbox .. code-block:: bash cd <U-Boot source directory> - pytest.py test/py/tests/test_efi_secboot/test_signed.py --bd sandbox + pytest test/py/tests/test_efi_secboot/test_signed.py --bd sandbox UEFI binaries may be signed by Microsoft using the following certificates: diff --git a/doc/usage/cmd/smbios.rst b/doc/usage/cmd/smbios.rst new file mode 100644 index 00000000000..1ffd706d7de --- /dev/null +++ b/doc/usage/cmd/smbios.rst @@ -0,0 +1,93 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later: + +smbios command +============== + +Synopsis +-------- + +:: + + smbios + +Description +----------- + +The smbios command displays information from the SMBIOS tables. + +Examples +-------- + +The example below shows an example output of the smbios command. + +:: + + => smbios + SMBIOS 2.8.0 present. + 8 structures occupying 81 bytes + Table at 0x6d35018 + + Handle 0x0100, DMI type 1, 27 bytes at 0x6d35018 + System Information + Manufacturer: QEMU + Product Name: Standard PC (i440FX + PIIX, 1996) + Version: pc-i440fx-2.5 + Serial Number: + UUID 00000000-0000-0000-0000-000000000000 + Wake Up Type: + Serial Number: + SKU Number: + + Handle 0x0300, DMI type 3, 22 bytes at 0x6d35069 + Header and Data: + 00000000: 03 16 00 03 01 01 02 00 00 03 03 03 02 00 00 00 + 00000010: 00 00 00 00 00 00 + Strings: + String 1: QEMU + String 2: pc-i440fx-2.5 + + Handle 0x0400, DMI type 4, 42 bytes at 0x6d35093 + Header and Data: + 00000000: 04 2a 00 04 01 03 01 02 63 06 00 00 fd ab 81 07 + 00000010: 03 00 00 00 d0 07 d0 07 41 01 ff ff ff ff ff ff + 00000020: 00 00 00 01 01 01 02 00 01 00 + Strings: + String 1: CPU 0 + String 2: QEMU + String 3: pc-i440fx-2.5 + + Handle 0x1000, DMI type 16, 23 bytes at 0x6d350d7 + Header and Data: + 00000000: 10 17 00 10 01 03 06 00 00 02 00 fe ff 01 00 00 + 00000010: 00 00 00 00 00 00 00 + + Handle 0x1100, DMI type 17, 40 bytes at 0x6d350f0 + Header and Data: + 00000000: 11 28 00 11 00 10 fe ff ff ff ff ff 80 00 09 00 + 00000010: 01 00 07 02 00 00 00 02 00 00 00 00 00 00 00 00 + 00000020: 00 00 00 00 00 00 00 00 + Strings: + String 1: DIMM 0 + String 2: QEMU + + Handle 0x1300, DMI type 19, 31 bytes at 0x6d35125 + Header and Data: + 00000000: 13 1f 00 13 00 00 00 00 ff ff 01 00 00 10 01 00 + 00000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + + Handle 0x2000, DMI type 32, 11 bytes at 0x6d35146 + Header and Data: + 00000000: 20 0b 00 20 00 00 00 00 00 00 00 + + Handle 0x7f00, DMI type 127, 4 bytes at 0x6d35153 + End Of Table + +Configuration +------------- + +The command is only available if CONFIG_CMD_SMBIOS=y. + +Return value +------------ + +The return value $? is 0 (true) on success, 1 (false) otherwise. diff --git a/doc/usage/index.rst b/doc/usage/index.rst index c171c029b80..0d174eefaa5 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -103,6 +103,7 @@ Shell commands cmd/size cmd/sleep cmd/sm + cmd/smbios cmd/sound cmd/source cmd/temperature diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index eecfacd7fc0..a15909329bb 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -1143,8 +1143,6 @@ static void ast2600_clk_dump(struct udevice *dev) ret = clk_get_rate(&clk); rate = ret; - clk_free(&clk); - if (ret == -EINVAL) { printf("clk ID %lu not supported yet\n", aspeed_clk_names[i].id); diff --git a/drivers/clk/at91/compat.c b/drivers/clk/at91/compat.c index 2fdc2fbd554..ee67093c607 100644 --- a/drivers/clk/at91/compat.c +++ b/drivers/clk/at91/compat.c @@ -516,7 +516,6 @@ static ulong periph_get_rate(struct clk *clk) { struct udevice *dev; struct clk clk_dev; - ulong clk_rate; int ret; dev = dev_get_parent(clk->dev); @@ -525,11 +524,7 @@ static ulong periph_get_rate(struct clk *clk) if (ret) return ret; - clk_rate = clk_get_rate(&clk_dev); - - clk_free(&clk_dev); - - return clk_rate; + return clk_get_rate(&clk_dev); } static struct clk_ops periph_clk_ops = { @@ -762,7 +757,6 @@ static ulong generic_clk_get_rate(struct clk *clk) struct pmc_plat *plat = dev_get_plat(clk->dev); struct at91_pmc *pmc = plat->reg_base; struct clk parent; - ulong clk_rate; u32 tmp, gckdiv; u8 clock_source, parent_index; int ret; @@ -778,11 +772,7 @@ static ulong generic_clk_get_rate(struct clk *clk) if (ret) return 0; - clk_rate = clk_get_rate(&parent) / (gckdiv + 1); - - clk_free(&parent); - - return clk_rate; + return clk_get_rate(&parent) / (gckdiv + 1); } static ulong generic_clk_set_rate(struct clk *clk, ulong rate) diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 26d795b9783..4ed14306575 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -3,19 +3,23 @@ * Copyright (C) 2023 Marek Vasut <marek.vasut+renesas@mailbox.org> */ -#include <asm/gpio.h> -#include <common.h> +#include <clk.h> #include <clk-uclass.h> #include <dm.h> +#include <linux/clk-provider.h> + +#include <asm/gpio.h> struct clk_gpio_priv { - struct gpio_desc enable; + struct gpio_desc enable; /* GPIO, controlling the gate */ + struct clk *clk; /* Gated clock */ }; static int clk_gpio_enable(struct clk *clk) { struct clk_gpio_priv *priv = dev_get_priv(clk->dev); + clk_enable(priv->clk); dm_gpio_set_value(&priv->enable, 1); return 0; @@ -26,21 +30,45 @@ static int clk_gpio_disable(struct clk *clk) struct clk_gpio_priv *priv = dev_get_priv(clk->dev); dm_gpio_set_value(&priv->enable, 0); + clk_disable(priv->clk); return 0; } +static ulong clk_gpio_get_rate(struct clk *clk) +{ + struct clk_gpio_priv *priv = dev_get_priv(clk->dev); + + return clk_get_rate(priv->clk); +} + const struct clk_ops clk_gpio_ops = { .enable = clk_gpio_enable, .disable = clk_gpio_disable, + .get_rate = clk_gpio_get_rate, }; static int clk_gpio_probe(struct udevice *dev) { struct clk_gpio_priv *priv = dev_get_priv(dev); + int ret; + + priv->clk = devm_clk_get(dev, NULL); + if (IS_ERR(priv->clk)) { + log_debug("%s: Could not get gated clock: %ld\n", + __func__, PTR_ERR(priv->clk)); + return PTR_ERR(priv->clk); + } - return gpio_request_by_name(dev, "enable-gpios", 0, - &priv->enable, GPIOD_IS_OUT); + ret = gpio_request_by_name(dev, "enable-gpios", 0, + &priv->enable, GPIOD_IS_OUT); + if (ret) { + log_debug("%s: Could not decode enable-gpios (%d)\n", + __func__, ret); + return ret; + } + + return 0; } /* diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index 3e9d68feb3c..ed6e60bc484 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -437,8 +437,6 @@ int clk_release_all(struct clk *clk, unsigned int count) ret = clk_disable(&clk[i]); if (ret && ret != -ENOSYS) return ret; - - clk_free(&clk[i]); } return 0; @@ -461,24 +459,9 @@ int clk_request(struct udevice *dev, struct clk *clk) return ops->request(clk); } -void clk_free(struct clk *clk) -{ - const struct clk_ops *ops; - - debug("%s(clk=%p)\n", __func__, clk); - if (!clk_valid(clk)) - return; - ops = clk_dev_ops(clk->dev); - - if (ops->rfree) - ops->rfree(clk); - return; -} - ulong clk_get_rate(struct clk *clk) { const struct clk_ops *ops; - ulong ret; debug("%s(clk=%p)\n", __func__, clk); if (!clk_valid(clk)) @@ -488,11 +471,7 @@ ulong clk_get_rate(struct clk *clk) if (!ops->get_rate) return -ENOSYS; - ret = ops->get_rate(clk); - if (ret) - return log_ret(ret); - - return 0; + return ops->get_rate(clk); } struct clk *clk_get_parent(struct clk *clk) @@ -791,22 +770,12 @@ bool clk_is_match(const struct clk *p, const struct clk *q) return false; } -static void devm_clk_release(struct udevice *dev, void *res) -{ - clk_free(res); -} - -static int devm_clk_match(struct udevice *dev, void *res, void *data) -{ - return res == data; -} - struct clk *devm_clk_get(struct udevice *dev, const char *id) { int rc; struct clk *clk; - clk = devres_alloc(devm_clk_release, sizeof(struct clk), __GFP_ZERO); + clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL); if (unlikely(!clk)) return ERR_PTR(-ENOMEM); @@ -814,21 +783,9 @@ struct clk *devm_clk_get(struct udevice *dev, const char *id) if (rc) return ERR_PTR(rc); - devres_add(dev, clk); return clk; } -void devm_clk_put(struct udevice *dev, struct clk *clk) -{ - int rc; - - if (!clk) - return; - - rc = devres_release(dev, devm_clk_release, devm_clk_match, clk); - WARN_ON(rc); -} - int clk_uclass_post_probe(struct udevice *dev) { /* diff --git a/drivers/clk/clk-xlnx-clock-wizard.c b/drivers/clk/clk-xlnx-clock-wizard.c index 70ee3af1074..a10a843f11f 100644 --- a/drivers/clk/clk-xlnx-clock-wizard.c +++ b/drivers/clk/clk-xlnx-clock-wizard.c @@ -137,7 +137,6 @@ static int clk_wzrd_probe(struct udevice *dev) ret = clk_enable(&clk_in1); if (ret) { dev_err(dev, "failed to enable clock\n"); - clk_free(&clk_in1); return ret; } diff --git a/drivers/clk/clk_sandbox.c b/drivers/clk/clk_sandbox.c index 636914db8ca..73d943f9e09 100644 --- a/drivers/clk/clk_sandbox.c +++ b/drivers/clk/clk_sandbox.c @@ -101,17 +101,6 @@ static int sandbox_clk_request(struct clk *clk) return 0; } -static void sandbox_clk_free(struct clk *clk) -{ - struct sandbox_clk_priv *priv = dev_get_priv(clk->dev); - - if (clk->id >= SANDBOX_CLK_ID_COUNT) - return; - - priv->requested[clk->id] = false; - return; -} - static struct clk_ops sandbox_clk_ops = { .round_rate = sandbox_clk_round_rate, .get_rate = sandbox_clk_get_rate, @@ -119,7 +108,6 @@ static struct clk_ops sandbox_clk_ops = { .enable = sandbox_clk_enable, .disable = sandbox_clk_disable, .request = sandbox_clk_request, - .rfree = sandbox_clk_free, }; static int sandbox_clk_probe(struct udevice *dev) diff --git a/drivers/clk/clk_sandbox_test.c b/drivers/clk/clk_sandbox_test.c index c695b69321e..c224dc1d2cb 100644 --- a/drivers/clk/clk_sandbox_test.c +++ b/drivers/clk/clk_sandbox_test.c @@ -135,18 +135,6 @@ int sandbox_clk_test_disable_bulk(struct udevice *dev) return clk_disable_bulk(&sbct->bulk); } -int sandbox_clk_test_free(struct udevice *dev) -{ - struct sandbox_clk_test *sbct = dev_get_priv(dev); - int i; - - devm_clk_put(dev, sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1]); - for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++) - clk_free(&sbct->clks[i]); - - return 0; -} - int sandbox_clk_test_release_bulk(struct udevice *dev) { struct sandbox_clk_test *sbct = dev_get_priv(dev); diff --git a/drivers/clk/clk_versaclock.c b/drivers/clk/clk_versaclock.c index 699df3cf3ee..bbe72256032 100644 --- a/drivers/clk/clk_versaclock.c +++ b/drivers/clk/clk_versaclock.c @@ -1000,26 +1000,18 @@ int versaclock_probe(struct udevice *dev) return 0; free_out: - for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) { - clk_free(&vc5->clk_out[n].hw); + for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) free(out_name[n]); - } free_selb: - clk_free(&vc5->clk_out[0].hw); free(outsel_name); free_fod: - for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) { - clk_free(&vc5->clk_fod[n].hw); + for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) free(fod_name[n]); - } free_pll: - clk_free(&vc5->clk_pll.hw); free(pll_name); free_pfd: - clk_free(&vc5->clk_pfd); free(pfd_name); free_mux: - clk_free(&vc5->clk_mux); free(mux_name); return ret; diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c index 34f964d72af..e3cefe2e0c7 100644 --- a/drivers/clk/clk_zynq.c +++ b/drivers/clk/clk_zynq.c @@ -491,8 +491,6 @@ static void zynq_clk_dump(struct udevice *dev) rate = clk_get_rate(&clk); - clk_free(&clk); - if ((rate == (unsigned long)-ENOSYS) || (rate == (unsigned long)-ENXIO)) printf("%10s%20s\n", name, "unknown"); diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c index 0ffac194a19..e23f7da3f92 100644 --- a/drivers/clk/clk_zynqmp.c +++ b/drivers/clk/clk_zynqmp.c @@ -757,8 +757,6 @@ static void zynqmp_clk_dump(struct udevice *dev) rate = clk_get_rate(&clk); - clk_free(&clk); - if ((rate == (unsigned long)-ENOSYS) || (rate == (unsigned long)-ENXIO) || (rate == (unsigned long)-EIO)) diff --git a/drivers/clk/imx/clk-imx8.c b/drivers/clk/imx/clk-imx8.c index 9600672e071..d39b87b2e24 100644 --- a/drivers/clk/imx/clk-imx8.c +++ b/drivers/clk/imx/clk-imx8.c @@ -62,8 +62,6 @@ static void imx8_clk_dump(struct udevice *dev) ret = clk_get_rate(&clk); rate = ret; - clk_free(&clk); - if (ret == -EINVAL) { printf("clk ID %lu not supported yet\n", imx8_clk_names[i].id); diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index cdc9d6f76ce..ee33c611400 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -29,3 +29,13 @@ config CLK_MESON_A1 help Enable clock support for the Amlogic A1 SoC family, such as the A113L + +config CLK_MESON_MSR + bool "Enable clock measure driver for Amlogic SoCs" + depends on CLK && ARCH_MESON + depends on CMD_CLK + default ARCH_MESON + help + Enable measuring a set of internal Amlogic SoC clock frequencies + using the Hardware Clock Measure registers and print them using + the clk dump command. diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index d975f07aab0..c7a446e86c4 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_CLK_MESON_AXG) += axg-ao.o obj-$(CONFIG_CLK_MESON_G12A) += g12a.o obj-$(CONFIG_CLK_MESON_G12A) += g12a-ao.o obj-$(CONFIG_CLK_MESON_A1) += a1.o +obj-$(CONFIG_CLK_MESON_MSR) += clk-measure.o diff --git a/drivers/clk/meson/clk-measure.c b/drivers/clk/meson/clk-measure.c new file mode 100644 index 00000000000..f653fc63552 --- /dev/null +++ b/drivers/clk/meson/clk-measure.c @@ -0,0 +1,634 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Based on Linux driver from: + * (C) Copyright 2018 - BayLibre, SAS + * Author: Neil Armstrong <narmstrong@baylibre.com> + * (C) Copyright 2023 - Neil Armstrong <neil.armstrong@linaro.org> + */ + +#include <log.h> +#include <clk-uclass.h> +#include <div64.h> +#include <dm.h> +#include <time.h> +#include <regmap.h> +#include <syscon.h> +#include <linux/bitops.h> +#include <linux/bitfield.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/kernel.h> + +#define MSR_CLK_DUTY 0x0 +#define MSR_CLK_REG0 0x4 +#define MSR_CLK_REG1 0x8 +#define MSR_CLK_REG2 0xc + +#define MSR_DURATION GENMASK(15, 0) +#define MSR_ENABLE BIT(16) +#define MSR_CONT BIT(17) /* continuous measurement */ +#define MSR_INTR BIT(18) /* interrupts */ +#define MSR_RUN BIT(19) +#define MSR_CLK_SRC GENMASK(26, 20) +#define MSR_BUSY BIT(31) + +#define MSR_VAL_MASK GENMASK(15, 0) + +#define DIV_MIN 32 +#define DIV_STEP 32 +#define DIV_MAX 640 + +#define CLK_MSR_MAX 128 + +struct meson_msr_id { + unsigned int id; + const char *name; +}; + +struct meson_msr { + struct regmap *regmap; + struct meson_msr_id *msr_table; +}; + +#define CLK_MSR_ID(__id, __name) \ + [__id] = {.id = __id, .name = __name,} + +static struct meson_msr_id clk_msr_m8[CLK_MSR_MAX] = { + CLK_MSR_ID(0, "ring_osc_out_ee0"), + CLK_MSR_ID(1, "ring_osc_out_ee1"), + CLK_MSR_ID(2, "ring_osc_out_ee2"), + CLK_MSR_ID(3, "a9_ring_osck"), + CLK_MSR_ID(6, "vid_pll"), + CLK_MSR_ID(7, "clk81"), + CLK_MSR_ID(8, "encp"), + CLK_MSR_ID(9, "encl"), + CLK_MSR_ID(11, "eth_rmii"), + CLK_MSR_ID(13, "amclk"), + CLK_MSR_ID(14, "fec_clk_0"), + CLK_MSR_ID(15, "fec_clk_1"), + CLK_MSR_ID(16, "fec_clk_2"), + CLK_MSR_ID(18, "a9_clk_div16"), + CLK_MSR_ID(19, "hdmi_sys"), + CLK_MSR_ID(20, "rtc_osc_clk_out"), + CLK_MSR_ID(21, "i2s_clk_in_src0"), + CLK_MSR_ID(22, "clk_rmii_from_pad"), + CLK_MSR_ID(23, "hdmi_ch0_tmds"), + CLK_MSR_ID(24, "lvds_fifo"), + CLK_MSR_ID(26, "sc_clk_int"), + CLK_MSR_ID(28, "sar_adc"), + CLK_MSR_ID(30, "mpll_clk_test_out"), + CLK_MSR_ID(31, "audac_clkpi"), + CLK_MSR_ID(32, "vdac"), + CLK_MSR_ID(33, "sdhc_rx"), + CLK_MSR_ID(34, "sdhc_sd"), + CLK_MSR_ID(35, "mali"), + CLK_MSR_ID(36, "hdmi_tx_pixel"), + CLK_MSR_ID(38, "vdin_meas"), + CLK_MSR_ID(39, "pcm_sclk"), + CLK_MSR_ID(40, "pcm_mclk"), + CLK_MSR_ID(41, "eth_rx_tx"), + CLK_MSR_ID(42, "pwm_d"), + CLK_MSR_ID(43, "pwm_c"), + CLK_MSR_ID(44, "pwm_b"), + CLK_MSR_ID(45, "pwm_a"), + CLK_MSR_ID(46, "pcm2_sclk"), + CLK_MSR_ID(47, "ddr_dpll_pt"), + CLK_MSR_ID(48, "pwm_f"), + CLK_MSR_ID(49, "pwm_e"), + CLK_MSR_ID(59, "hcodec"), + CLK_MSR_ID(60, "usb_32k_alt"), + CLK_MSR_ID(61, "gpio"), + CLK_MSR_ID(62, "vid2_pll"), + CLK_MSR_ID(63, "mipi_csi_cfg"), +}; + +static struct meson_msr_id clk_msr_gx[CLK_MSR_MAX] = { + CLK_MSR_ID(0, "ring_osc_out_ee_0"), + CLK_MSR_ID(1, "ring_osc_out_ee_1"), + CLK_MSR_ID(2, "ring_osc_out_ee_2"), + CLK_MSR_ID(3, "a53_ring_osc"), + CLK_MSR_ID(4, "gp0_pll"), + CLK_MSR_ID(6, "enci"), + CLK_MSR_ID(7, "clk81"), + CLK_MSR_ID(8, "encp"), + CLK_MSR_ID(9, "encl"), + CLK_MSR_ID(10, "vdac"), + CLK_MSR_ID(11, "rgmii_tx"), + CLK_MSR_ID(12, "pdm"), + CLK_MSR_ID(13, "amclk"), + CLK_MSR_ID(14, "fec_0"), + CLK_MSR_ID(15, "fec_1"), + CLK_MSR_ID(16, "fec_2"), + CLK_MSR_ID(17, "sys_pll_div16"), + CLK_MSR_ID(18, "sys_cpu_div16"), + CLK_MSR_ID(19, "hdmitx_sys"), + CLK_MSR_ID(20, "rtc_osc_out"), + CLK_MSR_ID(21, "i2s_in_src0"), + CLK_MSR_ID(22, "eth_phy_ref"), + CLK_MSR_ID(23, "hdmi_todig"), + CLK_MSR_ID(26, "sc_int"), + CLK_MSR_ID(28, "sar_adc"), + CLK_MSR_ID(31, "mpll_test_out"), + CLK_MSR_ID(32, "vdec"), + CLK_MSR_ID(35, "mali"), + CLK_MSR_ID(36, "hdmi_tx_pixel"), + CLK_MSR_ID(37, "i958"), + CLK_MSR_ID(38, "vdin_meas"), + CLK_MSR_ID(39, "pcm_sclk"), + CLK_MSR_ID(40, "pcm_mclk"), + CLK_MSR_ID(41, "eth_rx_or_rmii"), + CLK_MSR_ID(42, "mp0_out"), + CLK_MSR_ID(43, "fclk_div5"), + CLK_MSR_ID(44, "pwm_b"), + CLK_MSR_ID(45, "pwm_a"), + CLK_MSR_ID(46, "vpu"), + CLK_MSR_ID(47, "ddr_dpll_pt"), + CLK_MSR_ID(48, "mp1_out"), + CLK_MSR_ID(49, "mp2_out"), + CLK_MSR_ID(50, "mp3_out"), + CLK_MSR_ID(51, "nand_core"), + CLK_MSR_ID(52, "sd_emmc_b"), + CLK_MSR_ID(53, "sd_emmc_a"), + CLK_MSR_ID(55, "vid_pll_div_out"), + CLK_MSR_ID(56, "cci"), + CLK_MSR_ID(57, "wave420l_c"), + CLK_MSR_ID(58, "wave420l_b"), + CLK_MSR_ID(59, "hcodec"), + CLK_MSR_ID(60, "alt_32k"), + CLK_MSR_ID(61, "gpio_msr"), + CLK_MSR_ID(62, "hevc"), + CLK_MSR_ID(66, "vid_lock"), + CLK_MSR_ID(70, "pwm_f"), + CLK_MSR_ID(71, "pwm_e"), + CLK_MSR_ID(72, "pwm_d"), + CLK_MSR_ID(73, "pwm_c"), + CLK_MSR_ID(75, "aoclkx2_int"), + CLK_MSR_ID(76, "aoclk_int"), + CLK_MSR_ID(77, "rng_ring_osc_0"), + CLK_MSR_ID(78, "rng_ring_osc_1"), + CLK_MSR_ID(79, "rng_ring_osc_2"), + CLK_MSR_ID(80, "rng_ring_osc_3"), + CLK_MSR_ID(81, "vapb"), + CLK_MSR_ID(82, "ge2d"), +}; + +static struct meson_msr_id clk_msr_axg[CLK_MSR_MAX] = { + CLK_MSR_ID(0, "ring_osc_out_ee_0"), + CLK_MSR_ID(1, "ring_osc_out_ee_1"), + CLK_MSR_ID(2, "ring_osc_out_ee_2"), + CLK_MSR_ID(3, "a53_ring_osc"), + CLK_MSR_ID(4, "gp0_pll"), + CLK_MSR_ID(5, "gp1_pll"), + CLK_MSR_ID(7, "clk81"), + CLK_MSR_ID(9, "encl"), + CLK_MSR_ID(17, "sys_pll_div16"), + CLK_MSR_ID(18, "sys_cpu_div16"), + CLK_MSR_ID(20, "rtc_osc_out"), + CLK_MSR_ID(23, "mmc_clk"), + CLK_MSR_ID(28, "sar_adc"), + CLK_MSR_ID(31, "mpll_test_out"), + CLK_MSR_ID(40, "mod_eth_tx_clk"), + CLK_MSR_ID(41, "mod_eth_rx_clk_rmii"), + CLK_MSR_ID(42, "mp0_out"), + CLK_MSR_ID(43, "fclk_div5"), + CLK_MSR_ID(44, "pwm_b"), + CLK_MSR_ID(45, "pwm_a"), + CLK_MSR_ID(46, "vpu"), + CLK_MSR_ID(47, "ddr_dpll_pt"), + CLK_MSR_ID(48, "mp1_out"), + CLK_MSR_ID(49, "mp2_out"), + CLK_MSR_ID(50, "mp3_out"), + CLK_MSR_ID(51, "sd_emmm_c"), + CLK_MSR_ID(52, "sd_emmc_b"), + CLK_MSR_ID(61, "gpio_msr"), + CLK_MSR_ID(66, "audio_slv_lrclk_c"), + CLK_MSR_ID(67, "audio_slv_lrclk_b"), + CLK_MSR_ID(68, "audio_slv_lrclk_a"), + CLK_MSR_ID(69, "audio_slv_sclk_c"), + CLK_MSR_ID(70, "audio_slv_sclk_b"), + CLK_MSR_ID(71, "audio_slv_sclk_a"), + CLK_MSR_ID(72, "pwm_d"), + CLK_MSR_ID(73, "pwm_c"), + CLK_MSR_ID(74, "wifi_beacon"), + CLK_MSR_ID(75, "tdmin_lb_lrcl"), + CLK_MSR_ID(76, "tdmin_lb_sclk"), + CLK_MSR_ID(77, "rng_ring_osc_0"), + CLK_MSR_ID(78, "rng_ring_osc_1"), + CLK_MSR_ID(79, "rng_ring_osc_2"), + CLK_MSR_ID(80, "rng_ring_osc_3"), + CLK_MSR_ID(81, "vapb"), + CLK_MSR_ID(82, "ge2d"), + CLK_MSR_ID(84, "audio_resample"), + CLK_MSR_ID(85, "audio_pdm_sys"), + CLK_MSR_ID(86, "audio_spdifout"), + CLK_MSR_ID(87, "audio_spdifin"), + CLK_MSR_ID(88, "audio_lrclk_f"), + CLK_MSR_ID(89, "audio_lrclk_e"), + CLK_MSR_ID(90, "audio_lrclk_d"), + CLK_MSR_ID(91, "audio_lrclk_c"), + CLK_MSR_ID(92, "audio_lrclk_b"), + CLK_MSR_ID(93, "audio_lrclk_a"), + CLK_MSR_ID(94, "audio_sclk_f"), + CLK_MSR_ID(95, "audio_sclk_e"), + CLK_MSR_ID(96, "audio_sclk_d"), + CLK_MSR_ID(97, "audio_sclk_c"), + CLK_MSR_ID(98, "audio_sclk_b"), + CLK_MSR_ID(99, "audio_sclk_a"), + CLK_MSR_ID(100, "audio_mclk_f"), + CLK_MSR_ID(101, "audio_mclk_e"), + CLK_MSR_ID(102, "audio_mclk_d"), + CLK_MSR_ID(103, "audio_mclk_c"), + CLK_MSR_ID(104, "audio_mclk_b"), + CLK_MSR_ID(105, "audio_mclk_a"), + CLK_MSR_ID(106, "pcie_refclk_n"), + CLK_MSR_ID(107, "pcie_refclk_p"), + CLK_MSR_ID(108, "audio_locker_out"), + CLK_MSR_ID(109, "audio_locker_in"), +}; + +static struct meson_msr_id clk_msr_g12a[CLK_MSR_MAX] = { + CLK_MSR_ID(0, "ring_osc_out_ee_0"), + CLK_MSR_ID(1, "ring_osc_out_ee_1"), + CLK_MSR_ID(2, "ring_osc_out_ee_2"), + CLK_MSR_ID(3, "sys_cpu_ring_osc"), + CLK_MSR_ID(4, "gp0_pll"), + CLK_MSR_ID(6, "enci"), + CLK_MSR_ID(7, "clk81"), + CLK_MSR_ID(8, "encp"), + CLK_MSR_ID(9, "encl"), + CLK_MSR_ID(10, "vdac"), + CLK_MSR_ID(11, "eth_tx"), + CLK_MSR_ID(12, "hifi_pll"), + CLK_MSR_ID(13, "mod_tcon"), + CLK_MSR_ID(14, "fec_0"), + CLK_MSR_ID(15, "fec_1"), + CLK_MSR_ID(16, "fec_2"), + CLK_MSR_ID(17, "sys_pll_div16"), + CLK_MSR_ID(18, "sys_cpu_div16"), + CLK_MSR_ID(19, "lcd_an_ph2"), + CLK_MSR_ID(20, "rtc_osc_out"), + CLK_MSR_ID(21, "lcd_an_ph3"), + CLK_MSR_ID(22, "eth_phy_ref"), + CLK_MSR_ID(23, "mpll_50m"), + CLK_MSR_ID(24, "eth_125m"), + CLK_MSR_ID(25, "eth_rmii"), + CLK_MSR_ID(26, "sc_int"), + CLK_MSR_ID(27, "in_mac"), + CLK_MSR_ID(28, "sar_adc"), + CLK_MSR_ID(29, "pcie_inp"), + CLK_MSR_ID(30, "pcie_inn"), + CLK_MSR_ID(31, "mpll_test_out"), + CLK_MSR_ID(32, "vdec"), + CLK_MSR_ID(33, "sys_cpu_ring_osc_1"), + CLK_MSR_ID(34, "eth_mpll_50m"), + CLK_MSR_ID(35, "mali"), + CLK_MSR_ID(36, "hdmi_tx_pixel"), + CLK_MSR_ID(37, "cdac"), + CLK_MSR_ID(38, "vdin_meas"), + CLK_MSR_ID(39, "bt656"), + CLK_MSR_ID(41, "eth_rx_or_rmii"), + CLK_MSR_ID(42, "mp0_out"), + CLK_MSR_ID(43, "fclk_div5"), + CLK_MSR_ID(44, "pwm_b"), + CLK_MSR_ID(45, "pwm_a"), + CLK_MSR_ID(46, "vpu"), + CLK_MSR_ID(47, "ddr_dpll_pt"), + CLK_MSR_ID(48, "mp1_out"), + CLK_MSR_ID(49, "mp2_out"), + CLK_MSR_ID(50, "mp3_out"), + CLK_MSR_ID(51, "sd_emmc_c"), + CLK_MSR_ID(52, "sd_emmc_b"), + CLK_MSR_ID(53, "sd_emmc_a"), + CLK_MSR_ID(54, "vpu_clkc"), + CLK_MSR_ID(55, "vid_pll_div_out"), + CLK_MSR_ID(56, "wave420l_a"), + CLK_MSR_ID(57, "wave420l_c"), + CLK_MSR_ID(58, "wave420l_b"), + CLK_MSR_ID(59, "hcodec"), + CLK_MSR_ID(61, "gpio_msr"), + CLK_MSR_ID(62, "hevcb"), + CLK_MSR_ID(63, "dsi_meas"), + CLK_MSR_ID(64, "spicc_1"), + CLK_MSR_ID(65, "spicc_0"), + CLK_MSR_ID(66, "vid_lock"), + CLK_MSR_ID(67, "dsi_phy"), + CLK_MSR_ID(68, "hdcp22_esm"), + CLK_MSR_ID(69, "hdcp22_skp"), + CLK_MSR_ID(70, "pwm_f"), + CLK_MSR_ID(71, "pwm_e"), + CLK_MSR_ID(72, "pwm_d"), + CLK_MSR_ID(73, "pwm_c"), + CLK_MSR_ID(75, "hevcf"), + CLK_MSR_ID(77, "rng_ring_osc_0"), + CLK_MSR_ID(78, "rng_ring_osc_1"), + CLK_MSR_ID(79, "rng_ring_osc_2"), + CLK_MSR_ID(80, "rng_ring_osc_3"), + CLK_MSR_ID(81, "vapb"), + CLK_MSR_ID(82, "ge2d"), + CLK_MSR_ID(83, "co_rx"), + CLK_MSR_ID(84, "co_tx"), + CLK_MSR_ID(89, "hdmi_todig"), + CLK_MSR_ID(90, "hdmitx_sys"), + CLK_MSR_ID(91, "sys_cpub_div16"), + CLK_MSR_ID(92, "sys_pll_cpub_div16"), + CLK_MSR_ID(94, "eth_phy_rx"), + CLK_MSR_ID(95, "eth_phy_pll"), + CLK_MSR_ID(96, "vpu_b"), + CLK_MSR_ID(97, "cpu_b_tmp"), + CLK_MSR_ID(98, "ts"), + CLK_MSR_ID(99, "ring_osc_out_ee_3"), + CLK_MSR_ID(100, "ring_osc_out_ee_4"), + CLK_MSR_ID(101, "ring_osc_out_ee_5"), + CLK_MSR_ID(102, "ring_osc_out_ee_6"), + CLK_MSR_ID(103, "ring_osc_out_ee_7"), + CLK_MSR_ID(104, "ring_osc_out_ee_8"), + CLK_MSR_ID(105, "ring_osc_out_ee_9"), + CLK_MSR_ID(106, "ephy_test"), + CLK_MSR_ID(107, "au_dac_g128x"), + CLK_MSR_ID(108, "audio_locker_out"), + CLK_MSR_ID(109, "audio_locker_in"), + CLK_MSR_ID(110, "audio_tdmout_c_sclk"), + CLK_MSR_ID(111, "audio_tdmout_b_sclk"), + CLK_MSR_ID(112, "audio_tdmout_a_sclk"), + CLK_MSR_ID(113, "audio_tdmin_lb_sclk"), + CLK_MSR_ID(114, "audio_tdmin_c_sclk"), + CLK_MSR_ID(115, "audio_tdmin_b_sclk"), + CLK_MSR_ID(116, "audio_tdmin_a_sclk"), + CLK_MSR_ID(117, "audio_resample"), + CLK_MSR_ID(118, "audio_pdm_sys"), + CLK_MSR_ID(119, "audio_spdifout_b"), + CLK_MSR_ID(120, "audio_spdifout"), + CLK_MSR_ID(121, "audio_spdifin"), + CLK_MSR_ID(122, "audio_pdm_dclk"), +}; + +static struct meson_msr_id clk_msr_sm1[CLK_MSR_MAX] = { + CLK_MSR_ID(0, "ring_osc_out_ee_0"), + CLK_MSR_ID(1, "ring_osc_out_ee_1"), + CLK_MSR_ID(2, "ring_osc_out_ee_2"), + CLK_MSR_ID(3, "ring_osc_out_ee_3"), + CLK_MSR_ID(4, "gp0_pll"), + CLK_MSR_ID(5, "gp1_pll"), + CLK_MSR_ID(6, "enci"), + CLK_MSR_ID(7, "clk81"), + CLK_MSR_ID(8, "encp"), + CLK_MSR_ID(9, "encl"), + CLK_MSR_ID(10, "vdac"), + CLK_MSR_ID(11, "eth_tx"), + CLK_MSR_ID(12, "hifi_pll"), + CLK_MSR_ID(13, "mod_tcon"), + CLK_MSR_ID(14, "fec_0"), + CLK_MSR_ID(15, "fec_1"), + CLK_MSR_ID(16, "fec_2"), + CLK_MSR_ID(17, "sys_pll_div16"), + CLK_MSR_ID(18, "sys_cpu_div16"), + CLK_MSR_ID(19, "lcd_an_ph2"), + CLK_MSR_ID(20, "rtc_osc_out"), + CLK_MSR_ID(21, "lcd_an_ph3"), + CLK_MSR_ID(22, "eth_phy_ref"), + CLK_MSR_ID(23, "mpll_50m"), + CLK_MSR_ID(24, "eth_125m"), + CLK_MSR_ID(25, "eth_rmii"), + CLK_MSR_ID(26, "sc_int"), + CLK_MSR_ID(27, "in_mac"), + CLK_MSR_ID(28, "sar_adc"), + CLK_MSR_ID(29, "pcie_inp"), + CLK_MSR_ID(30, "pcie_inn"), + CLK_MSR_ID(31, "mpll_test_out"), + CLK_MSR_ID(32, "vdec"), + CLK_MSR_ID(34, "eth_mpll_50m"), + CLK_MSR_ID(35, "mali"), + CLK_MSR_ID(36, "hdmi_tx_pixel"), + CLK_MSR_ID(37, "cdac"), + CLK_MSR_ID(38, "vdin_meas"), + CLK_MSR_ID(39, "bt656"), + CLK_MSR_ID(40, "arm_ring_osc_out_4"), + CLK_MSR_ID(41, "eth_rx_or_rmii"), + CLK_MSR_ID(42, "mp0_out"), + CLK_MSR_ID(43, "fclk_div5"), + CLK_MSR_ID(44, "pwm_b"), + CLK_MSR_ID(45, "pwm_a"), + CLK_MSR_ID(46, "vpu"), + CLK_MSR_ID(47, "ddr_dpll_pt"), + CLK_MSR_ID(48, "mp1_out"), + CLK_MSR_ID(49, "mp2_out"), + CLK_MSR_ID(50, "mp3_out"), + CLK_MSR_ID(51, "sd_emmc_c"), + CLK_MSR_ID(52, "sd_emmc_b"), + CLK_MSR_ID(53, "sd_emmc_a"), + CLK_MSR_ID(54, "vpu_clkc"), + CLK_MSR_ID(55, "vid_pll_div_out"), + CLK_MSR_ID(56, "wave420l_a"), + CLK_MSR_ID(57, "wave420l_c"), + CLK_MSR_ID(58, "wave420l_b"), + CLK_MSR_ID(59, "hcodec"), + CLK_MSR_ID(60, "arm_ring_osc_out_5"), + CLK_MSR_ID(61, "gpio_msr"), + CLK_MSR_ID(62, "hevcb"), + CLK_MSR_ID(63, "dsi_meas"), + CLK_MSR_ID(64, "spicc_1"), + CLK_MSR_ID(65, "spicc_0"), + CLK_MSR_ID(66, "vid_lock"), + CLK_MSR_ID(67, "dsi_phy"), + CLK_MSR_ID(68, "hdcp22_esm"), + CLK_MSR_ID(69, "hdcp22_skp"), + CLK_MSR_ID(70, "pwm_f"), + CLK_MSR_ID(71, "pwm_e"), + CLK_MSR_ID(72, "pwm_d"), + CLK_MSR_ID(73, "pwm_c"), + CLK_MSR_ID(74, "arm_ring_osc_out_6"), + CLK_MSR_ID(75, "hevcf"), + CLK_MSR_ID(76, "arm_ring_osc_out_7"), + CLK_MSR_ID(77, "rng_ring_osc_0"), + CLK_MSR_ID(78, "rng_ring_osc_1"), + CLK_MSR_ID(79, "rng_ring_osc_2"), + CLK_MSR_ID(80, "rng_ring_osc_3"), + CLK_MSR_ID(81, "vapb"), + CLK_MSR_ID(82, "ge2d"), + CLK_MSR_ID(83, "co_rx"), + CLK_MSR_ID(84, "co_tx"), + CLK_MSR_ID(85, "arm_ring_osc_out_8"), + CLK_MSR_ID(86, "arm_ring_osc_out_9"), + CLK_MSR_ID(87, "mipi_dsi_phy"), + CLK_MSR_ID(88, "cis2_adapt"), + CLK_MSR_ID(89, "hdmi_todig"), + CLK_MSR_ID(90, "hdmitx_sys"), + CLK_MSR_ID(91, "nna_core"), + CLK_MSR_ID(92, "nna_axi"), + CLK_MSR_ID(93, "vad"), + CLK_MSR_ID(94, "eth_phy_rx"), + CLK_MSR_ID(95, "eth_phy_pll"), + CLK_MSR_ID(96, "vpu_b"), + CLK_MSR_ID(97, "cpu_b_tmp"), + CLK_MSR_ID(98, "ts"), + CLK_MSR_ID(99, "arm_ring_osc_out_10"), + CLK_MSR_ID(100, "arm_ring_osc_out_11"), + CLK_MSR_ID(101, "arm_ring_osc_out_12"), + CLK_MSR_ID(102, "arm_ring_osc_out_13"), + CLK_MSR_ID(103, "arm_ring_osc_out_14"), + CLK_MSR_ID(104, "arm_ring_osc_out_15"), + CLK_MSR_ID(105, "arm_ring_osc_out_16"), + CLK_MSR_ID(106, "ephy_test"), + CLK_MSR_ID(107, "au_dac_g128x"), + CLK_MSR_ID(108, "audio_locker_out"), + CLK_MSR_ID(109, "audio_locker_in"), + CLK_MSR_ID(110, "audio_tdmout_c_sclk"), + CLK_MSR_ID(111, "audio_tdmout_b_sclk"), + CLK_MSR_ID(112, "audio_tdmout_a_sclk"), + CLK_MSR_ID(113, "audio_tdmin_lb_sclk"), + CLK_MSR_ID(114, "audio_tdmin_c_sclk"), + CLK_MSR_ID(115, "audio_tdmin_b_sclk"), + CLK_MSR_ID(116, "audio_tdmin_a_sclk"), + CLK_MSR_ID(117, "audio_resample"), + CLK_MSR_ID(118, "audio_pdm_sys"), + CLK_MSR_ID(119, "audio_spdifout_b"), + CLK_MSR_ID(120, "audio_spdifout"), + CLK_MSR_ID(121, "audio_spdifin"), + CLK_MSR_ID(122, "audio_pdm_dclk"), + CLK_MSR_ID(123, "audio_resampled"), + CLK_MSR_ID(124, "earcrx_pll"), + CLK_MSR_ID(125, "earcrx_pll_test"), + CLK_MSR_ID(126, "csi_phy0"), + CLK_MSR_ID(127, "csi2_data"), +}; + +static int meson_clk_msr_measure_id(struct meson_msr *priv, unsigned int id, + unsigned int duration) +{ + unsigned int val; + int ret; + + regmap_write(priv->regmap, MSR_CLK_REG0, 0); + + /* Set measurement duration */ + regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_DURATION, + FIELD_PREP(MSR_DURATION, duration - 1)); + + /* Set ID */ + regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_CLK_SRC, + FIELD_PREP(MSR_CLK_SRC, id)); + + /* Enable & Start */ + regmap_update_bits(priv->regmap, MSR_CLK_REG0, + MSR_RUN | MSR_ENABLE, + MSR_RUN | MSR_ENABLE); + + ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0, + val, !(val & MSR_BUSY), 10, 10000); + if (ret) + return ret; + + /* Disable */ + regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0); + + /* Get the value in multiple of gate time counts */ + regmap_read(priv->regmap, MSR_CLK_REG2, &val); + + if (val >= MSR_VAL_MASK) + return -EINVAL; + + return DIV_ROUND_CLOSEST_ULL((val & MSR_VAL_MASK) * 1000000ULL, + duration); +} + +static int meson_clk_msr_best_id(struct meson_msr *priv, unsigned int id, + unsigned int *precision) +{ + unsigned int duration = DIV_MAX; + int ret; + + /* Start from max duration and down to min duration */ + do { + ret = meson_clk_msr_measure_id(priv, id, duration); + if (ret >= 0) + *precision = (2 * 1000000) / duration; + else + duration -= DIV_STEP; + } while (duration >= DIV_MIN && ret == -EINVAL); + + return ret; +} + +static void meson_clk_msr_dump(struct udevice *dev) +{ + struct meson_msr *priv = dev_get_priv(dev); + unsigned int precision = 0; + int val, i; + + printf(" clock rate precision\n"); + printf("---------------------------------------------\n"); + + for (i = 0 ; i < CLK_MSR_MAX ; ++i) { + if (!priv->msr_table[i].name) + continue; + + val = meson_clk_msr_best_id(priv, i, &precision); + if (val < 0) + return; + + printf(" %-20s %10d +/-%dHz\n", + priv->msr_table[i].name, val, precision); + } +} + +static int meson_clk_msr_xlate(struct clk *clk, struct ofnode_phandle_args *args) +{ + /* This driver doesn't expose any clocks */ + return -EINVAL; +} + +static int meson_clk_msr_probe(struct udevice *dev) +{ + struct meson_msr *priv = dev_get_priv(dev); + int ret; + + priv->msr_table = (struct meson_msr_id *)dev_get_driver_data(dev); + + ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap); + if (ret) + return ret; + + return 0; +} + +static struct clk_ops meson_clk_msr_ops = { + .of_xlate = meson_clk_msr_xlate, + .dump = meson_clk_msr_dump, +}; + +static const struct udevice_id meson_clk_msr_ids[] = { + { + .compatible = "amlogic,meson-gx-clk-measure", + .data = (ulong)clk_msr_gx, + }, + { + .compatible = "amlogic,meson8-clk-measure", + .data = (ulong)clk_msr_m8, + }, + { + .compatible = "amlogic,meson8b-clk-measure", + .data = (ulong)clk_msr_m8, + }, + { + .compatible = "amlogic,meson-axg-clk-measure", + .data = (ulong)clk_msr_axg, + }, + { + .compatible = "amlogic,meson-g12a-clk-measure", + .data = (ulong)clk_msr_g12a, + }, + { + .compatible = "amlogic,meson-sm1-clk-measure", + .data = (ulong)clk_msr_sm1, + }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(meson_clk_msr) = { + .name = "meson_clk_msr", + .id = UCLASS_CLK, + .of_match = meson_clk_msr_ids, + .priv_auto = sizeof(struct meson_msr), + .ops = &meson_clk_msr_ops, + .probe = meson_clk_msr_probe, +}; diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index 1a7097029ae..f5c9bd735c1 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c @@ -454,7 +454,6 @@ static int armada_37xx_periph_clk_set_parent(struct clk *clk, if (parent->dev != check_parent.dev) ret = -EINVAL; - clk_free(&check_parent); if (ret < 0) return ret; @@ -596,7 +595,6 @@ static int armada_37xx_periph_clk_probe(struct udevice *dev) } priv->parents[i] = clk_get_rate(&clk); - clk_free(&clk); } return 0; diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c index 850d6411190..66ffef96b69 100644 --- a/drivers/clk/renesas/clk-rcar-gen2.c +++ b/drivers/clk/renesas/clk-rcar-gen2.c @@ -10,7 +10,6 @@ * Copyright (C) 2016 Glider bvba */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <errno.h> diff --git a/drivers/clk/renesas/clk-rcar-gen3.c b/drivers/clk/renesas/clk-rcar-gen3.c index 0d274bb986e..196903e406c 100644 --- a/drivers/clk/renesas/clk-rcar-gen3.c +++ b/drivers/clk/renesas/clk-rcar-gen3.c @@ -10,7 +10,6 @@ * Copyright (C) 2016 Glider bvba */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <dm/device-internal.h> diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c index 6f94906cc99..d23041a8026 100644 --- a/drivers/clk/renesas/r8a774a1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c @@ -9,7 +9,6 @@ * Copyright (C) 2016 Glider bvba */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> diff --git a/drivers/clk/renesas/r8a774b1-cpg-mssr.c b/drivers/clk/renesas/r8a774b1-cpg-mssr.c index 1a794980319..81d7dfe5421 100644 --- a/drivers/clk/renesas/r8a774b1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774b1-cpg-mssr.c @@ -9,7 +9,6 @@ * Copyright (C) 2016 Glider bvba */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c index ec8ce6ad7d6..f92fd25c0f7 100644 --- a/drivers/clk/renesas/r8a774c0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774c0-cpg-mssr.c @@ -10,7 +10,6 @@ * Copyright (C) 2015 Renesas Electronics Corp. */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <linux/bitops.h> diff --git a/drivers/clk/renesas/r8a774e1-cpg-mssr.c b/drivers/clk/renesas/r8a774e1-cpg-mssr.c index 6a8fe92b975..7c7cb7b6a05 100644 --- a/drivers/clk/renesas/r8a774e1-cpg-mssr.c +++ b/drivers/clk/renesas/r8a774e1-cpg-mssr.c @@ -9,7 +9,6 @@ * Copyright (C) 2015 Glider bvba */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <linux/bitops.h> diff --git a/drivers/clk/renesas/r8a7790-cpg-mssr.c b/drivers/clk/renesas/r8a7790-cpg-mssr.c index 686f2af0052..190b68ee7d3 100644 --- a/drivers/clk/renesas/r8a7790-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7790-cpg-mssr.c @@ -9,7 +9,6 @@ * Copyright (C) 2013 Ideas On Board SPRL */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <linux/bitops.h> diff --git a/drivers/clk/renesas/r8a7791-cpg-mssr.c b/drivers/clk/renesas/r8a7791-cpg-mssr.c index dcb0fd85c52..30711bf8921 100644 --- a/drivers/clk/renesas/r8a7791-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7791-cpg-mssr.c @@ -9,7 +9,6 @@ * Copyright (C) 2013 Ideas On Board SPRL */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <linux/bitops.h> diff --git a/drivers/clk/renesas/r8a7792-cpg-mssr.c b/drivers/clk/renesas/r8a7792-cpg-mssr.c index 496e51aa73f..623981e9c38 100644 --- a/drivers/clk/renesas/r8a7792-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7792-cpg-mssr.c @@ -9,7 +9,6 @@ * Copyright (C) 2013 Ideas On Board SPRL */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <linux/bitops.h> diff --git a/drivers/clk/renesas/r8a7794-cpg-mssr.c b/drivers/clk/renesas/r8a7794-cpg-mssr.c index f1828a6e543..c4124917923 100644 --- a/drivers/clk/renesas/r8a7794-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7794-cpg-mssr.c @@ -9,7 +9,6 @@ * Copyright (C) 2013 Ideas On Board SPRL */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <linux/bitops.h> diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c index 0e9b9ccf979..e511f74982b 100644 --- a/drivers/clk/renesas/r8a7795-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c @@ -10,7 +10,6 @@ * Copyright (C) 2015 Renesas Electronics Corp. */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <linux/bitops.h> diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c index d741d547ec8..02b078ad3df 100644 --- a/drivers/clk/renesas/r8a7796-cpg-mssr.c +++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c @@ -12,7 +12,6 @@ * Copyright (C) 2015 Renesas Electronics Corp. */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <linux/bitops.h> diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c index cf4503803d0..037861eb9b4 100644 --- a/drivers/clk/renesas/r8a77965-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c @@ -11,7 +11,6 @@ * Copyright (C) 2015 Renesas Electronics Corp. */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <linux/bitops.h> diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c index 32923b423fe..d8bb5aab1fe 100644 --- a/drivers/clk/renesas/r8a77970-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c @@ -9,7 +9,6 @@ * Copyright (C) 2015 Glider bvba */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <linux/bitops.h> diff --git a/drivers/clk/renesas/r8a77980-cpg-mssr.c b/drivers/clk/renesas/r8a77980-cpg-mssr.c index f35032b95f1..9d8335af783 100644 --- a/drivers/clk/renesas/r8a77980-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77980-cpg-mssr.c @@ -10,7 +10,6 @@ * Copyright (C) 2015 Glider bvba */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <linux/bitops.h> diff --git a/drivers/clk/renesas/r8a77990-cpg-mssr.c b/drivers/clk/renesas/r8a77990-cpg-mssr.c index 87b06666c8b..4c9acd76e18 100644 --- a/drivers/clk/renesas/r8a77990-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77990-cpg-mssr.c @@ -10,7 +10,6 @@ * Copyright (C) 2015 Renesas Electronics Corp. */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <linux/bitops.h> diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c index dd2c9483292..f49faa47cb3 100644 --- a/drivers/clk/renesas/r8a77995-cpg-mssr.c +++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c @@ -10,7 +10,6 @@ * Copyright (C) 2015 Renesas Electronics Corp. */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <linux/bitops.h> diff --git a/drivers/clk/renesas/r8a779a0-cpg-mssr.c b/drivers/clk/renesas/r8a779a0-cpg-mssr.c index 652bfe4f6d3..ba086be0268 100644 --- a/drivers/clk/renesas/r8a779a0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779a0-cpg-mssr.c @@ -10,7 +10,6 @@ * Copyright (C) 2015 Renesas Electronics Corp. */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> diff --git a/drivers/clk/renesas/r8a779f0-cpg-mssr.c b/drivers/clk/renesas/r8a779f0-cpg-mssr.c index 643e8b8da97..108655f145d 100644 --- a/drivers/clk/renesas/r8a779f0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779f0-cpg-mssr.c @@ -7,7 +7,6 @@ * Based on r8a779a0-cpg-mssr.c */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> diff --git a/drivers/clk/renesas/r8a779g0-cpg-mssr.c b/drivers/clk/renesas/r8a779g0-cpg-mssr.c index 219024a7416..781806eed58 100644 --- a/drivers/clk/renesas/r8a779g0-cpg-mssr.c +++ b/drivers/clk/renesas/r8a779g0-cpg-mssr.c @@ -7,7 +7,6 @@ * Based on r8a779f0-cpg-mssr.c */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c index d2f61236fee..d207bf615ce 100644 --- a/drivers/clk/renesas/r9a06g032-clocks.c +++ b/drivers/clk/renesas/r9a06g032-clocks.c @@ -7,7 +7,6 @@ * Michel Pollet <michel.pollet@bp.renesas.com>, <buserror@gmail.com> */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <dm/device_compat.h> diff --git a/drivers/clk/renesas/rcar-cpg-lib.c b/drivers/clk/renesas/rcar-cpg-lib.c index a2fca660a8e..8862fbc7579 100644 --- a/drivers/clk/renesas/rcar-cpg-lib.c +++ b/drivers/clk/renesas/rcar-cpg-lib.c @@ -10,7 +10,6 @@ * Copyright (C) 2016 Glider bvba */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <errno.h> diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 10bd54d6002..35bad7f5f73 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -9,7 +9,6 @@ * * Copyright (C) 2016 Glider bvba */ -#include <common.h> #include <clk-uclass.h> #include <dm.h> #include <errno.h> diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c index 034b9b49c05..5d1026b37da 100644 --- a/drivers/cpu/riscv_cpu.c +++ b/drivers/cpu/riscv_cpu.c @@ -11,6 +11,7 @@ #include <errno.h> #include <log.h> #include <asm/global_data.h> +#include <asm/sbi.h> #include <dm/device-internal.h> #include <dm/lists.h> #include <linux/bitops.h> @@ -45,7 +46,6 @@ static int riscv_cpu_get_info(const struct udevice *dev, struct cpu_info *info) ret = clk_get_rate(&clk); if (!IS_ERR_VALUE(ret)) info->cpu_freq = ret; - clk_free(&clk); } if (!info->cpu_freq) @@ -95,13 +95,24 @@ static int riscv_cpu_bind(struct udevice *dev) struct cpu_plat *plat = dev_get_parent_plat(dev); struct driver *drv; int ret; + long mvendorid; /* save the hart id */ plat->cpu_id = dev_read_addr(dev); + /* provide data for SMBIOS */ if (IS_ENABLED(CONFIG_64BIT)) plat->family = 0x201; else plat->family = 0x200; + if (CONFIG_IS_ENABLED(RISCV_SMODE)) { + /* + * For RISC-V CPUs the SMBIOS Processor ID field contains + * the Machine Vendor ID from CSR mvendorid. + */ + ret = sbi_get_mvendorid(&mvendorid); + if (!ret) + plat->id[0] = mvendorid; + } /* first examine the property in current cpu node */ ret = dev_read_u32(dev, "timebase-frequency", &plat->timebase_freq); /* if not found, then look at the parent /cpus node */ @@ -145,7 +156,6 @@ static int riscv_cpu_probe(struct udevice *dev) return 0; ret = clk_enable(&clk); - clk_free(&clk); if (ret == -ENOSYS || ret == -ENOTSUPP) return 0; else diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c index d4cfe0c1868..33c7b981415 100644 --- a/drivers/dma/bcm6348-iudma.c +++ b/drivers/dma/bcm6348-iudma.c @@ -596,8 +596,6 @@ static int bcm6348_iudma_probe(struct udevice *dev) pr_err("error enabling clock %d\n", i); return ret; } - - clk_free(&clk); } /* try to perform resets */ diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c index 1409db5dc11..f80f4afd24f 100644 --- a/drivers/gpio/at91_gpio.c +++ b/drivers/gpio/at91_gpio.c @@ -603,8 +603,6 @@ static int at91_gpio_probe(struct udevice *dev) if (ret) return ret; - clk_free(&clk); - #if CONFIG_IS_ENABLED(OF_CONTROL) plat->base_addr = dev_read_addr(dev); #endif diff --git a/drivers/gpio/atmel_pio4.c b/drivers/gpio/atmel_pio4.c index 47ed2979814..be1dd752bf7 100644 --- a/drivers/gpio/atmel_pio4.c +++ b/drivers/gpio/atmel_pio4.c @@ -310,8 +310,6 @@ static int atmel_pio4_probe(struct udevice *dev) if (ret) return ret; - clk_free(&clk); - addr_base = dev_read_addr(dev); if (addr_base == FDT_ADDR_T_NONE) return -EINVAL; diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index d6cfbd231a8..70778501232 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -165,7 +165,6 @@ static int rcar_gpio_probe(struct udevice *dev) } ret = clk_enable(&clk); - clk_free(&clk); if (ret) { dev_err(dev, "Failed to enable GPIO bank clock\n"); return ret; diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c index 46ed64655a8..346b138e98f 100644 --- a/drivers/hwspinlock/stm32_hwspinlock.c +++ b/drivers/hwspinlock/stm32_hwspinlock.c @@ -69,11 +69,7 @@ static int stm32mp1_hwspinlock_probe(struct udevice *dev) if (ret) return ret; - ret = clk_enable(&clk); - if (ret) - clk_free(&clk); - - return ret; + return clk_enable(&clk); } static const struct hwspinlock_ops stm32mp1_hwspinlock_ops = { diff --git a/drivers/i2c/at91_i2c.c b/drivers/i2c/at91_i2c.c index e743d2a849a..b7a25885e66 100644 --- a/drivers/i2c/at91_i2c.c +++ b/drivers/i2c/at91_i2c.c @@ -201,8 +201,6 @@ static int at91_i2c_enable_clk(struct udevice *dev) bus->bus_clk_rate = clk_rate; - clk_free(&clk); - return 0; } diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index 215ce010cb7..29cf63375c7 100644 --- a/drivers/i2c/designware_i2c.c +++ b/drivers/i2c/designware_i2c.c @@ -770,7 +770,6 @@ int designware_i2c_of_to_plat(struct udevice *bus) ret = clk_enable(&priv->clk); if (ret && ret != -ENOSYS && ret != -ENOTSUPP) { - clk_free(&priv->clk); dev_err(bus, "failed to enable clock\n"); return ret; } @@ -803,7 +802,6 @@ int designware_i2c_remove(struct udevice *dev) #if CONFIG_IS_ENABLED(CLK) clk_disable(&priv->clk); - clk_free(&priv->clk); #endif return reset_release_bulk(&priv->resets); diff --git a/drivers/i2c/i2c-microchip.c b/drivers/i2c/i2c-microchip.c index d82b80f5355..d453e243d6f 100644 --- a/drivers/i2c/i2c-microchip.c +++ b/drivers/i2c/i2c-microchip.c @@ -183,8 +183,6 @@ static int mpfs_i2c_init(struct mpfs_i2c_bus *bus, struct udevice *dev) if (!clk_rate) return -EINVAL; - clk_free(&bus->i2c_clk); - divisor = clk_rate / bus->clk_rate; ctrl = readl(bus->base + MPFS_I2C_CTRL); diff --git a/drivers/i2c/npcm_i2c.c b/drivers/i2c/npcm_i2c.c index b867b6c8e91..c64752e1467 100644 --- a/drivers/i2c/npcm_i2c.c +++ b/drivers/i2c/npcm_i2c.c @@ -570,7 +570,6 @@ static int npcm_i2c_probe(struct udevice *dev) printf("%s: fail to get rate\n", __func__); return -EINVAL; } - clk_free(&clk); bus->num = dev->seq_; bus->reg = dev_read_addr_ptr(dev); diff --git a/drivers/i2c/ocores_i2c.c b/drivers/i2c/ocores_i2c.c index 3b19ba78fa3..fff85118d0d 100644 --- a/drivers/i2c/ocores_i2c.c +++ b/drivers/i2c/ocores_i2c.c @@ -396,8 +396,6 @@ static int ocores_i2c_enable_clk(struct udevice *dev) bus->ip_clk_khz = clk_rate / 1000; - clk_free(&bus->clk); - return 0; } diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c index eaa1d692898..f42e08a6418 100644 --- a/drivers/i2c/stm32f7_i2c.c +++ b/drivers/i2c/stm32f7_i2c.c @@ -890,7 +890,7 @@ static int stm32_i2c_probe(struct udevice *dev) ret = clk_enable(&i2c_priv->clk); if (ret) - goto clk_free; + return ret; ret = reset_get_by_index(dev, 0, &reset_ctl); if (ret) @@ -904,8 +904,6 @@ static int stm32_i2c_probe(struct udevice *dev) clk_disable: clk_disable(&i2c_priv->clk); -clk_free: - clk_free(&i2c_priv->clk); return ret; } diff --git a/drivers/mailbox/stm32-ipcc.c b/drivers/mailbox/stm32-ipcc.c index 69c86e059f5..046e1a8aca6 100644 --- a/drivers/mailbox/stm32-ipcc.c +++ b/drivers/mailbox/stm32-ipcc.c @@ -134,18 +134,13 @@ static int stm32_ipcc_probe(struct udevice *dev) ret = clk_enable(&clk); if (ret) - goto clk_free; + return ret; /* get channel number */ ipcc->n_chans = readl(ipcc->reg_base + IPCC_HWCFGR); ipcc->n_chans &= IPCFGR_CHAN_MASK; return 0; - -clk_free: - clk_free(&clk); - - return ret; } static const struct udevice_id stm32_ipcc_ids[] = { diff --git a/drivers/misc/ls2_sfp.c b/drivers/misc/ls2_sfp.c index 2a81bc7de5f..5351c7ed34f 100644 --- a/drivers/misc/ls2_sfp.c +++ b/drivers/misc/ls2_sfp.c @@ -249,7 +249,6 @@ static int ls2_sfp_probe(struct udevice *dev) } rate = clk_get_rate(&clk); - clk_free(&clk); if (!rate || IS_ERR_VALUE(rate)) { ret = rate ? rate : -ENOENT; dev_dbg(dev, "could not get clock rate (err %d)\n", diff --git a/drivers/misc/qfw_smbios.c b/drivers/misc/qfw_smbios.c index 9019345783f..c3e8c310d00 100644 --- a/drivers/misc/qfw_smbios.c +++ b/drivers/misc/qfw_smbios.c @@ -90,7 +90,7 @@ static int qfw_parse_smbios_anchor(struct udevice *dev, entry->length = sizeof(struct smbios3_entry); entry->major_ver = entry2->major_ver; entry->minor_ver = entry2->minor_ver; - entry->max_struct_size = entry2->max_struct_size; + entry->table_maximum_size = entry2->struct_table_length; } else { ret = -ENOENT; goto out; diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 9c5d48e90cd..5cf5502ed54 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -447,7 +447,6 @@ static int arm_pl180_mmc_probe(struct udevice *dev) ret = clk_enable(&clk); if (ret) { - clk_free(&clk); dev_err(dev, "failed to enable clock\n"); return ret; } diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c index 9d79bf58cc7..c9626c6beb8 100644 --- a/drivers/mmc/aspeed_sdhci.c +++ b/drivers/mmc/aspeed_sdhci.c @@ -35,7 +35,7 @@ static int aspeed_sdhci_probe(struct udevice *dev) ret = clk_enable(&clk); if (ret) { debug("%s: clock enable failed %d\n", __func__, ret); - goto free; + return ret; } host->name = dev->name; @@ -66,8 +66,6 @@ static int aspeed_sdhci_probe(struct udevice *dev) err: clk_disable(&clk); -free: - clk_free(&clk); return ret; } diff --git a/drivers/mmc/atmel_sdhci.c b/drivers/mmc/atmel_sdhci.c index 5347ba90431..d92bad97b71 100644 --- a/drivers/mmc/atmel_sdhci.c +++ b/drivers/mmc/atmel_sdhci.c @@ -147,8 +147,6 @@ static int atmel_sdhci_probe(struct udevice *dev) host->ops = &atmel_sdhci_ops; upriv->mmc = host->mmc; - clk_free(&clk); - ret = sdhci_probe(dev); if (ret) return ret; diff --git a/drivers/mmc/bcmstb_sdhci.c b/drivers/mmc/bcmstb_sdhci.c index dc96818cff4..49846adcf54 100644 --- a/drivers/mmc/bcmstb_sdhci.c +++ b/drivers/mmc/bcmstb_sdhci.c @@ -38,15 +38,52 @@ */ #define BCMSTB_SDHCI_MINIMUM_CLOCK_FREQUENCY 400000 -/* - * This driver has only been tested with eMMC devices; SD devices may - * not work. - */ +#define SDIO_CFG_CTRL 0x0 +#define SDIO_CFG_CTRL_SDCD_N_TEST_EN BIT(31) +#define SDIO_CFG_CTRL_SDCD_N_TEST_LEV BIT(30) + +#define SDIO_CFG_SD_PIN_SEL 0x44 +#define SDIO_CFG_SD_PIN_SEL_MASK 0x3 +#define SDIO_CFG_SD_PIN_SEL_CARD BIT(1) + struct sdhci_bcmstb_plat { struct mmc_config cfg; struct mmc mmc; }; +struct sdhci_brcmstb_dev_priv { + int (*init)(struct udevice *dev); +}; + +static int sdhci_brcmstb_init_2712(struct udevice *dev) +{ + struct sdhci_host *host = dev_get_priv(dev); + void *cfg_regs; + u32 reg; + + /* Map in the non-standard CFG registers */ + cfg_regs = dev_remap_addr_name(dev, "cfg"); + if (!cfg_regs) + return -ENOENT; + + if ((host->mmc->host_caps & MMC_CAP_NONREMOVABLE) || + (host->mmc->host_caps & MMC_CAP_NEEDS_POLL)) { + /* Force presence */ + reg = readl(cfg_regs + SDIO_CFG_CTRL); + reg &= ~SDIO_CFG_CTRL_SDCD_N_TEST_LEV; + reg |= SDIO_CFG_CTRL_SDCD_N_TEST_EN; + writel(reg, cfg_regs + SDIO_CFG_CTRL); + } else { + /* Enable card detection line */ + reg = readl(cfg_regs + SDIO_CFG_SD_PIN_SEL); + reg &= ~SDIO_CFG_SD_PIN_SEL_MASK; + reg |= SDIO_CFG_SD_PIN_SEL_CARD; + writel(reg, cfg_regs + SDIO_CFG_SD_PIN_SEL); + } + + return 0; +} + static int sdhci_bcmstb_bind(struct udevice *dev) { struct sdhci_bcmstb_plat *plat = dev_get_plat(dev); @@ -54,14 +91,20 @@ static int sdhci_bcmstb_bind(struct udevice *dev) return sdhci_bind(dev, &plat->mmc, &plat->cfg); } +/* No specific SDHCI operations are required */ +static const struct sdhci_ops bcmstb_sdhci_ops = { 0 }; + static int sdhci_bcmstb_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct sdhci_bcmstb_plat *plat = dev_get_plat(dev); struct sdhci_host *host = dev_get_priv(dev); + struct sdhci_brcmstb_dev_priv *dev_priv; fdt_addr_t base; int ret; + dev_priv = (struct sdhci_brcmstb_dev_priv *)dev_get_driver_data(dev); + base = dev_read_addr(dev); if (base == FDT_ADDR_T_NONE) return -EINVAL; @@ -75,6 +118,8 @@ static int sdhci_bcmstb_probe(struct udevice *dev) host->mmc = &plat->mmc; host->mmc->dev = dev; + host->ops = &bcmstb_sdhci_ops; + ret = sdhci_setup_cfg(&plat->cfg, host, BCMSTB_SDHCI_MAXIMUM_CLOCK_FREQUENCY, BCMSTB_SDHCI_MINIMUM_CLOCK_FREQUENCY); @@ -84,10 +129,21 @@ static int sdhci_bcmstb_probe(struct udevice *dev) upriv->mmc = &plat->mmc; host->mmc->priv = host; + if (dev_priv && dev_priv->init) { + ret = dev_priv->init(dev); + if (ret) + return ret; + } + return sdhci_probe(dev); } +static const struct sdhci_brcmstb_dev_priv match_priv_2712 = { + .init = sdhci_brcmstb_init_2712, +}; + static const struct udevice_id sdhci_bcmstb_match[] = { + { .compatible = "brcm,bcm2712-sdhci", .data = (ulong)&match_priv_2712 }, { .compatible = "brcm,bcm7425-sdhci" }, { .compatible = "brcm,sdhci-brcmstb" }, { } diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index d91819acfd7..3ee99558f6f 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -559,27 +559,20 @@ static int atmel_mci_enable_clk(struct udevice *dev) int ret = 0; ret = clk_get_by_index(dev, 0, &clk); - if (ret) { - ret = -EINVAL; - goto failed; - } + if (ret) + return -EINVAL; ret = clk_enable(&clk); if (ret) - goto failed; + return ret; clk_rate = clk_get_rate(&clk); - if (!clk_rate) { - ret = -EINVAL; - goto failed; - } + if (!clk_rate) + return -EINVAL; priv->bus_clk_rate = clk_rate; -failed: - clk_free(&clk); - - return ret; + return 0; } static int atmel_mci_probe(struct udevice *dev) diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c index 604f9c3ff99..fe1e754bfde 100644 --- a/drivers/mmc/msm_sdhci.c +++ b/drivers/mmc/msm_sdhci.c @@ -81,7 +81,6 @@ static int msm_sdc_clk_init(struct udevice *dev) return ret; ret = clk_set_rate(&clk, clk_rate); - clk_free(&clk); if (ret < 0) return ret; diff --git a/drivers/mmc/pic32_sdhci.c b/drivers/mmc/pic32_sdhci.c index fe555106a1d..7a8e33dbc7a 100644 --- a/drivers/mmc/pic32_sdhci.c +++ b/drivers/mmc/pic32_sdhci.c @@ -32,7 +32,6 @@ static int pic32_sdhci_probe(struct udevice *dev) return ret; clk_rate = clk_get_rate(&clk); - clk_free(&clk); if (IS_ERR_VALUE(clk_rate)) return clk_rate; diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index 97aaf1e4ec3..a74559ca686 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -979,19 +979,19 @@ static int rzg2l_sdhi_setup(struct udevice *dev) ret = clk_get_by_name(dev, "cd", &imclk2); if (ret < 0) { dev_err(dev, "failed to get imclk2 (chip detect clk)\n"); - goto err_get_imclk2; + return ret; } ret = clk_get_by_name(dev, "aclk", &aclk); if (ret < 0) { dev_err(dev, "failed to get aclk\n"); - goto err_get_aclk; + return ret; } ret = clk_enable(&imclk2); if (ret < 0) { dev_err(dev, "failed to enable imclk2 (chip detect clk)\n"); - goto err_imclk2; + return ret; } ret = clk_enable(&aclk); @@ -1026,11 +1026,6 @@ err_get_reset: clk_disable(&aclk); err_aclk: clk_disable(&imclk2); -err_imclk2: - clk_free(&aclk); -err_get_aclk: - clk_free(&imclk2); -err_get_imclk2: return ret; } @@ -1071,7 +1066,7 @@ static int renesas_sdhi_probe(struct udevice *dev) ret = clk_set_rate(&priv->clkh, 800000000); if (ret < 0) { dev_err(dev, "failed to set rate for SDnH clock (%d)\n", ret); - goto err_clk; + return ret; } } @@ -1079,13 +1074,13 @@ static int renesas_sdhi_probe(struct udevice *dev) ret = clk_set_rate(&priv->clk, 200000000); if (ret < 0) { dev_err(dev, "failed to set rate for SDn clock (%d)\n", ret); - goto err_clkh; + return ret; } ret = clk_enable(&priv->clk); if (ret) { dev_err(dev, "failed to enable SDn clock (%d)\n", ret); - goto err_clkh; + return ret; } if (device_is_compatible(dev, "renesas,sdhi-r9a07g044")) @@ -1107,10 +1102,6 @@ static int renesas_sdhi_probe(struct udevice *dev) err_tmio_probe: clk_disable(&priv->clk); -err_clkh: - clk_free(&priv->clkh); -err_clk: - clk_free(&priv->clk); return ret; } diff --git a/drivers/mmc/snps_dw_mmc.c b/drivers/mmc/snps_dw_mmc.c index 50a8805e736..0134399e393 100644 --- a/drivers/mmc/snps_dw_mmc.c +++ b/drivers/mmc/snps_dw_mmc.c @@ -46,7 +46,7 @@ static int snps_dwmmc_clk_setup(struct udevice *dev) ret = clk_enable(&clk_ciu); if (ret && ret != -ENOSYS && ret != -ENOTSUPP) - goto clk_err_ciu; + goto clk_err; host->bus_hz = clk_get_rate(&clk_ciu); if (host->bus_hz < CLOCK_MIN) { @@ -60,16 +60,12 @@ static int snps_dwmmc_clk_setup(struct udevice *dev) ret = clk_enable(&clk_biu); if (ret && ret != -ENOSYS && ret != -ENOTSUPP) - goto clk_err_biu; + goto clk_err_ciu_dis; return 0; -clk_err_biu: - clk_free(&clk_biu); clk_err_ciu_dis: clk_disable(&clk_ciu); -clk_err_ciu: - clk_free(&clk_ciu); clk_err: dev_err(dev, "failed to setup clocks, ret %d\n", ret); diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c index be3d8bfb3d7..387cb8b6b50 100644 --- a/drivers/mmc/socfpga_dw_mmc.c +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -99,7 +99,6 @@ static int socfpga_dwmmc_get_clk_rate(struct udevice *dev) host->bus_hz = clk_get_rate(&clk); - clk_free(&clk); #else /* Fixed clock divide by 4 which due to the SDMMC wrapper */ host->bus_hz = cm_get_mmc_controller_clk_hz(); diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c index 5ff5e1a4d8b..a2b111a8435 100644 --- a/drivers/mmc/stm32_sdmmc2.c +++ b/drivers/mmc/stm32_sdmmc2.c @@ -766,10 +766,8 @@ static int stm32_sdmmc2_probe(struct udevice *dev) int ret; ret = clk_enable(&plat->clk); - if (ret) { - clk_free(&plat->clk); + if (ret) return ret; - } upriv->mmc = &plat->mmc; diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c index 75003a0113e..8cde4308aae 100644 --- a/drivers/mmc/uniphier-sd.c +++ b/drivers/mmc/uniphier-sd.c @@ -64,7 +64,6 @@ static int uniphier_sd_probe(struct udevice *dev) ret = clk_set_rate(&priv->clk, ULONG_MAX); if (ret < 0) { dev_err(dev, "failed to set rate for host clock\n"); - clk_free(&priv->clk); return ret; } diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index a2151f98491..0e0441472b8 100644 --- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -1999,10 +1999,8 @@ atmel_hsmc_nand_controller_remove(struct atmel_nand_controller *nc) hsmc_nc = container_of(nc, struct atmel_hsmc_nand_controller, base); - if (hsmc_nc->clk) { + if (hsmc_nc->clk) clk_disable_unprepare(hsmc_nc->clk); - devm_clk_put(nc->dev, hsmc_nc->clk); - } return 0; } diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c index e2e3f1ee6b5..51f6bd2e65b 100644 --- a/drivers/mtd/nand/raw/atmel/pmecc.c +++ b/drivers/mtd/nand/raw/atmel/pmecc.c @@ -816,9 +816,6 @@ int atmel_pmecc_wait_rdy(struct atmel_pmecc_user *user) } EXPORT_SYMBOL_GPL(atmel_pmecc_wait_rdy); -#define ATMEL_BASE_PMECC 0xffffe000 -#define ATMEL_BASE_PMERRLOC 0xffffe600 - static struct atmel_pmecc * atmel_pmecc_create(struct udevice *dev, const struct atmel_pmecc_caps *caps, diff --git a/drivers/mtd/renesas_rpc_hf.c b/drivers/mtd/renesas_rpc_hf.c index aca7a6cdd25..979b64d4a2f 100644 --- a/drivers/mtd/renesas_rpc_hf.c +++ b/drivers/mtd/renesas_rpc_hf.c @@ -370,7 +370,6 @@ static int rpc_hf_probe(struct udevice *dev) } ret = clk_enable(&clk); - clk_free(&clk); if (ret) { dev_err(dev, "Failed to enable RPC clock\n"); return ret; diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 3f5f3c89ac1..f86003ca8c0 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -331,18 +331,42 @@ static int spansion_read_any_reg(struct spi_nor *nor, u32 addr, u8 dummy, u8 *val) { struct spi_mem_op op = - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDAR, 1), - SPI_MEM_OP_ADDR(nor->addr_mode_nbytes, addr, 1), - SPI_MEM_OP_DUMMY(dummy / 8, 1), - SPI_MEM_OP_DATA_IN(1, NULL, 1)); + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 0), + SPI_MEM_OP_ADDR(nor->addr_mode_nbytes, addr, 0), + SPI_MEM_OP_DUMMY(dummy, 0), + SPI_MEM_OP_DATA_IN(1, NULL, 0)); + u8 buf[2]; + int ret; + + spi_nor_setup_op(nor, &op, nor->reg_proto); + + /* + * In Octal DTR mode, the number of address bytes is always 4 regardless + * of addressing mode setting. + */ + if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) + op.addr.nbytes = 4; + + /* + * We don't want to read only one byte in DTR mode. So, read 2 and then + * discard the second byte. + */ + if (spi_nor_protocol_is_dtr(nor->reg_proto)) + op.data.nbytes = 2; - return spi_nor_read_write_reg(nor, &op, val); + ret = spi_nor_read_write_reg(nor, &op, buf); + if (ret) + return ret; + + *val = buf[0]; + + return 0; } static int spansion_write_any_reg(struct spi_nor *nor, u32 addr, u8 val) { struct spi_mem_op op = - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRAR, 1), + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1), SPI_MEM_OP_ADDR(nor->addr_mode_nbytes, addr, 1), SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_OUT(1, NULL, 1)); @@ -714,7 +738,7 @@ static int set_4byte(struct spi_nor *nor, const struct flash_info *info, */ static int spansion_sr_ready(struct spi_nor *nor, u32 addr_base, u8 dummy) { - u32 reg_addr = addr_base + SPINOR_REG_ADDR_STR1V; + u32 reg_addr = addr_base + SPINOR_REG_CYPRESS_STR1V; u8 sr; int ret; @@ -728,7 +752,7 @@ static int spansion_sr_ready(struct spi_nor *nor, u32 addr_base, u8 dummy) else dev_dbg(nor->dev, "Programming Error occurred\n"); - nor->write_reg(nor, SPINOR_OP_CLSR, NULL, 0); + nor->write_reg(nor, SPINOR_OP_CYPRESS_CLPEF, NULL, 0); return -EIO; } @@ -1856,7 +1880,7 @@ static int macronix_quad_enable(struct spi_nor *nor) static int spansion_quad_enable_volatile(struct spi_nor *nor, u32 addr_base, u8 dummy) { - u32 addr = addr_base + SPINOR_REG_ADDR_CFR1V; + u32 addr = addr_base + SPINOR_REG_CYPRESS_CFR1V; u8 cr; int ret; @@ -3293,11 +3317,11 @@ static int s25fs_s_setup(struct spi_nor *nor, const struct flash_info *info, * Read CR3V to check if uniform sector is selected. If not, assign an * erase hook that supports non-uniform erase. */ - ret = spansion_read_any_reg(nor, SPINOR_REG_ADDR_CFR3V, + ret = spansion_read_any_reg(nor, SPINOR_REG_CYPRESS_CFR3V, S25FS_S_RDAR_DUMMY, &cfr3v); if (ret) return ret; - if (!(cfr3v & CFR3V_UNHYSA)) + if (!(cfr3v & SPINOR_REG_CYPRESS_CFR3_UNISECT)) nor->erase = s25fs_s_erase_non_uniform; return spi_nor_default_setup(nor, info, params); @@ -3346,13 +3370,13 @@ static struct spi_nor_fixups s25fs_s_fixups = { .post_sfdp = s25fs_s_post_sfdp_fixup, }; -static int s25_mdp_ready(struct spi_nor *nor) +static int s25_s28_mdp_ready(struct spi_nor *nor) { u32 addr; int ret; for (addr = 0; addr < nor->mtd.size; addr += SZ_128M) { - ret = spansion_sr_ready(nor, addr, 0); + ret = spansion_sr_ready(nor, addr, nor->rdsr_dummy); if (!ret) return ret; } @@ -3374,15 +3398,15 @@ static int s25_quad_enable(struct spi_nor *nor) return 0; } -static int s25_erase_non_uniform(struct spi_nor *nor, loff_t addr) +static int s25_s28_erase_non_uniform(struct spi_nor *nor, loff_t addr) { /* Support 32 x 4KB sectors at bottom */ return spansion_erase_non_uniform(nor, addr, SPINOR_OP_BE_4K_4B, 0, SZ_128K); } -static int s25_setup(struct spi_nor *nor, const struct flash_info *info, - const struct spi_nor_flash_parameter *params) +static int s25_s28_setup(struct spi_nor *nor, const struct flash_info *info, + const struct spi_nor_flash_parameter *params) { int ret; u8 cr; @@ -3396,7 +3420,8 @@ static int s25_setup(struct spi_nor *nor, const struct flash_info *info, * uniform 128KB only due to complexity of non-uniform layout. */ if (nor->info->id[4] == S25FS256T_ID4) { - ret = spansion_read_any_reg(nor, SPINOR_REG_ADDR_ARCFN, 8, &cr); + ret = spansion_read_any_reg(nor, SPINOR_REG_CYPRESS_ARCFN, 8, + &cr); if (ret) return ret; @@ -3410,31 +3435,31 @@ static int s25_setup(struct spi_nor *nor, const struct flash_info *info, * Read CFR3V to check if uniform sector is selected. If not, assign an * erase hook that supports non-uniform erase. */ - ret = spansion_read_any_reg(nor, SPINOR_REG_ADDR_CFR3V, 0, &cr); + ret = spansion_read_any_reg(nor, SPINOR_REG_CYPRESS_CFR3V, 0, &cr); if (ret) return ret; - if (!(cr & CFR3V_UNHYSA)) - nor->erase = s25_erase_non_uniform; + if (!(cr & SPINOR_REG_CYPRESS_CFR3_UNISECT)) + nor->erase = s25_s28_erase_non_uniform; /* * For the multi-die package parts, the ready() hook is needed to check * all dies' status via read any register. */ if (nor->mtd.size > SZ_128M) - nor->ready = s25_mdp_ready; + nor->ready = s25_s28_mdp_ready; return spi_nor_default_setup(nor, info, params); } static void s25_default_init(struct spi_nor *nor) { - nor->setup = s25_setup; + nor->setup = s25_s28_setup; } -static int s25_post_bfpt_fixup(struct spi_nor *nor, - const struct sfdp_parameter_header *header, - const struct sfdp_bfpt *bfpt, - struct spi_nor_flash_parameter *params) +static int s25_s28_post_bfpt_fixup(struct spi_nor *nor, + const struct sfdp_parameter_header *header, + const struct sfdp_bfpt *bfpt, + struct spi_nor_flash_parameter *params) { int ret; u32 addr; @@ -3474,12 +3499,13 @@ static int s25_post_bfpt_fixup(struct spi_nor *nor, * dies are configured to 512B buffer. */ for (addr = 0; addr < params->size; addr += SZ_128M) { - ret = spansion_read_any_reg(nor, addr + SPINOR_REG_ADDR_CFR3V, - 0, &cfr3v); + ret = spansion_read_any_reg(nor, + addr + SPINOR_REG_CYPRESS_CFR3V, 0, + &cfr3v); if (ret) return ret; - if (!(cfr3v & CFR3V_PGMBUF)) { + if (!(cfr3v & SPINOR_REG_CYPRESS_CFR3_PGSZ)) { params->page_size = 256; return 0; } @@ -3507,7 +3533,7 @@ static void s25_post_sfdp_fixup(struct spi_nor *nor, static struct spi_nor_fixups s25_fixups = { .default_init = s25_default_init, - .post_bfpt = s25_post_bfpt_fixup, + .post_bfpt = s25_s28_post_bfpt_fixup, .post_sfdp = s25_post_sfdp_fixup, }; @@ -3539,97 +3565,57 @@ static struct spi_nor_fixups s25fl256l_fixups = { */ static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor) { - struct spi_mem_op op; + u32 addr; u8 buf; - u8 addr_width = 3; int ret; - /* Use 24 dummy cycles for memory array reads. */ ret = write_enable(nor); if (ret) return ret; - buf = SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24; - op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1), - SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR2V, 1), - SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_OUT(1, &buf, 1)); - ret = spi_mem_exec_op(nor->spi, &op); - if (ret) { - dev_warn(nor->dev, - "failed to set default memory latency value: %d\n", - ret); - return ret; - } - ret = spi_nor_wait_till_ready(nor); - if (ret) - return ret; + /* Use 24 dummy cycles for memory array reads. */ + for (addr = 0; addr < nor->mtd.size; addr += SZ_128M) { + ret = spansion_read_any_reg(nor, + addr + SPINOR_REG_CYPRESS_CFR2V, 0, + &buf); + if (ret) + return ret; + buf &= ~SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK; + buf |= SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24; + ret = spansion_write_any_reg(nor, + addr + SPINOR_REG_CYPRESS_CFR2V, + buf); + if (ret) { + dev_warn(nor->dev, "failed to set default memory latency value: %d\n", ret); + return ret; + } + } nor->read_dummy = 24; - /* Set the octal and DTR enable bits. */ ret = write_enable(nor); if (ret) return ret; + /* Set the octal and DTR enable bits. */ buf = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN; - op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1), - SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR5V, 1), - SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_OUT(1, &buf, 1)); - ret = spi_mem_exec_op(nor->spi, &op); - if (ret) { - dev_warn(nor->dev, "Failed to enable octal DTR mode\n"); - return ret; + for (addr = 0; addr < nor->mtd.size; addr += SZ_128M) { + ret = spansion_write_any_reg(nor, + addr + SPINOR_REG_CYPRESS_CFR5V, + buf); + if (ret) { + dev_warn(nor->dev, "Failed to enable octal DTR mode\n"); + return ret; + } } return 0; } -static int s28hx_t_erase_non_uniform(struct spi_nor *nor, loff_t addr) -{ - /* Factory default configuration: 32 x 4 KiB sectors at bottom. */ - return spansion_erase_non_uniform(nor, addr, SPINOR_OP_S28_SE_4K, - 0, SZ_128K); -} - -static int s28hx_t_setup(struct spi_nor *nor, const struct flash_info *info, - const struct spi_nor_flash_parameter *params) -{ - struct spi_mem_op op; - u8 buf; - u8 addr_width = 3; - int ret; - - ret = spi_nor_wait_till_ready(nor); - if (ret) - return ret; - - /* - * Check CFR3V to check if non-uniform sector mode is selected. If it - * is, set the erase hook to the non-uniform erase procedure. - */ - op = (struct spi_mem_op) - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 1), - SPI_MEM_OP_ADDR(addr_width, - SPINOR_REG_CYPRESS_CFR3V, 1), - SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_IN(1, &buf, 1)); - - ret = spi_mem_exec_op(nor->spi, &op); - if (ret) - return ret; - - if (!(buf & SPINOR_REG_CYPRESS_CFR3_UNISECT)) - nor->erase = s28hx_t_erase_non_uniform; - - return spi_nor_default_setup(nor, info, params); -} - static void s28hx_t_default_init(struct spi_nor *nor) { nor->octal_dtr_enable = spi_nor_cypress_octal_dtr_enable; - nor->setup = s28hx_t_setup; + nor->setup = s25_s28_setup; } static void s28hx_t_post_sfdp_fixup(struct spi_nor *nor, @@ -3663,50 +3649,10 @@ static void s28hx_t_post_sfdp_fixup(struct spi_nor *nor, params->rdsr_addr_nbytes = 4; } -static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor, - const struct sfdp_parameter_header *bfpt_header, - const struct sfdp_bfpt *bfpt, - struct spi_nor_flash_parameter *params) -{ - struct spi_mem_op op; - u8 buf; - u8 addr_width = 3; - int ret; - - /* - * The BFPT table advertises a 512B page size but the page size is - * actually configurable (with the default being 256B). Read from - * CFR3V[4] and set the correct size. - */ - op = (struct spi_mem_op) - SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 1), - SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR3V, 1), - SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_IN(1, &buf, 1)); - ret = spi_mem_exec_op(nor->spi, &op); - if (ret) - return ret; - - if (buf & SPINOR_REG_CYPRESS_CFR3_PGSZ) - params->page_size = 512; - else - params->page_size = 256; - - /* - * The BFPT advertises that it supports 4k erases, and the datasheet - * says the same. But 4k erases did not work when testing. So, use 256k - * erases for now. - */ - nor->erase_opcode = SPINOR_OP_SE_4B; - nor->mtd.erasesize = 0x40000; - - return 0; -} - static struct spi_nor_fixups s28hx_t_fixups = { .default_init = s28hx_t_default_init, .post_sfdp = s28hx_t_post_sfdp_fixup, - .post_bfpt = s28hx_t_post_bfpt_fixup, + .post_bfpt = s25_s28_post_bfpt_fixup, }; #endif /* CONFIG_SPI_FLASH_S28HX_T */ diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c index 8db522fca06..38a287487ed 100644 --- a/drivers/mtd/spi/spi-nor-ids.c +++ b/drivers/mtd/spi/spi-nor-ids.c @@ -239,6 +239,8 @@ const struct flash_info spi_nor_ids[] = { SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("is25wx256", 0x9d5b19, 0, 128 * 1024, 256, SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) }, + { INFO("is25lx512", 0x9d5a1a, 0, 64 * 1024, 1024, + SECT_4K | USE_FSR | SPI_NOR_4B_OPCODES | SPI_NOR_HAS_TB) }, #endif #ifdef CONFIG_SPI_FLASH_MACRONIX /* MACRONIX */ /* Macronix */ @@ -381,6 +383,7 @@ const struct flash_info spi_nor_ids[] = { { INFO("s28hl01gt", 0x345a1b, 0, 256 * 1024, 512, SPI_NOR_OCTAL_DTR_READ) }, { INFO("s28hs512t", 0x345b1a, 0, 256 * 1024, 256, SPI_NOR_OCTAL_DTR_READ) }, { INFO("s28hs01gt", 0x345b1b, 0, 256 * 1024, 512, SPI_NOR_OCTAL_DTR_READ) }, + { INFO("s28hs02gt", 0x345b1c, 0, 256 * 1024, 1024, SPI_NOR_OCTAL_DTR_READ) }, #endif #endif #ifdef CONFIG_SPI_FLASH_SST /* SST */ @@ -554,6 +557,10 @@ const struct flash_info spi_nor_ids[] = { { INFO("XM25QH64C", 0x204017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("XM25QH128A", 0x207018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { INFO("XM25QU128C", 0x204118, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { INFO("XM25QH256C", 0x204019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, + { INFO("XM25QU256C", 0x204119, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, + { INFO("XM25QH512C", 0x204020, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, + { INFO("XM25QU512C", 0x204120, 0, 64 * 1024, 1024, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) }, #endif #ifdef CONFIG_SPI_FLASH_XTX /* XTX Technology Limited */ diff --git a/drivers/net/bcm6348-eth.c b/drivers/net/bcm6348-eth.c index 72dcd07d30d..15a94f6ce9a 100644 --- a/drivers/net/bcm6348-eth.c +++ b/drivers/net/bcm6348-eth.c @@ -457,8 +457,6 @@ static int bcm6348_eth_probe(struct udevice *dev) pr_err("%s: error enabling clock %d\n", __func__, i); return ret; } - - clk_free(&clk); } /* try to perform resets */ diff --git a/drivers/net/bcm6368-eth.c b/drivers/net/bcm6368-eth.c index fdd938ce0dd..9679a45b075 100644 --- a/drivers/net/bcm6368-eth.c +++ b/drivers/net/bcm6368-eth.c @@ -546,8 +546,6 @@ static int bcm6368_eth_probe(struct udevice *dev) pr_err("%s: error enabling clock %d\n", __func__, i); return ret; } - - clk_free(&clk); } /* try to perform resets */ diff --git a/drivers/net/designware.c b/drivers/net/designware.c index a174344b3ef..c8696358d6f 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -702,7 +702,6 @@ int designware_eth_probe(struct udevice *dev) err = clk_enable(&priv->clocks[i]); if (err && err != -ENOSYS && err != -ENOTSUPP) { pr_err("failed to enable clock %d\n", i); - clk_free(&priv->clocks[i]); goto clk_err; } priv->clock_count++; diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index e40e399c802..9b3bce1dc87 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1382,38 +1382,30 @@ static int eqos_probe_resources_tegra186(struct udevice *dev) ret = clk_get_by_name(dev, "master_bus", &eqos->clk_master_bus); if (ret) { pr_err("clk_get_by_name(master_bus) failed: %d", ret); - goto err_free_clk_slave_bus; + goto err_free_gpio_phy_reset; } ret = clk_get_by_name(dev, "rx", &eqos->clk_rx); if (ret) { pr_err("clk_get_by_name(rx) failed: %d", ret); - goto err_free_clk_master_bus; + goto err_free_gpio_phy_reset; } ret = clk_get_by_name(dev, "ptp_ref", &eqos->clk_ptp_ref); if (ret) { pr_err("clk_get_by_name(ptp_ref) failed: %d", ret); - goto err_free_clk_rx; + goto err_free_gpio_phy_reset; } ret = clk_get_by_name(dev, "tx", &eqos->clk_tx); if (ret) { pr_err("clk_get_by_name(tx) failed: %d", ret); - goto err_free_clk_ptp_ref; + goto err_free_gpio_phy_reset; } debug("%s: OK\n", __func__); return 0; -err_free_clk_ptp_ref: - clk_free(&eqos->clk_ptp_ref); -err_free_clk_rx: - clk_free(&eqos->clk_rx); -err_free_clk_master_bus: - clk_free(&eqos->clk_master_bus); -err_free_clk_slave_bus: - clk_free(&eqos->clk_slave_bus); err_free_gpio_phy_reset: dm_gpio_free(dev, &eqos->phy_reset_gpio); err_free_reset_eqos: @@ -1451,13 +1443,13 @@ static int eqos_probe_resources_stm32(struct udevice *dev) ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx); if (ret) { pr_err("clk_get_by_name(rx) failed: %d", ret); - goto err_free_clk_master_bus; + goto err_probe; } ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx); if (ret) { pr_err("clk_get_by_name(tx) failed: %d", ret); - goto err_free_clk_rx; + goto err_probe; } /* Get ETH_CLK clocks (optional) */ @@ -1468,10 +1460,6 @@ static int eqos_probe_resources_stm32(struct udevice *dev) debug("%s: OK\n", __func__); return 0; -err_free_clk_rx: - clk_free(&eqos->clk_rx); -err_free_clk_master_bus: - clk_free(&eqos->clk_master_bus); err_probe: debug("%s: returns %d\n", __func__, ret); @@ -1489,13 +1477,6 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); -#ifdef CONFIG_CLK - clk_free(&eqos->clk_tx); - clk_free(&eqos->clk_ptp_ref); - clk_free(&eqos->clk_rx); - clk_free(&eqos->clk_slave_bus); - clk_free(&eqos->clk_master_bus); -#endif dm_gpio_free(dev, &eqos->phy_reset_gpio); reset_free(&eqos->reset_ctl); @@ -1505,19 +1486,7 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) static int eqos_remove_resources_stm32(struct udevice *dev) { - struct eqos_priv * __maybe_unused eqos = dev_get_priv(dev); - debug("%s(dev=%p):\n", __func__, dev); - -#ifdef CONFIG_CLK - clk_free(&eqos->clk_tx); - clk_free(&eqos->clk_rx); - clk_free(&eqos->clk_master_bus); - if (clk_valid(&eqos->clk_ck)) - clk_free(&eqos->clk_ck); -#endif - - debug("%s: OK\n", __func__); return 0; } diff --git a/drivers/net/dwc_eth_qos_imx.c b/drivers/net/dwc_eth_qos_imx.c index e3f55dd9817..9c4e3904413 100644 --- a/drivers/net/dwc_eth_qos_imx.c +++ b/drivers/net/dwc_eth_qos_imx.c @@ -70,30 +70,24 @@ static int eqos_probe_resources_imx(struct udevice *dev) ret = clk_get_by_name(dev, "ptp_ref", &eqos->clk_ptp_ref); if (ret) { dev_dbg(dev, "clk_get_by_name(ptp_ref) failed: %d", ret); - goto err_free_clk_master_bus; + goto err_probe; } ret = clk_get_by_name(dev, "tx", &eqos->clk_tx); if (ret) { dev_dbg(dev, "clk_get_by_name(tx) failed: %d", ret); - goto err_free_clk_ptp_ref; + goto err_probe; } ret = clk_get_by_name(dev, "pclk", &eqos->clk_ck); if (ret) { dev_dbg(dev, "clk_get_by_name(pclk) failed: %d", ret); - goto err_free_clk_tx; + goto err_probe; } debug("%s: OK\n", __func__); return 0; -err_free_clk_tx: - clk_free(&eqos->clk_tx); -err_free_clk_ptp_ref: - clk_free(&eqos->clk_ptp_ref); -err_free_clk_master_bus: - clk_free(&eqos->clk_master_bus); err_probe: debug("%s: returns %d\n", __func__, ret); @@ -102,16 +96,7 @@ err_probe: static int eqos_remove_resources_imx(struct udevice *dev) { - struct eqos_priv *eqos = dev_get_priv(dev); - debug("%s(dev=%p):\n", __func__, dev); - - clk_free(&eqos->clk_ck); - clk_free(&eqos->clk_tx); - clk_free(&eqos->clk_ptp_ref); - clk_free(&eqos->clk_master_bus); - - debug("%s: OK\n", __func__); return 0; } diff --git a/drivers/net/dwc_eth_qos_qcom.c b/drivers/net/dwc_eth_qos_qcom.c index df83f1c5f9e..8178138fc65 100644 --- a/drivers/net/dwc_eth_qos_qcom.c +++ b/drivers/net/dwc_eth_qos_qcom.c @@ -575,7 +575,6 @@ static int eqos_remove_resources_qcom(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); - clk_free(&eqos->clk_tx); dm_gpio_free(dev, &eqos->phy_reset_gpio); reset_free(&eqos->reset_ctl); diff --git a/drivers/net/dwc_eth_qos_rockchip.c b/drivers/net/dwc_eth_qos_rockchip.c index 834307a4477..fa9e513faea 100644 --- a/drivers/net/dwc_eth_qos_rockchip.c +++ b/drivers/net/dwc_eth_qos_rockchip.c @@ -372,7 +372,7 @@ static int eqos_probe_resources_rk(struct udevice *dev) ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx); if (ret) { dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret); - goto err_free_clk_master_bus; + goto err_release_resets; } } @@ -393,8 +393,6 @@ static int eqos_probe_resources_rk(struct udevice *dev) return 0; -err_free_clk_master_bus: - clk_free(&eqos->clk_master_bus); err_release_resets: reset_release_bulk(&data->resets); err_free: @@ -412,8 +410,6 @@ static int eqos_remove_resources_rk(struct udevice *dev) if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) dm_gpio_free(dev, &eqos->phy_reset_gpio); - clk_free(&eqos->clk_tx); - clk_free(&eqos->clk_master_bus); reset_release_bulk(&data->resets); free(data); diff --git a/drivers/net/phy/motorcomm.c b/drivers/net/phy/motorcomm.c index 8635a960d6e..a2c763c8791 100644 --- a/drivers/net/phy/motorcomm.c +++ b/drivers/net/phy/motorcomm.c @@ -23,6 +23,12 @@ #define YTPHY_SYNCE_CFG_REG 0xA012 +#define YT8531_PAD_DRIVE_STRENGTH_CFG_REG 0xA010 +#define YT8531_RGMII_RXC_DS_MASK GENMASK(15, 13) +#define YT8531_RGMII_RXD_DS_HI_MASK BIT(12) /* Bit 2 of rxd_ds */ +#define YT8531_RGMII_RXD_DS_LOW_MASK GENMASK(5, 4) /* Bit 1/0 of rxd_ds */ +#define YT8531_RGMII_RX_DS_DEFAULT 0x3 + #define YTPHY_DTS_OUTPUT_CLK_DIS 0 #define YTPHY_DTS_OUTPUT_CLK_25M 25000000 #define YTPHY_DTS_OUTPUT_CLK_125M 125000000 @@ -114,6 +120,10 @@ #define YT8531_CCR_RXC_DLY_EN BIT(8) #define YT8531_CCR_RXC_DLY_1_900_NS 1900 +#define YT8531_CCR_CFG_LDO_MASK GENMASK(5, 4) +#define YT8531_CCR_CFG_LDO_3V3 0x0 +#define YT8531_CCR_CFG_LDO_1V8 0x2 + /* bits in struct ytphy_plat_priv->flag */ #define TX_CLK_ADJ_ENABLED BIT(0) #define AUTO_SLEEP_DISABLED BIT(1) @@ -224,6 +234,17 @@ static int ytphy_modify_ext(struct phy_device *phydev, u16 regnum, u16 mask, return phy_modify(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA, mask, set); } +static int ytphy_read_ext(struct phy_device *phydev, u16 regnum) +{ + int ret; + + ret = phy_write(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_SELECT, regnum); + if (ret < 0) + return ret; + + return phy_read(phydev, MDIO_DEVAD_NONE, YTPHY_PAGE_DATA); +} + static int ytphy_rgmii_clk_delay_config(struct phy_device *phydev) { struct ytphy_plat_priv *priv = phydev->priv; @@ -425,6 +446,111 @@ static int yt8511_config(struct phy_device *phydev) return 0; } +/** + * struct ytphy_ldo_vol_map - map a current value to a register value + * @vol: ldo voltage + * @ds: value in the register + * @cur: value in device configuration + */ +struct ytphy_ldo_vol_map { + u32 vol; + u32 ds; + u32 cur; +}; + +static const struct ytphy_ldo_vol_map yt8531_ldo_vol[] = { + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 0, .cur = 1200}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 1, .cur = 2100}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 2, .cur = 2700}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 3, .cur = 2910}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 4, .cur = 3110}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 5, .cur = 3600}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 6, .cur = 3970}, + {.vol = YT8531_CCR_CFG_LDO_1V8, .ds = 7, .cur = 4350}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 0, .cur = 3070}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 1, .cur = 4080}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 2, .cur = 4370}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 3, .cur = 4680}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 4, .cur = 5020}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 5, .cur = 5450}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 6, .cur = 5740}, + {.vol = YT8531_CCR_CFG_LDO_3V3, .ds = 7, .cur = 6140}, +}; + +static u32 yt8531_get_ldo_vol(struct phy_device *phydev) +{ + u32 val; + + val = ytphy_read_ext(phydev, YT8531_CHIP_CONFIG_REG); + val = FIELD_GET(YT8531_CCR_CFG_LDO_MASK, val); + + return val <= YT8531_CCR_CFG_LDO_1V8 ? val : YT8531_CCR_CFG_LDO_1V8; +} + +static int yt8531_get_ds_map(struct phy_device *phydev, u32 cur) +{ + u32 vol; + int i; + + vol = yt8531_get_ldo_vol(phydev); + for (i = 0; i < ARRAY_SIZE(yt8531_ldo_vol); i++) { + if (yt8531_ldo_vol[i].vol == vol && yt8531_ldo_vol[i].cur == cur) + return yt8531_ldo_vol[i].ds; + } + + return -EINVAL; +} + +static int yt8531_set_ds(struct phy_device *phydev) +{ + u32 ds_field_low, ds_field_hi, val; + int ret, ds; + + /* set rgmii rx clk driver strength */ + if (!ofnode_read_u32(phydev->node, "motorcomm,rx-clk-drv-microamp", &val)) { + ds = yt8531_get_ds_map(phydev, val); + if (ds < 0) { + pr_warn("No matching current value was found."); + return -EINVAL; + } + } else { + ds = YT8531_RGMII_RX_DS_DEFAULT; + } + + ret = ytphy_modify_ext(phydev, + YT8531_PAD_DRIVE_STRENGTH_CFG_REG, + YT8531_RGMII_RXC_DS_MASK, + FIELD_PREP(YT8531_RGMII_RXC_DS_MASK, ds)); + if (ret < 0) + return ret; + + /* set rgmii rx data driver strength */ + if (!ofnode_read_u32(phydev->node, "motorcomm,rx-data-drv-microamp", &val)) { + ds = yt8531_get_ds_map(phydev, val); + if (ds < 0) { + pr_warn("No matching current value was found."); + return -EINVAL; + } + } else { + ds = YT8531_RGMII_RX_DS_DEFAULT; + } + + ds_field_hi = FIELD_GET(BIT(2), ds); + ds_field_hi = FIELD_PREP(YT8531_RGMII_RXD_DS_HI_MASK, ds_field_hi); + + ds_field_low = FIELD_GET(GENMASK(1, 0), ds); + ds_field_low = FIELD_PREP(YT8531_RGMII_RXD_DS_LOW_MASK, ds_field_low); + + ret = ytphy_modify_ext(phydev, + YT8531_PAD_DRIVE_STRENGTH_CFG_REG, + YT8531_RGMII_RXD_DS_LOW_MASK | YT8531_RGMII_RXD_DS_HI_MASK, + ds_field_low | ds_field_hi); + if (ret < 0) + return ret; + + return 0; +} + static int yt8531_config(struct phy_device *phydev) { struct ytphy_plat_priv *priv = phydev->priv; @@ -487,6 +613,10 @@ static int yt8531_config(struct phy_device *phydev) return ret; } + ret = yt8531_set_ds(phydev); + if (ret < 0) + return ret; + return 0; } diff --git a/drivers/net/sni_ave.c b/drivers/net/sni_ave.c index 8eeecbc4cf3..a265ce9df57 100644 --- a/drivers/net/sni_ave.c +++ b/drivers/net/sni_ave.c @@ -777,7 +777,7 @@ static int ave_of_to_plat(struct udevice *dev) if (ret) { dev_err(dev, "Failed to get clocks property: %d\n", ret); - goto out_clk_free; + return ret; } priv->nclks++; } @@ -823,9 +823,6 @@ static int ave_of_to_plat(struct udevice *dev) out_reset_free: while (--nr >= 0) reset_free(&priv->rst[nr]); -out_clk_free: - while (--nc >= 0) - clk_free(&priv->clk[nc]); return ret; } diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index a12f7e32e8f..8bff4fe9a9e 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -833,11 +833,8 @@ static int sun8i_emac_eth_of_to_plat(struct udevice *dev) priv->use_internal_phy = false; offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "phy-handle"); - if (offset < 0) { - debug("%s: Cannot find PHY address\n", __func__); - return -EINVAL; - } - priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1); + if (offset >= 0) + priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1); pdata->phy_interface = dev_read_phy_mode(dev); debug("phy interface %d\n", pdata->phy_interface); diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c index 18a33c4c0e3..6da018c0f9d 100644 --- a/drivers/net/ti/am65-cpsw-nuss.c +++ b/drivers/net/ti/am65-cpsw-nuss.c @@ -948,7 +948,6 @@ static int am65_cpsw_probe_nuss(struct udevice *dev) cpsw_common->bus_freq); out: - clk_free(&cpsw_common->fclk); power_domain_free(&cpsw_common->pwrdmn); return ret; } diff --git a/drivers/phy/bcm6318-usbh-phy.c b/drivers/phy/bcm6318-usbh-phy.c index 1c10853940a..a2fa446cb1c 100644 --- a/drivers/phy/bcm6318-usbh-phy.c +++ b/drivers/phy/bcm6318-usbh-phy.c @@ -98,8 +98,6 @@ static int bcm6318_usbh_probe(struct udevice *dev) if (ret < 0) return ret; - clk_free(&clk); - /* enable power domain */ ret = power_domain_get(dev, &pwr_dom); if (ret < 0) diff --git a/drivers/phy/bcm6348-usbh-phy.c b/drivers/phy/bcm6348-usbh-phy.c index ce6be3d7dab..857fb575ef1 100644 --- a/drivers/phy/bcm6348-usbh-phy.c +++ b/drivers/phy/bcm6348-usbh-phy.c @@ -62,8 +62,6 @@ static int bcm6348_usbh_probe(struct udevice *dev) if (ret < 0) return ret; - clk_free(&clk); - /* perform reset */ ret = reset_get_by_index(dev, 0, &rst_ctl); if (ret < 0) diff --git a/drivers/phy/bcm6368-usbh-phy.c b/drivers/phy/bcm6368-usbh-phy.c index d057f1f52e8..1a2870d5149 100644 --- a/drivers/phy/bcm6368-usbh-phy.c +++ b/drivers/phy/bcm6368-usbh-phy.c @@ -137,8 +137,6 @@ static int bcm6368_usbh_probe(struct udevice *dev) if (ret < 0) return ret; - clk_free(&clk); - #if defined(CONFIG_POWER_DOMAIN) /* enable power domain */ ret = power_domain_get(dev, &pwr_dom); @@ -173,8 +171,6 @@ static int bcm6368_usbh_probe(struct udevice *dev) ret = clk_enable(&clk); if (ret < 0) return ret; - - clk_free(&clk); } mdelay(100); diff --git a/drivers/phy/meson-axg-mipi-dphy.c b/drivers/phy/meson-axg-mipi-dphy.c index a69b6c97594..faa1d9d6d37 100644 --- a/drivers/phy/meson-axg-mipi-dphy.c +++ b/drivers/phy/meson-axg-mipi-dphy.c @@ -369,7 +369,6 @@ int meson_axg_mipi_dphy_probe(struct udevice *dev) ret = clk_enable(&priv->clk); if (ret && ret != -ENOSYS && ret != -ENOTSUPP) { pr_err("failed to enable PHY clock\n"); - clk_free(&priv->clk); return ret; } #endif diff --git a/drivers/phy/meson-g12a-usb3-pcie.c b/drivers/phy/meson-g12a-usb3-pcie.c index 40a5da948dc..1eaff410efa 100644 --- a/drivers/phy/meson-g12a-usb3-pcie.c +++ b/drivers/phy/meson-g12a-usb3-pcie.c @@ -398,7 +398,6 @@ int meson_g12a_usb3_pcie_phy_probe(struct udevice *dev) ret = clk_enable(&priv->clk); if (ret && ret != -ENOENT && ret != -ENOTSUPP) { pr_err("failed to enable PHY clock\n"); - clk_free(&priv->clk); return ret; } #endif diff --git a/drivers/phy/meson-gxl-usb2.c b/drivers/phy/meson-gxl-usb2.c index 8f5e4a43661..d633effa404 100644 --- a/drivers/phy/meson-gxl-usb2.c +++ b/drivers/phy/meson-gxl-usb2.c @@ -203,7 +203,6 @@ int meson_gxl_usb2_phy_probe(struct udevice *dev) ret = clk_enable(&priv->clk); if (ret && ret != -ENOSYS && ret != -ENOTSUPP) { pr_err("failed to enable PHY clock\n"); - clk_free(&priv->clk); return ret; } #endif diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c index 17940959246..e528c4ec579 100644 --- a/drivers/phy/phy-rcar-gen2.c +++ b/drivers/phy/phy-rcar-gen2.c @@ -172,7 +172,6 @@ static int rcar_gen2_phy_remove(struct udevice *dev) struct rcar_gen2_phy *priv = dev_get_priv(dev); clk_disable(&priv->clk); - clk_free(&priv->clk); return 0; } diff --git a/drivers/phy/phy-rcar-gen3.c b/drivers/phy/phy-rcar-gen3.c index 7159e7e8716..03c747b373b 100644 --- a/drivers/phy/phy-rcar-gen3.c +++ b/drivers/phy/phy-rcar-gen3.c @@ -142,7 +142,6 @@ static int rcar_gen3_phy_remove(struct udevice *dev) struct rcar_gen3_phy *priv = dev_get_priv(dev); clk_disable(&priv->clk); - clk_free(&priv->clk); return 0; } diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c index 13f0a342686..ee35dfe1420 100644 --- a/drivers/pinctrl/pinctrl-k210.c +++ b/drivers/pinctrl/pinctrl-k210.c @@ -691,23 +691,19 @@ static int k210_pc_probe(struct udevice *dev) ret = clk_enable(&priv->clk); if (ret && ret != -ENOSYS && ret != -ENOTSUPP) - goto err; + return ret; ret = dev_read_phandle_with_args(dev, "canaan,k210-sysctl-power", NULL, 1, 0, &args); if (ret) - goto err; + return ret; - if (args.args_count != 1) { - ret = -EINVAL; - goto err; - } + if (args.args_count != 1) + return -EINVAL; priv->sysctl = syscon_node_to_regmap(args.node); - if (IS_ERR(priv->sysctl)) { - ret = PTR_ERR(priv->sysctl); - goto err; - } + if (IS_ERR(priv->sysctl)) + return PTR_ERR(priv->sysctl); priv->power_offset = args.args[0]; @@ -728,10 +724,6 @@ static int k210_pc_probe(struct udevice *dev) } return 0; - -err: - clk_free(&priv->clk); - return ret; } static const struct udevice_id k210_pc_ids[] = { diff --git a/drivers/pinctrl/renesas/pfc-r8a7790.c b/drivers/pinctrl/renesas/pfc-r8a7790.c index 7203648bbc8..e1811c4c908 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7790.c +++ b/drivers/pinctrl/renesas/pfc-r8a7790.c @@ -8,7 +8,6 @@ * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc-r8a7791.c b/drivers/pinctrl/renesas/pfc-r8a7791.c index b25453ed285..fa94a51e5e7 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7791.c +++ b/drivers/pinctrl/renesas/pfc-r8a7791.c @@ -6,7 +6,6 @@ * Copyright (C) 2014-2017 Cogent Embedded, Inc. */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc-r8a7792.c b/drivers/pinctrl/renesas/pfc-r8a7792.c index 08f1f97af6e..7c1e6d40749 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7792.c +++ b/drivers/pinctrl/renesas/pfc-r8a7792.c @@ -6,7 +6,6 @@ * Copyright (C) 2016 Cogent Embedded, Inc., <source@cogentembedded.com> */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc-r8a7794.c b/drivers/pinctrl/renesas/pfc-r8a7794.c index e5d125ceca0..29eab2610c1 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7794.c +++ b/drivers/pinctrl/renesas/pfc-r8a7794.c @@ -7,7 +7,6 @@ * Copyright (C) 2015-2017 Cogent Embedded, Inc. <source@cogentembedded.com> */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc-r8a77951.c b/drivers/pinctrl/renesas/pfc-r8a77951.c index 5d1c81c3eae..81568ae4a5e 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77951.c +++ b/drivers/pinctrl/renesas/pfc-r8a77951.c @@ -5,7 +5,6 @@ * Copyright (C) 2015-2019 Renesas Electronics Corporation */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc-r8a7796.c b/drivers/pinctrl/renesas/pfc-r8a7796.c index 163d1805dfb..3de43febbd3 100644 --- a/drivers/pinctrl/renesas/pfc-r8a7796.c +++ b/drivers/pinctrl/renesas/pfc-r8a7796.c @@ -11,7 +11,6 @@ * Copyright (C) 2015 Renesas Electronics Corporation */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc-r8a77965.c b/drivers/pinctrl/renesas/pfc-r8a77965.c index 377143d3918..3a6813cee61 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77965.c +++ b/drivers/pinctrl/renesas/pfc-r8a77965.c @@ -12,7 +12,6 @@ * Copyright (C) 2015 Renesas Electronics Corporation */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc-r8a77970.c b/drivers/pinctrl/renesas/pfc-r8a77970.c index 1cc6fa4f3fc..3c9c060d245 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77970.c +++ b/drivers/pinctrl/renesas/pfc-r8a77970.c @@ -12,7 +12,6 @@ * Copyright (C) 2015 Renesas Electronics Corporation */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc-r8a77980.c b/drivers/pinctrl/renesas/pfc-r8a77980.c index 523faa0ac8f..14a4b4dc731 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77980.c +++ b/drivers/pinctrl/renesas/pfc-r8a77980.c @@ -12,7 +12,6 @@ * Copyright (C) 2015 Renesas Electronics Corporation */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc-r8a77990.c b/drivers/pinctrl/renesas/pfc-r8a77990.c index 215a19ef9cd..e3a9c5e053d 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77990.c +++ b/drivers/pinctrl/renesas/pfc-r8a77990.c @@ -11,7 +11,6 @@ * Copyright (C) 2016-2017 Renesas Electronics Corp. */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc-r8a77995.c b/drivers/pinctrl/renesas/pfc-r8a77995.c index c0d69937ddb..eccf5c15907 100644 --- a/drivers/pinctrl/renesas/pfc-r8a77995.c +++ b/drivers/pinctrl/renesas/pfc-r8a77995.c @@ -11,7 +11,6 @@ * Copyright (C) 2015 Renesas Electronics Corporation */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc-r8a779a0.c b/drivers/pinctrl/renesas/pfc-r8a779a0.c index 3c4b03b1b4c..6f898385027 100644 --- a/drivers/pinctrl/renesas/pfc-r8a779a0.c +++ b/drivers/pinctrl/renesas/pfc-r8a779a0.c @@ -7,7 +7,6 @@ * This file is based on the drivers/pinctrl/renesas/pfc-r8a7795.c */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc-r8a779f0.c b/drivers/pinctrl/renesas/pfc-r8a779f0.c index 5123e26e0ac..de5ec6c812a 100644 --- a/drivers/pinctrl/renesas/pfc-r8a779f0.c +++ b/drivers/pinctrl/renesas/pfc-r8a779f0.c @@ -7,7 +7,6 @@ * This file is based on the drivers/pinctrl/renesas/pfc-r8a779a0.c */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc-r8a779g0.c b/drivers/pinctrl/renesas/pfc-r8a779g0.c index 20498a1c2f7..6749c15f4ea 100644 --- a/drivers/pinctrl/renesas/pfc-r8a779g0.c +++ b/drivers/pinctrl/renesas/pfc-r8a779g0.c @@ -7,7 +7,6 @@ * This file is based on the drivers/pinctrl/renesas/pfc-r8a779a0.c */ -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/pinctrl.h> diff --git a/drivers/pinctrl/renesas/pfc.c b/drivers/pinctrl/renesas/pfc.c index 3ac25cbd080..4ceb5db47ff 100644 --- a/drivers/pinctrl/renesas/pfc.c +++ b/drivers/pinctrl/renesas/pfc.c @@ -11,7 +11,6 @@ #define DRV_NAME "sh-pfc" -#include <common.h> #include <dm.h> #include <errno.h> #include <dm/device_compat.h> diff --git a/drivers/pinctrl/renesas/pinctrl-rza1.c b/drivers/pinctrl/renesas/pinctrl-rza1.c index a445cdba713..2d993be2b2a 100644 --- a/drivers/pinctrl/renesas/pinctrl-rza1.c +++ b/drivers/pinctrl/renesas/pinctrl-rza1.c @@ -5,7 +5,6 @@ * Copyright (C) 2019 Marek Vasut <marek.vasut@gmail.com> */ -#include <common.h> #include <dm.h> #include <asm/global_data.h> #include <dm/lists.h> diff --git a/drivers/power/domain/imx8mp-hsiomix.c b/drivers/power/domain/imx8mp-hsiomix.c index 6a721a934a7..e2d772c5ec7 100644 --- a/drivers/power/domain/imx8mp-hsiomix.c +++ b/drivers/power/domain/imx8mp-hsiomix.c @@ -111,7 +111,7 @@ static int imx8mp_hsiomix_probe(struct udevice *dev) ret = power_domain_get_by_name(dev, &priv->pd_bus, "bus"); if (ret < 0) - goto err_pd_bus; + return ret; ret = power_domain_get_by_name(dev, &priv->pd_usb, "usb"); if (ret < 0) @@ -133,8 +133,6 @@ err_pd_usb_phy1: power_domain_free(&priv->pd_usb); err_pd_usb: power_domain_free(&priv->pd_bus); -err_pd_bus: - clk_free(&priv->clk_usb); return ret; } diff --git a/drivers/reset/reset-hisilicon.c b/drivers/reset/reset-hisilicon.c index 8152cec2271..85e02b296b0 100644 --- a/drivers/reset/reset-hisilicon.c +++ b/drivers/reset/reset-hisilicon.c @@ -49,7 +49,18 @@ static int hisi_reset_assert(struct reset_ctl *rst) static int hisi_reset_of_xlate(struct reset_ctl *rst, struct ofnode_phandle_args *args) { - if (args->args_count != 3) { + unsigned long polarity; + + switch (args->args_count) { + case 2: + polarity = ASSERT_SET; + break; + + case 3: + polarity = args->args[2]; + break; + + default: debug("Invalid args_count: %d\n", args->args_count); return -EINVAL; } @@ -57,7 +68,7 @@ static int hisi_reset_of_xlate(struct reset_ctl *rst, /* Use .data field as register offset and .id field as bit shift */ rst->data = args->args[0]; rst->id = args->args[1]; - rst->polarity = args->args[2]; + rst->polarity = polarity; return 0; } diff --git a/drivers/rtc/stm32_rtc.c b/drivers/rtc/stm32_rtc.c index 1753283460d..ec7584c3d70 100644 --- a/drivers/rtc/stm32_rtc.c +++ b/drivers/rtc/stm32_rtc.c @@ -223,10 +223,8 @@ static int stm32_rtc_init(struct udevice *dev) return ret; ret = clk_enable(&clk); - if (ret) { - clk_free(&clk); + if (ret) return ret; - } rate = clk_get_rate(&clk); @@ -275,10 +273,8 @@ static int stm32_rtc_init(struct udevice *dev) unlock: stm32_rtc_lock(dev); - if (ret) { + if (ret) clk_disable(&clk); - clk_free(&clk); - } return ret; } @@ -298,17 +294,13 @@ static int stm32_rtc_probe(struct udevice *dev) return ret; ret = clk_enable(&clk); - if (ret) { - clk_free(&clk); + if (ret) return ret; - } ret = stm32_rtc_init(dev); - if (ret) { + if (ret) clk_disable(&clk); - clk_free(&clk); - } return ret; } diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c index 9853f49c94f..9827c006fa8 100644 --- a/drivers/serial/atmel_usart.c +++ b/drivers/serial/atmel_usart.c @@ -253,8 +253,6 @@ static int atmel_serial_enable_clk(struct udevice *dev) priv->usart_clk_rate = clk_rate; - clk_free(&clk); - return 0; } #endif diff --git a/drivers/serial/serial_bcm6345.c b/drivers/serial/serial_bcm6345.c index 2359656a239..13bc51725cd 100644 --- a/drivers/serial/serial_bcm6345.c +++ b/drivers/serial/serial_bcm6345.c @@ -239,7 +239,6 @@ static int bcm6345_serial_probe(struct udevice *dev) if (ret < 0) return ret; priv->uartclk = clk_get_rate(&clk); - clk_free(&clk); /* initialize serial */ return bcm6345_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE); diff --git a/drivers/serial/serial_msm.c b/drivers/serial/serial_msm.c index a22623c316e..f4d96313b93 100644 --- a/drivers/serial/serial_msm.c +++ b/drivers/serial/serial_msm.c @@ -185,7 +185,6 @@ static int msm_uart_clk_init(struct udevice *dev) return ret; ret = clk_set_rate(&clk, clk_rate); - clk_free(&clk); if (ret < 0) return ret; diff --git a/drivers/serial/serial_pic32.c b/drivers/serial/serial_pic32.c index 3c5d37ce0ab..0a03a9a2549 100644 --- a/drivers/serial/serial_pic32.c +++ b/drivers/serial/serial_pic32.c @@ -155,7 +155,6 @@ static int pic32_uart_probe(struct udevice *dev) if (ret < 0) return ret; priv->uartclk = clk_get_rate(&clk); - clk_free(&clk); /* initialize serial */ return pic32_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE); diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c index de9c14837cd..70cb242cd31 100644 --- a/drivers/spi/atcspi200_spi.c +++ b/drivers/spi/atcspi200_spi.c @@ -362,7 +362,6 @@ static int atcspi200_spi_get_clk(struct udevice *bus) return -EINVAL; ns->clock = clk_rate; - clk_free(&clk); return 0; } diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c index cb64119f972..bd73e4fddf1 100644 --- a/drivers/spi/atmel-quadspi.c +++ b/drivers/spi/atmel-quadspi.c @@ -877,7 +877,6 @@ static int atmel_qspi_set_gclk(struct udevice *bus, uint hz) ret = clk_enable(&gclk); if (ret) dev_err(bus, "Failed to enable QSPI generic clock\n"); - clk_free(&gclk); return ret; } @@ -1000,7 +999,7 @@ static int atmel_qspi_enable_clk(struct udevice *dev) ret = clk_enable(&pclk); if (ret) { dev_err(dev, "Failed to enable QSPI peripheral clock\n"); - goto free_pclk; + return ret; } if (aq->caps->has_qspick) { @@ -1008,32 +1007,27 @@ static int atmel_qspi_enable_clk(struct udevice *dev) ret = clk_get_by_name(dev, "qspick", &qspick); if (ret) { dev_err(dev, "Missing QSPI peripheral clock\n"); - goto free_pclk; + return ret; } ret = clk_enable(&qspick); if (ret) dev_err(dev, "Failed to enable QSPI system clock\n"); - clk_free(&qspick); } else if (aq->caps->has_gclk) { ret = clk_get_by_name(dev, "gclk", &gclk); if (ret) { dev_err(dev, "Missing QSPI generic clock\n"); - goto free_pclk; + return ret; } ret = clk_enable(&gclk); if (ret) dev_err(dev, "Failed to enable QSPI system clock\n"); - clk_free(&gclk); } aq->bus_clk_rate = clk_get_rate(&pclk); if (!aq->bus_clk_rate) - ret = -EINVAL; - -free_pclk: - clk_free(&pclk); + return -EINVAL; return ret; } diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index aec6f4eca9a..d4f0c4c4483 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -338,8 +338,6 @@ static int atmel_spi_enable_clk(struct udevice *bus) priv->bus_clk_rate = clk_rate; - clk_free(&clk); - return 0; } diff --git a/drivers/spi/bcm63xx_hsspi.c b/drivers/spi/bcm63xx_hsspi.c index 19d9a5ae23c..23ac5bb76c0 100644 --- a/drivers/spi/bcm63xx_hsspi.c +++ b/drivers/spi/bcm63xx_hsspi.c @@ -581,8 +581,6 @@ static int bcm63xx_hsspi_probe(struct udevice *dev) if (ret < 0 && ret != -ENOSYS) return ret; - clk_free(&clk); - /* get clock rate */ ret = clk_get_by_name(dev, "pll", &clk); if (ret < 0 && ret != -ENOSYS) @@ -590,8 +588,6 @@ static int bcm63xx_hsspi_probe(struct udevice *dev) priv->clk_rate = clk_get_rate(&clk); - clk_free(&clk); - /* perform reset */ ret = reset_get_by_index(dev, 0, &rst_ctl); if (ret >= 0) { diff --git a/drivers/spi/bcm63xx_spi.c b/drivers/spi/bcm63xx_spi.c index 0600d56c69e..889ac1f966e 100644 --- a/drivers/spi/bcm63xx_spi.c +++ b/drivers/spi/bcm63xx_spi.c @@ -391,8 +391,6 @@ static int bcm63xx_spi_probe(struct udevice *dev) if (ret < 0) return ret; - clk_free(&clk); - /* perform reset */ ret = reset_get_by_index(dev, 0, &rst_ctl); if (ret < 0) diff --git a/drivers/spi/bcmbca_hsspi.c b/drivers/spi/bcmbca_hsspi.c index fbe315a7d45..af45882db0a 100644 --- a/drivers/spi/bcmbca_hsspi.c +++ b/drivers/spi/bcmbca_hsspi.c @@ -375,8 +375,6 @@ static int bcmbca_hsspi_probe(struct udevice *dev) if (ret < 0 && ret != -ENOSYS) return ret; - clk_free(&clk); - /* get clock rate */ ret = clk_get_by_name(dev, "pll", &clk); if (ret < 0 && ret != -ENOSYS) @@ -384,8 +382,6 @@ static int bcmbca_hsspi_probe(struct udevice *dev) priv->clk_rate = clk_get_rate(&clk); - clk_free(&clk); - /* initialize hardware */ writel(0, priv->regs + SPI_IR_MASK_REG); diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index e02a3b3de37..c2be307f1d8 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -18,9 +18,6 @@ #include "cadence_qspi.h" #include <dt-bindings/power/xlnx-versal-power.h> -#define CMD_4BYTE_READ 0x13 -#define CMD_4BYTE_FAST_READ 0x0C - int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index dfc74c882d2..f4593c47b8c 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -236,7 +236,6 @@ static int cadence_spi_probe(struct udevice *bus) #endif } else { priv->ref_clk_hz = clk_get_rate(&clk); - clk_free(&clk); if (IS_ERR_VALUE(priv->ref_clk_hz)) return priv->ref_clk_hz; } diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index 12825f8911c..693474a2871 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -33,6 +33,10 @@ #define CQSPI_DUMMY_BYTES_MAX 4 #define CQSPI_DUMMY_CLKS_MAX 31 +#define CMD_4BYTE_FAST_READ 0x0C +#define CMD_4BYTE_OCTAL_READ 0x7c +#define CMD_4BYTE_READ 0x13 + /**************************************************************************** * Controller's configuration and status register (offset from QSPI_BASE) ****************************************************************************/ diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index d033184aa46..fb905322178 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -469,6 +469,9 @@ int cadence_qspi_apb_command_read(struct cadence_spi_priv *priv, else opcode = op->cmd.opcode; + if (opcode == CMD_4BYTE_OCTAL_READ && !priv->dtr) + opcode = CMD_4BYTE_FAST_READ; + reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB; /* Set up dummy cycles. */ diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c index 1c7d0ca310b..22a79da2333 100644 --- a/drivers/spi/designware_spi.c +++ b/drivers/spi/designware_spi.c @@ -111,6 +111,9 @@ #define SR_TX_ERR BIT(5) #define SR_DCOL BIT(6) +/* Bit field in RISR */ +#define RISR_INT_RXOI BIT(3) + #define RX_TIMEOUT 1000 /* timeout in ms */ struct dw_spi_plat { @@ -316,7 +319,6 @@ __weak int dw_spi_get_clk(struct udevice *bus, ulong *rate) err_rate: clk_disable(&priv->clk); - clk_free(&priv->clk); return -EINVAL; } @@ -588,7 +590,7 @@ static int dw_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) struct dw_spi_priv *priv = dev_get_priv(bus); u8 op_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes; u8 op_buf[op_len]; - u32 cr0; + u32 cr0, sts; if (read) priv->tmode = CTRLR0_TMOD_EPROMREAD; @@ -632,12 +634,21 @@ static int dw_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op) * them to fail because we are not reading/writing the fifo fast enough. */ if (read) { - priv->rx = op->data.buf.in; + void *prev_rx = priv->rx = op->data.buf.in; priv->rx_end = priv->rx + op->data.nbytes; dw_write(priv, DW_SPI_SER, 1 << spi_chip_select(slave->dev)); - while (priv->rx != priv->rx_end) + while (priv->rx != priv->rx_end) { dw_reader(priv); + if (prev_rx == priv->rx) { + sts = dw_read(priv, DW_SPI_RISR); + if (sts & RISR_INT_RXOI) { + dev_err(bus, "FIFO overflow on Rx\n"); + return -EIO; + } + } + prev_rx = priv->rx; + } } else { u32 val; @@ -731,10 +742,6 @@ static int dw_spi_remove(struct udevice *bus) ret = clk_disable(&priv->clk); if (ret) return ret; - - clk_free(&priv->clk); - if (ret) - return ret; #endif return 0; } diff --git a/drivers/spi/meson_spifc_a1.c b/drivers/spi/meson_spifc_a1.c index cca4debb412..943bf6986f1 100644 --- a/drivers/spi/meson_spifc_a1.c +++ b/drivers/spi/meson_spifc_a1.c @@ -343,15 +343,6 @@ static int amlogic_spifc_a1_probe(struct udevice *dev) return 0; } -static int amlogic_spifc_a1_remove(struct udevice *dev) -{ - struct amlogic_spifc_a1 *spifc = dev_get_priv(dev); - - clk_free(&spifc->clk); - - return 0; -} - static const struct udevice_id meson_spifc_ids[] = { { .compatible = "amlogic,a1-spifc", }, { } @@ -379,6 +370,5 @@ U_BOOT_DRIVER(meson_spifc_a1) = { .of_match = meson_spifc_ids, .ops = &amlogic_spifc_a1_ops, .probe = amlogic_spifc_a1_probe, - .remove = amlogic_spifc_a1_remove, .priv_auto = sizeof(struct amlogic_spifc_a1), }; diff --git a/drivers/spi/mvebu_a3700_spi.c b/drivers/spi/mvebu_a3700_spi.c index 52882e8b263..bba2383a111 100644 --- a/drivers/spi/mvebu_a3700_spi.c +++ b/drivers/spi/mvebu_a3700_spi.c @@ -296,15 +296,6 @@ static int mvebu_spi_of_to_plat(struct udevice *bus) return 0; } -static int mvebu_spi_remove(struct udevice *bus) -{ - struct mvebu_spi_plat *plat = dev_get_plat(bus); - - clk_free(&plat->clk); - - return 0; -} - static const struct dm_spi_ops mvebu_spi_ops = { .xfer = mvebu_spi_xfer, .set_speed = mvebu_spi_set_speed, @@ -328,5 +319,4 @@ U_BOOT_DRIVER(mvebu_spi) = { .of_to_plat = mvebu_spi_of_to_plat, .plat_auto = sizeof(struct mvebu_spi_plat), .probe = mvebu_spi_probe, - .remove = mvebu_spi_remove, }; diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c index 39620310218..7d5f101a766 100644 --- a/drivers/spi/spi-aspeed-smc.c +++ b/drivers/spi/spi-aspeed-smc.c @@ -1148,7 +1148,6 @@ static int apseed_spi_of_to_plat(struct udevice *bus) } plat->hclk_rate = clk_get_rate(&hclk); - clk_free(&hclk); dev_dbg(bus, "ctrl_base = 0x%x, ahb_base = 0x%p, size = 0x%llx\n", (u32)priv->regs, plat->ahb_base, (fdt64_t)plat->ahb_sz); diff --git a/drivers/spi/stm32_spi.c b/drivers/spi/stm32_spi.c index 82f6ed783f9..ddb410a94c0 100644 --- a/drivers/spi/stm32_spi.c +++ b/drivers/spi/stm32_spi.c @@ -526,22 +526,16 @@ static int stm32_spi_of_to_plat(struct udevice *dev) ret = reset_get_by_index(dev, 0, &plat->rst_ctl); if (ret < 0) - goto clk_err; + return ret; ret = gpio_request_list_by_name(dev, "cs-gpios", plat->cs_gpios, ARRAY_SIZE(plat->cs_gpios), 0); if (ret < 0) { dev_err(dev, "Can't get %s cs gpios: %d", dev->name, ret); - ret = -ENOENT; - goto clk_err; + return -ENOENT; } return 0; - -clk_err: - clk_free(&plat->clk); - - return ret; } static int stm32_spi_probe(struct udevice *dev) @@ -610,7 +604,6 @@ static int stm32_spi_probe(struct udevice *dev) clk_err: clk_disable(&plat->clk); - clk_free(&plat->clk); return ret; }; @@ -630,13 +623,7 @@ static int stm32_spi_remove(struct udevice *dev) reset_free(&plat->rst_ctl); - ret = clk_disable(&plat->clk); - if (ret < 0) - return ret; - - clk_free(&plat->clk); - - return ret; + return clk_disable(&plat->clk); }; static const struct dm_spi_ops stm32_spi_ops = { diff --git a/drivers/timer/dw-apb-timer.c b/drivers/timer/dw-apb-timer.c index 6cd25251f94..0607f751ca7 100644 --- a/drivers/timer/dw-apb-timer.c +++ b/drivers/timer/dw-apb-timer.c @@ -74,8 +74,6 @@ static int dw_apb_timer_probe(struct udevice *dev) return ret; uc_priv->clock_rate = clk_get_rate(&clk); - - clk_free(&clk); } /* init timer */ diff --git a/drivers/timer/ostm_timer.c b/drivers/timer/ostm_timer.c index 3ec729d2c43..3bf0d4647b5 100644 --- a/drivers/timer/ostm_timer.c +++ b/drivers/timer/ostm_timer.c @@ -49,8 +49,6 @@ static int ostm_probe(struct udevice *dev) return ret; uc_priv->clock_rate = clk_get_rate(&clk); - - clk_free(&clk); #else uc_priv->clock_rate = get_board_sys_clk() / 2; #endif diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c index 196035215a6..1a3e9350c46 100644 --- a/drivers/usb/dwc3/dwc3-meson-g12a.c +++ b/drivers/usb/dwc3/dwc3-meson-g12a.c @@ -361,10 +361,8 @@ static int dwc3_meson_g12a_clk_init(struct dwc3_meson_g12a *priv) #if CONFIG_IS_ENABLED(CLK) ret = clk_enable(&priv->clk); - if (ret) { - clk_free(&priv->clk); + if (ret) return ret; - } #endif return 0; diff --git a/drivers/usb/dwc3/dwc3-meson-gxl.c b/drivers/usb/dwc3/dwc3-meson-gxl.c index cbe8aaa005b..2ce915701a8 100644 --- a/drivers/usb/dwc3/dwc3-meson-gxl.c +++ b/drivers/usb/dwc3/dwc3-meson-gxl.c @@ -284,10 +284,8 @@ static int dwc3_meson_gxl_clk_init(struct dwc3_meson_gxl *priv) #if CONFIG_IS_ENABLED(CLK) ret = clk_enable(&priv->clk); - if (ret) { - clk_free(&priv->clk); + if (ret) return ret; - } #endif return 0; diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c index fba3595e10f..c6d50fd4551 100644 --- a/drivers/usb/host/ehci-atmel.c +++ b/drivers/usb/host/ehci-atmel.c @@ -70,13 +70,7 @@ static int ehci_atmel_enable_clk(struct udevice *dev) if (ret) return -EINVAL; - ret = clk_enable(&clk); - if (ret) - return ret; - - clk_free(&clk); - - return 0; + return clk_enable(&clk); } static int ehci_atmel_probe(struct udevice *dev) diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index 33c4a911a09..d3d73d23844 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c @@ -115,7 +115,6 @@ static int ohci_da8xx_probe(struct udevice *dev) err = clk_enable(&priv->clocks[i]); if (err) { dev_err(dev, "failed to enable clock %d\n", i); - clk_free(&priv->clocks[i]); goto clk_err; } priv->clock_count++; diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c index 5fc7afb7d21..fedcf786929 100644 --- a/drivers/usb/host/xhci-rcar.c +++ b/drivers/usb/host/xhci-rcar.c @@ -90,7 +90,7 @@ static int xhci_rcar_probe(struct udevice *dev) ret = clk_enable(&plat->clk); if (ret) { dev_err(dev, "Failed to enable USB3 clock\n"); - goto err_clk; + return ret; } ctx->hcd = (struct xhci_hccr *)plat->hcd_base; @@ -114,8 +114,6 @@ static int xhci_rcar_probe(struct udevice *dev) err_fw: clk_disable(&plat->clk); -err_clk: - clk_free(&plat->clk); return ret; } @@ -127,7 +125,6 @@ static int xhci_rcar_deregister(struct udevice *dev) ret = xhci_deregister(dev); clk_disable(&plat->clk); - clk_free(&plat->clk); return ret; } diff --git a/drivers/video/atmel_hlcdfb.c b/drivers/video/atmel_hlcdfb.c index 2bf19a6684b..652ba141801 100644 --- a/drivers/video/atmel_hlcdfb.c +++ b/drivers/video/atmel_hlcdfb.c @@ -62,8 +62,6 @@ static int at91_hlcdc_enable_clk(struct udevice *dev) priv->clk_rate = clk_rate; - clk_free(&clk); - return 0; } diff --git a/drivers/video/bcm2835.c b/drivers/video/bcm2835.c index 14942526f19..63efa762db1 100644 --- a/drivers/video/bcm2835.c +++ b/drivers/video/bcm2835.c @@ -16,7 +16,7 @@ static int bcm2835_video_probe(struct udevice *dev) struct video_uc_plat *plat = dev_get_uclass_plat(dev); struct video_priv *uc_priv = dev_get_uclass_priv(dev); int ret; - int w, h, pitch; + int w, h, pitch, bpp; ulong fb_base, fb_size, fb_start, fb_end; debug("bcm2835: Query resolution...\n"); @@ -41,9 +41,23 @@ static int bcm2835_video_probe(struct udevice *dev) DCACHE_WRITEBACK); video_set_flush_dcache(dev, true); + bpp = pitch / w; + switch (bpp) { + case 2: + uc_priv->bpix = VIDEO_BPP16; + break; + case 4: + uc_priv->bpix = VIDEO_BPP32; + break; + default: + printf("bcm2835: unexpected bpp %d, pitch %d, width %d\n", + bpp, pitch, w); + uc_priv->bpix = VIDEO_BPP32; + break; + } + uc_priv->xsize = w; uc_priv->ysize = h; - uc_priv->bpix = VIDEO_BPP32; plat->base = fb_base; plat->size = fb_size; diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c index d17764d0b08..939363653f6 100644 --- a/drivers/video/console_core.c +++ b/drivers/video/console_core.c @@ -225,7 +225,7 @@ int console_simple_get_font(struct udevice *dev, int seq, struct vidfont_info *i { info->name = fonts[seq].name; - return 0; + return info->name ? 0 : -ENOENT; } int console_simple_select_font(struct udevice *dev, const char *name, uint size) diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index 14fb81e9563..547e5a8d9cf 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -397,7 +397,10 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, if (vid_priv->colour_bg) val = 255 - val; - out = val | val << 8 | val << 16; + if (vid_priv->format == VIDEO_X2R10G10B10) + out = val << 2 | val << 12 | val << 22; + else + out = val | val << 8 | val << 16; if (vid_priv->colour_fg) *dst++ |= out; else @@ -911,7 +914,10 @@ static int truetype_set_cursor_visible(struct udevice *dev, bool visible, for (i = 0; i < width; i++) { int out; - out = val | val << 8 | val << 16; + if (vid_priv->format == VIDEO_X2R10G10B10) + out = val << 2 | val << 12 | val << 22; + else + out = val | val << 8 | val << 16; if (vid_priv->colour_fg) *dst++ |= out; else diff --git a/drivers/video/mali_dp.c b/drivers/video/mali_dp.c index cbcdb99e1f0..dbb2f538617 100644 --- a/drivers/video/mali_dp.c +++ b/drivers/video/mali_dp.c @@ -360,25 +360,18 @@ static int malidp_probe(struct udevice *dev) err = malidp_setup_mode(priv, &timings); if (err) - goto fail_timings; + return err; malidp_setup_layer(priv, &timings, MALIDP_LAYER_LV1, (phys_addr_t)uc_plat->base); err = malidp_leave_config(priv); if (err) - goto fail_timings; + return err; malidp_set_configvalid(priv); return 0; - -fail_timings: - clk_free(&priv->aclk); -fail_aclk: - clk_free(&priv->pxlclk); - - return err; } static int malidp_bind(struct udevice *dev) diff --git a/drivers/video/rockchip/rk3288_hdmi.c b/drivers/video/rockchip/rk3288_hdmi.c index 327ae787125..8bedee55ad4 100644 --- a/drivers/video/rockchip/rk3288_hdmi.c +++ b/drivers/video/rockchip/rk3288_hdmi.c @@ -67,10 +67,8 @@ static int rk3288_clk_config(struct udevice *dev) * monitor wants */ ret = clk_get_by_index(uc_plat->src_dev, 0, &clk); - if (ret >= 0) { + if (ret >= 0) ret = clk_set_rate(&clk, 384000000); - clk_free(&clk); - } if (ret < 0) { debug("%s: Failed to set clock in source device '%s': ret=%d\n", __func__, uc_plat->src_dev->name, ret); diff --git a/drivers/video/rockchip/rk_edp.c b/drivers/video/rockchip/rk_edp.c index 3697d582510..dbd70ad583a 100644 --- a/drivers/video/rockchip/rk_edp.c +++ b/drivers/video/rockchip/rk_edp.c @@ -1095,20 +1095,16 @@ static int rk_edp_probe(struct udevice *dev) if (edp_data->chip_type == RK3288_DP) { ret = clk_get_by_index(dev, 1, &clk); - if (ret >= 0) { + if (ret >= 0) ret = clk_set_rate(&clk, 0); - clk_free(&clk); - } if (ret) { debug("%s: Failed to set EDP clock: ret=%d\n", __func__, ret); return ret; } } ret = clk_get_by_index(uc_plat->src_dev, 0, &clk); - if (ret >= 0) { + if (ret >= 0) ret = clk_set_rate(&clk, 192000000); - clk_free(&clk); - } if (ret < 0) { debug("%s: Failed to set clock in source device '%s': ret=%d\n", __func__, uc_plat->src_dev->name, ret); diff --git a/drivers/video/tidss/tidss_drv.c b/drivers/video/tidss/tidss_drv.c index e285f255d76..1380c6b6937 100644 --- a/drivers/video/tidss/tidss_drv.c +++ b/drivers/video/tidss/tidss_drv.c @@ -107,7 +107,7 @@ const struct dss_features dss_am625_feats = { .num_planes = 2, /* note: vid is plane_id 0 and vidl1 is plane_id 1 */ - .vid_name = { "vidl1", "vid1" }, + .vid_name = { "vidl1", "vid" }, .vid_lite = { true, false }, .vid_order = { 1, 0 }, }; @@ -814,13 +814,13 @@ static int tidss_drv_probe(struct udevice *dev) priv->bus_format = &dss_bus_formats[8]; /* Common address */ - priv->base_common = dev_remap_addr_index(dev, 0); + priv->base_common = dev_remap_addr_name(dev, priv->feat->common); if (!priv->base_common) return -EINVAL; /* plane address setup and enable */ for (i = 0; i < priv->feat->num_planes; i++) { - priv->base_vid[i] = dev_remap_addr_index(dev, i + 2); + priv->base_vid[i] = dev_remap_addr_name(dev, priv->feat->vid_name[i]); if (!priv->base_vid[i]) return -EINVAL; } @@ -841,8 +841,8 @@ static int tidss_drv_probe(struct udevice *dev) /* video port address clocks and enable */ for (i = 0; i < priv->feat->num_vps; i++) { - priv->base_ovr[i] = dev_remap_addr_index(dev, i + 4); - priv->base_vp[i] = dev_remap_addr_index(dev, i + 6); + priv->base_ovr[i] = dev_remap_addr_name(dev, priv->feat->ovr_name[i]); + priv->base_vp[i] = dev_remap_addr_name(dev, priv->feat->vp_name[i]); } ret = clk_get_by_name(dev, "vp1", &priv->vp_clk[0]); diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index f743ed74c81..3571e62ba2d 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -123,6 +123,9 @@ int video_reserve(ulong *addrp) struct udevice *dev; ulong size; + if (IS_ENABLED(CONFIG_SPL_VIDEO_HANDOFF) && spl_phase() == PHASE_BOARD_F) + return 0; + gd->video_top = *addrp; for (uclass_find_first_device(UCLASS_VIDEO, &dev); dev; @@ -141,16 +144,6 @@ int video_reserve(ulong *addrp) debug("Video frame buffers from %lx to %lx\n", gd->video_bottom, gd->video_top); - if (spl_phase() == PHASE_SPL && CONFIG_IS_ENABLED(VIDEO_HANDOFF)) { - struct video_handoff *ho; - - ho = bloblist_add(BLOBLISTT_U_BOOT_VIDEO, sizeof(*ho), 0); - if (!ho) - return log_msg_ret("blf", -ENOENT); - ho->fb = *addrp; - ho->size = size; - } - return 0; } @@ -208,11 +201,14 @@ int video_fill_part(struct udevice *dev, int xstart, int ystart, int xend, int video_reserve_from_bloblist(struct video_handoff *ho) { + if (!ho->fb || ho->size == 0) + return -ENOENT; + gd->video_bottom = ho->fb; gd->fb_base = ho->fb; gd->video_top = ho->fb + ho->size; - debug("Reserving %luk for video using blob at: %08x\n", - ((unsigned long)ho->size) >> 10, (u32)ho->fb); + debug("%s: Reserving %lx bytes at %08x as per bloblist received\n", + __func__, (unsigned long)ho->size, (u32)ho->fb); return 0; } @@ -546,6 +542,26 @@ static int video_post_probe(struct udevice *dev) priv->fb_size = priv->line_length * priv->ysize; + /* + * Set up video handoff fields for passing video blob to next stage + * NOTE: + * This assumes that reserved video memory only uses a single framebuffer + */ + if (spl_phase() == PHASE_SPL && CONFIG_IS_ENABLED(BLOBLIST)) { + struct video_handoff *ho; + + ho = bloblist_add(BLOBLISTT_U_BOOT_VIDEO, sizeof(*ho), 0); + if (!ho) + return log_msg_ret("blf", -ENOENT); + ho->fb = gd->video_bottom; + /* Fill aligned size here as calculated in video_reserve() */ + ho->size = gd->video_top - gd->video_bottom; + ho->xsize = priv->xsize; + ho->ysize = priv->ysize; + ho->line_length = priv->line_length; + ho->bpix = priv->bpix; + } + if (IS_ENABLED(CONFIG_VIDEO_COPY) && plat->copy_base) priv->copy_fb = map_sysmem(plat->copy_base, plat->size); diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 569726119ca..8318fd77a32 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -130,6 +130,12 @@ config WDT_AT91 Select this to enable Microchip watchdog timer, which can be found on some AT91 devices. +config WDT_ATCWDT200 + bool "Andes watchdog timer support" + depends on WDT + help + Select this to enable Andes ATCWDT200 watchdog timer + config WDT_BCM6345 bool "BCM6345 watchdog timer support" depends on WDT && (ARCH_BMIPS || BCM6856 || \ diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 5520d3d9ae8..7b39adcf0ff 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_WDT_ARM_SMC) += arm_smc_wdt.o obj-$(CONFIG_WDT_ARMADA_37XX) += armada-37xx-wdt.o obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o obj-$(CONFIG_WDT_AST2600) += ast2600_wdt.o +obj-$(CONFIG_WDT_ATCWDT200) += atcwdt200_wdt.o obj-$(CONFIG_WDT_BCM2835) += bcm2835_wdt.o obj-$(CONFIG_WDT_BCM6345) += bcm6345_wdt.o obj-$(CONFIG_WDT_BOOKE) += booke_wdt.o diff --git a/drivers/watchdog/atcwdt200_wdt.c b/drivers/watchdog/atcwdt200_wdt.c new file mode 100644 index 00000000000..a29b42d607e --- /dev/null +++ b/drivers/watchdog/atcwdt200_wdt.c @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023 Andes Technology Corporation. + * + */ + +#include <asm/io.h> +#include <dm.h> +#include <hang.h> +#include <linux/bitops.h> +#include <wdt.h> + +#define NODE_NOT_FOUND 0xFFFFFFFF + +#define WDT_WP_MAGIC 0x5aa5 +#define WDT_RESTART_MAGIC 0xcafe + +/* Control Register */ +#define REG_WDT_ID 0x00 +#define REG_WDT_CFG 0x10 +#define REG_WDT_RS 0x14 +#define REG_WDT_WE 0x18 +#define REG_WDT_STA 0x1C + +#define RST_TIME_OFF 8 +#define RST_TIME_MSK (0x7 << RST_TIME_OFF) +#define RST_CLK_128 (0 << RST_TIME_OFF) +#define RST_CLK_256 (1 << RST_TIME_OFF) +#define RST_CLK_512 (2 << RST_TIME_OFF) +#define RST_CLK_1024 (3 << RST_TIME_OFF) +#define INT_TIME_OFF 4 +#define INT_TIME_MSK (0xf << INT_TIME_OFF) +#define INT_CLK_2_6 (0 << INT_TIME_OFF) /* clk period*2^6 */ +#define INT_CLK_2_8 (1 << INT_TIME_OFF) /* clk period*2^8 */ +#define INT_CLK_2_10 (2 << INT_TIME_OFF) /* clk period*2^10 */ +#define INT_CLK_2_11 (3 << INT_TIME_OFF) /* clk period*2^11 */ +#define INT_CLK_2_12 (4 << INT_TIME_OFF) /* clk period*2^12 */ +#define INT_CLK_2_13 (5 << INT_TIME_OFF) /* clk period*2^13 */ +#define INT_CLK_2_14 (6 << INT_TIME_OFF) /* clk period*2^14 */ +#define INT_CLK_2_15 (7 << INT_TIME_OFF) /* clk period*2^15 */ +#define INT_CLK_2_17 (8 << INT_TIME_OFF) /* clk period*2^17 */ +#define INT_CLK_2_19 (9 << INT_TIME_OFF) /* clk period*2^19 */ +#define INT_CLK_2_21 (10 << INT_TIME_OFF) /* clk period*2^21 */ +#define INT_CLK_2_23 (11 << INT_TIME_OFF) /* clk period*2^23 */ +#define INT_CLK_2_25 (12 << INT_TIME_OFF) /* clk period*2^25 */ +#define INT_CLK_2_27 (13 << INT_TIME_OFF) /* clk period*2^27 */ +#define INT_CLK_2_29 (14 << INT_TIME_OFF) /* clk period*2^29 */ +#define INT_CLK_2_31 (15 << INT_TIME_OFF) /* clk period*2^31 */ +#define INT_CLK_MIN 0x0 +#define INT_CLK_MAX_16B 0x7 +#define INT_CLK_MAX_32B 0xF +#define RST_EN BIT(3) +#define INT_EN BIT(2) +#define CLK_PCLK BIT(1) +#define WDT_EN BIT(0) +#define INT_EXPIRED BIT(0) + +#define INT_TIME_ARRAY 16 +#define RST_TIME_ARRAY 8 + +struct wdt_priv { + void __iomem *base; + u32 wdt_clk_src; + u32 clk_freq; + u8 max_clk; +}; + +static inline u8 atcwdt_get_2_power_of_n(u8 index, u8 type) +{ + const u8 div_int[INT_TIME_ARRAY] = {6, 8, 10, 11, 12, 13, 14, 15, + 17, 19, 21, 23, 25, 27, 29, 31}; + const u8 div_rst[RST_TIME_ARRAY] = {7, 8, 9, 10, 11, 12, 13, 14}; + const u8 *pdiv; + + if (type == RST_TIME_ARRAY) + pdiv = div_rst; + else + pdiv = div_int; + + if (index >= type) + index = type - 1; + + return pdiv[index]; +} + +static u8 atcwdt_search_msb(u64 freq_ms, u8 type) +{ + u64 result; + u64 freq_sec; + u8 index; + + freq_sec = freq_ms / 1000; + for (index = 0; index < type; index++) { + result = freq_sec >> atcwdt_get_2_power_of_n(index, type); + + if (result <= 1) + break; + } + + return index; +} + +static int atcwdt_wdt_start(struct udevice *dev, u64 timeout, ulong flags) +{ + struct wdt_priv *priv = dev_get_priv(dev); + u64 rst_max_count; + u32 rst_max_time_ms; + u64 rst_time_ms; + u64 int_time_ms; + u8 rst_time; + u8 int_time; + + rst_max_count = 1 << atcwdt_get_2_power_of_n(RST_TIME_ARRAY, RST_TIME_ARRAY); + rst_max_time_ms = (rst_max_count * 1000) / priv->clk_freq; + + if (timeout > rst_max_time_ms) { + int_time_ms = timeout - rst_max_time_ms; + rst_time_ms = rst_max_time_ms; + } else { + int_time_ms = 0; + rst_time_ms = timeout; + } + + rst_time = atcwdt_search_msb(rst_time_ms * priv->clk_freq, RST_TIME_ARRAY); + + if (int_time_ms) { + int_time = atcwdt_search_msb(int_time_ms * priv->clk_freq, INT_TIME_ARRAY); + if (int_time > priv->max_clk) + int_time = priv->max_clk; + } else { + int_time = 0; + } + + writel(WDT_WP_MAGIC, priv->base + REG_WDT_WE); + writel(((rst_time << RST_TIME_OFF) & RST_TIME_MSK) | ((int_time << INT_TIME_OFF) & + INT_TIME_MSK) | INT_EN | RST_EN | priv->wdt_clk_src | WDT_EN, + priv->base + REG_WDT_CFG); + + return 0; +} + +static int atcwdt_wdt_stop(struct udevice *dev) +{ + struct wdt_priv *priv = dev_get_priv(dev); + + writel(WDT_WP_MAGIC, priv->base + REG_WDT_WE); + writel(0, priv->base + REG_WDT_CFG); + + return 0; +} + +static int atcwdt_wdt_restart(struct udevice *dev) +{ + struct wdt_priv *priv = dev_get_priv(dev); + + writel(WDT_WP_MAGIC, priv->base + REG_WDT_WE); + writel(WDT_RESTART_MAGIC, priv->base + REG_WDT_RS); + setbits_le32(priv->base + REG_WDT_STA, INT_EXPIRED); + + return 0; +} + +static int atcwdt_wdt_expire_now(struct udevice *dev, ulong flags) +{ + atcwdt_wdt_start(dev, 0, 0); + hang(); + + return 0; +} + +static int atcwdt_wdt_probe(struct udevice *dev) +{ + struct wdt_priv *priv = dev_get_priv(dev); + int timer_16bit; + + priv->base = dev_remap_addr_index(dev, 0); + if (!priv->base) + return -EFAULT; + + priv->wdt_clk_src = dev_read_u32_default(dev, "clock-source", NODE_NOT_FOUND); + if (priv->wdt_clk_src == NODE_NOT_FOUND || priv->wdt_clk_src > 1) + priv->wdt_clk_src = CLK_PCLK; + + timer_16bit = dev_read_u32_default(dev, "16bit_timer", NODE_NOT_FOUND); + if (timer_16bit == 1 || timer_16bit == NODE_NOT_FOUND) + priv->max_clk = INT_CLK_MAX_16B; + else + priv->max_clk = INT_CLK_MAX_32B; + + priv->clk_freq = dev_read_u32_default(dev, "clock-frequency", NODE_NOT_FOUND); + if (priv->clk_freq == NODE_NOT_FOUND) { + printf("atcwdt200: Please provide a valid \"clock-frequency\" in DTB\n"); + return -EINVAL; + } + + atcwdt_wdt_stop(dev); + + return 0; +} + +static const struct wdt_ops atcwdt_wdt_ops = { + .start = atcwdt_wdt_start, + .reset = atcwdt_wdt_restart, + .stop = atcwdt_wdt_stop, + .expire_now = atcwdt_wdt_expire_now, +}; + +static const struct udevice_id atcwdt_wdt_ids[] = { + {.compatible = "andestech,atcwdt200"}, + {} +}; + +U_BOOT_DRIVER(atcwdt) = { + .name = "atcwdt200", + .id = UCLASS_WDT, + .probe = atcwdt_wdt_probe, + .of_match = atcwdt_wdt_ids, + .ops = &atcwdt_wdt_ops, + .priv_auto = sizeof(struct wdt_priv), +}; diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c index 447a22d3b36..b22e0ee06a4 100644 --- a/drivers/watchdog/designware_wdt.c +++ b/drivers/watchdog/designware_wdt.c @@ -124,13 +124,11 @@ static int designware_wdt_probe(struct udevice *dev) ret = clk_enable(&clk); if (ret) - goto err; + return ret; priv->clk_khz = clk_get_rate(&clk) / 1000; - if (!priv->clk_khz) { - ret = -EINVAL; - goto err; - } + if (!priv->clk_khz) + return -EINVAL; #else priv->clk_khz = CFG_DW_WDT_CLOCK_KHZ; #endif @@ -139,21 +137,15 @@ static int designware_wdt_probe(struct udevice *dev) ofnode_read_prop(dev_ofnode(dev), "resets", &ret)) { ret = reset_get_bulk(dev, &priv->resets); if (ret) - goto err; + return ret; ret = reset_deassert_bulk(&priv->resets); if (ret) - goto err; + return ret; } /* reset to disable the watchdog */ return designware_wdt_stop(dev); - -err: -#if CONFIG_IS_ENABLED(CLK) - clk_free(&clk); -#endif - return ret; } static const struct wdt_ops designware_wdt_ops = { diff --git a/drivers/watchdog/meson_gxbb_wdt.c b/drivers/watchdog/meson_gxbb_wdt.c index 6ab005813f9..01a35b3ab30 100644 --- a/drivers/watchdog/meson_gxbb_wdt.c +++ b/drivers/watchdog/meson_gxbb_wdt.c @@ -98,10 +98,8 @@ static int amlogic_wdt_probe(struct udevice *dev) return ret; ret = clk_enable(&clk); - if (ret) { - clk_free(&clk); + if (ret) return ret; - } /* Setup with 1ms timebase */ writel(((clk_get_rate(&clk) / 1000) & GXBB_WDT_CTRL_DIV_MASK) | @@ -210,8 +210,10 @@ static int env_sf_save(void) saved_size = sect_size - CONFIG_ENV_SIZE; saved_offset = CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE; saved_buffer = malloc(saved_size); - if (!saved_buffer) + if (!saved_buffer) { + ret = -ENOMEM; goto done; + } ret = spi_flash_read(env_flash, saved_offset, saved_size, saved_buffer); diff --git a/include/clk-uclass.h b/include/clk-uclass.h index cd62848bece..8c07e723cff 100644 --- a/include/clk-uclass.h +++ b/include/clk-uclass.h @@ -18,7 +18,6 @@ struct ofnode_phandle_args; * struct clk_ops - The functions that a clock driver must implement. * @of_xlate: Translate a client's device-tree (OF) clock specifier. * @request: Request a translated clock. - * @rfree: Free a previously requested clock. * @round_rate: Adjust a rate to the exact rate a clock can provide. * @get_rate: Get current clock rate. * @set_rate: Set current clock rate. @@ -33,7 +32,6 @@ struct clk_ops { int (*of_xlate)(struct clk *clock, struct ofnode_phandle_args *args); int (*request)(struct clk *clock); - void (*rfree)(struct clk *clock); ulong (*round_rate)(struct clk *clk, ulong rate); ulong (*get_rate)(struct clk *clk); ulong (*set_rate)(struct clk *clk, ulong rate); @@ -58,11 +56,20 @@ struct clk_ops { * default implementation, which assumes #clock-cells = <1>, and that * the DT cell contains a simple integer clock ID. * + * This function should be a simple translation of @args into @clock->id and + * (optionally) @clock->data. All other processing, allocation, or error + * checking should take place in request(). + * * At present, the clock API solely supports device-tree. If this * changes, other xxx_xlate() functions may be added to support those * other mechanisms. * - * Return: 0 if OK, or a negative error code. + * Return: + * * 0 on success + * * -%EINVAL if @args does not have the correct format. For example, it could + * have too many/few arguments. + * * -%ENOENT if @args has the correct format but cannot be translated. This can + * happen if translation involves a table lookup and @args is not present. */ int of_xlate(struct clk *clock, struct ofnode_phandle_args *args); @@ -77,24 +84,36 @@ int of_xlate(struct clk *clock, struct ofnode_phandle_args *args); * xxx_xlate() call, or as the only step in implementing a client's * clk_request() call. * - * Return: 0 if OK, or a negative error code. - */ -int request(struct clk *clock); - -/** - * rfree() - Free a previously requested clock. - * @clock: The clock to free. + * This is the right place to do bounds checking (rejecting invalid or + * unimplemented clocks), allocate resources, or perform other setup not done + * during driver probe(). Most clock drivers should allocate resources in their + * probe() function, but it is possible to lazily initialize something here. * - * Free any resources allocated in request(). + * Return: + * * 0 on success + * * -%ENOENT, if there is no clock corresponding to @clock->id and + * @clock->data. */ -void rfree(struct clk *clock); +int request(struct clk *clock); /** * round_rate() - Adjust a rate to the exact rate a clock can provide. - * @clk: The clock to manipulate. - * @rate: Desidered clock rate in Hz. + * @clk: The clock to query. + * @rate: Desired clock rate in Hz. + * + * This function returns a new rate which can be provided to set_rate(). This + * new rate should be the closest rate to @rate which can be set without + * rounding. The following pseudo-code should hold:: * - * Return: rounded rate in Hz, or -ve error code. + * for all rate in range(ULONG_MAX): + * rounded = round_rate(clk, rate) + * new_rate = set_rate(clk, rate) + * assert(IS_ERR_VALUE(new_rate) || new_rate == rounded) + * + * Return: + * * The rounded rate in Hz on success + * * A negative error value from another API (such as clk_get_rate()). This + * function must not return an error for any other reason. */ ulong round_rate(struct clk *clk, ulong rate); @@ -102,7 +121,22 @@ ulong round_rate(struct clk *clk, ulong rate); * get_rate() - Get current clock rate. * @clk: The clock to query. * - * Return: clock rate in Hz, or -ve error code + * This returns the current rate of a clock. If the clock is disabled, it + * returns the rate at which the clock would run if it was enabled. The + * following pseudo-code should hold:: + * + * disable(clk) + * rate = get_rate(clk) + * enable(clk) + * assert(get_rate(clk) == rate) + * + * Return: + * * The rate of @clk + * * -%ENOSYS if this function is not implemented for @clk + * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing + * this check in request(). + * * Another negative error value (such as %EIO or %ECOMM) if the rate could + * not be determined due to a bus error. */ ulong get_rate(struct clk *clk); @@ -111,7 +145,27 @@ ulong get_rate(struct clk *clk); * @clk: The clock to manipulate. * @rate: New clock rate in Hz. * - * Return: new rate, or -ve error code. + * Set the rate of @clk to @rate. The actual rate may be rounded. However, + * excessive rounding should be avoided. It is left to the driver author's + * discretion when this function should attempt to round and when it should + * return an error. For example, a dividing clock might use the following + * pseudo-logic when implemening this function:: + * + * divisor = parent_rate / rate + * if divisor < min || divisor > max: + * return -EINVAL + * + * If there is any concern about rounding, prefer to let consumers make the + * decision by calling round_rate(). + * + * Return: + * * The new rate on success + * * -%ENOSYS if this function is not implemented for @clk + * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing + * this check in request(). + * * -%EINVAL if @rate is not valid for @clk. + * * Another negative error value (such as %EIO or %ECOMM) if the rate could + * not be set due to a bus error. */ ulong set_rate(struct clk *clk, ulong rate); @@ -120,7 +174,19 @@ ulong set_rate(struct clk *clk, ulong rate); * @clk: The clock to manipulate. * @parent: New clock parent. * - * Return: zero on success, or -ve error code. + * Set the current parent of @clk to @parent. The rate of the clock may be + * modified by this call. If @clk was enabled before this function, it should + * remain enabled after this function, although it may be temporarily disabled + * if necessary. + * + * Return: + * * 0 on success + * * -%ENOSYS if this function is not implemented for @clk + * * -%ENOENT if @clk->id or @parent->id is invalid. Prefer using an assert + * instead, and doing this check in request(). + * * -%EINVAL if @parent is not a valid parent for @clk. + * * Another negative error value (such as %EIO or %ECOMM) if the parent could + * not be set due to a bus error. */ int set_parent(struct clk *clk, struct clk *parent); @@ -128,7 +194,16 @@ int set_parent(struct clk *clk, struct clk *parent); * enable() - Enable a clock. * @clk: The clock to manipulate. * - * Return: zero on success, or -ve error code. + * Enable (un-gate) the clock. This function should not modify the rate of the + * clock (see get_rate() for details). + * + * Return: + * * 0 on success + * * -%ENOSYS if this function is not implemented for @clk + * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing + * this check in request(). + * * Another negative error value (such as %EIO or %ECOMM) if the clock could + * not be enabled due to a bus error. */ int enable(struct clk *clk); @@ -136,7 +211,15 @@ int enable(struct clk *clk); * disable() - Disable a clock. * @clk: The clock to manipulate. * - * Return: zero on success, or -ve error code. + * Disable (gate) the clock. This function should not modify the rate of the + * clock (see get_rate() for details). + * + * * 0 on success + * * -%ENOSYS if this function is not implemented for @clk + * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing + * this check in request(). + * * Another negative error value (such as %EIO or %ECOMM) if the clock could + * not be disabled due to a bus error. */ int disable(struct clk *clk); diff --git a/include/clk.h b/include/clk.h index 3d6394477be..af23e4f3475 100644 --- a/include/clk.h +++ b/include/clk.h @@ -247,19 +247,6 @@ static inline struct clk *devm_clk_get_optional(struct udevice *dev, */ int clk_release_all(struct clk *clk, unsigned int count); -/** - * devm_clk_put - "free" a managed clock source - * @dev: device used to acquire the clock - * @clk: clock source acquired with devm_clk_get() - * - * Note: drivers must ensure that all clk_enable calls made on this - * clock source are balanced by clk_disable calls prior to calling - * this function. - * - * clk_put should not be called from within interrupt context. - */ -void devm_clk_put(struct udevice *dev, struct clk *clk); - #else static inline int clk_get_by_phandle(struct udevice *dev, const @@ -313,10 +300,6 @@ static inline int clk_release_all(struct clk *clk, unsigned int count) { return -ENOSYS; } - -static inline void devm_clk_put(struct udevice *dev, struct clk *clk) -{ -} #endif /** @@ -442,15 +425,6 @@ static inline int clk_release_bulk(struct clk_bulk *bulk) int clk_request(struct udevice *dev, struct clk *clk); /** - * clk_free() - Free a previously requested clock. - * @clk: A clock struct that was previously successfully requested by - * clk_request/get_by_*(). - * - * Free resources allocated by clk_request() (or any clk_get_* function). - */ -void clk_free(struct clk *clk); - -/** * clk_get_rate() - Get current clock rate. * @clk: A clock struct that was previously successfully requested by * clk_request/get_by_*(). @@ -594,11 +568,6 @@ static inline int clk_request(struct udevice *dev, struct clk *clk) return -ENOSYS; } -static inline void clk_free(struct clk *clk) -{ - return; -} - static inline ulong clk_get_rate(struct clk *clk) { return -ENOSYS; diff --git a/include/configs/milkv_duo.h b/include/configs/milkv_duo.h new file mode 100644 index 00000000000..0b4109dc1f7 --- /dev/null +++ b/include/configs/milkv_duo.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com> + * + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define CFG_SYS_SDRAM_BASE 0x80000000 + +#endif /* __CONFIG_H */ diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h index 584559cfa32..2f594bfcfd6 100644 --- a/include/configs/qemu-riscv.h +++ b/include/configs/qemu-riscv.h @@ -23,6 +23,7 @@ #define BOOT_TARGET_DEVICES(func) \ func(VIRTIO, virtio, 0) \ + func(VIRTIO, virtio, 1) \ func(SCSI, scsi, 0) \ func(DHCP, dhcp, na) diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index b8ca77d031d..b29a25d5617 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -14,8 +14,9 @@ #include <linux/stringify.h> -/* Serial & console */ -/* ns16550 reg in the low bits of cpu reg */ +/**************************************************************************** + * base addresses for the SPL UART driver * + ****************************************************************************/ #ifdef CONFIG_MACH_SUNIV /* suniv doesn't have apb2 and uart is connected to apb1 */ #define CFG_SYS_NS16550_CLK 100000000 @@ -31,8 +32,9 @@ # define CFG_SYS_NS16550_COM5 SUNXI_R_UART_BASE #endif -/* CPU */ - +/**************************************************************************** + * DRAM base address * + ****************************************************************************/ /* * The DRAM Base differs between some models. We cannot use macros for the * CONFIG_FOO defines which contain the DRAM base address since they end @@ -52,16 +54,6 @@ /* V3s do not have enough memory to place code at 0x4a000000 */ #endif -/* - * The A80's A1 sram starts at 0x00010000 rather then at 0x00000000 and is - * slightly bigger. Note that it is possible to map the first 32 KiB of the - * A1 at 0x00000000 like with older SoCs by writing 0x16aa0001 to the - * undocumented 0x008000e0 SYS_CTRL register. Where the 16aa is a key and - * the 1 actually activates the mapping of the first 32 KiB to 0x00000000. - * A64 and H5 also has SRAM A1 at 0x00010000, but no magic remap register - * is known yet. - * H6 has SRAM A1 at 0x00020000. - */ #define CFG_SYS_INIT_RAM_ADDR CONFIG_SUNXI_SRAM_ADDRESS /* FIXME: this may be larger on some SoCs */ #define CFG_SYS_INIT_RAM_SIZE 0x8000 /* 32 KiB */ @@ -69,36 +61,13 @@ #define PHYS_SDRAM_0 CFG_SYS_SDRAM_BASE #define PHYS_SDRAM_0_SIZE 0x80000000 /* 2 GiB */ -/* - * Miscellaneous configurable options - */ - -/* FLASH and environment organization */ - +/**************************************************************************** + * environment variables holding default load addresses * + ****************************************************************************/ /* * We cannot use expressions here, because expressions won't be evaluated in * autoconf.mk. */ -#if CONFIG_SUNXI_SRAM_ADDRESS == 0x10000 -#ifdef CONFIG_ARM64 -/* end of SRAM A2 for now, as SRAM A1 is pretty tight for an ARM64 build */ -#define LOW_LEVEL_SRAM_STACK 0x00054000 -#else -#define LOW_LEVEL_SRAM_STACK 0x00018000 -#endif /* !CONFIG_ARM64 */ -#elif CONFIG_SUNXI_SRAM_ADDRESS == 0x20000 -#ifdef CONFIG_MACH_SUN50I_H616 -#define LOW_LEVEL_SRAM_STACK 0x52a00 /* below FEL buffers */ -#else -/* end of SRAM A2 on H6 for now */ -#define LOW_LEVEL_SRAM_STACK 0x00118000 -#endif -#else -#define LOW_LEVEL_SRAM_STACK 0x00008000 /* End of sram */ -#endif - -/* Ethernet support */ - #ifdef CONFIG_ARM64 /* * Boards seem to come with at least 512MB of DRAM. @@ -174,15 +143,11 @@ "ramdisk_addr_r=" RAMDISK_ADDR_R "\0" #ifdef CONFIG_ARM64 - #define MEM_LAYOUT_ENV_EXTRA_SETTINGS \ "kernel_comp_addr_r=" KERNEL_COMP_ADDR_R "\0" \ "kernel_comp_size=" KERNEL_COMP_SIZE "\0" - #else - #define MEM_LAYOUT_ENV_EXTRA_SETTINGS "" - #endif #define DFU_ALT_INFO_RAM \ @@ -191,6 +156,9 @@ "fdt ram " FDT_ADDR_R " 0x100000;" \ "ramdisk ram " RAMDISK_ADDR_R " 0x4000000\0" +/**************************************************************************** + * definitions for the distro boot system * + ****************************************************************************/ #ifdef CONFIG_MMC #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1 #define BOOTENV_DEV_MMC_AUTO(devtypeu, devtypel, instance) \ diff --git a/include/efi_loader.h b/include/efi_loader.h index d5fca2fa5ef..7daca0afba2 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -340,6 +340,7 @@ extern const efi_guid_t efi_guid_firmware_management_protocol; extern const efi_guid_t efi_esrt_guid; /* GUID of the SMBIOS table */ extern const efi_guid_t smbios_guid; +extern const efi_guid_t smbios3_guid; /*GUID of console */ extern const efi_guid_t efi_guid_text_input_protocol; extern const efi_guid_t efi_guid_text_output_protocol; @@ -545,6 +546,8 @@ void efi_setup_console_size(void); /* Set up load options from environment variable */ efi_status_t efi_env_set_load_options(efi_handle_t handle, const char *env_var, u16 **load_options); +/* Get EFI configuration table */ +void *efi_get_configuration_table(const efi_guid_t *guid); /* Install device tree */ efi_status_t efi_install_fdt(void *fdt); /* Execute loaded UEFI image */ diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 2861b73edbc..d1dbf3eadbf 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -136,14 +136,6 @@ #define SPINOR_OP_BRRD 0x16 /* Bank register read */ #define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ #define SPINOR_OP_EX4B_CYPRESS 0xB8 /* Exit 4-byte mode */ -#define SPINOR_OP_RDAR 0x65 /* Read any register */ -#define SPINOR_OP_WRAR 0x71 /* Write any register */ -#define SPINOR_REG_ADDR_STR1V 0x00800000 -#define SPINOR_REG_ADDR_CFR1V 0x00800002 -#define SPINOR_REG_ADDR_CFR3V 0x00800004 -#define SPINOR_REG_ADDR_ARCFN 0x00000006 -#define CFR3V_UNHYSA BIT(3) /* Uniform sectors or not */ -#define CFR3V_PGMBUF BIT(4) /* Program buffer size */ /* Used for Micron flashes only. */ #define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */ @@ -188,8 +180,12 @@ /* For Cypress flash. */ #define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */ #define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */ -#define SPINOR_OP_S28_SE_4K 0x21 +#define SPINOR_OP_CYPRESS_CLPEF 0x82 /* Clear P/E err flag */ +#define SPINOR_REG_CYPRESS_ARCFN 0x00000006 +#define SPINOR_REG_CYPRESS_STR1V 0x00800000 +#define SPINOR_REG_CYPRESS_CFR1V 0x00800002 #define SPINOR_REG_CYPRESS_CFR2V 0x00800003 +#define SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK GENMASK(3, 0) #define SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24 0xb #define SPINOR_REG_CYPRESS_CFR3V 0x00800004 #define SPINOR_REG_CYPRESS_CFR3_PGSZ BIT(4) /* Page size. */ diff --git a/include/smbios.h b/include/smbios.h index b507b9d9d72..3df8827b60d 100644 --- a/include/smbios.h +++ b/include/smbios.h @@ -75,7 +75,7 @@ struct __packed smbios3_entry { /** @reserved: reserved */ u8 reserved; /** maximum size of SMBIOS table */ - u32 max_struct_size; + u32 table_maximum_size; /** @struct_table_address: 64-bit physical starting address */ u64 struct_table_address; }; @@ -139,6 +139,7 @@ struct __packed smbios_type2 { u8 chassis_location; u16 chassis_handle; u8 board_type; + u8 number_contained_objects; char eos[SMBIOS_STRUCT_EOS_BYTES]; }; @@ -326,10 +327,10 @@ int smbios_update_version_full(void *smbios_tab, const char *version); * This function clear the device dependent parameters such as * serial number for the measurement. * - * @entry: pointer to a struct smbios_entry + * @entry: pointer to a struct smbios3_entry * @header: pointer to a struct smbios_header */ -void smbios_prepare_measurement(const struct smbios_entry *entry, +void smbios_prepare_measurement(const struct smbios3_entry *entry, struct smbios_header *header); #endif /* _SMBIOS_H_ */ diff --git a/include/spl.h b/include/spl.h index 09521889014..043875f10f4 100644 --- a/include/spl.h +++ b/include/spl.h @@ -889,6 +889,16 @@ int spl_usb_load(struct spl_image_info *spl_image, int spl_ymodem_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev); +/** + * spl_reserve_video_from_ram_top() - Reserve framebuffer memory from end of RAM + * + * This enforces framebuffer reservation at SPL stage from end of RAM so that + * next stage can directly skip this pre-reserved area before carrying out + * further reservations. The allocation address is stored in struct video_uc_plat. + * + * Return: 0 on success, otherwise error code + */ +int spl_reserve_video_from_ram_top(void); /** * spl_invoke_atf - boot using an ARM trusted firmware image diff --git a/lib/charset.c b/lib/charset.c index 89057ef7ce2..2b43175b1d9 100644 --- a/lib/charset.c +++ b/lib/charset.c @@ -570,6 +570,10 @@ int utf8_to_utf32_stream(u8 c, char *buffer) } if (pos == end) return 0; + /* + * Appending the byte lead to an invalid UTF-8 byte sequence. + * Consider it as the start of a new code sequence. + */ *buffer = 0; } } diff --git a/lib/efi_loader/efi_firmware.c b/lib/efi_loader/efi_firmware.c index 9fd13297a60..ba5aba098c0 100644 --- a/lib/efi_loader/efi_firmware.c +++ b/lib/efi_loader/efi_firmware.c @@ -400,18 +400,18 @@ efi_status_t efi_firmware_set_fmp_state_var(struct fmp_state *state, u8 image_in } size = num_banks * sizeof(*var_state); - var_state = calloc(1, size); + var_state = malloc(size); if (!var_state) return EFI_OUT_OF_RESOURCES; /* * GetVariable may fail, EFI_NOT_FOUND is returned if FmpState * variable has not been set yet. - * Ignore the error here since the correct FmpState variable - * is set later. */ - efi_get_variable_int(varname, image_type_id, NULL, &size, var_state, - NULL); + ret = efi_get_variable_int(varname, image_type_id, NULL, &size, + var_state, NULL); + if (ret != EFI_SUCCESS) + memset(var_state, 0, num_banks * sizeof(*var_state)); /* * Only the fw_version is set here. diff --git a/lib/efi_loader/efi_helper.c b/lib/efi_loader/efi_helper.c index 11066eb505d..5dd9cc876e4 100644 --- a/lib/efi_loader/efi_helper.c +++ b/lib/efi_loader/efi_helper.c @@ -380,12 +380,12 @@ done: } /** - * get_config_table() - get configuration table + * efi_get_configuration_table() - get configuration table * * @guid: GUID of the configuration table * Return: pointer to configuration table or NULL */ -static void *get_config_table(const efi_guid_t *guid) +void *efi_get_configuration_table(const efi_guid_t *guid) { size_t i; @@ -430,7 +430,7 @@ efi_status_t efi_install_fdt(void *fdt) uintptr_t fdt_addr; /* Look for device tree that is already installed */ - if (get_config_table(&efi_guid_fdt)) + if (efi_get_configuration_table(&efi_guid_fdt)) return EFI_SUCCESS; /* Check if there is a hardware device tree */ fdt_opt = env_get("fdt_addr"); diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index 8db35d0b3c8..b07e0099c27 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -1075,12 +1075,17 @@ error: */ static efi_status_t tcg2_measure_smbios(struct udevice *dev, - const struct smbios_entry *entry) + const struct smbios3_entry *entry) { efi_status_t ret; struct smbios_header *smbios_copy; struct smbios_handoff_table_pointers2 *event = NULL; u32 event_size; + const char smbios3_anchor[] = "_SM3_"; + + /* We only support SMBIOS 3.0 Entry Point structure */ + if (memcmp(entry->anchor, smbios3_anchor, sizeof(smbios3_anchor) - 1)) + return EFI_UNSUPPORTED; /* * TCG PC Client PFP Spec says @@ -1093,7 +1098,7 @@ tcg2_measure_smbios(struct udevice *dev, */ event_size = sizeof(struct smbios_handoff_table_pointers2) + FIELD_SIZEOF(struct efi_configuration_table, guid) + - entry->struct_table_length; + entry->table_maximum_size; event = calloc(1, event_size); if (!event) { ret = EFI_OUT_OF_RESOURCES; @@ -1104,11 +1109,11 @@ tcg2_measure_smbios(struct udevice *dev, memcpy(event->table_description, SMBIOS_HANDOFF_TABLE_DESC, sizeof(SMBIOS_HANDOFF_TABLE_DESC)); put_unaligned_le64(1, &event->number_of_tables); - guidcpy(&event->table_entry[0].guid, &smbios_guid); + guidcpy(&event->table_entry[0].guid, &smbios3_guid); smbios_copy = (struct smbios_header *)((uintptr_t)&event->table_entry[0].table); memcpy(&event->table_entry[0].table, (void *)((uintptr_t)entry->struct_table_address), - entry->struct_table_length); + entry->table_maximum_size); smbios_prepare_measurement(entry, smbios_copy); @@ -1124,23 +1129,6 @@ out: } /** - * find_smbios_table() - find smbios table - * - * Return: pointer to the smbios table - */ -static void *find_smbios_table(void) -{ - u32 i; - - for (i = 0; i < systab.nr_tables; i++) { - if (!guidcmp(&smbios_guid, &systab.tables[i].guid)) - return systab.tables[i].table; - } - - return NULL; -} - -/** * tcg2_measure_gpt_table() - measure gpt table * * @dev: TPM device @@ -1360,7 +1348,7 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha u32 pcr_index; struct udevice *dev; u32 event = 0; - struct smbios_entry *entry; + struct smbios3_entry *entry; if (!is_tcg2_protocol_installed()) return EFI_SUCCESS; @@ -1382,7 +1370,7 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha if (ret != EFI_SUCCESS) goto out; - entry = (struct smbios_entry *)find_smbios_table(); + entry = efi_get_configuration_table(&smbios3_guid); if (entry) { ret = tcg2_measure_smbios(dev, entry); if (ret != EFI_SUCCESS) diff --git a/lib/efi_loader/smbiosdump.c b/lib/efi_loader/smbiosdump.c index f0b901897e9..2f0b91a353d 100644 --- a/lib/efi_loader/smbiosdump.c +++ b/lib/efi_loader/smbiosdump.c @@ -329,7 +329,7 @@ efi_status_t do_check(void) return EFI_LOAD_ERROR; } table = (void *)(uintptr_t)smbios3_anchor->struct_table_address; - len = smbios3_anchor->max_struct_size; + len = smbios3_anchor->table_maximum_size; } else { struct smbios_entry *smbios_anchor; int r; @@ -469,7 +469,7 @@ static efi_status_t do_save(u16 *filename) smbios3_anchor = get_config_table(&smbios3_guid); if (smbios3_anchor) { - size = 0x20 + smbios3_anchor->max_struct_size; + size = 0x20 + smbios3_anchor->table_maximum_size; ret = bs->allocate_pool(EFI_LOADER_DATA, size, (void **)&buf); if (ret != EFI_SUCCESS) { error(u"Out of memory\n"); @@ -480,7 +480,7 @@ static efi_status_t do_save(u16 *filename) memcpy(buf, smbios3_anchor, smbios3_anchor->length); memcpy(buf + 0x20, (void *)(uintptr_t)smbios3_anchor->struct_table_address, - smbios3_anchor->max_struct_size); + smbios3_anchor->table_maximum_size); smbios3_anchor = (struct smbios3_entry *)buf; smbios3_anchor->struct_table_address = 0x20; diff --git a/lib/efi_selftest/efi_selftest_miniapp_exit.c b/lib/efi_selftest/efi_selftest_miniapp_exit.c index 8b2e60cc711..0909a5ca748 100644 --- a/lib/efi_selftest/efi_selftest_miniapp_exit.c +++ b/lib/efi_selftest/efi_selftest_miniapp_exit.c @@ -39,7 +39,7 @@ static efi_status_t EFIAPI check_loaded_image_protocol NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (ret != EFI_SUCCESS) { cout->output_string(cout, - u"Could not open loaded image protocol"); + u"Could not open loaded image protocol\n"); return ret; } if ((void *)check_loaded_image_protocol < diff --git a/lib/efi_selftest/efi_selftest_tcg2.c b/lib/efi_selftest/efi_selftest_tcg2.c index 67a886efaa8..fb8b997653a 100644 --- a/lib/efi_selftest/efi_selftest_tcg2.c +++ b/lib/efi_selftest/efi_selftest_tcg2.c @@ -126,41 +126,40 @@ static u8 boot_order[] = {0x02, 0x10, 0x00, 0x10, 0x01, 0x10}; static void *orig_smbios_table; static u64 dmi_addr = U32_MAX; -#define SMBIOS_ENTRY_HEADER_SIZE 0x20 +#define SMBIOS3_ENTRY_HEADER_SIZE 0x18 /* smbios table for the measurement test */ -static u8 smbios_table_test[] = { -0x5f, 0x53, 0x4d, 0x5f, 0x2c, 0x1f, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x5f, 0x44, 0x4d, 0x49, 0x5f, 0xe4, 0x5c, 0x01, -0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, -0x01, 0x02, 0x00, 0x00, 0x03, 0x00, 0x80, 0x08, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x0c, 0x15, 0x0a, 0xff, 0xff, 0x55, 0x2d, 0x42, 0x6f, -0x6f, 0x74, 0x00, 0x32, 0x30, 0x32, 0x31, 0x2e, 0x31, 0x30, 0x2d, 0x72, -0x63, 0x34, 0x2d, 0x30, 0x30, 0x30, 0x30, 0x35, 0x2d, 0x67, 0x37, 0x32, -0x37, 0x63, 0x33, 0x66, 0x33, 0x32, 0x35, 0x39, 0x2d, 0x64, 0x69, 0x72, -0x74, 0x79, 0x00, 0x31, 0x30, 0x2f, 0x30, 0x31, 0x2f, 0x32, 0x30, 0x32, -0x31, 0x00, 0x00, 0x01, 0x1b, 0x01, 0x00, 0x01, 0x02, 0x00, 0x03, 0x31, -0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, -0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x50, 0x72, -0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, -0x37, 0x38, 0x00, 0x00, 0x02, 0x0e, 0x02, 0x00, 0x01, 0x02, 0x00, 0x04, -0x03, 0x01, 0x01, 0x01, 0x00, 0x0a, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, -0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x50, 0x72, -0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, -0x33, 0x33, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, -0x00, 0x03, 0x15, 0x03, 0x00, 0x01, 0x03, 0x00, 0x02, 0x03, 0x03, 0x03, -0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x6e, -0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, -0x37, 0x38, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, -0x00, 0x04, 0x30, 0x04, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x03, 0x04, -0x04, 0x04, 0x08, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x08, 0x00, 0x01, -0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x31, 0x32, 0x33, -0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, -0x33, 0x33, 0x00, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x00, -0x00, 0x20, 0x0b, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x7f, 0x04, 0x06, 0x00, 0x00, 0x00 +static u8 smbios3_table_test[] = { +0x5f, 0x53, 0x4d, 0x33, 0x5f, 0x00, 0x18, 0x03, 0x07, 0x00, 0x01, 0x00, +0x5c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x18, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x03, 0x00, 0x80, 0x08, +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x15, 0x0a, 0xff, 0xff, +0x55, 0x2d, 0x42, 0x6f, 0x6f, 0x74, 0x00, 0x32, 0x30, 0x32, 0x31, 0x2e, +0x31, 0x30, 0x2d, 0x72, 0x63, 0x34, 0x2d, 0x30, 0x30, 0x30, 0x30, 0x35, +0x2d, 0x67, 0x37, 0x32, 0x37, 0x63, 0x33, 0x66, 0x33, 0x32, 0x35, 0x39, +0x2d, 0x64, 0x69, 0x72, 0x74, 0x79, 0x00, 0x31, 0x30, 0x2f, 0x30, 0x31, +0x2f, 0x32, 0x30, 0x32, 0x31, 0x00, 0x00, 0x01, 0x1b, 0x01, 0x00, 0x01, +0x02, 0x00, 0x03, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x55, 0x6e, +0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, +0x6e, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x31, 0x32, +0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x00, 0x02, 0x0e, 0x02, 0x00, +0x01, 0x02, 0x00, 0x04, 0x03, 0x01, 0x01, 0x01, 0x00, 0x0a, 0x55, 0x6e, +0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, +0x6e, 0x20, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x33, 0x33, +0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, +0x36, 0x37, 0x38, 0x00, 0x00, 0x03, 0x15, 0x03, 0x00, 0x01, 0x03, 0x00, +0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x31, 0x32, +0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, +0x33, 0x33, 0x33, 0x00, 0x00, 0x04, 0x30, 0x04, 0x00, 0x00, 0x03, 0x02, +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, +0xff, 0x02, 0x03, 0x04, 0x04, 0x04, 0x08, 0x00, 0x00, 0x02, 0x00, 0x08, +0x00, 0x08, 0x00, 0x01, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, +0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x33, 0x33, +0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x35, 0x35, 0x35, 0x35, 0x35, +0x35, 0x35, 0x35, 0x00, 0x00, 0x20, 0x0b, 0x05, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x04, 0x06, 0x00, 0x00, 0x00 }; #define IDX_ARRAY_SZ 3 /* support 24 PCRs */ @@ -179,10 +178,10 @@ static u8 expected_pcrs[EFI_TCG2_MAX_PCR_INDEX + 1][TPM2_SHA256_DIGEST_SIZE] = { 0x7b, 0xb9, 0xfe, 0xa1, 0xcd, 0x64, 0x49, 0xdd, 0xed, 0xe2, 0x65, 0x82, 0xc5, 0x3e, 0xf4, 0xc4}, - {0xf5, 0x79, 0xf3, 0x20, 0x62, 0x6e, 0x8b, 0x58, - 0x62, 0xa3, 0x4e, 0x2f, 0xb7, 0x10, 0xac, 0x34, - 0x4e, 0x68, 0x94, 0x37, 0x87, 0x29, 0xc4, 0xbe, - 0xa3, 0xc4, 0xd9, 0x14, 0x2b, 0x66, 0x79, 0x9b}, + {0x75, 0xb5, 0x91, 0x54, 0x12, 0xa8, 0xa4, 0x25, + 0x73, 0x79, 0xa7, 0x47, 0xd9, 0x32, 0x54, 0x78, + 0x9a, 0x80, 0x3f, 0xa8, 0x34, 0xfe, 0xd2, 0xae, + 0x76, 0xd3, 0x16, 0x4a, 0xb2, 0x03, 0xac, 0xe6}, {0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, @@ -543,7 +542,7 @@ static void *find_smbios_table(const struct efi_system_table *systable) u32 i; for (i = 0; i < systable->nr_tables; i++) { - if (!guidcmp(&smbios_guid, &systable->tables[i].guid)) + if (!guidcmp(&smbios3_guid, &systable->tables[i].guid)) return systable->tables[i].table; } @@ -558,14 +557,12 @@ static void *find_smbios_table(const struct efi_system_table *systable) */ static efi_status_t setup_smbios_table(const struct efi_system_table *systable) { - struct smbios_entry *se; + struct smbios3_entry *se; efi_status_t ret; /* Map within the low 32 bits, to allow for 32bit SMBIOS tables */ void *dmi; - char *istart; - int isize; - if (sizeof(smbios_table_test) > EFI_PAGE_SIZE) + if (sizeof(smbios3_table_test) > EFI_PAGE_SIZE) return EFI_OUT_OF_RESOURCES; orig_smbios_table = find_smbios_table(systable); @@ -586,19 +583,15 @@ static efi_status_t setup_smbios_table(const struct efi_system_table *systable) dmi = (void *)(uintptr_t)dmi_addr; se = dmi; - boottime->copy_mem(se, smbios_table_test, sizeof(smbios_table_test)); + boottime->copy_mem(se, smbios3_table_test, sizeof(smbios3_table_test)); /* update smbios table start address */ - se->struct_table_address = (uintptr_t)((u8 *)dmi + SMBIOS_ENTRY_HEADER_SIZE); + se->struct_table_address = (uintptr_t)((u8 *)dmi + SMBIOS3_ENTRY_HEADER_SIZE); - /* calculate checksums */ - istart = (char *)se + SMBIOS_INTERMEDIATE_OFFSET; - isize = sizeof(struct smbios_entry) - SMBIOS_INTERMEDIATE_OFFSET; - se->intermediate_checksum = table_compute_checksum(istart, isize); - se->checksum = table_compute_checksum(se, sizeof(struct smbios_entry)); + se->checksum = table_compute_checksum(se, sizeof(struct smbios3_entry)); /* Install SMBIOS information as configuration table */ - ret = boottime->install_configuration_table(&smbios_guid, dmi); + ret = boottime->install_configuration_table(&smbios3_guid, dmi); if (ret != EFI_SUCCESS) { efi_st_error("Cannot install SMBIOS table\n"); boottime->free_pages(dmi_addr, 1); @@ -992,7 +985,7 @@ static int efi_st_tcg2_teardown(void) * If orig_smbios_table is NULL, calling install_configuration_table() * removes dummy SMBIOS table form systab. */ - r = boottime->install_configuration_table(&smbios_guid, orig_smbios_table); + r = boottime->install_configuration_table(&smbios3_guid, orig_smbios_table); if (r != EFI_SUCCESS) { efi_st_error("Failed to restore SMBOIS table\n"); return EFI_ST_FAILURE; diff --git a/lib/smbios-parser.c b/lib/smbios-parser.c index ac9a367a878..9a62b3c760d 100644 --- a/lib/smbios-parser.c +++ b/lib/smbios-parser.c @@ -15,7 +15,7 @@ const struct smbios_entry *smbios_entry(u64 address, u32 size) { const struct smbios_entry *entry = (struct smbios_entry *)(uintptr_t)address; - if (!address | !size) + if (!address || !size) return NULL; if (memcmp(entry->anchor, "_SM_", 4)) @@ -223,21 +223,24 @@ static void clear_smbios_table(struct smbios_header *header, } } -void smbios_prepare_measurement(const struct smbios_entry *entry, +void smbios_prepare_measurement(const struct smbios3_entry *entry, struct smbios_header *smbios_copy) { u32 i, j; + void *table_end; struct smbios_header *header; + table_end = (void *)((u8 *)smbios_copy + entry->table_maximum_size); + for (i = 0; i < ARRAY_SIZE(smbios_filter_tables); i++) { header = smbios_copy; - for (j = 0; j < entry->struct_count; j++) { + for (j = 0; (void *)header < table_end; j++) { if (header->type == smbios_filter_tables[i].type) break; header = get_next_header(header); } - if (j >= entry->struct_count) + if ((void *)header >= table_end) continue; clear_smbios_table(header, diff --git a/lib/smbios.c b/lib/smbios.c index 7bd9805fec0..c83af730a91 100644 --- a/lib/smbios.c +++ b/lib/smbios.c @@ -135,13 +135,16 @@ static const struct map_sysinfo *convert_sysinfo_to_dt(const char *node, const c * * @ctx: SMBIOS context * @str: string to add - * Return: string number in the string area (1 or more) + * Return: string number in the string area. 0 if str is NULL. */ static int smbios_add_string(struct smbios_ctx *ctx, const char *str) { int i = 1; char *p = ctx->eos; + if (!str) + return 0; + for (;;) { if (!*p) { ctx->last_str = p; @@ -207,6 +210,7 @@ void get_str_from_dt(const struct map_sysinfo *nprop, char *str, size_t size) * * @ctx: context for writing the tables * @prop: property to write + * @sysinfo_id: unique identifier for the string value to be read * @dval: Default value to use if the string is not found or is empty * Return: 0 if not found, else SMBIOS string number (1 or more) */ @@ -216,7 +220,7 @@ static int smbios_add_prop_si(struct smbios_ctx *ctx, const char *prop, int ret; if (!dval || !*dval) - dval = "Unknown"; + dval = NULL; if (!prop) return smbios_add_string(ctx, dval); @@ -311,6 +315,10 @@ int smbios_update_version(const char *version) */ static int smbios_string_table_len(const struct smbios_ctx *ctx) { + /* In case no string is defined we have to return two \0 */ + if (ctx->next_ptr == ctx->eos) + return 2; + /* Allow for the final \0 after all strings */ return (ctx->next_ptr + 1) - ctx->eos; } @@ -375,19 +383,19 @@ static int smbios_write_type1(ulong *current, int handle, memset(t, 0, sizeof(struct smbios_type1)); fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle); smbios_set_eos(ctx, t->eos); - t->manufacturer = smbios_add_prop(ctx, "manufacturer", "Unknown"); - t->product_name = smbios_add_prop(ctx, "product", "Unknown"); + t->manufacturer = smbios_add_prop(ctx, "manufacturer", NULL); + t->product_name = smbios_add_prop(ctx, "product", NULL); t->version = smbios_add_prop_si(ctx, "version", SYSINFO_ID_SMBIOS_SYSTEM_VERSION, - "Unknown"); + NULL); if (serial_str) { t->serial_number = smbios_add_prop(ctx, NULL, serial_str); strncpy((char *)t->uuid, serial_str, sizeof(t->uuid)); } else { - t->serial_number = smbios_add_prop(ctx, "serial", "Unknown"); + t->serial_number = smbios_add_prop(ctx, "serial", NULL); } - t->sku_number = smbios_add_prop(ctx, "sku", "Unknown"); - t->family = smbios_add_prop(ctx, "family", "Unknown"); + t->sku_number = smbios_add_prop(ctx, "sku", NULL); + t->family = smbios_add_prop(ctx, "family", NULL); len = t->length + smbios_string_table_len(ctx); *current += len; @@ -406,14 +414,15 @@ static int smbios_write_type2(ulong *current, int handle, memset(t, 0, sizeof(struct smbios_type2)); fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle); smbios_set_eos(ctx, t->eos); - t->manufacturer = smbios_add_prop(ctx, "manufacturer", "Unknown"); - t->product_name = smbios_add_prop(ctx, "product", "Unknown"); + t->manufacturer = smbios_add_prop(ctx, "manufacturer", NULL); + t->product_name = smbios_add_prop(ctx, "product", NULL); t->version = smbios_add_prop_si(ctx, "version", SYSINFO_ID_SMBIOS_BASEBOARD_VERSION, - "Unknown"); - t->asset_tag_number = smbios_add_prop(ctx, "asset-tag", "Unknown"); + NULL); + t->asset_tag_number = smbios_add_prop(ctx, "asset-tag", NULL); t->feature_flags = SMBIOS_BOARD_FEATURE_HOSTING; t->board_type = SMBIOS_BOARD_MOTHERBOARD; + t->chassis_handle = handle + 1; len = t->length + smbios_string_table_len(ctx); *current += len; @@ -432,7 +441,7 @@ static int smbios_write_type3(ulong *current, int handle, memset(t, 0, sizeof(struct smbios_type3)); fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle); smbios_set_eos(ctx, t->eos); - t->manufacturer = smbios_add_prop(ctx, "manufacturer", "Unknown"); + t->manufacturer = smbios_add_prop(ctx, "manufacturer", NULL); t->chassis_type = SMBIOS_ENCLOSURE_DESKTOP; t->bootup_state = SMBIOS_STATE_SAFE; t->power_supply_state = SMBIOS_STATE_SAFE; @@ -450,8 +459,8 @@ static void smbios_write_type4_dm(struct smbios_type4 *t, struct smbios_ctx *ctx) { u16 processor_family = SMBIOS_PROCESSOR_FAMILY_UNKNOWN; - const char *vendor = "Unknown"; - const char *name = "Unknown"; + const char *vendor = NULL; + const char *name = NULL; #ifdef CONFIG_CPU char processor_name[49]; @@ -542,6 +551,7 @@ static struct smbios_write_method smbios_write_funcs[] = { { smbios_write_type0, "bios", }, { smbios_write_type1, "system", }, { smbios_write_type2, "baseboard", }, + /* Type 3 must immediately follow type 2 due to chassis handle. */ { smbios_write_type3, "chassis", }, { smbios_write_type4, }, { smbios_write_type32, }, @@ -556,7 +566,6 @@ ulong write_smbios_table(ulong addr) struct smbios_ctx ctx; ulong tables; int len = 0; - int max_struct_size = 0; int handle = 0; int i; @@ -578,7 +587,6 @@ ulong write_smbios_table(ulong addr) /* populate minimum required tables */ for (i = 0; i < ARRAY_SIZE(smbios_write_funcs); i++) { const struct smbios_write_method *method; - int tmp; method = &smbios_write_funcs[i]; ctx.subnode_name = NULL; @@ -588,10 +596,7 @@ ulong write_smbios_table(ulong addr) ctx.node = ofnode_find_subnode(parent_node, method->subnode_name); } - tmp = method->write((ulong *)&addr, handle++, &ctx); - - max_struct_size = max(max_struct_size, tmp); - len += tmp; + len += method->write((ulong *)&addr, handle++, &ctx); } /* @@ -610,7 +615,7 @@ ulong write_smbios_table(ulong addr) se->minor_ver = SMBIOS_MINOR_VER; se->doc_rev = 0; se->entry_point_rev = 1; - se->max_struct_size = len; + se->table_maximum_size = len; se->struct_table_address = table_addr; se->checksum = table_compute_checksum(se, sizeof(struct smbios3_entry)); unmap_sysmem(se); diff --git a/lib/uuid.c b/lib/uuid.c index 0be22bc05f7..2d7d99535e7 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -177,6 +177,10 @@ static const struct { SMBIOS_TABLE_GUID, }, { + "SMBIOS3 table", + SMBIOS3_TABLE_GUID, + }, + { "Runtime properties", EFI_RT_PROPERTIES_TABLE_GUID, }, diff --git a/test/dm/clk.c b/test/dm/clk.c index 01417fbd825..57fabbdce08 100644 --- a/test/dm/clk.c +++ b/test/dm/clk.c @@ -182,19 +182,10 @@ static int dm_test_clk(struct unit_test_state *uts) SANDBOX_CLK_ID_I2C)); ut_asserteq(1, sandbox_clk_query_requested(dev_clk, SANDBOX_CLK_ID_UART2)); - ut_assertok(sandbox_clk_test_free(dev_test)); - ut_asserteq(0, sandbox_clk_query_requested(dev_clk, - SANDBOX_CLK_ID_SPI)); - ut_asserteq(0, sandbox_clk_query_requested(dev_clk, - SANDBOX_CLK_ID_I2C)); - ut_asserteq(0, sandbox_clk_query_requested(dev_clk, - SANDBOX_CLK_ID_UART2)); ut_asserteq(1, sandbox_clk_query_requested(dev_clk, SANDBOX_CLK_ID_UART1)); ut_assertok(device_remove(dev_test, DM_REMOVE_NORMAL)); - ut_asserteq(0, sandbox_clk_query_requested(dev_clk, - SANDBOX_CLK_ID_UART1)); return 0; } DM_TEST(dm_test_clk, UT_TESTF_SCAN_FDT); diff --git a/test/py/requirements.txt b/test/py/requirements.txt index c3cc9163fb8..0f67c3c6194 100644 --- a/test/py/requirements.txt +++ b/test/py/requirements.txt @@ -11,10 +11,10 @@ more-itertools==7.2.0 packaging==23.2 pbr==5.4.3 pluggy==0.13.0 -py==1.10.0 +py==1.11.0 pycryptodomex==3.19.1 pyelftools==0.27 -pygit2==1.9.2 +pygit2==1.13.3 pyparsing==3.0.7 pytest==6.2.5 pytest-xdist==2.5.0 diff --git a/test/py/tests/test_gpio.py b/test/py/tests/test_gpio.py index 0af186f2360..3e16e636574 100644 --- a/test/py/tests/test_gpio.py +++ b/test/py/tests/test_gpio.py @@ -85,6 +85,13 @@ env__gpio_dev_config = { 'gpio_ip_pin_clear':'66', 'gpio_clear_value': 'value is 0', 'gpio_set_value': 'value is 1', + # GPIO pin list to test gpio functionality for each pins, pin should be + # pin names (str) + 'gpio_pin_list': ['gpio@1000031', 'gpio@1000032', 'gpio@20000033'], + # GPIO input output list for shorted gpio pins to test gpio + # functionality for each of pairs, where the first element is + # configured as input and second as output + 'gpio_ip_op_list': [['gpio0', 'gpio1'], ['gpio2', 'gpio3']], } """ @@ -223,3 +230,86 @@ def test_gpio_input_generic(u_boot_console): response = u_boot_console.run_command(cmd) good_response = gpio_set_value assert good_response in response + +@pytest.mark.buildconfigspec('cmd_gpio') +def test_gpio_pins_generic(u_boot_console): + """Test various gpio related functionality, such as the input, set, clear, + and toggle for the set of gpio pin list. + + Specific set of gpio pins (by mentioning gpio pin name) configured as + input (mentioned as 'gpio_pin_list') to be tested for multiple gpio + commands. + """ + + f = u_boot_console.config.env.get('env__gpio_dev_config', False) + if not f: + pytest.skip('gpio not configured') + + gpio_pins = f.get('gpio_pin_list', None) + if not gpio_pins: + pytest.skip('gpio pin list are not configured') + + for gpin in gpio_pins: + # gpio input + u_boot_console.run_command(f'gpio input {gpin}') + expected_response = f'{gpin}: input:' + response = u_boot_console.run_command(f'gpio status -a {gpin}') + assert expected_response in response + + # gpio set + u_boot_console.run_command(f'gpio set {gpin}') + expected_response = f'{gpin}: output: 1' + response = u_boot_console.run_command(f'gpio status -a {gpin}') + assert expected_response in response + + # gpio clear + u_boot_console.run_command(f'gpio clear {gpin}') + expected_response = f'{gpin}: output: 0' + response = u_boot_console.run_command(f'gpio status -a {gpin}') + assert expected_response in response + + # gpio toggle + u_boot_console.run_command(f'gpio toggle {gpin}') + expected_response = f'{gpin}: output: 1' + response = u_boot_console.run_command(f'gpio status -a {gpin}') + assert expected_response in response + +@pytest.mark.buildconfigspec('cmd_gpio') +def test_gpio_pins_input_output_generic(u_boot_console): + """Test gpio related functionality such as input and output for the list of + shorted gpio pins provided as a pair of input and output pins. This test + will fail, if the gpio pins are not shorted properly. + + Specific set of shorted gpio pins (by mentioning gpio pin name) + configured as input and output (mentioned as 'gpio_ip_op_list') as a + pair to be tested for gpio input output case. + """ + + f = u_boot_console.config.env.get('env__gpio_dev_config', False) + if not f: + pytest.skip('gpio not configured') + + gpio_pins = f.get('gpio_ip_op_list', None) + if not gpio_pins: + pytest.skip('gpio pin list for input and output are not configured') + + for gpins in gpio_pins: + u_boot_console.run_command(f'gpio input {gpins[0]}') + expected_response = f'{gpins[0]}: input:' + response = u_boot_console.run_command(f'gpio status -a {gpins[0]}') + assert expected_response in response + + u_boot_console.run_command(f'gpio set {gpins[1]}') + expected_response = f'{gpins[1]}: output:' + response = u_boot_console.run_command(f'gpio status -a {gpins[1]}') + assert expected_response in response + + u_boot_console.run_command(f'gpio clear {gpins[1]}') + expected_response = f'{gpins[0]}: input: 0' + response = u_boot_console.run_command(f'gpio status -a {gpins[0]}') + assert expected_response in response + + u_boot_console.run_command(f'gpio set {gpins[1]}') + expected_response = f'{gpins[0]}: input: 1' + response = u_boot_console.run_command(f'gpio status -a {gpins[0]}') + assert expected_response in response diff --git a/test/py/tests/test_mmc.py b/test/py/tests/test_mmc.py new file mode 100644 index 00000000000..a96c4e8fd89 --- /dev/null +++ b/test/py/tests/test_mmc.py @@ -0,0 +1,671 @@ +# SPDX-License-Identifier: GPL-2.0 +# (C) Copyright 2023, Advanced Micro Devices, Inc. + +import pytest +import random +import re +import u_boot_utils + +""" +Note: This test doesn't rely on boardenv_* configuration values but it can +change the test behavior. To test MMC file system cases (fat32, ext2, ext4), +MMC device should be formatted and valid partitions should be created for +different file system, otherwise it may leads to failure. This test will be +skipped if the MMC device is not detected. + +For example: + +# Setup env__mmc_device_test_skip to not skipping the test. By default, its +# value is set to True. Set it to False to run all tests for MMC device. +env__mmc_device_test_skip = False +""" + +mmc_set_up = False +controllers = 0 +devices = {} + +def setup_mmc(u_boot_console): + if u_boot_console.config.env.get('env__mmc_device_test_skip', True): + pytest.skip('MMC device test is not enabled') + +@pytest.mark.buildconfigspec('cmd_mmc') +def test_mmc_list(u_boot_console): + setup_mmc(u_boot_console) + output = u_boot_console.run_command('mmc list') + if 'No MMC device available' in output: + pytest.skip('No SD/MMC/eMMC controller available') + + if 'Card did not respond to voltage select' in output: + pytest.skip('No SD/MMC card present') + + array = output.split() + global devices + global controllers + controllers = int(len(array) / 2) + for x in range(0, controllers): + y = x * 2 + devices[x] = {} + devices[x]['name'] = array[y] + + global mmc_set_up + mmc_set_up = True + +@pytest.mark.buildconfigspec('cmd_mmc') +def test_mmc_dev(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + fail = 0 + for x in range(0, controllers): + devices[x]['detected'] = 'yes' + output = u_boot_console.run_command('mmc dev %d' % x) + + # Some sort of switch here + if 'Card did not respond to voltage select' in output: + fail = 1 + devices[x]['detected'] = 'no' + + if 'no mmc device at slot' in output: + devices[x]['detected'] = 'no' + + if 'MMC: no card present' in output: + devices[x]['detected'] = 'no' + + if fail: + pytest.fail('Card not present') + +@pytest.mark.buildconfigspec('cmd_mmc') +def test_mmcinfo(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + output = u_boot_console.run_command('mmcinfo') + if 'busy timeout' in output: + pytest.skip('No SD/MMC/eMMC device present') + + obj = re.search(r'Capacity: (\d+|\d+[\.]?\d)', output) + try: + capacity = float(obj.groups()[0]) + print(capacity) + devices[x]['capacity'] = capacity + print('Capacity of dev %d is: %g GiB' % (x, capacity)) + except ValueError: + pytest.fail('MMC capacity not recognized') + +@pytest.mark.buildconfigspec('cmd_mmc') +def test_mmc_info(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + + output = u_boot_console.run_command('mmc info') + + obj = re.search(r'Capacity: (\d+|\d+[\.]?\d)', output) + try: + capacity = float(obj.groups()[0]) + print(capacity) + if devices[x]['capacity'] != capacity: + pytest.fail("MMC capacity doesn't match mmcinfo") + + except ValueError: + pytest.fail('MMC capacity not recognized') + +@pytest.mark.buildconfigspec('cmd_mmc') +def test_mmc_rescan(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + output = u_boot_console.run_command('mmc rescan') + if output: + pytest.fail('mmc rescan has something to check') + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_mmc') +def test_mmc_part(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + output = u_boot_console.run_command('mmc part') + + lines = output.split('\n') + part_fat = [] + part_ext = [] + for line in lines: + obj = re.search( + r'(\d)\s+\d+\s+\d+\s+\w+\d+\w+-\d+\s+(\d+\w+)', line) + if obj: + part_id = int(obj.groups()[0]) + part_type = obj.groups()[1] + print('part_id:%d, part_type:%s' % (part_id, part_type)) + + if part_type in ['0c', '0b', '0e']: + print('Fat detected') + part_fat.append(part_id) + elif part_type == '83': + print('ext detected') + part_ext.append(part_id) + else: + pytest.fail('Unsupported Filesystem on device %d' % x) + devices[x]['ext4'] = part_ext + devices[x]['ext2'] = part_ext + devices[x]['fat'] = part_fat + + if not part_ext and not part_fat: + pytest.fail('No partition detected on device %d' % x) + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_fat') +def test_mmc_fatls_fatinfo(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'fat' + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + output = u_boot_console.run_command( + 'fatls mmc %d:%s' % (x, part)) + if 'Unrecognized filesystem type' in output: + partitions.remove(part) + pytest.fail('Unrecognized filesystem') + + if not re.search(r'\d file\(s\), \d dir\(s\)', output): + pytest.fail('%s read failed on device %d' % (fs.upper, x)) + output = u_boot_console.run_command( + 'fatinfo mmc %d:%s' % (x, part)) + string = 'Filesystem: %s' % fs.upper + if re.search(string, output): + pytest.fail('%s FS failed on device %d' % (fs.upper(), x)) + part_detect = 1 + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_fat') +@pytest.mark.buildconfigspec('cmd_memory') +def test_mmc_fatload_fatwrite(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'fat' + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = u_boot_utils.find_ram_base(u_boot_console) + devices[x]['addr_%d' % part] = addr + size = random.randint(4, 1 * 1024 * 1024) + devices[x]['size_%d' % part] = size + # count CRC32 + output = u_boot_console.run_command('crc32 %x %x' % (addr, size)) + m = re.search('==> (.+?)', output) + if not m: + pytest.fail('CRC32 failed') + expected_crc32 = m.group(1) + devices[x]['expected_crc32_%d' % part] = expected_crc32 + # do write + file = '%s_%d' % ('uboot_test', size) + devices[x]['file_%d' % part] = file + output = u_boot_console.run_command( + '%swrite mmc %d:%s %x %s %x' % (fs, x, part, addr, file, size) + ) + assert 'Unable to write' not in output + assert 'Error' not in output + assert 'overflow' not in output + expected_text = '%d bytes written' % size + assert expected_text in output + + alignment = int( + u_boot_console.config.buildconfig.get( + 'config_sys_cacheline_size', 128 + ) + ) + offset = random.randrange(alignment, 1024, alignment) + output = u_boot_console.run_command( + '%sload mmc %d:%s %x %s' % (fs, x, part, addr + offset, file) + ) + assert 'Invalid FAT entry' not in output + assert 'Unable to read file' not in output + assert 'Misaligned buffer address' not in output + expected_text = '%d bytes read' % size + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr + offset) + ) + assert expected_crc32 in output + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_ext4') +def test_mmc_ext4ls(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'ext4' + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + u_boot_console.run_command('mmc dev %d' % x) + for part in partitions: + output = u_boot_console.run_command('%sls mmc %d:%s' % (fs, x, part)) + if 'Unrecognized filesystem type' in output: + partitions.remove(part) + pytest.fail('Unrecognized filesystem') + part_detect = 1 + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_ext4') +@pytest.mark.buildconfigspec('ext4_write') +@pytest.mark.buildconfigspec('cmd_memory') +def test_mmc_ext4load_ext4write(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'ext4' + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = u_boot_utils.find_ram_base(u_boot_console) + devices[x]['addr_%d' % part] = addr + size = random.randint(4, 1 * 1024 * 1024) + devices[x]['size_%d' % part] = size + # count CRC32 + output = u_boot_console.run_command('crc32 %x %x' % (addr, size)) + m = re.search('==> (.+?)', output) + if not m: + pytest.fail('CRC32 failed') + expected_crc32 = m.group(1) + devices[x]['expected_crc32_%d' % part] = expected_crc32 + # do write + + file = '%s_%d' % ('uboot_test', size) + devices[x]['file_%d' % part] = file + output = u_boot_console.run_command( + '%swrite mmc %d:%s %x /%s %x' % (fs, x, part, addr, file, size) + ) + assert 'Unable to write' not in output + assert 'Error' not in output + assert 'overflow' not in output + expected_text = '%d bytes written' % size + assert expected_text in output + + offset = random.randrange(128, 1024, 128) + output = u_boot_console.run_command( + '%sload mmc %d:%s %x /%s' % (fs, x, part, addr + offset, file) + ) + expected_text = '%d bytes read' % size + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr + offset) + ) + assert expected_crc32 in output + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_ext2') +def test_mmc_ext2ls(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'ext2' + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + output = u_boot_console.run_command('%sls mmc %d:%s' % (fs, x, part)) + if 'Unrecognized filesystem type' in output: + partitions.remove(part) + pytest.fail('Unrecognized filesystem') + part_detect = 1 + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_ext2') +@pytest.mark.buildconfigspec('cmd_ext4') +@pytest.mark.buildconfigspec('ext4_write') +@pytest.mark.buildconfigspec('cmd_memory') +def test_mmc_ext2load(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'ext2' + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = devices[x]['addr_%d' % part] + size = devices[x]['size_%d' % part] + expected_crc32 = devices[x]['expected_crc32_%d' % part] + file = devices[x]['file_%d' % part] + + offset = random.randrange(128, 1024, 128) + output = u_boot_console.run_command( + '%sload mmc %d:%s %x /%s' % (fs, x, part, addr + offset, file) + ) + expected_text = '%d bytes read' % size + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr + offset) + ) + assert expected_crc32 in output + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_fs_generic') +def test_mmc_ls(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + for fs in ['fat', 'ext4']: + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + output = u_boot_console.run_command('ls mmc %d:%s' % (x, part)) + if re.search(r'No \w+ table on this device', output): + pytest.fail( + '%s: Partition table not found %d' % (fs.upper(), x) + ) + + if not part_detect: + pytest.skip('No partition detected') + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_fs_generic') +def test_mmc_load(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + for fs in ['fat', 'ext4']: + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = devices[x]['addr_%d' % part] + size = devices[x]['size_%d' % part] + expected_crc32 = devices[x]['expected_crc32_%d' % part] + file = devices[x]['file_%d' % part] + + offset = random.randrange(128, 1024, 128) + output = u_boot_console.run_command( + 'load mmc %d:%s %x /%s' % (x, part, addr + offset, file) + ) + expected_text = '%d bytes read' % size + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr + offset) + ) + assert expected_crc32 in output + + if not part_detect: + pytest.skip('No partition detected') + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_fs_generic') +def test_mmc_save(u_boot_console): + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + for fs in ['fat', 'ext4']: + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = devices[x]['addr_%d' % part] + size = 0 + file = devices[x]['file_%d' % part] + + offset = random.randrange(128, 1024, 128) + output = u_boot_console.run_command( + 'save mmc %d:%s %x /%s %d' + % (x, part, addr + offset, file, size) + ) + expected_text = '%d bytes written' % size + assert expected_text in output + + if not part_detect: + pytest.skip('No partition detected') + +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_fat') +@pytest.mark.buildconfigspec('cmd_memory') +def test_mmc_fat_read_write_files(u_boot_console): + test_mmc_list(u_boot_console) + test_mmc_dev(u_boot_console) + test_mmcinfo(u_boot_console) + test_mmc_part(u_boot_console) + if not mmc_set_up: + pytest.skip('No SD/MMC/eMMC controller available') + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'fat' + + # Number of files to be written/read in MMC card + num_files = 100 + + for x in range(0, controllers): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('mmc dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = u_boot_utils.find_ram_base(u_boot_console) + count_f = 0 + addr_l = [] + size_l = [] + file_l = [] + crc32_l = [] + offset_l = [] + addr_l.append(addr) + + while count_f < num_files: + size_l.append(random.randint(4, 1 * 1024 * 1024)) + + # CRC32 count + output = u_boot_console.run_command( + 'crc32 %x %x' % (addr_l[count_f], size_l[count_f]) + ) + m = re.search('==> (.+?)', output) + if not m: + pytest.fail('CRC32 failed') + crc32_l.append(m.group(1)) + + # Write operation + file_l.append('%s_%d_%d' % ('uboot_test', count_f, size_l[count_f])) + output = u_boot_console.run_command( + '%swrite mmc %d:%s %x %s %x' + % ( + fs, + x, + part, + addr_l[count_f], + file_l[count_f], + size_l[count_f], + ) + ) + assert 'Unable to write' not in output + assert 'Error' not in output + assert 'overflow' not in output + expected_text = '%d bytes written' % size_l[count_f] + assert expected_text in output + + addr_l.append(addr_l[count_f] + size_l[count_f] + 1048576) + count_f += 1 + + count_f = 0 + while count_f < num_files: + alignment = int( + u_boot_console.config.buildconfig.get( + 'config_sys_cacheline_size', 128 + ) + ) + offset_l.append(random.randrange(alignment, 1024, alignment)) + + # Read operation + output = u_boot_console.run_command( + '%sload mmc %d:%s %x %s' + % ( + fs, + x, + part, + addr_l[count_f] + offset_l[count_f], + file_l[count_f], + ) + ) + assert 'Invalid FAT entry' not in output + assert 'Unable to read file' not in output + assert 'Misaligned buffer address' not in output + expected_text = '%d bytes read' % size_l[count_f] + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr_l[count_f] + offset_l[count_f]) + ) + assert crc32_l[count_f] in output + + count_f += 1 + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) diff --git a/test/py/tests/test_scsi.py b/test/py/tests/test_scsi.py new file mode 100644 index 00000000000..be2e283e7d2 --- /dev/null +++ b/test/py/tests/test_scsi.py @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: GPL-2.0 +# (C) Copyright 2023, Advanced Micro Devices, Inc. + +import pytest + +""" +Note: This test relies on boardenv_* containing configuration values to define +the SCSI device number, type and capacity. This test will be automatically +skipped without this. + +For example: + +# Setup env__scsi_device_test to set the SCSI device number/slot, the type of +device, and the device capacity in MB. +env__scsi_device_test = { + 'dev_num': 0, + 'device_type': 'Hard Disk', + 'device_capacity': '476940.0 MB', +} +""" + +def scsi_setup(u_boot_console): + f = u_boot_console.config.env.get('env__scsi_device_test', None) + if not f: + pytest.skip('No SCSI device to test') + + dev_num = f.get('dev_num', None) + if not isinstance(dev_num, int): + pytest.skip('No device number specified in env file to read') + + dev_type = f.get('device_type') + if not dev_type: + pytest.skip('No device type specified in env file to read') + + dev_size = f.get('device_capacity') + if not dev_size: + pytest.skip('No device capacity specified in env file to read') + + return dev_num, dev_type, dev_size + +@pytest.mark.buildconfigspec('cmd_scsi') +def test_scsi_reset(u_boot_console): + dev_num, dev_type, dev_size = scsi_setup(u_boot_console) + output = u_boot_console.run_command('scsi reset') + assert f'Device {dev_num}:' in output + assert f'Type: {dev_type}' in output + assert f'Capacity: {dev_size}' in output + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_scsi') +def test_scsi_info(u_boot_console): + dev_num, dev_type, dev_size = scsi_setup(u_boot_console) + output = u_boot_console.run_command('scsi info') + assert f'Device {dev_num}:' in output + assert f'Type: {dev_type}' in output + assert f'Capacity: {dev_size}' in output + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_scsi') +def test_scsi_scan(u_boot_console): + dev_num, dev_type, dev_size = scsi_setup(u_boot_console) + output = u_boot_console.run_command('scsi scan') + assert f'Device {dev_num}:' in output + assert f'Type: {dev_type}' in output + assert f'Capacity: {dev_size}' in output + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_scsi') +def test_scsi_dev(u_boot_console): + dev_num, dev_type, dev_size = scsi_setup(u_boot_console) + output = u_boot_console.run_command('scsi device') + assert 'no scsi devices available' not in output + assert f'device {dev_num}:' in output + assert f'Type: {dev_type}' in output + assert f'Capacity: {dev_size}' in output + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + output = u_boot_console.run_command('scsi device %d' % dev_num) + assert 'is now current device' in output + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_scsi') +def test_scsi_part(u_boot_console): + test_scsi_dev(u_boot_console) + output = u_boot_console.run_command('scsi part') + assert 'Partition Map for SCSI device' in output + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') diff --git a/test/py/tests/test_smbios.py b/test/py/tests/test_smbios.py new file mode 100644 index 00000000000..82b0b689830 --- /dev/null +++ b/test/py/tests/test_smbios.py @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +"""Test smbios command""" + +import pytest + +@pytest.mark.buildconfigspec('cmd_smbios') +@pytest.mark.notbuildconfigspec('qfw_smbios') +@pytest.mark.notbuildconfigspec('sandbox') +def test_cmd_smbios(u_boot_console): + """Run the smbios command""" + output = u_boot_console.run_command('smbios') + assert 'DMI type 127,' in output + +@pytest.mark.buildconfigspec('cmd_smbios') +@pytest.mark.buildconfigspec('qfw_smbios') +@pytest.mark.notbuildconfigspec('sandbox') +# TODO: +# QEMU v8.2.0 lacks SMBIOS support for RISC-V +# Once support is available in our Docker image we can remove the constraint. +@pytest.mark.notbuildconfigspec('riscv') +def test_cmd_smbios_qemu(u_boot_console): + """Run the smbios command on QEMU""" + output = u_boot_console.run_command('smbios') + assert 'DMI type 1,' in output + assert 'Manufacturer: QEMU' in output + assert 'DMI type 127,' in output + +@pytest.mark.buildconfigspec('cmd_smbios') +@pytest.mark.buildconfigspec('sandbox') +def test_cmd_smbios_sandbox(u_boot_console): + """Run the smbios command on the sandbox""" + output = u_boot_console.run_command('smbios') + assert 'DMI type 0,' in output + assert 'String 1: U-Boot' in output + assert 'DMI type 1,' in output + assert 'Manufacturer: sandbox' in output + assert 'DMI type 2,' in output + assert 'DMI type 3,' in output + assert 'DMI type 4,' in output + assert 'DMI type 127,' in output diff --git a/test/py/tests/test_usb.py b/test/py/tests/test_usb.py new file mode 100644 index 00000000000..fb3d20f0826 --- /dev/null +++ b/test/py/tests/test_usb.py @@ -0,0 +1,626 @@ +# SPDX-License-Identifier: GPL-2.0 +# (C) Copyright 2023, Advanced Micro Devices, Inc. + +import pytest +import random +import re +import u_boot_utils + +""" +Note: This test doesn't rely on boardenv_* configuration values but it can +change the test behavior. To test USB file system cases (fat32, ext2, ext4), +USB device should be formatted and valid partitions should be created for +different file system, otherwise it may leads to failure. This test will be +skipped if the USB device is not detected. + +For example: + +# Setup env__usb_device_test_skip to not skipping the test. By default, its +# value is set to True. Set it to False to run all tests for USB device. +env__usb_device_test_skip = False +""" + +def setup_usb(u_boot_console): + if u_boot_console.config.env.get('env__usb_device_test_skip', True): + pytest.skip('USB device test is not enabled') + +@pytest.mark.buildconfigspec('cmd_usb') +def test_usb_start(u_boot_console): + setup_usb(u_boot_console) + output = u_boot_console.run_command('usb start') + + # if output is empty, usb start may already run as part of preboot command + # re-start the usb, in that case + if not output: + u_boot_console.run_command('usb stop') + output = u_boot_console.run_command('usb start') + + if 'No USB device found' in output: + pytest.skip('No USB controller available') + + if 'Card did not respond to voltage select' in output: + pytest.skip('No USB device present') + + controllers = 0 + storage_device = 0 + obj = re.search(r'\d USB Device\(s\) found', output) + controllers = int(obj.group()[0]) + + if not controllers: + pytest.skip('No USB device present') + + obj = re.search(r'\d Storage Device\(s\) found', output) + storage_device = int(obj.group()[0]) + + if not storage_device: + pytest.skip('No USB storage device present') + + assert 'USB init failed' not in output + assert 'starting USB...' in output + + if 'Starting the controller' in output: + assert 'USB XHCI' in output + + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + return controllers, storage_device + +@pytest.mark.buildconfigspec('cmd_usb') +def test_usb_stop(u_boot_console): + setup_usb(u_boot_console) + output = u_boot_console.run_command('usb stop') + assert 'stopping USB..' in output + + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + + output = u_boot_console.run_command('usb dev') + assert "USB is stopped. Please issue 'usb start' first." in output + +@pytest.mark.buildconfigspec('cmd_usb') +def test_usb_reset(u_boot_console): + setup_usb(u_boot_console) + output = u_boot_console.run_command('usb reset') + + if 'No USB device found' in output: + pytest.skip('No USB controller available') + + if 'Card did not respond to voltage select' in output: + pytest.skip('No USB device present') + + obj = re.search(r'\d USB Device\(s\) found', output) + usb_dev_num = int(obj.group()[0]) + + if not usb_dev_num: + pytest.skip('No USB device present') + + obj = re.search(r'\d Storage Device\(s\) found', output) + usb_stor_num = int(obj.group()[0]) + + if not usb_stor_num: + pytest.skip('No USB storage device present') + + assert 'BUG' not in output + assert 'USB init failed' not in output + assert 'resetting USB...' in output + + if 'Starting the controller' in output: + assert 'USB XHCI' in output + + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_usb') +def test_usb_info(u_boot_console): + controllers, storage_device = test_usb_start(u_boot_console) + output = u_boot_console.run_command('usb info') + + num_controller = len(re.findall(': Hub,', output)) + num_mass_storage = len(re.findall(': Mass Storage,', output)) + + assert num_controller == controllers - 1 + assert num_mass_storage == storage_device + + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + + for i in range(0, storage_device + controllers - 1): + output = u_boot_console.run_command('usb info %d' % i) + num_controller = len(re.findall(': Hub,', output)) + num_mass_storage = len(re.findall(': Mass Storage,', output)) + assert num_controller + num_mass_storage == 1 + assert 'No device available' not in output + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_usb') +def test_usb_tree(u_boot_console): + controllers, storage_device = test_usb_start(u_boot_console) + output = u_boot_console.run_command('usb tree') + + num_controller = len(re.findall('Hub', output)) + num_mass_storage = len(re.findall('Mass Storage', output)) + + assert num_controller == controllers - 1 + assert num_mass_storage == storage_device + + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_usb') +@pytest.mark.buildconfigspec('usb_storage') +def test_usb_storage(u_boot_console): + controllers, storage_device = test_usb_start(u_boot_console) + output = u_boot_console.run_command('usb storage') + + obj = re.findall(r'Capacity: (\d+|\d+[\.]?\d)', output) + devices = {} + + for key in range(int(storage_device)): + devices[key] = {} + + for x in range(int(storage_device)): + try: + capacity = float(obj[x].split()[0]) + devices[x]['capacity'] = capacity + print('USB storage device %d capacity is: %g MB' % (x, capacity)) + except ValueError: + pytest.fail('USB storage device capacity not recognized') + + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_usb') +def test_usb_dev(u_boot_console): + controllers, storage_device = test_usb_start(u_boot_console) + output = u_boot_console.run_command('usb dev') + + assert 'no usb devices available' not in output + + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + + devices = {} + + for key in range(int(storage_device)): + devices[key] = {} + + fail = 0 + for x in range(0, storage_device): + devices[x]['detected'] = 'yes' + output = u_boot_console.run_command('usb dev %d' % x) + + if 'Card did not respond to voltage select' in output: + fail = 1 + devices[x]['detected'] = 'no' + + if 'No USB device found' in output: + devices[x]['detected'] = 'no' + + if 'unknown device' in output: + devices[x]['detected'] = 'no' + + assert 'is now current device' in output + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + + if fail: + pytest.fail('USB device not present') + + return devices, controllers, storage_device + +@pytest.mark.buildconfigspec('cmd_usb') +def test_usb_part(u_boot_console): + devices, controllers, storage_device = test_usb_dev(u_boot_console) + if not devices: + pytest.skip('No devices detected') + + u_boot_console.run_command('usb part') + + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + + for i in range(0, storage_device): + if devices[i]['detected'] == 'yes': + u_boot_console.run_command('usb dev %d' % i) + output = u_boot_console.run_command('usb part') + + lines = output.split('\n') + part_fat = [] + part_ext = [] + for line in lines: + obj = re.search(r'(\d)\s+\d+\s+\d+\s+\w+\d+\w+-\d+\s+(\d+\w+)', line) + if obj: + part_id = int(obj.groups()[0]) + part_type = obj.groups()[1] + print('part_id:%d, part_type:%s' % (part_id, part_type)) + + if part_type == '0c' or part_type == '0b' or part_type == '0e': + print('Fat detected') + part_fat.append(part_id) + elif part_type == '83': + print('ext detected') + part_ext.append(part_id) + else: + pytest.fail('Unsupported Filesystem on device %d' % i) + devices[i]['ext4'] = part_ext + devices[i]['ext2'] = part_ext + devices[i]['fat'] = part_fat + + if not part_ext and not part_fat: + pytest.fail('No partition detected on device %d' % i) + + return devices, controllers, storage_device + +@pytest.mark.buildconfigspec('cmd_usb') +@pytest.mark.buildconfigspec('cmd_fat') +def test_usb_fatls_fatinfo(u_boot_console): + devices, controllers, storage_device = test_usb_part(u_boot_console) + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'fat' + for x in range(0, int(storage_device)): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('usb dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + output = u_boot_console.run_command('fatls usb %d:%s' % (x, part)) + if 'Unrecognized filesystem type' in output: + partitions.remove(part) + pytest.fail('Unrecognized filesystem') + + if not re.search(r'\d file\(s\), \d dir\(s\)', output): + pytest.fail('%s read failed on device %d' % (fs.upper, x)) + + output = u_boot_console.run_command('fatinfo usb %d:%s' % (x, part)) + string = 'Filesystem: %s' % fs.upper + if re.search(string, output): + pytest.fail('%s FS failed on device %d' % (fs.upper(), x)) + part_detect = 1 + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_usb') +@pytest.mark.buildconfigspec('cmd_fat') +@pytest.mark.buildconfigspec('cmd_memory') +def test_usb_fatload_fatwrite(u_boot_console): + devices, controllers, storage_device = test_usb_part(u_boot_console) + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'fat' + for x in range(0, int(storage_device)): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('usb dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = u_boot_utils.find_ram_base(u_boot_console) + size = random.randint(4, 1 * 1024 * 1024) + output = u_boot_console.run_command('crc32 %x %x' % (addr, size)) + m = re.search('==> (.+?)', output) + if not m: + pytest.fail('CRC32 failed') + expected_crc32 = m.group(1) + + file = '%s_%d' % ('uboot_test', size) + output = u_boot_console.run_command( + '%swrite usb %d:%s %x %s %x' % (fs, x, part, addr, file, size) + ) + assert 'Unable to write' not in output + assert 'Error' not in output + assert 'overflow' not in output + expected_text = '%d bytes written' % size + assert expected_text in output + + alignment = int( + u_boot_console.config.buildconfig.get( + 'config_sys_cacheline_size', 128 + ) + ) + offset = random.randrange(alignment, 1024, alignment) + output = u_boot_console.run_command( + '%sload usb %d:%s %x %s' % (fs, x, part, addr + offset, file) + ) + assert 'Invalid FAT entry' not in output + assert 'Unable to read file' not in output + assert 'Misaligned buffer address' not in output + expected_text = '%d bytes read' % size + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr + offset) + ) + assert expected_crc32 in output + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + + return file, size + +@pytest.mark.buildconfigspec('cmd_usb') +@pytest.mark.buildconfigspec('cmd_ext4') +def test_usb_ext4ls(u_boot_console): + devices, controllers, storage_device = test_usb_part(u_boot_console) + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'ext4' + for x in range(0, int(storage_device)): + if devices[x]['detected'] == 'yes': + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + u_boot_console.run_command('usb dev %d' % x) + for part in partitions: + output = u_boot_console.run_command('%sls usb %d:%s' % (fs, x, part)) + if 'Unrecognized filesystem type' in output: + partitions.remove(part) + pytest.fail('Unrecognized filesystem') + part_detect = 1 + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_usb') +@pytest.mark.buildconfigspec('cmd_ext4') +@pytest.mark.buildconfigspec('ext4_write') +@pytest.mark.buildconfigspec('cmd_memory') +def test_usb_ext4load_ext4write(u_boot_console): + devices, controllers, storage_device = test_usb_part(u_boot_console) + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'ext4' + for x in range(0, int(storage_device)): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('usb dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = u_boot_utils.find_ram_base(u_boot_console) + size = random.randint(4, 1 * 1024 * 1024) + output = u_boot_console.run_command('crc32 %x %x' % (addr, size)) + m = re.search('==> (.+?)', output) + if not m: + pytest.fail('CRC32 failed') + expected_crc32 = m.group(1) + file = '%s_%d' % ('uboot_test', size) + + output = u_boot_console.run_command( + '%swrite usb %d:%s %x /%s %x' % (fs, x, part, addr, file, size) + ) + assert 'Unable to write' not in output + assert 'Error' not in output + assert 'overflow' not in output + expected_text = '%d bytes written' % size + assert expected_text in output + + offset = random.randrange(128, 1024, 128) + output = u_boot_console.run_command( + '%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file) + ) + expected_text = '%d bytes read' % size + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr + offset) + ) + assert expected_crc32 in output + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + + return file, size + +@pytest.mark.buildconfigspec('cmd_usb') +@pytest.mark.buildconfigspec('cmd_ext2') +def test_usb_ext2ls(u_boot_console): + devices, controllers, storage_device = test_usb_part(u_boot_console) + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'ext2' + for x in range(0, int(storage_device)): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('usb dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + output = u_boot_console.run_command('%sls usb %d:%s' % (fs, x, part)) + if 'Unrecognized filesystem type' in output: + partitions.remove(part) + pytest.fail('Unrecognized filesystem') + part_detect = 1 + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_usb') +@pytest.mark.buildconfigspec('cmd_ext2') +@pytest.mark.buildconfigspec('cmd_ext4') +@pytest.mark.buildconfigspec('ext4_write') +@pytest.mark.buildconfigspec('cmd_memory') +def test_usb_ext2load(u_boot_console): + devices, controllers, storage_device = test_usb_part(u_boot_console) + file, size = test_usb_ext4load_ext4write(u_boot_console) + + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + fs = 'ext2' + for x in range(0, int(storage_device)): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('usb dev %d' % x) + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = u_boot_utils.find_ram_base(u_boot_console) + output = u_boot_console.run_command('crc32 %x %x' % (addr, size)) + m = re.search('==> (.+?)', output) + if not m: + pytest.fail('CRC32 failed') + expected_crc32 = m.group(1) + + offset = random.randrange(128, 1024, 128) + output = u_boot_console.run_command( + '%sload usb %d:%s %x /%s' % (fs, x, part, addr + offset, file) + ) + expected_text = '%d bytes read' % size + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr + offset) + ) + assert expected_crc32 in output + + if not part_detect: + pytest.skip('No %s partition detected' % fs.upper()) + +@pytest.mark.buildconfigspec('cmd_usb') +@pytest.mark.buildconfigspec('cmd_fs_generic') +def test_usb_ls(u_boot_console): + devices, controllers, storage_device = test_usb_part(u_boot_console) + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + for x in range(0, int(storage_device)): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('usb dev %d' % x) + for fs in ['fat', 'ext4']: + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + output = u_boot_console.run_command('ls usb %d:%s' % (x, part)) + if re.search(r'No \w+ table on this device', output): + pytest.fail( + '%s: Partition table not found %d' % (fs.upper(), x) + ) + + if not part_detect: + pytest.skip('No partition detected') + +@pytest.mark.buildconfigspec('cmd_usb') +@pytest.mark.buildconfigspec('cmd_fs_generic') +def test_usb_load(u_boot_console): + devices, controllers, storage_device = test_usb_part(u_boot_console) + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + for x in range(0, int(storage_device)): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('usb dev %d' % x) + for fs in ['fat', 'ext4']: + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = u_boot_utils.find_ram_base(u_boot_console) + + if fs == 'fat': + file, size = test_usb_fatload_fatwrite(u_boot_console) + elif fs == 'ext4': + file, size = test_usb_ext4load_ext4write(u_boot_console) + + output = u_boot_console.run_command('crc32 %x %x' % (addr, size)) + m = re.search('==> (.+?)', output) + if not m: + pytest.fail('CRC32 failed') + expected_crc32 = m.group(1) + + offset = random.randrange(128, 1024, 128) + output = u_boot_console.run_command( + 'load usb %d:%s %x /%s' % (x, part, addr + offset, file) + ) + expected_text = '%d bytes read' % size + assert expected_text in output + + output = u_boot_console.run_command( + 'crc32 %x $filesize' % (addr + offset) + ) + assert expected_crc32 in output + + if not part_detect: + pytest.skip('No partition detected') + +@pytest.mark.buildconfigspec('cmd_usb') +@pytest.mark.buildconfigspec('cmd_fs_generic') +def test_usb_save(u_boot_console): + devices, controllers, storage_device = test_usb_part(u_boot_console) + if not devices: + pytest.skip('No devices detected') + + part_detect = 0 + for x in range(0, int(storage_device)): + if devices[x]['detected'] == 'yes': + u_boot_console.run_command('usb dev %d' % x) + for fs in ['fat', 'ext4']: + try: + partitions = devices[x][fs] + except: + print('No %s table on this device' % fs.upper()) + continue + + for part in partitions: + part_detect = 1 + addr = u_boot_utils.find_ram_base(u_boot_console) + size = random.randint(4, 1 * 1024 * 1024) + file = '%s_%d' % ('uboot_test', size) + + offset = random.randrange(128, 1024, 128) + output = u_boot_console.run_command( + 'save usb %d:%s %x /%s %x' + % (x, part, addr + offset, file, size) + ) + expected_text = '%d bytes written' % size + assert expected_text in output + + if not part_detect: + pytest.skip('No partition detected') diff --git a/test/py/tests/test_zynq_secure.py b/test/py/tests/test_zynq_secure.py new file mode 100644 index 00000000000..0ee5aebc484 --- /dev/null +++ b/test/py/tests/test_zynq_secure.py @@ -0,0 +1,190 @@ +# SPDX-License-Identifier: GPL-2.0 +# (C) Copyright 2023, Advanced Micro Devices, Inc. + +import pytest +import re +import u_boot_utils +import test_net + +""" +This test verifies different type of secure boot images to authentication and +decryption using AES and RSA features for AMD's Zynq SoC. + +Note: This test relies on boardenv_* containing configuration values to define +the network available and files to be used for testing. Without this, this test +will be automatically skipped. It also relies on dhcp or setup_static net test +to support tftp to load files from a TFTP server. + +For example: + +# Details regarding the files that may be read from a TFTP server and addresses +# and size for aes and rsa cases respectively. This variable may be omitted or +# set to None if zynqmp secure testing is not possible or desired. +env__zynq_aes_readable_file = { + 'fn': 'zynq_aes_image.bin', + 'fnbit': 'zynq_aes_bit.bin', + 'fnpbit': 'zynq_aes_par_bit.bin', + 'srcaddr': 0x1000000, + 'dstaddr': 0x2000000, + 'dstlen': 0x1000000, +} + +env__zynq_rsa_readable_file = { + 'fn': 'zynq_rsa_image.bin', + 'fninvalid': 'zynq_rsa_image_invalid.bin', + 'srcaddr': 0x1000000, +} +""" + +def zynq_secure_pre_commands(u_boot_console): + output = u_boot_console.run_command('print modeboot') + if not 'modeboot=' in output: + pytest.skip('bootmode cannnot be determined') + m = re.search('modeboot=(.+?)boot', output) + if not m: + pytest.skip('bootmode cannnot be determined') + bootmode = m.group(1) + if bootmode == 'jtag': + pytest.skip('skipping due to jtag bootmode') + +@pytest.mark.buildconfigspec('cmd_zynq_aes') +def test_zynq_aes_image(u_boot_console): + f = u_boot_console.config.env.get('env__zynq_aes_readable_file', None) + if not f: + pytest.skip('No TFTP readable file for zynq secure aes case to read') + + dstaddr = f.get('dstaddr', None) + if not dstaddr: + pytest.skip('No dstaddr specified in env file to read') + + dstsize = f.get('dstlen', None) + if not dstsize: + pytest.skip('No dstlen specified in env file to read') + + zynq_secure_pre_commands(u_boot_console) + test_net.test_net_dhcp(u_boot_console) + if not test_net.net_set_up: + test_net.test_net_setup_static(u_boot_console) + + srcaddr = f.get('srcaddr', None) + if not srcaddr: + addr = u_boot_utils.find_ram_base(u_boot_console) + + expected_tftp = 'Bytes transferred = ' + fn = f['fn'] + output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn)) + assert expected_tftp in output + + expected_op = 'zynq aes [operation type] <srcaddr>' + output = u_boot_console.run_command( + 'zynq aes %x $filesize %x %x' % (srcaddr, dstaddr, dstsize) + ) + assert expected_op not in output + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_zynq_aes') +def test_zynq_aes_bitstream(u_boot_console): + f = u_boot_console.config.env.get('env__zynq_aes_readable_file', None) + if not f: + pytest.skip('No TFTP readable file for zynq secure aes case to read') + + zynq_secure_pre_commands(u_boot_console) + test_net.test_net_dhcp(u_boot_console) + if not test_net.net_set_up: + test_net.test_net_setup_static(u_boot_console) + + srcaddr = f.get('srcaddr', None) + if not srcaddr: + addr = u_boot_utils.find_ram_base(u_boot_console) + + expected_tftp = 'Bytes transferred = ' + fn = f['fnbit'] + output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn)) + assert expected_tftp in output + + expected_op = 'zynq aes [operation type] <srcaddr>' + output = u_boot_console.run_command( + 'zynq aes load %x $filesize' % (srcaddr) + ) + assert expected_op not in output + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_zynq_aes') +def test_zynq_aes_partial_bitstream(u_boot_console): + f = u_boot_console.config.env.get('env__zynq_aes_readable_file', None) + if not f: + pytest.skip('No TFTP readable file for zynq secure aes case to read') + + zynq_secure_pre_commands(u_boot_console) + test_net.test_net_dhcp(u_boot_console) + if not test_net.net_set_up: + test_net.test_net_setup_static(u_boot_console) + + srcaddr = f.get('srcaddr', None) + if not srcaddr: + addr = u_boot_utils.find_ram_base(u_boot_console) + + expected_tftp = 'Bytes transferred = ' + fn = f['fnpbit'] + output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn)) + assert expected_tftp in output + + expected_op = 'zynq aes [operation type] <srcaddr>' + output = u_boot_console.run_command('zynq aes loadp %x $filesize' % (srcaddr)) + assert expected_op not in output + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_zynq_rsa') +def test_zynq_rsa_image(u_boot_console): + f = u_boot_console.config.env.get('env__zynq_rsa_readable_file', None) + if not f: + pytest.skip('No TFTP readable file for zynq secure rsa case to read') + + zynq_secure_pre_commands(u_boot_console) + test_net.test_net_dhcp(u_boot_console) + if not test_net.net_set_up: + test_net.test_net_setup_static(u_boot_console) + + srcaddr = f.get('srcaddr', None) + if not srcaddr: + addr = u_boot_utils.find_ram_base(u_boot_console) + + expected_tftp = 'Bytes transferred = ' + fn = f['fn'] + output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fn)) + assert expected_tftp in output + + expected_op = 'zynq rsa <baseaddr>' + output = u_boot_console.run_command('zynq rsa %x ' % (srcaddr)) + assert expected_op not in output + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + +@pytest.mark.buildconfigspec('cmd_zynq_rsa') +def test_zynq_rsa_image_invalid(u_boot_console): + f = u_boot_console.config.env.get('env__zynq_rsa_readable_file', None) + if not f: + pytest.skip('No TFTP readable file for zynq secure rsa case to read') + + zynq_secure_pre_commands(u_boot_console) + test_net.test_net_dhcp(u_boot_console) + if not test_net.net_set_up: + test_net.test_net_setup_static(u_boot_console) + + srcaddr = f.get('srcaddr', None) + if not srcaddr: + addr = u_boot_utils.find_ram_base(u_boot_console) + + expected_tftp = 'Bytes transferred = ' + fninvalid = f['fninvalid'] + output = u_boot_console.run_command('tftpboot %x %s' % (srcaddr, fninvalid)) + assert expected_tftp in output + + expected_op = 'zynq rsa <baseaddr>' + output = u_boot_console.run_command('zynq rsa %x ' % (srcaddr)) + assert expected_op in output + output = u_boot_console.run_command('echo $?') + assert not output.endswith('0') diff --git a/test/py/tests/test_zynqmp_rpu.py b/test/py/tests/test_zynqmp_rpu.py new file mode 100644 index 00000000000..479a612b4ec --- /dev/null +++ b/test/py/tests/test_zynqmp_rpu.py @@ -0,0 +1,208 @@ +# SPDX-License-Identifier: GPL-2.0 +# (C) Copyright 2023, Advanced Micro Devices, Inc. + +import pytest +import random +import string +import test_net + +""" +Note: This test relies on boardenv_* containing configuration values to define +RPU applications information for AMD's ZynqMP SoC which contains, application +names, processors, address where it is built, expected output and the tftp load +addresses. This test will be automatically skipped without this. + +It also relies on dhcp or setup_static net test to support tftp to load +application on DDR. All the environment parameters are stored sequentially. +The length of all parameters values should be same. For example, if 2 app_names +are defined in a list as a value of parameter 'app_name' then the other +parameters value also should have a list with 2 items. +It will run RPU cases for all the applications defined in boardenv_* +configuration file. + +Example: +env__zynqmp_rpu_apps = { + 'app_name': ['hello_world_r5_0_ddr.elf', 'hello_world_r5_1_ddr.elf'], + 'proc': ['rpu0', 'rpu1'], + 'cpu_num': [4, 5], + 'addr': [0xA00000, 0xB00000], + 'output': ['Successfully ran Hello World application on DDR from RPU0', + 'Successfully ran Hello World application on DDR from RPU1'], + 'tftp_addr': [0x100000, 0x200000], +} +""" + +# Get rpu apps params from env +def get_rpu_apps_env(u_boot_console): + rpu_apps = u_boot_console.config.env.get('env__zynqmp_rpu_apps', False) + if not rpu_apps: + pytest.skip('ZynqMP RPU application info not defined!') + + apps = rpu_apps.get('app_name', None) + if not apps: + pytest.skip('No RPU application found!') + + procs = rpu_apps.get('proc', None) + if not procs: + pytest.skip('No RPU application processor provided!') + + cpu_nums = rpu_apps.get('cpu_num', None) + if not cpu_nums: + pytest.skip('No CPU number for respective processor provided!') + + addrs = rpu_apps.get('addr', None) + if not addrs: + pytest.skip('No RPU application build address found!') + + outputs = rpu_apps.get('output', None) + if not outputs: + pytest.skip('Expected output not found!') + + tftp_addrs = rpu_apps.get('tftp_addr', None) + if not tftp_addrs: + pytest.skip('TFTP address to load application not found!') + + return apps, procs, cpu_nums, addrs, outputs, tftp_addrs + +# Check return code +def ret_code(u_boot_console): + return u_boot_console.run_command('echo $?') + +# Initialize tcm +def tcminit(u_boot_console, rpu_mode): + output = u_boot_console.run_command('zynqmp tcminit %s' % rpu_mode) + assert 'Initializing TCM overwrites TCM content' in output + return ret_code(u_boot_console) + +# Load application in DDR +def load_app_ddr(u_boot_console, tftp_addr, app): + output = u_boot_console.run_command('tftpboot %x %s' % (tftp_addr, app)) + assert 'TIMEOUT' not in output + assert 'Bytes transferred = ' in output + + # Load elf + u_boot_console.run_command('bootelf -p %x' % tftp_addr) + assert ret_code(u_boot_console).endswith('0') + +# Disable cpus +def disable_cpus(u_boot_console, cpu_nums): + for num in cpu_nums: + u_boot_console.run_command(f'cpu {num} disable') + +# Load apps on RPU cores +def rpu_apps_load(u_boot_console, rpu_mode): + apps, procs, cpu_nums, addrs, outputs, tftp_addrs = get_rpu_apps_env( + u_boot_console) + test_net.test_net_dhcp(u_boot_console) + if not test_net.net_set_up: + test_net.test_net_setup_static(u_boot_console) + + try: + assert tcminit(u_boot_console, rpu_mode).endswith('0') + + for i in range(len(apps)): + if rpu_mode == 'lockstep' and procs[i] != 'rpu0': + continue + + load_app_ddr(u_boot_console, tftp_addrs[i], apps[i]) + rel_addr = int(addrs[i] + 0x3C) + + # Release cpu at app load address + cpu_num = cpu_nums[i] + cmd = 'cpu %d release %x %s' % (cpu_num, rel_addr, rpu_mode) + output = u_boot_console.run_command(cmd) + exp_op = f'Using TCM jump trampoline for address {hex(rel_addr)}' + assert exp_op in output + assert f'R5 {rpu_mode} mode' in output + u_boot_console.wait_for(outputs[i]) + assert ret_code(u_boot_console).endswith('0') + finally: + disable_cpus(u_boot_console, cpu_nums) + +@pytest.mark.buildconfigspec('cmd_zynqmp') +def test_zynqmp_rpu_app_load_split(u_boot_console): + rpu_apps_load(u_boot_console, 'split') + +@pytest.mark.buildconfigspec('cmd_zynqmp') +def test_zynqmp_rpu_app_load_lockstep(u_boot_console): + rpu_apps_load(u_boot_console, 'lockstep') + +@pytest.mark.buildconfigspec('cmd_zynqmp') +def test_zynqmp_rpu_app_load_negative(u_boot_console): + apps, procs, cpu_nums, addrs, outputs, tftp_addrs = get_rpu_apps_env( + u_boot_console) + + # Invalid commands + u_boot_console.run_command('zynqmp tcminit mode') + assert ret_code(u_boot_console).endswith('1') + + rand_str = ''.join(random.choices(string.ascii_lowercase, k=4)) + u_boot_console.run_command('zynqmp tcminit %s' % rand_str) + assert ret_code(u_boot_console).endswith('1') + + rand_num = random.randint(2, 100) + u_boot_console.run_command('zynqmp tcminit %d' % rand_num) + assert ret_code(u_boot_console).endswith('1') + + test_net.test_net_dhcp(u_boot_console) + if not test_net.net_set_up: + test_net.test_net_setup_static(u_boot_console) + + try: + rpu_mode = 'split' + assert tcminit(u_boot_console, rpu_mode).endswith('0') + + for i in range(len(apps)): + load_app_ddr(u_boot_console, tftp_addrs[i], apps[i]) + + # Run in split mode at different load address + rel_addr = int(addrs[i]) + random.randint(200, 1000) + cpu_num = cpu_nums[i] + cmd = 'cpu %d release %x %s' % (cpu_num, rel_addr, rpu_mode) + output = u_boot_console.run_command(cmd) + exp_op = f'Using TCM jump trampoline for address {hex(rel_addr)}' + assert exp_op in output + assert f'R5 {rpu_mode} mode' in output + assert not outputs[i] in output + + # Invalid rpu mode + rand_str = ''.join(random.choices(string.ascii_lowercase, k=4)) + cmd = 'cpu %d release %x %s' % (cpu_num, rel_addr, rand_str) + output = u_boot_console.run_command(cmd) + assert exp_op in output + assert f'Unsupported mode' in output + assert not ret_code(u_boot_console).endswith('0') + + # Switch to lockstep mode, without disabling CPUs + rpu_mode = 'lockstep' + u_boot_console.run_command('zynqmp tcminit %s' % rpu_mode) + assert not ret_code(u_boot_console).endswith('0') + + # Disable cpus + disable_cpus(u_boot_console, cpu_nums) + + # Switch to lockstep mode, after disabling CPUs + output = u_boot_console.run_command('zynqmp tcminit %s' % rpu_mode) + assert 'Initializing TCM overwrites TCM content' in output + assert ret_code(u_boot_console).endswith('0') + + # Run lockstep mode for RPU1 + for i in range(len(apps)): + if procs[i] == 'rpu0': + continue + + load_app_ddr(u_boot_console, tftp_addrs[i], apps[i]) + rel_addr = int(addrs[i] + 0x3C) + cpu_num = cpu_nums[i] + cmd = 'cpu %d release %x %s' % (cpu_num, rel_addr, rpu_mode) + output = u_boot_console.run_command(cmd) + exp_op = f'Using TCM jump trampoline for address {hex(rel_addr)}' + assert exp_op in output + assert f'R5 {rpu_mode} mode' in output + assert u_boot_console.p.expect([outputs[i]]) + finally: + disable_cpus(u_boot_console, cpu_nums) + # This forces the console object to be shutdown, so any subsequent test + # will reset the board back into U-Boot. + u_boot_console.drain_console() + u_boot_console.cleanup_spawn() diff --git a/test/py/tests/test_zynqmp_secure.py b/test/py/tests/test_zynqmp_secure.py new file mode 100644 index 00000000000..570bd2439c1 --- /dev/null +++ b/test/py/tests/test_zynqmp_secure.py @@ -0,0 +1,104 @@ +# SPDX-License-Identifier: GPL-2.0 +# (C) Copyright 2023, Advanced Micro Devices, Inc. + +import pytest +import re +import u_boot_utils +import test_net + +""" +This test verifies different type of secure boot images loaded at the DDR for +AMD's ZynqMP SoC. + +Note: This test relies on boardenv_* containing configuration values to define +the files to be used for testing. Without this, this test will be automatically +skipped. It also relies on dhcp or setup_static net test to support tftp to +load files from a TFTP server. + +For example: + +# Details regarding the files that may be read from a TFTP server. This +# variable may be omitted or set to None if zynqmp secure testing is not +# possible or desired. +env__zynqmp_secure_readable_file = { + 'fn': 'auth_bhdr_ppk1.bin', + 'enckupfn': 'auth_bhdr_enc_kup_load.bin', + 'addr': 0x1000000, + 'keyaddr': 0x100000, + 'keyfn': 'aes.txt', +} +""" + +@pytest.mark.buildconfigspec('cmd_zynqmp') +def test_zynqmp_secure_boot_image(u_boot_console): + """This test verifies secure boot image at the DDR address for + authentication only case. + """ + + f = u_boot_console.config.env.get('env__zynqmp_secure_readable_file', None) + if not f: + pytest.skip('No TFTP readable file for zynqmp secure cases to read') + + test_net.test_net_dhcp(u_boot_console) + if not test_net.net_set_up: + test_net.test_net_setup_static(u_boot_console) + + addr = f.get('addr', None) + if not addr: + addr = u_boot_utils.find_ram_base(u_boot_console) + + expected_tftp = 'Bytes transferred = ' + fn = f['fn'] + output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn)) + assert expected_tftp in output + + output = u_boot_console.run_command('zynqmp secure %x $filesize' % (addr)) + assert 'Verified image at' in output + ver_addr = re.search(r'Verified image at 0x(.+)', output).group(1) + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + output = u_boot_console.run_command('print zynqmp_verified_img_addr') + assert f'zynqmp_verified_img_addr={ver_addr}' in output + assert 'Error' not in output + + +@pytest.mark.buildconfigspec('cmd_zynqmp') +def test_zynqmp_secure_boot_img_kup(u_boot_console): + """This test verifies secure boot image at the DDR address for encryption + with kup key case. + """ + + f = u_boot_console.config.env.get('env__zynqmp_secure_readable_file', None) + if not f: + pytest.skip('No TFTP readable file for zynqmp secure cases to read') + + test_net.test_net_dhcp(u_boot_console) + if not test_net.net_set_up: + test_net.test_net_setup_static(u_boot_console) + + keyaddr = f.get('keyaddr', None) + if not keyaddr: + addr = u_boot_utils.find_ram_base(u_boot_console) + expected_tftp = 'Bytes transferred = ' + keyfn = f['keyfn'] + output = u_boot_console.run_command('tftpboot %x %s' % (keyaddr, keyfn)) + assert expected_tftp in output + + addr = f.get('addr', None) + if not addr: + addr = u_boot_utils.find_ram_base(u_boot_console) + expected_tftp = 'Bytes transferred = ' + fn = f['enckupfn'] + output = u_boot_console.run_command('tftpboot %x %s' % (addr, fn)) + assert expected_tftp in output + + output = u_boot_console.run_command( + 'zynqmp secure %x $filesize %x' % (addr, keyaddr) + ) + assert 'Verified image at' in output + ver_addr = re.search(r'Verified image at 0x(.+)', output).group(1) + output = u_boot_console.run_command('echo $?') + assert output.endswith('0') + output = u_boot_console.run_command('print zynqmp_verified_img_addr') + assert f'zynqmp_verified_img_addr={ver_addr}' in output + assert 'Error' not in output diff --git a/test/unicode_ut.c b/test/unicode_ut.c index 1d0d90c2d73..47c3f52774c 100644 --- a/test/unicode_ut.c +++ b/test/unicode_ut.c @@ -752,9 +752,10 @@ static int unicode_test_utf8_to_utf32_stream(struct unit_test_state *uts) const u32 u1[] = {0x55, 0x2D, 0x42, 0x6F, 0x6F, 0x74, 0x0000}; const u32 u2[] = {0x6B, 0x61, 0x66, 0x62, 0xE1, 0x74, 0x75, 0x72, 0x00}; - const u32 u3[] = {0x0392, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, 0x74, - 0x20, 0x42, 0x00}; + const u32 u3[] = {0x6f5c, 0x6c34, 0x8266}; const u32 u4[] = {0x6A, 0x32, 0x6C, 0x00}; + const u32 u5[] = {0x0392, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, 0x74, + 0x20, 0x42, 0x00}; memset(buf, 0, sizeof(buf)); utf8_to_utf32_stream_helper(d1, buf); @@ -765,10 +766,14 @@ static int unicode_test_utf8_to_utf32_stream(struct unit_test_state *uts) ut_asserteq_mem(u2, buf, sizeof(u2)); memset(buf, 0, sizeof(buf)); - utf8_to_utf32_stream_helper(d5, buf); + utf8_to_utf32_stream_helper(d3, buf); ut_asserteq_mem(u3, buf, sizeof(u3)); memset(buf, 0, sizeof(buf)); + utf8_to_utf32_stream_helper(d5, buf); + ut_asserteq_mem(u5, buf, sizeof(u5)); + + memset(buf, 0, sizeof(buf)); utf8_to_utf32_stream_helper(j2, buf); ut_asserteq_mem(u4, buf, sizeof(u4)); diff --git a/tools/buildman/bsettings.py b/tools/buildman/bsettings.py index f7f8276e629..e225ac2ca0f 100644 --- a/tools/buildman/bsettings.py +++ b/tools/buildman/bsettings.py @@ -16,7 +16,7 @@ def setup(fname=''): global settings global config_fname - settings = configparser.SafeConfigParser() + settings = configparser.ConfigParser() if fname is not None: config_fname = fname if config_fname == '': diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index 0e2dd0a6a94..6122776bc64 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -240,12 +240,14 @@ USER uboot:uboot # COPY / ADD directives don't work as we need them to. RUN wget -O /tmp/pytest-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/test/py/requirements.txt RUN wget -O /tmp/sphinx-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/doc/sphinx/requirements.txt +RUN wget -O /tmp/buildman-requirements.txt https://source.denx.de/u-boot/u-boot/-/raw/master/tools/buildman/requirements.txt RUN virtualenv -p /usr/bin/python3 /tmp/venv && \ . /tmp/venv/bin/activate && \ pip install -r /tmp/pytest-requirements.txt \ - -r /tmp/sphinx-requirements.txt && \ + -r /tmp/sphinx-requirements.txt \ + -r /tmp/buildman-requirements.txt && \ deactivate && \ - rm -rf /tmp/venv /tmp/pytest-requirements.txt /tmp/sphinx-requirements.txt + rm -rf /tmp/venv /tmp/*-requirements.txt # Create the buildman config file RUN /bin/echo -e "[toolchain]\nroot = /usr" > ~/.buildman |