Merge patch series "configs: ti: Enable basic settings for SystemReady ACS"
Jonathan Humphreys <j-humphreys@ti.com> says:
Set basic settings needed for System Ready IR ACS testing, for several TI SoC
based platforms: AM64, AM62, AM62p, BeaglePlay, J7, and BeagleboneAI.
For AM64, AM62, and AM62p, also includes some config cleanup. Should be no
functional change.
diff --git a/Kconfig b/Kconfig
index 75f9563..82df59f 100644
--- a/Kconfig
+++ b/Kconfig
@@ -715,6 +715,20 @@
A static value for the CPU frequency. Note that if not required
for a given SoC, this can be left at 0.
+config HAS_LDR
+ bool
+ help
+ Enables building .ldr targets for U-Boot and SPL. This does not
+ automatically build any additional targets with make or buildman.
+
+config LDR_CPU
+ string "CPU name to be passed to LDR utility."
+ depends on HAS_LDR
+ help
+ Set the CPU name for the -T parameter in the LDR utility. This is
+ generally used on processors from Analog Devices, but may be also
+ be useful for other vendors.
+
source "api/Kconfig"
endmenu # General setup
diff --git a/Makefile b/Makefile
index 1069adc..7321fe1 100644
--- a/Makefile
+++ b/Makefile
@@ -1360,7 +1360,7 @@
u-boot.ldr: u-boot
$(CREATE_LDR_ENV)
- $(LDR) -T $(CONFIG_CPU) -c $@ $< $(LDR_FLAGS)
+ $(LDR) -T $(CONFIG_LDR_CPU) -c $@ $< $(LDR_FLAGS)
$(BOARD_SIZE_CHECK)
# binman
diff --git a/arch/Kconfig b/arch/Kconfig
index f9aaf37..abd406d 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -254,7 +254,6 @@
imply CMD_PCI
imply CMD_SF
imply CMD_SF_TEST
- imply CMD_ZBOOT
imply DM_GPIO
imply DM_KEYBOARD
imply DM_MMC
diff --git a/arch/arc/lib/Makefile b/arch/arc/lib/Makefile
index 0eb44bc..bde1c3d 100644
--- a/arch/arc/lib/Makefile
+++ b/arch/arc/lib/Makefile
@@ -12,6 +12,6 @@
obj-y += ints_low.o
obj-y += init_helpers.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
lib-$(CONFIG_USE_PRIVATE_LIBGCC) += _millicodethunk.o libgcc2.o
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4cdf08d..23ee252 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1321,6 +1321,14 @@
select SPL_DM_SPI_FLASH if SPL_DM_SPI
select SPL_DM_MAILBOX if SPL
imply SPL_FIRMWARE if SPL
+ imply SPL_FS_FAT if SPL
+ imply SPL_LIBCOMMON_SUPPORT if SPL
+ imply SPL_LIBDISK_SUPPORT if SPL
+ imply SPL_LIBGENERIC_SUPPORT if SPL
+ imply SPL_MMC if SPL && MMC_SDHCI_ZYNQ
+ imply SPL_SERIAL if SPL
+ imply SPL_SPI if SPL && ZYNQ_QSPI
+ imply SPL_SPI_FLASH_SUPPORT if SPL && ZYNQ_QSPI
select SPL_SEPARATE_BSS if SPL
select SUPPORT_SPL
imply ZYNQMP_IPI if DM_MAILBOX
diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c
index 6973340..57d06f0 100644
--- a/arch/arm/cpu/armv8/cache_v8.c
+++ b/arch/arm/cpu/armv8/cache_v8.c
@@ -326,6 +326,8 @@
/* Going one level down */
if (pte_type(&table[i]) == PTE_TYPE_FAULT)
set_pte_table(&table[i], create_table());
+ else if (pte_type(&table[i]) != PTE_TYPE_TABLE)
+ split_block(&table[i], level);
next_table = (u64 *)(table[i] & GENMASK_ULL(47, PAGE_SHIFT));
next_size = min(map_size - (virt & (map_size - 1)), size);
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 2634bb4..08dfbdd 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1353,7 +1353,6 @@
k3-am625-r5-sk.dtb \
k3-am625-beagleplay.dtb \
k3-am625-r5-beagleplay.dtb \
- k3-am625-verdin-wifi-dev.dtb \
k3-am625-verdin-r5.dtb \
k3-am625-phyboard-lyra-rdk.dtb \
k3-am625-r5-phycore-som-2gb.dtb
diff --git a/arch/arm/dts/k3-am62-verdin-dev.dtsi b/arch/arm/dts/k3-am62-verdin-dev.dtsi
deleted file mode 100644
index 6701cb8..0000000
--- a/arch/arm/dts/k3-am62-verdin-dev.dtsi
+++ /dev/null
@@ -1,240 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-/*
- * Copyright 2023 Toradex
- *
- * Common dtsi for Verdin AM62 SoM on Development carrier board
- *
- * https://www.toradex.com/computer-on-modules/verdin-arm-family/ti-am62
- * https://www.toradex.com/products/carrier-board/verdin-development-board-kit
- */
-
-/ {
- sound {
- compatible = "simple-audio-card";
- simple-audio-card,bitclock-master = <&codec_dai>;
- simple-audio-card,format = "i2s";
- simple-audio-card,frame-master = <&codec_dai>;
- simple-audio-card,name = "verdin-nau8822";
- simple-audio-card,routing =
- "Headphones", "LHP",
- "Headphones", "RHP",
- "Speaker", "LSPK",
- "Speaker", "RSPK",
- "Line Out", "AUXOUT1",
- "Line Out", "AUXOUT2",
- "LAUX", "Line In",
- "RAUX", "Line In",
- "LMICP", "Mic In",
- "RMICP", "Mic In";
- simple-audio-card,widgets =
- "Headphones", "Headphones",
- "Line Out", "Line Out",
- "Speaker", "Speaker",
- "Microphone", "Mic In",
- "Line", "Line In";
-
- codec_dai: simple-audio-card,codec {
- clocks = <&audio_refclk1>;
- sound-dai = <&nau8822_1a>;
- };
-
- simple-audio-card,cpu {
- sound-dai = <&mcasp0>;
- };
- };
-};
-
-/* Verdin ETHs */
-&cpsw3g {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_rgmii1>, <&pinctrl_rgmii2>;
- status = "okay";
-};
-
-/* MDIO, shared by Verdin ETH_1 (On-module PHY) and Verdin ETH_2_RGMII */
-&cpsw3g_mdio {
- status = "okay";
-
- cpsw3g_phy1: ethernet-phy@7 {
- compatible = "ethernet-phy-ieee802.3-c22";
- reg = <7>;
- interrupt-parent = <&main_gpio0>;
- interrupts = <38 IRQ_TYPE_EDGE_FALLING>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_eth2_rgmii_int>;
- micrel,led-mode = <0>;
- };
-};
-
-/* Verdin ETH_1 (On-module PHY) */
-&cpsw_port1 {
- status = "okay";
-};
-
-/* Verdin ETH_2_RGMII */
-&cpsw_port2 {
- phy-handle = <&cpsw3g_phy1>;
- phy-mode = "rgmii-rxid";
- status = "okay";
-};
-
-/* Verdin PWM_1, PWM_2 */
-&epwm0 {
- status = "okay";
-};
-
-/* Verdin PWM_3_DSI */
-&epwm1 {
- status = "okay";
-};
-
-&main_gpio0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ctrl_sleep_moci>,
- <&pinctrl_gpio_5>,
- <&pinctrl_gpio_6>,
- <&pinctrl_gpio_7>,
- <&pinctrl_gpio_8>;
-};
-
-/* Verdin I2C_1 */
-&main_i2c1 {
- status = "okay";
-
- /* Audio Codec */
- nau8822_1a: audio-codec@1a {
- compatible = "nuvoton,nau8822";
- reg = <0x1a>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2s1_mclk>;
- #sound-dai-cells = <0>;
- };
-
- /* IO Expander */
- gpio_expander_21: gpio@21 {
- compatible = "nxp,pcal6416";
- reg = <0x21>;
- #gpio-cells = <2>;
- gpio-controller;
- };
-
- /* Current measurement into module VCC */
- hwmon@40 {
- compatible = "ti,ina219";
- reg = <0x40>;
- shunt-resistor = <10000>;
- };
-
- /* Temperature sensor */
- sensor@4f {
- compatible = "ti,tmp75c";
- reg = <0x4f>;
- };
-
- /* EEPROM */
- eeprom@57 {
- compatible = "st,24c02", "atmel,24c02";
- reg = <0x57>;
- pagesize = <16>;
- };
-};
-
-/* Verdin I2C_2_DSI */
-&main_i2c2 {
- status = "okay";
-};
-
-/* Verdin I2C_4_CSI */
-&main_i2c3 {
- status = "okay";
-};
-
-/* Verdin CAN_1 */
-&main_mcan0 {
- status = "okay";
-};
-
-/* Verdin SPI_1 */
-&main_spi1 {
- status = "okay";
-};
-
-/* Verdin UART_3 */
-&main_uart0 {
- status = "okay";
-};
-
-/* Verdin UART_1, connector X50 through RS485 transceiver. */
-&main_uart1 {
- linux,rs485-enabled-at-boot-time;
- rs485-rx-during-tx;
- status = "okay";
-};
-
-/* Verdin I2S_1 */
-&mcasp0 {
- status = "okay";
-};
-
-&mcu_gpio0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_gpio_1>,
- <&pinctrl_gpio_2>,
- <&pinctrl_gpio_3>,
- <&pinctrl_gpio_4>;
-};
-
-/* Verdin I2C_3_HDMI */
-&mcu_i2c0 {
- status = "okay";
-};
-
-/* Verdin CAN_2 */
-&mcu_mcan0 {
- status = "okay";
-};
-
-/* Verdin UART_4 */
-&mcu_uart0 {
- status = "okay";
-};
-
-/* Verdin QSPI_1 */
-&ospi0 {
- status = "okay";
-};
-
-/* Verdin SD_1 */
-&sdhci1 {
- ti,driver-strength-ohm = <33>;
- status = "okay";
-};
-
-/* Verdin USB_1 */
-&usbss0 {
- status = "okay";
-};
-
-&usb0 {
- status = "okay";
-};
-
-/* Verdin USB_2 */
-&usbss1 {
- status = "okay";
-};
-
-&usb1 {
- status = "okay";
-};
-
-/* Verdin CTRL_WAKE1_MICO# */
-&verdin_gpio_keys {
- status = "okay";
-};
-
-/* Verdin UART_2 */
-&wkup_uart0 {
- /* FIXME: WKUP UART0 is used by DM firmware */
- status = "reserved";
-};
diff --git a/arch/arm/dts/k3-am62-verdin-wifi.dtsi b/arch/arm/dts/k3-am62-verdin-wifi.dtsi
deleted file mode 100644
index a6808b1..0000000
--- a/arch/arm/dts/k3-am62-verdin-wifi.dtsi
+++ /dev/null
@@ -1,45 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-/*
- * Copyright 2023 Toradex
- *
- * Common dtsi for Verdin AM62 SoM WB variant
- *
- * https://www.toradex.com/computer-on-modules/verdin-arm-family/ti-am62
- */
-
-/ {
- wifi_pwrseq: wifi-pwrseq {
- compatible = "mmc-pwrseq-simple";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_wifi_en>;
- reset-gpios = <&main_gpio0 22 GPIO_ACTIVE_LOW>;
- };
-};
-
-/* On-module Wi-Fi */
-&sdhci2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_sdhci2>;
- bus-width = <4>;
- cap-power-off-card;
- keep-power-in-suspend;
- mmc-pwrseq = <&wifi_pwrseq>;
- non-removable;
- ti,fails-without-test-cd;
- ti,driver-strength-ohm = <50>;
- vmmc-supply = <®_3v3>;
- status = "okay";
-};
-
-/* On-module Bluetooth */
-&main_uart5 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart5>;
- uart-has-rtscts;
- status = "okay";
-
- bluetooth {
- compatible = "nxp,88w8987-bt";
- fw-init-baudrate = <3000000>;
- };
-};
diff --git a/arch/arm/dts/k3-am62-verdin.dtsi b/arch/arm/dts/k3-am62-verdin.dtsi
deleted file mode 100644
index 5db52f2..0000000
--- a/arch/arm/dts/k3-am62-verdin.dtsi
+++ /dev/null
@@ -1,1443 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-/*
- * Copyright 2023 Toradex
- *
- * Common dtsi for Verdin AM62 SoM
- *
- * https://www.toradex.com/computer-on-modules/verdin-arm-family/ti-am62
- */
-
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/net/ti-dp83867.h>
-
-/ {
- chosen {
- stdout-path = "serial2:115200n8";
- };
-
- aliases {
- can0 = &main_mcan0;
- can1 = &mcu_mcan0;
- ethernet0 = &cpsw_port1;
- ethernet1 = &cpsw_port2;
- i2c0 = &main_i2c0;
- i2c1 = &main_i2c1;
- i2c2 = &main_i2c2;
- i2c3 = &mcu_i2c0;
- i2c4 = &main_i2c3;
- mmc0 = &sdhci0;
- mmc1 = &sdhci1;
- mmc2 = &sdhci2;
- rtc0 = &rtc_i2c;
- rtc1 = &wkup_rtc0;
- serial0 = &main_uart1;
- serial1 = &wkup_uart0;
- serial2 = &main_uart0;
- serial3 = &mcu_uart0;
- serial4 = &main_uart5;
- usb0 = &usb0;
- usb1 = &usb1;
- };
-
- verdin_gpio_keys: gpio-keys {
- compatible = "gpio-keys";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ctrl_wake1_mico>;
- status = "disabled";
-
- verdin_key_wakeup: key-wakeup {
- debounce-interval = <10>;
- /* Verdin CTRL_WAKE1_MICO# (SODIMM 252) */
- gpios = <&main_gpio0 32 GPIO_ACTIVE_LOW>;
- label = "Wake-Up";
- linux,code = <KEY_WAKEUP>;
- wakeup-source;
- };
- };
-
- memory@80000000 {
- device_type = "memory";
- reg = <0x00000000 0x80000000 0x00000000 0x40000000>; /* 1G RAM */
- };
-
- opp-table {
- /* Add 1.4GHz OPP. Requires VDD_CORE to be at 0.85V */
- opp-1400000000 {
- opp-hz = /bits/ 64 <1400000000>;
- opp-supported-hw = <0x01 0x0004>;
- clock-latency-ns = <6000000>;
- };
- };
-
- /* Module Power Supply */
- reg_vsodimm: regulator-vsodimm {
- compatible = "regulator-fixed";
- regulator-name = "+V_SODIMM";
- };
-
- /* Non PMIC On-module Supplies */
- reg_3v3: regulator-3v3 {
- compatible = "regulator-fixed";
- regulator-max-microvolt = <3300000>;
- regulator-min-microvolt = <3300000>;
- regulator-name = "On-module +V3.3";
- vin-supply = <®_vsodimm>;
- };
-
- reg_1v2_dsi: regulator-1v2-dsi {
- compatible = "regulator-fixed";
- regulator-max-microvolt = <1200000>;
- regulator-min-microvolt = <1200000>;
- regulator-name = "On-module +V1.2_DSI";
- vin-supply = <®_1v8>;
- };
-
- /* Enabled by +V1.2_DSI */
- reg_1v8_dsi: regulator-1v8-dsi {
- compatible = "regulator-fixed";
- regulator-max-microvolt = <1800000>;
- regulator-min-microvolt = <1800000>;
- regulator-name = "On-module +V1.8_DSI";
- vin-supply = <®_1v8>;
- };
-
- /* Enabled by +V2.5_ETH */
- reg_1v0_eth: regulator-1v0-eth {
- compatible = "regulator-fixed";
- regulator-max-microvolt = <1000000>;
- regulator-min-microvolt = <1000000>;
- regulator-name = "On-module +V1.0_ETH";
- vin-supply = <®_1v8>;
- };
-
- /* Enabled by +V2.5_ETH */
- reg_1v8_eth: regulator-1v8-eth {
- compatible = "regulator-fixed";
- regulator-max-microvolt = <1800000>;
- regulator-min-microvolt = <1800000>;
- regulator-name = "On-module +V1.8_ETH";
- vin-supply = <®_1v8>;
- };
-
- /* Verdin SD_1 Power Supply */
- reg_sdhc1_vmmc: regulator-sdhci1 {
- compatible = "regulator-fixed";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_sd1_pwr_en>;
- enable-active-high;
- /* Verdin SD_1_PWR_EN (SODIMM 76) */
- gpio = <&main_gpio0 29 GPIO_ACTIVE_HIGH>;
- off-on-delay-us = <100000>;
- regulator-max-microvolt = <3300000>;
- regulator-min-microvolt = <3300000>;
- regulator-name = "+V3.3_SD";
- startup-delay-us = <2000>;
- };
-
- reg_sdhc1_vqmmc: regulator-sdhci1-vqmmc {
- compatible = "regulator-gpio";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_vsel_sd>;
- /* PMIC_VSEL_SD */
- gpios = <&main_gpio0 21 GPIO_ACTIVE_HIGH>;
- regulator-name = "LDO1-VSEL-SD (PMIC)";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- states = <1800000 0x0>,
- <3300000 0x1>;
- vin-supply = <®_sd_3v3_1v8>;
- };
-
- reserved-memory {
- #address-cells = <2>;
- #size-cells = <2>;
- ranges;
-
- secure_tfa_ddr: tfa@9e780000 {
- reg = <0x00 0x9e780000 0x00 0x80000>;
- alignment = <0x1000>;
- no-map;
- };
-
- secure_ddr: optee@9e800000 {
- reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */
- alignment = <0x1000>;
- no-map;
- };
-
- wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory@9db00000 {
- compatible = "shared-dma-pool";
- reg = <0x00 0x9db00000 0x00 0xc00000>;
- no-map;
- };
- };
-};
-
-&main_pmx0 {
- /* Verdin PWM_1 */
- pinctrl_epwm0_a: main-epwm0a-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x01b4, PIN_OUTPUT, 2) /* (A13) SPI0_CS0.EHRPWM0_A */ /* SODIMM 15 */
- >;
- };
-
- /* Verdin PWM_2 */
- pinctrl_epwm0_b: main-epwm0b-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x01b8, PIN_OUTPUT, 2) /* (C13) SPI0_CS1.EHRPWM0_B */ /* SODIMM 16 */
- >;
- };
-
- /* Verdin PWM_3_DSI */
- pinctrl_epwm1_a: main-epwm1a-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x01bc, PIN_OUTPUT, 2) /* (A14) SPI0_CLK.EHRPWM1_A */ /* SODIMM 19 */
- >;
- };
-
- /* Verdin QSPI_1_CLK as GPIO (conflict with Verdin QSPI_1 interface) */
- pinctrl_qspi1_clk_gpio: main-gpio0-0-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0000, PIN_INPUT, 7) /* (H24) OSPI0_CLK.GPIO0_0 */ /* SODIMM 52 */
- >;
- };
-
- /* Verdin QSPI_1_IO0 as GPIO (conflict with Verdin QSPI_1 interface) */
- pinctrl_qspi1_io0_gpio: main-gpio0-3-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x000c, PIN_INPUT, 7) /* (E25) OSPI0_D0.GPIO0_3 */ /* SODIMM 56 */
- >;
- };
-
- /* Verdin QSPI_1_IO1 as GPIO (conflict with Verdin QSPI_1 interface) */
- pinctrl_qspi1_io1_gpio: main-gpio0-4-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0010, PIN_INPUT, 7) /* (G24) OSPI0_D1.GPIO0_4 */ /* SODIMM 58 */
- >;
- };
-
- /* Verdin QSPI_1_IO2 as GPIO (conflict with Verdin QSPI_1 interface) */
- pinctrl_qspi1_io2_gpio: main-gpio0-5-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0014, PIN_INPUT, 7) /* (F25) OSPI0_D2.GPIO0_5 */ /* SODIMM 60 */
- >;
- };
-
- /* Verdin QSPI_1_IO3 as GPIO (conflict with Verdin QSPI_1 interface) */
- pinctrl_qspi1_io3_gpio: main-gpio0-6-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0018, PIN_INPUT, 7) /* (F24) OSPI0_D3.GPIO0_6 */ /* SODIMM 62 */
- >;
- };
-
- /* Verdin QSPI_1_CS# as GPIO (conflict with Verdin QSPI_1 interface) */
- pinctrl_qspi1_cs_gpio: main-gpio0-11-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x002c, PIN_INPUT, 7) /* (F23) OSPI0_CSn0.GPIO0_11 */ /* SODIMM 54 */
- >;
- };
-
- /* Verdin QSPI_1_CS2# as GPIO (conflict with Verdin QSPI_1 interface) */
- pinctrl_qspi1_cs2_gpio: main-gpio0-12-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0030, PIN_INPUT, 7) /* (G21) OSPI0_CSn1.GPIO0_12 */ /* SODIMM 64 */
- >;
- };
-
- /* WiFi_W_WKUP_HOST# */
- pinctrl_wifi_w_wkup_host: main-gpio0-15-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x003c, PIN_INPUT, 7) /* (M25) GPMC0_AD0.GPIO0_15 */ /* SODIMM 174 */
- >;
- };
-
- /* WiFi_BT_WKUP_HOST# */
- pinctrl_bt_wkup_host: main-gpio0-16-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0040, PIN_INPUT, 7) /* (N23) GPMC0_AD1.GPIO0_16 */ /* SODIMM 172 */
- >;
- };
-
- /* PMIC_ETH_RESET# */
- pinctrl_eth_reset: main-gpio0-17-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0044, PIN_INPUT, 7) /* (N24) GPMC0_AD2.GPIO0_17 */
- >;
- };
-
- /* PMIC_BRIDGE_RESET# */
- pinctrl_bridge_reset: main-gpio0-20-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0050, PIN_INPUT, 7) /* (P22) GPMC0_AD5.GPIO0_20 */
- >;
- };
-
- /* PMIC_VSEL_SD */
- pinctrl_vsel_sd: main-gpio0-21-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0054, PIN_INPUT, 7) /* (P21) GPMC0_AD6.GPIO0_21 */
- >;
- };
-
- /* PMIC_EN_WIFI */
- pinctrl_wifi_en: main-gpio0-22-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0058, PIN_INPUT, 7) /* (R23) GPMC0_AD7.GPIO0_22 */
- >;
- };
-
- /* PMIC_ETH_INT# */
- pinctrl_eth_int: main-gpio0-25-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0064, PIN_INPUT_PULLUP, 7) /* (T25) GPMC0_AD10.GPIO0_25 */
- >;
- };
-
- /* WiFi_WKUP_BT# */
- pinctrl_wifi_wkup_bt: main-gpio0-26-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0068, PIN_INPUT, 7) /* (R21) GPMC0_AD11.GPIO0_26 */
- >;
- };
-
- /* WiFi_WKUP_WLAN# */
- pinctrl_wifi_wkup_wlan: main-gpio0-27-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x006c, PIN_INPUT, 7) /* (T22) GPMC0_AD12.GPIO0_27 */
- >;
- };
-
- /* Verdin SD_1_PWR_EN */
- pinctrl_sd1_pwr_en: main-gpio0-29-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0074, PIN_INPUT, 7) /* (U25) GPMC0_AD14.GPIO0_29 */ /* SODIMM 76 */
- >;
- };
-
- /* Verdin DSI_1_BKL_EN */
- pinctrl_dsi1_bkl_en: main-gpio0-30-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0078, PIN_INPUT, 7) /* (U24) GPMC0_AD15.GPIO0_30 */ /* SODIMM 21 */
- >;
- };
-
- /* Verdin CTRL_SLEEP_MOCI# */
- pinctrl_ctrl_sleep_moci: main-gpio0-31-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x007c, PIN_INPUT, 7) /* (P25) GPMC0_CLK.GPIO0_31 */ /* SODIMM 256 */
- >;
- };
-
- /* Verdin CTRL_WAKE1_MICO# */
- pinctrl_ctrl_wake1_mico: main-gpio0-32-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0084, PIN_INPUT_PULLUP, 7) /* (L23) GPMC0_ADVn_ALE.GPIO0_32 */ /* SODIMM 252 */
- >;
- };
-
- /* Verdin I2S_2_D_OUT as GPIO (conflict with Verdin I2S_2 interface) */
- pinctrl_i2s_2_d_out_gpio: main-gpio0-34-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x008c, PIN_INPUT, 7) /* (L25) GPMC0_WEn.GPIO0_34 */ /* SODIMM 46 */
- >;
- };
-
- /* Verdin I2S_2_BCLK as GPIO (conflict with Verdin I2S_2 interface) */
- pinctrl_i2s_2_bclk_gpio: main-gpio0-35-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0090, PIN_INPUT, 7) /* (M24) GPMC0_BE0n_CLE.GPIO0_35 */ /* SODIMM 42 */
- >;
- };
-
- /* Verdin GPIO_6 */
- pinctrl_gpio_6: main-gpio0-36-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0094, PIN_INPUT, 7) /* (N20) GPMC0_BE1n.GPIO0_36 */ /* SODIMM 218 */
- >;
- };
-
- /* Verdin ETH_2_RGMII_INT# */
- pinctrl_eth2_rgmii_int: main-gpio0-38-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x009c, PIN_INPUT, 7) /* (V25) GPMC0_WAIT1.GPIO0_38 */ /* SODIMM 189 */
- >;
- };
-
- /* Verdin GPIO_5 */
- pinctrl_gpio_5: main-gpio0-40-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x00a4, PIN_INPUT, 7) /* (M22) GPMC0_DIR.GPIO0_40 */ /* SODIMM 216 */
- >;
- };
-
- /* Verdin GPIO_7 */
- pinctrl_gpio_7: main-gpio0-41-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x00a8, PIN_INPUT, 7) /* (M21) GPMC0_CSn0.GPIO0_41 */ /* SODIMM 220 */
- >;
- };
-
- /* Verdin GPIO_8 */
- pinctrl_gpio_8: main-gpio0-42-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x00ac, PIN_INPUT, 7) /* (L21) GPMC0_CSn1.GPIO0_42 */ /* SODIMM 222 */
- >;
- };
-
- /* Verdin USB_1_OC# */
- pinctrl_usb1_oc: main-gpio0-71-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0124, PIN_INPUT, 7) /* (A23) MMC2_SDCD.GPIO0_71 */ /* SODIMM 157 */
- >;
- };
-
- /* Verdin USB_2_OC# */
- pinctrl_usb2_oc: main-gpio0-72-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0128, PIN_INPUT, 7) /* (B23) MMC2_SDWP.GPIO0_72 */ /* SODIMM 187 */
- >;
- };
-
- /* Verdin PWM_3_DSI as GPIO */
- pinctrl_pwm3_dsi_gpio: main-gpio1-17-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x01bc, PIN_INPUT, 7) /* (A14) SPI0_CLK.GPIO1_17 */ /* SODIMM 19 */
- >;
- };
-
- /* Verdin QSPI_1_DQS as GPIO */
- pinctrl_qspi1_dqs_gpio: main-gpio1-18-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x01c0, PIN_INPUT, 7) /* (B13) SPI0_D0.GPIO1_18 */ /* SODIMM 66 */
- >;
- };
-
- /* Verdin USB_1_ID */
- pinctrl_usb0_id: main-gpio1-19-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x01c4, PIN_INPUT, 7) /* (B14) SPI0_D1.GPIO1_19 */ /* SODIMM 161 */
- >;
- };
-
- /* Verdin DSI_1_INT# (pulled-up as active-low) */
- pinctrl_dsi1_int: main-gpio1-49-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0244, PIN_INPUT_PULLUP, 7) /* (C17) MMC1_SDWP.GPIO1_49 */ /* SODIMM 17 */
- >;
- };
-
- /* On-module I2C - PMIC_I2C */
- pinctrl_i2c0: main-i2c0-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x01e0, PIN_INPUT, 0) /* (B16) I2C0_SCL */ /* PMIC_I2C_SCL */
- AM62X_IOPAD(0x01e4, PIN_INPUT, 0) /* (A16) I2C0_SDA */ /* PMIC_I2C_SDA */
- >;
- };
-
- /* Verdin I2C_1 */
- pinctrl_i2c1: main-i2c1-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x01e8, PIN_INPUT_PULLUP, 0) /* (B17) I2C1_SCL */ /* SODIMM 14 */
- AM62X_IOPAD(0x01ec, PIN_INPUT_PULLUP, 0) /* (A17) I2C1_SDA */ /* SODIMM 12 */
- >;
- };
-
- /* Verdin I2C_2_DSI */
- pinctrl_i2c2: main-i2c2-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x00b0, PIN_INPUT, 1) /* (K22) GPMC0_CSn2.I2C2_SCL */ /* SODIMM 55 */
- AM62X_IOPAD(0x00b4, PIN_INPUT, 1) /* (K24) GPMC0_CSn3.I2C2_SDA */ /* SODIMM 53 */
- >;
- };
-
- /* Verdin I2C_4_CSI */
- pinctrl_i2c3: main-i2c3-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x01d0, PIN_INPUT, 2) /* (A15) UART0_CTSn.I2C3_SCL */ /* SODIMM 95 */
- AM62X_IOPAD(0x01d4, PIN_INPUT, 2) /* (B15) UART0_RTSn.I2C3_SDA */ /* SODIMM 93 */
- >;
- };
-
- /* I2S_1_MCLK */
- pinctrl_i2s1_mclk: main-system-audio-ext-reflock1-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x00a0, PIN_OUTPUT, 1) /* (K25) GPMC0_WPn.AUDIO_EXT_REFCLK1 */ /* SODIMM 38 */
- >;
- };
-
- /* Verdin I2S_1 */
- pinctrl_mcasp0: main-mcasp0-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x01a4, PIN_INPUT, 0) /* (B20) MCASP0_ACLKX */ /* SODIMM 30 */
- AM62X_IOPAD(0x01a8, PIN_INPUT, 0) /* (D20) MCASP0_AFSX */ /* SODIMM 32 */
- AM62X_IOPAD(0x01a0, PIN_OUTPUT, 0) /* (E18) MCASP0_AXR0 */ /* SODIMM 34 */
- AM62X_IOPAD(0x019c, PIN_INPUT, 0) /* (B18) MCASP0_AXR1 */ /* SODIMM 36 */
- >;
- };
-
- /* Verdin I2S_2 */
- pinctrl_mcasp1: main-mcasp1-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0090, PIN_INPUT, 2) /* (M24) GPMC0_BE0n_CLE.MCASP1_ACLKX */ /* SODIMM 42 */
- AM62X_IOPAD(0x0098, PIN_INPUT, 2) /* (U23) GPMC0_WAIT0.MCASP1_AFSX */ /* SODIMM 44 */
- AM62X_IOPAD(0x008c, PIN_OUTPUT, 2) /* (L25) GPMC0_WEn.MCASP1_AXR0 */ /* SODIMM 46 */
- AM62X_IOPAD(0x0088, PIN_INPUT, 2) /* (L24) GPMC0_OEn_REn.MCASP1_AXR1 */ /* SODIMM 48 */
- >;
- };
-
- /* Verdin CAN_1 */
- pinctrl_mcan0: main-mcan0-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x01dc, PIN_INPUT, 0) /* (E15) MCAN0_RX */ /* SODIMM 22 */
- AM62X_IOPAD(0x01d8, PIN_OUTPUT, 0) /* (C15) MCAN0_TX */ /* SODIMM 20 */
- >;
- };
-
- /* MDIO, shared by Verdin ETH_1 (On-module PHY) and Verdin ETH_2_RGMII */
- pinctrl_mdio: main-mdio1-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x160, PIN_OUTPUT, 0) /* (AD24) MDIO0_MDC */ /* ETH_1_MDC, SODIMM 193 */
- AM62X_IOPAD(0x15c, PIN_INPUT, 0) /* (AB22) MDIO0_MDIO */ /* ETH_1_MDIO, SODIMM 191 */
- >;
- };
-
- /* On-module eMMC */
- pinctrl_sdhci0: main-mmc0-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */
- AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLK */
- AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */
- AM62X_IOPAD(0x210, PIN_INPUT, 0) /* (AA1) MMC0_DAT1 */
- AM62X_IOPAD(0x20c, PIN_INPUT, 0) /* (AA3) MMC0_DAT2 */
- AM62X_IOPAD(0x208, PIN_INPUT, 0) /* (Y4) MMC0_DAT3 */
- AM62X_IOPAD(0x204, PIN_INPUT, 0) /* (AB2) MMC0_DAT4 */
- AM62X_IOPAD(0x200, PIN_INPUT, 0) /* (AC1) MMC0_DAT5 */
- AM62X_IOPAD(0x1fc, PIN_INPUT, 0) /* (AD2) MMC0_DAT6 */
- AM62X_IOPAD(0x1f8, PIN_INPUT, 0) /* (AC2) MMC0_DAT7 */
- >;
- };
-
- /* Verdin SD_1 */
- pinctrl_sdhci1: main-mmc1-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x23c, PIN_INPUT, 0) /* (A21) MMC1_CMD */ /* SODIMM 74 */
- AM62X_IOPAD(0x234, PIN_INPUT, 0) /* (B22) MMC1_CLK */ /* SODIMM 78 */
- AM62X_IOPAD(0x230, PIN_INPUT, 0) /* (A22) MMC1_DAT0 */ /* SODIMM 80 */
- AM62X_IOPAD(0x22c, PIN_INPUT, 0) /* (B21) MMC1_DAT1 */ /* SODIMM 82 */
- AM62X_IOPAD(0x228, PIN_INPUT, 0) /* (C21) MMC1_DAT2 */ /* SODIMM 70 */
- AM62X_IOPAD(0x224, PIN_INPUT, 0) /* (D22) MMC1_DAT3 */ /* SODIMM 72 */
- AM62X_IOPAD(0x240, PIN_INPUT_PULLUP, 0) /* (D17) MMC1_SDCD */ /* SODIMM 84 */
- >;
- };
-
- /* On-module Wi-Fi on WB SKUs, module-specific SDIO otherwise */
- pinctrl_sdhci2: main-mmc2-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x120, PIN_INPUT, 0) /* (C24) MMC2_CMD */ /* WiFi_SDIO_CMD */
- AM62X_IOPAD(0x118, PIN_INPUT, 0) /* (D25) MMC2_CLK */ /* WiFi_SDIO_CLK */
- AM62X_IOPAD(0x114, PIN_INPUT, 0) /* (B24) MMC2_DAT0 */ /* WiFi_SDIO_DATA0 */
- AM62X_IOPAD(0x110, PIN_INPUT, 0) /* (C25) MMC2_DAT1 */ /* WiFi_SDIO_DATA1 */
- AM62X_IOPAD(0x10c, PIN_INPUT, 0) /* (E23) MMC2_DAT2 */ /* WiFi_SDIO_DATA2 */
- AM62X_IOPAD(0x108, PIN_INPUT, 0) /* (D24) MMC2_DAT3 */ /* WiFi_SDIO_DATA3 */
- AM62X_IOPAD(0x11c, PIN_INPUT, 0) /* (#N/A) MMC2_CLKB */
- >;
- };
-
- /* Verdin QSPI_1 */
- pinctrl_ospi0: main-ospi0-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0000, PIN_OUTPUT, 0) /* (H24) OSPI0_CLK */ /* SODIMM 52 */
- AM62X_IOPAD(0x002c, PIN_OUTPUT, 0) /* (F23) OSPI0_CSn0 */ /* SODIMM 54 */
- AM62X_IOPAD(0x0030, PIN_OUTPUT, 0) /* (G21) OSPI0_CSn1 */ /* SODIMM 64 */
- AM62X_IOPAD(0x000c, PIN_INPUT, 0) /* (E25) OSPI0_D0 */ /* SODIMM 56 */
- AM62X_IOPAD(0x0010, PIN_INPUT, 0) /* (G24) OSPI0_D1 */ /* SODIMM 58 */
- AM62X_IOPAD(0x0014, PIN_INPUT, 0) /* (F25) OSPI0_D2 */ /* SODIMM 60 */
- AM62X_IOPAD(0x0018, PIN_INPUT, 0) /* (F24) OSPI0_D3 */ /* SODIMM 62 */
- >;
- };
-
- /* Verdin ETH_1 RGMII (On-module PHY) */
- pinctrl_rgmii1: main-rgmii1-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x14c, PIN_INPUT, 0) /* (AB17) RGMII1_RD0 */
- AM62X_IOPAD(0x150, PIN_INPUT, 0) /* (AC17) RGMII1_RD1 */
- AM62X_IOPAD(0x154, PIN_INPUT, 0) /* (AB16) RGMII1_RD2 */
- AM62X_IOPAD(0x158, PIN_INPUT, 0) /* (AA15) RGMII1_RD3 */
- AM62X_IOPAD(0x148, PIN_INPUT, 0) /* (AD17) RGMII1_RXC */
- AM62X_IOPAD(0x144, PIN_INPUT, 0) /* (AE17) RGMII1_RX_CTL */
- AM62X_IOPAD(0x134, PIN_OUTPUT, 0) /* (AE20) RGMII1_TD0 */
- AM62X_IOPAD(0x138, PIN_OUTPUT, 0) /* (AD20) RGMII1_TD1 */
- AM62X_IOPAD(0x13c, PIN_OUTPUT, 0) /* (AE18) RGMII1_TD2 */
- AM62X_IOPAD(0x140, PIN_OUTPUT, 0) /* (AD18) RGMII1_TD3 */
- AM62X_IOPAD(0x130, PIN_OUTPUT, 0) /* (AE19) RGMII1_TXC */
- AM62X_IOPAD(0x12c, PIN_OUTPUT, 0) /* (AD19) RGMII1_TX_CTL */
- >;
- };
-
- /* Verdin ETH_2 RGMII */
- pinctrl_rgmii2: main-rgmii2-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x184, PIN_INPUT, 0) /* (AE23) RGMII2_RD0 */ /* SODIMM 201 */
- AM62X_IOPAD(0x188, PIN_INPUT, 0) /* (AB20) RGMII2_RD1 */ /* SODIMM 203 */
- AM62X_IOPAD(0x18c, PIN_INPUT, 0) /* (AC21) RGMII2_RD2 */ /* SODIMM 205 */
- AM62X_IOPAD(0x190, PIN_INPUT, 0) /* (AE22) RGMII2_RD3 */ /* SODIMM 207 */
- AM62X_IOPAD(0x180, PIN_INPUT, 0) /* (AD23) RGMII2_RXC */ /* SODIMM 197 */
- AM62X_IOPAD(0x17c, PIN_INPUT, 0) /* (AD22) RGMII2_RX_CTL */ /* SODIMM 199 */
- AM62X_IOPAD(0x16c, PIN_OUTPUT, 0) /* (Y18) RGMII2_TD0 */ /* SODIMM 221 */
- AM62X_IOPAD(0x170, PIN_OUTPUT, 0) /* (AA18) RGMII2_TD1 */ /* SODIMM 219 */
- AM62X_IOPAD(0x174, PIN_OUTPUT, 0) /* (AD21) RGMII2_TD2 */ /* SODIMM 217 */
- AM62X_IOPAD(0x178, PIN_OUTPUT, 0) /* (AC20) RGMII2_TD3 */ /* SODIMM 215 */
- AM62X_IOPAD(0x168, PIN_OUTPUT, 0) /* (AE21) RGMII2_TXC */ /* SODIMM 213 */
- AM62X_IOPAD(0x164, PIN_OUTPUT, 0) /* (AA19) RGMII2_TX_CTL */ /* SODIMM 211 */
- >;
- };
-
- /* Verdin SPI_1 */
- pinctrl_spi1: main-spi1-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0020, PIN_INPUT, 1) /* (J25) OSPI0_D5.SPI1_CLK */ /* SODIMM 196 */
- AM62X_IOPAD(0x001c, PIN_INPUT, 1) /* (J23) OSPI0_D4.SPI1_CS0 */ /* SODIMM 202 */
- AM62X_IOPAD(0x0024, PIN_INPUT, 1) /* (H25) OSPI0_D6.SPI1_D0 */ /* SODIMM 200 */
- AM62X_IOPAD(0x0028, PIN_INPUT, 1) /* (J22) OSPI0_D7.SPI1_D1 */ /* SODIMM 198 */
- >;
- };
-
- /* ETH_25MHz_CLK */
- pinctrl_eth_clock: main-system-clkout0-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x01f0, PIN_OUTPUT_PULLUP, 5) /* (A18) EXT_REFCLK1.CLKOUT0 */
- >;
- };
-
- /* PMIC_EXTINT# */
- pinctrl_pmic_extint: main-system-extint-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x01f4, PIN_INPUT, 0) /* (D16) EXTINTn */
- >;
- };
-
- /* Verdin UART_3, used as the Linux console */
- pinctrl_uart0: main-uart0-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x1c8, PIN_INPUT_PULLUP, 0) /* (D14) UART0_RXD */ /* SODIMM 147 */
- AM62X_IOPAD(0x1cc, PIN_OUTPUT, 0) /* (E14) UART0_TXD */ /* SODIMM 149 */
- >;
- };
-
- /* Verdin UART_1 */
- pinctrl_uart1: main-uart1-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0194, PIN_INPUT_PULLUP, 2) /* (B19) MCASP0_AXR3.UART1_CTSn */ /* SODIMM 135 */
- AM62X_IOPAD(0x0198, PIN_OUTPUT, 2) /* (A19) MCASP0_AXR2.UART1_RTSn */ /* SODIMM 133 */
- AM62X_IOPAD(0x01ac, PIN_INPUT_PULLUP, 2) /* (E19) MCASP0_AFSR.UART1_RXD */ /* SODIMM 129 */
- AM62X_IOPAD(0x01b0, PIN_OUTPUT, 2) /* (A20) MCASP0_ACLKR.UART1_TXD */ /* SODIMM 131 */
- >;
- };
-
- /* Bluetooth on WB SKUs, module-specific UART otherwise */
- pinctrl_uart5: main-uart5-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0008, PIN_INPUT_PULLUP, 5) /* (J24) OSPI0_DQS.UART5_CTSn */ /* WiFi_UART_CTS */
- AM62X_IOPAD(0x0004, PIN_OUTPUT, 5) /* (G25) OSPI0_LBCLKO.UART5_RTSn */ /* WiFi_UART_RTS */
- AM62X_IOPAD(0x0034, PIN_INPUT_PULLUP, 5) /* (H21) OSPI0_CSn2.UART5_RXD */ /* WiFi_UART_RXD */
- AM62X_IOPAD(0x0038, PIN_OUTPUT, 5) /* (E24) OSPI0_CSn3.UART5_TXD */ /* WiFi_UART_TXD */
- >;
- };
-
- /* Verdin USB_1 */
- pinctrl_usb0: main-usb0-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0254, PIN_OUTPUT, 0) /* (C20) USB0_DRVVBUS */ /* SODIMM 155 */
- >;
- };
-
- /* Verdin USB_2 */
- pinctrl_usb1: main-usb1-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0258, PIN_OUTPUT, 0) /* (F18) USB1_DRVVBUS */ /* SODIMM 185 */
- >;
- };
-
- /* DSS VOUT0 RGB */
- pinctrl_parallel_rgb: main-vout-default-pins {
- pinctrl-single,pins = <
- AM62X_IOPAD(0x0100, PIN_OUTPUT, 0) /* (AC25) VOUT0_VSYNC */
- AM62X_IOPAD(0x00f8, PIN_OUTPUT, 0) /* (AB24) VOUT0_HSYNC */
- AM62X_IOPAD(0x0104, PIN_OUTPUT, 0) /* (AC24) VOUT0_PCLK */
- AM62X_IOPAD(0x00fc, PIN_OUTPUT, 0) /* (Y20) VOUT0_DE */
- AM62X_IOPAD(0x00b8, PIN_OUTPUT, 0) /* (U22) VOUT0_DATA0 */
- AM62X_IOPAD(0x00bc, PIN_OUTPUT, 0) /* (V24) VOUT0_DATA1 */
- AM62X_IOPAD(0x00c0, PIN_OUTPUT, 0) /* (W25) VOUT0_DATA2 */
- AM62X_IOPAD(0x00c4, PIN_OUTPUT, 0) /* (W24) VOUT0_DATA3 */
- AM62X_IOPAD(0x00c8, PIN_OUTPUT, 0) /* (Y25) VOUT0_DATA4 */
- AM62X_IOPAD(0x00cc, PIN_OUTPUT, 0) /* (Y24) VOUT0_DATA5 */
- AM62X_IOPAD(0x00d0, PIN_OUTPUT, 0) /* (Y23) VOUT0_DATA6 */
- AM62X_IOPAD(0x00d4, PIN_OUTPUT, 0) /* (AA25) VOUT0_DATA7 */
- AM62X_IOPAD(0x00d8, PIN_OUTPUT, 0) /* (V21) VOUT0_DATA8 */
- AM62X_IOPAD(0x00dc, PIN_OUTPUT, 0) /* (W21) VOUT0_DATA9 */
- AM62X_IOPAD(0x00e0, PIN_OUTPUT, 0) /* (V20) VOUT0_DATA10 */
- AM62X_IOPAD(0x00e4, PIN_OUTPUT, 0) /* (AA23) VOUT0_DATA11 */
- AM62X_IOPAD(0x00e8, PIN_OUTPUT, 0) /* (AB25) VOUT0_DATA12 */
- AM62X_IOPAD(0x00ec, PIN_OUTPUT, 0) /* (AA24) VOUT0_DATA13 */
- AM62X_IOPAD(0x00f0, PIN_OUTPUT, 0) /* (Y22) VOUT0_DATA14 */
- AM62X_IOPAD(0x00f4, PIN_OUTPUT, 0) /* (AA21) VOUT0_DATA15 */
- AM62X_IOPAD(0x005c, PIN_OUTPUT, 1) /* (R24) GPMC0_AD8.VOUT0_DATA16 */
- AM62X_IOPAD(0x0060, PIN_OUTPUT, 1) /* (R25) GPMC0_AD9.VOUT0_DATA17 */
- >;
- };
-};
-
-&mcu_pmx0 {
- /* Verdin PCIE_1_RESET# */
- pinctrl_pcie_1_reset: mcu-gpio0-0-default-pins {
- pinctrl-single,pins = <
- AM62X_MCU_IOPAD(0x0000, PIN_INPUT, 7) /* (E8) MCU_SPI0_CS0.MCU_GPIO0_0 */ /* SODIMM 244 */
- >;
- };
-
- /* Verdin GPIO_1 */
- pinctrl_gpio_1: mcu-gpio0-1-default-pins {
- pinctrl-single,pins = <
- AM62X_MCU_IOPAD(0x0004, PIN_INPUT, 7) /* (B8) MCU_SPI0_CS1.MCU_GPIO0_1 */ /* SODIMM 206 */
- >;
- };
-
- /* Verdin GPIO_2 */
- pinctrl_gpio_2: mcu-gpio0-2-default-pins {
- pinctrl-single,pins = <
- AM62X_MCU_IOPAD(0x0008, PIN_INPUT, 7) /* (A7) MCU_SPI0_CLK.MCU_GPIO0_2 */ /* SODIMM 208 */
- >;
- };
-
- /* Verdin GPIO_3 */
- pinctrl_gpio_3: mcu-gpio0-3-default-pins {
- pinctrl-single,pins = <
- AM62X_MCU_IOPAD(0x000c, PIN_INPUT, 7) /* (D9) MCU_SPI0_D0.MCU_GPIO0_3 */ /* SODIMM 210 */
- >;
- };
-
- /* Verdin GPIO_4 */
- pinctrl_gpio_4: mcu-gpio0-4-default-pins {
- pinctrl-single,pins = <
- AM62X_MCU_IOPAD(0x0010, PIN_INPUT, 7) /* (C9) MCU_SPI0_D1.MCU_GPIO0_4 */ /* SODIMM 212 */
- >;
- };
-
- /* Verdin I2C_3_HDMI */
- pinctrl_mcu_i2c0: mcu-i2c0-default-pins {
- pinctrl-single,pins = <
- AM62X_MCU_IOPAD(0x0044, PIN_INPUT, 0) /* (A8) MCU_I2C0_SCL */ /* SODIMM 59 */
- AM62X_MCU_IOPAD(0x0048, PIN_INPUT, 0) /* (D10) MCU_I2C0_SDA */ /* SODIMM 57 */
- >;
- };
-
- /* Verdin CAN_2 */
- pinctrl_mcu_mcan0: mcu-mcan0-default-pins {
- pinctrl-single,pins = <
- AM62X_MCU_IOPAD(0x0038, PIN_INPUT, 0) /* (B3) MCU_MCAN0_RX */ /* SODIMM 26 */
- AM62X_MCU_IOPAD(0x0034, PIN_OUTPUT, 0) /* (D6) MCU_MCAN0_TX */ /* SODIMM 24 */
- >;
- };
-
- /* Verdin UART_4 - Reserved to Cortex-M4 */
- pinctrl_mcu_uart0: mcu-uart0-default-pins {
- pinctrl-single,pins = <
- AM62X_MCU_IOPAD(0x0014, PIN_INPUT_PULLUP, 0) /* (B5) MCU_UART0_RXD */ /* SODIMM 151 */
- AM62X_MCU_IOPAD(0x0018, PIN_OUTPUT, 0) /* (A5) MCU_UART0_TXD */ /* SODIMM 153 */
- >;
- };
-
- /* Verdin CSI_1_MCLK */
- pinctrl_csi1_mclk: wkup-clkout0-default-pins {
- pinctrl-single,pins = <
- AM62X_MCU_IOPAD(0x0084, PIN_OUTPUT, 0) /* (A12) WKUP_CLKOUT0 */ /* SODIMM 91 */
- >;
- };
-
- /* Verdin UART_2 */
- pinctrl_wkup_uart0: wkup-uart0-default-pins {
- pinctrl-single,pins = <
- AM62X_MCU_IOPAD(0x002c, PIN_INPUT_PULLUP, 0) /* (C6) WKUP_UART0_CTSn */ /* SODIMM 143 */
- AM62X_MCU_IOPAD(0x0030, PIN_OUTPUT, 0) /* (A4) WKUP_UART0_RTSn */ /* SODIMM 141 */
- AM62X_MCU_IOPAD(0x0024, PIN_INPUT_PULLUP, 0) /* (B4) WKUP_UART0_RXD */ /* SODIMM 137 */
- AM62X_MCU_IOPAD(0x0028, PIN_OUTPUT, 0) /* (C5) WKUP_UART0_TXD */ /* SODIMM 139 */
- >;
- };
-};
-
-/* VERDIN I2S_1_MCLK */
-&audio_refclk1 {
- assigned-clock-rates = <25000000>;
-};
-
-&cpsw3g {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_rgmii1>;
- status = "disabled";
-};
-
-/* Verdin ETH_1 (On-module PHY) */
-&cpsw_port1 {
- phy-handle = <&cpsw3g_phy0>;
- phy-mode = "rgmii-rxid";
- status = "disabled";
-};
-
-/* Verdin ETH_2_RGMII */
-&cpsw_port2 {
- status = "disabled";
-};
-
-/* MDIO, shared by Verdin ETH_1 (On-module PHY) and Verdin ETH_2_RGMII */
-&cpsw3g_mdio {
- assigned-clocks = <&k3_clks 157 20>;
- assigned-clock-parents = <&k3_clks 157 22>;
- assigned-clock-rates = <25000000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_eth_clock>, <&pinctrl_mdio>;
- status = "disabled";
-
- cpsw3g_phy0: ethernet-phy@0 {
- compatible = "ethernet-phy-id2000.a231";
- reg = <0>;
- interrupt-parent = <&main_gpio0>;
- interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_eth_int>, <&pinctrl_eth_reset>;
- reset-gpios = <&main_gpio0 17 GPIO_ACTIVE_LOW>;
- reset-assert-us = <10>;
- reset-deassert-us = <1000>;
- ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
- ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
- };
-};
-
-&dss {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_parallel_rgb>;
- status = "disabled";
-};
-
-&dss_ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* VP2: DPI Output */
- port@1 {
- reg = <1>;
-
- dpi_out: endpoint {
- remote-endpoint = <&rgb_in>;
- };
- };
-};
-
-/* Verdin PWM_1, PWM_2 */
-&epwm0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_epwm0_a>, <&pinctrl_epwm0_b>;
- status = "disabled";
-};
-
-/* Verdin PWM_3_DSI */
-&epwm1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_epwm1_a>;
- status = "disabled";
-};
-
-&main_gpio0 {
- gpio-line-names =
- "SODIMM_52", /* 0 */
- "",
- "",
- "SODIMM_56",
- "SODIMM_58",
- "SODIMM_60",
- "SODIMM_62",
- "",
- "",
- "",
- "", /* 10 */
- "SODIMM_54",
- "SODIMM_64",
- "",
- "",
- "SODIMM_174",
- "SODIMM_172",
- "",
- "",
- "",
- "", /* 20 */
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "SODIMM_76",
- "SODIMM_21", /* 30 */
- "SODIMM_256",
- "SODIMM_252",
- "",
- "SODIMM_46",
- "SODIMM_42",
- "SODIMM_218",
- "",
- "SODIMM_189",
- "",
- "SODIMM_216", /* 40 */
- "SODIMM_220",
- "SODIMM_222",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "", /* 50 */
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "", /* 60 */
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "", /* 70 */
- "SODIMM_157",
- "SODIMM_187",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "", /* 80 */
- "",
- "",
- "",
- "",
- "",
- "";
-
- verdin_ctrl_sleep_moci: ctrl-sleep-moci-hog {
- gpio-hog;
- /* Verdin CTRL_SLEEP_MOCI# (SODIMM 256) */
- gpios = <31 GPIO_ACTIVE_HIGH>;
- line-name = "CTRL_SLEEP_MOCI#";
- output-high;
- };
-};
-
-&main_gpio1 {
- gpio-line-names =
- "", /* 0 */
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "", /* 10 */
- "",
- "",
- "",
- "",
- "SODIMM_15",
- "SODIMM_16",
- "SODIMM_19",
- "SODIMM_66",
- "SODIMM_161",
- "", /* 20 */
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "", /* 30 */
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "", /* 40 */
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "SODIMM_17",
- "", /* 50 */
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "", /* 60 */
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "", /* 70 */
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "", /* 80 */
- "",
- "",
- "",
- "",
- "",
- "",
- "";
-};
-
-/* On-module I2C - PMIC_I2C */
-&main_i2c0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c0>;
- clock-frequency = <400000>;
- status = "okay";
-
- dsi_bridge: dsi@e {
- compatible = "toshiba,tc358778";
- reg = <0xe>;
- assigned-clocks = <&k3_clks 157 20>;
- assigned-clock-parents = <&k3_clks 157 22>;
- assigned-clock-rates = <25000000>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_bridge_reset>;
- clocks = <&k3_clks 157 20>;
- clock-names = "refclk";
- reset-gpios = <&main_gpio0 20 GPIO_ACTIVE_LOW>;
- vddc-supply = <®_1v2_dsi>;
- vddmipi-supply = <®_1v2_dsi>;
- vddio-supply = <®_1v8_dsi>;
- status = "disabled";
-
- dsi_bridge_ports: ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@0 {
- reg = <0>;
-
- rgb_in: endpoint {
- data-lines = <18>;
- remote-endpoint = <&dpi_out>;
- };
- };
-
- port@1 {
- reg = <1>;
- };
- };
- };
-
- pmic@30 {
- compatible = "ti,tps65219";
- reg = <0x30>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_pmic_extint>;
- interrupt-parent = <&gic500>;
- interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
-
- buck1-supply = <®_vsodimm>;
- buck2-supply = <®_vsodimm>;
- buck3-supply = <®_vsodimm>;
- ldo1-supply = <®_3v3>;
- ldo2-supply = <®_1v8>;
- ldo3-supply = <®_3v3>;
- ldo4-supply = <®_3v3>;
- system-power-controller;
- ti,power-button;
-
- regulators {
- reg_vdd_core: buck1 {
- regulator-always-on;
- regulator-boot-on;
- regulator-max-microvolt = <850000>;
- regulator-min-microvolt = <850000>;
- regulator-name = "+VDD_CORE (PMIC BUCK1)";
- };
-
- reg_1v8: buck2 {
- regulator-always-on;
- regulator-boot-on;
- regulator-max-microvolt = <1800000>;
- regulator-min-microvolt = <1800000>;
- regulator-name = "+V1.8 (PMIC BUCK2)"; /* On-module and SODIMM 214 */
- };
-
- reg_vdd_ddr: buck3 {
- regulator-always-on;
- regulator-boot-on;
- regulator-max-microvolt = <1100000>;
- regulator-min-microvolt = <1100000>;
- regulator-name = "+VDD_DDR (PMIC BUCK3)";
- };
-
- reg_sd_3v3_1v8: ldo1 {
- regulator-allow-bypass;
- regulator-always-on;
- regulator-boot-on;
- regulator-max-microvolt = <3300000>;
- regulator-min-microvolt = <3300000>;
- regulator-name = "+V3.3_1.8_SD (PMIC LDO1)";
- };
-
- reg_vddr_core: ldo2 {
- regulator-always-on;
- regulator-boot-on;
- regulator-max-microvolt = <850000>;
- regulator-min-microvolt = <850000>;
- regulator-name = "+VDDR_CORE (PMIC LDO2)";
- };
-
- reg_1v8a: ldo3 {
- regulator-always-on;
- regulator-boot-on;
- regulator-max-microvolt = <1800000>;
- regulator-min-microvolt = <1800000>;
- regulator-name = "+V1.8A (PMIC LDO3)";
- };
-
- reg_eth_2v5: ldo4 {
- regulator-always-on;
- regulator-boot-on;
- regulator-max-microvolt = <2500000>;
- regulator-min-microvolt = <2500000>;
- regulator-name = "+V2.5_ETH (PMIC LDO4)";
- };
- };
- };
-
- rtc_i2c: rtc@32 {
- compatible = "epson,rx8130";
- reg = <0x32>;
- };
-
- sensor@48 {
- compatible = "ti,tmp1075";
- reg = <0x48>;
- };
-
- adc@49 {
- compatible = "ti,ads1015";
- reg = <0x49>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- /* Verdin PMIC_I2C (ADC_4 - ADC_3) */
- channel@0 {
- reg = <0>;
- ti,datarate = <4>;
- ti,gain = <2>;
- };
-
- /* Verdin PMIC_I2C (ADC_4 - ADC_1) */
- channel@1 {
- reg = <1>;
- ti,datarate = <4>;
- ti,gain = <2>;
- };
-
- /* Verdin PMIC_I2C (ADC_3 - ADC_1) */
- channel@2 {
- reg = <2>;
- ti,datarate = <4>;
- ti,gain = <2>;
- };
-
- /* Verdin PMIC_I2C (ADC_2 - ADC_1) */
- channel@3 {
- reg = <3>;
- ti,datarate = <4>;
- ti,gain = <2>;
- };
-
- /* Verdin PMIC_I2C ADC_4 */
- channel@4 {
- reg = <4>;
- ti,datarate = <4>;
- ti,gain = <2>;
- };
-
- /* Verdin PMIC_I2C ADC_3 */
- channel@5 {
- reg = <5>;
- ti,datarate = <4>;
- ti,gain = <2>;
- };
-
- /* Verdin PMIC_I2C ADC_2 */
- channel@6 {
- reg = <6>;
- ti,datarate = <4>;
- ti,gain = <2>;
- };
-
- /* Verdin PMIC_I2C ADC_1 */
- channel@7 {
- reg = <7>;
- ti,datarate = <4>;
- ti,gain = <2>;
- };
- };
-
- eeprom@50 {
- compatible = "st,24c02", "atmel,24c02";
- pagesize = <16>;
- reg = <0x50>;
- };
-};
-
-/* Verdin I2C_1 */
-&main_i2c1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c1>;
- status = "disabled";
-};
-
-/* Verdin I2C_2_DSI */
-&main_i2c2 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c2>;
- status = "disabled";
-};
-
-/* Verdin I2C_4_CSI */
-&main_i2c3 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_i2c3>;
- status = "disabled";
-};
-
-&mailbox0_cluster0 {
- mbox_m4_0: mbox-m4-0 {
- ti,mbox-rx = <0 0 0>;
- ti,mbox-tx = <1 0 0>;
- };
-};
-
-/* Verdin CAN_1 */
-&main_mcan0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mcan0>;
- status = "disabled";
-};
-
-/* Verdin SPI_1 */
-&main_spi1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_spi1>;
- ti,pindir-d0-out-d1-in;
- status = "disabled";
-};
-
-/* Verdin UART_3, used as the Linux console */
-&main_uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart0>;
- status = "disabled";
-};
-
-/* Verdin UART_1 */
-&main_uart1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_uart1>;
- status = "disabled";
-};
-
-/* Verdin I2S_1 */
-&mcasp0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mcasp0>;
- op-mode = <0>; /* I2S mode */
- serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
- 1 2 0 0
- 0 0 0 0
- 0 0 0 0
- 0 0 0 0
- >;
- tdm-slots = <2>;
- rx-num-evt = <32>;
- tx-num-evt = <32>;
- #sound-dai-cells = <0>;
- status = "disabled";
-};
-
-/* Verdin I2S_2 */
-&mcasp1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mcasp1>;
- op-mode = <0>; /* I2S mode */
- serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
- 1 2 0 0
- 0 0 0 0
- 0 0 0 0
- 0 0 0 0
- >;
- tdm-slots = <2>;
- rx-num-evt = <32>;
- tx-num-evt = <32>;
- #sound-dai-cells = <0>;
- status = "disabled";
-};
-
-/* Verdin I2C_3_HDMI */
-&mcu_i2c0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mcu_i2c0>;
- status = "disabled";
-};
-
-&mcu_gpio0 {
- gpio-line-names =
- "SODIMM_244",
- "SODIMM_206",
- "SODIMM_208",
- "SODIMM_210",
- "SODIMM_212",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "",
- "";
-};
-
-/* Verdin CAN_2 */
-&mcu_mcan0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mcu_mcan0>;
- status = "disabled";
-};
-
-/* Verdin UART_4 - Cortex-M4 UART */
-&mcu_uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_mcu_uart0>;
- status = "disabled";
-};
-
-/* Verdin QSPI_1 */
-&ospi0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_ospi0>;
- status = "disabled";
-};
-
-/* On-module eMMC */
-&sdhci0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_sdhci0>;
- non-removable;
- ti,driver-strength-ohm = <50>;
- status = "okay";
-};
-
-/* Verdin SD_1 */
-&sdhci1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_sdhci1>;
- disable-wp;
- ti,driver-strength-ohm = <50>;
- vmmc-supply = <®_sdhc1_vmmc>;
- vqmmc-supply = <®_sdhc1_vqmmc>;
- status = "disabled";
-};
-
-/* Verdin USB_1 */
-&usbss0 {
- ti,vbus-divider;
- status = "disabled";
-};
-
-/* TODO: role swich using ID pin */
-&usb0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb0>, <&pinctrl_usb0_id>;
- status = "disabled";
-};
-
-/* Verdin USB_2 */
-&usbss1 {
- ti,vbus-divider;
- status = "disabled";
-};
-
-&usb1 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usb1>;
- dr_mode = "host";
- status = "disabled";
-};
-
-/* Verdin UART_2 */
-&wkup_uart0 {
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_wkup_uart0>;
- status = "disabled";
-};
diff --git a/arch/arm/dts/k3-am625-beagleplay-u-boot.dtsi b/arch/arm/dts/k3-am625-beagleplay-u-boot.dtsi
index cca0f44..fb20320 100644
--- a/arch/arm/dts/k3-am625-beagleplay-u-boot.dtsi
+++ b/arch/arm/dts/k3-am625-beagleplay-u-boot.dtsi
@@ -41,13 +41,6 @@
clock-frequency = <25000000>;
};
-&dmsc {
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
-};
-
&sd_pins_default {
/* Force to use SDCD card detect pin */
pinctrl-single,pins = <
diff --git a/arch/arm/dts/k3-am625-phyboard-lyra-rdk-u-boot.dtsi b/arch/arm/dts/k3-am625-phyboard-lyra-rdk-u-boot.dtsi
index f6138f3..9416228 100644
--- a/arch/arm/dts/k3-am625-phyboard-lyra-rdk-u-boot.dtsi
+++ b/arch/arm/dts/k3-am625-phyboard-lyra-rdk-u-boot.dtsi
@@ -42,13 +42,6 @@
bootph-all;
};
-&dmsc {
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
-};
-
&fss {
bootph-all;
};
diff --git a/arch/arm/dts/k3-am625-sk-binman.dtsi b/arch/arm/dts/k3-am625-sk-binman.dtsi
index 5b058bd..dfd38d6 100644
--- a/arch/arm/dts/k3-am625-sk-binman.dtsi
+++ b/arch/arm/dts/k3-am625-sk-binman.dtsi
@@ -151,11 +151,107 @@
filename = "ti-dm/am62xx/ipc_echo_testb_mcu1_0_release_strip.xer5f";
};
};
+
+ tifsstub-hs {
+ filename = "tifsstub.bin_hs";
+ ti-secure-rom {
+ content = <&tifsstub_hs_cert>;
+ core = "secure";
+ load = <0x40000>;
+ sw-rev = <CONFIG_K3_X509_SWRV>;
+ keyfile = "custMpk.pem";
+ countersign;
+ tifsstub;
+ };
+ tifsstub_hs_cert: tifsstub-hs-cert.bin {
+ filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-cert.bin";
+ type = "blob-ext";
+ optional;
+ };
+ tifsstub_hs_enc: tifsstub-hs-enc.bin {
+ filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-enc.bin";
+ type = "blob-ext";
+ optional;
+ };
+ };
+
+ tifsstub-fs {
+ filename = "tifsstub.bin_fs";
+ tifsstub_fs_cert: tifsstub-fs-cert.bin {
+ filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-cert.bin";
+ type = "blob-ext";
+ optional;
+ };
+ tifsstub_fs_enc: tifsstub-fs-enc.bin {
+ filename = "ti-sysfw/ti-fs-stub-firmware-am62x-hs-enc.bin";
+ type = "blob-ext";
+ optional;
+ };
+
+ };
+
+ tifsstub-gp {
+ filename = "tifsstub.bin_gp";
+ ti-secure-rom {
+ content = <&tifsstub_gp>;
+ core = "secure";
+ load = <0x60000>;
+ sw-rev = <CONFIG_K3_X509_SWRV>;
+ keyfile = "ti-degenerate-key.pem";
+ tifsstub;
+ };
+ tifsstub_gp: tifsstub-gp.bin {
+ filename = "ti-sysfw/ti-fs-stub-firmware-am62x-gp.bin";
+ type = "blob-ext";
+ optional;
+ };
+ };
+
ti-spl {
insert-template = <&ti_spl_template>;
fit {
images {
+
+ tifsstub-hs {
+ description = "TIFSSTUB";
+ type = "firmware";
+ arch = "arm32";
+ compression = "none";
+ os = "tifsstub-hs";
+ load = <0x9dc00000>;
+ entry = <0x9dc00000>;
+ blob-ext {
+ filename = "tifsstub.bin_hs";
+ };
+ };
+
+ tifsstub-fs {
+ description = "TIFSSTUB";
+ type = "firmware";
+ arch = "arm32";
+ compression = "none";
+ os = "tifsstub-fs";
+ load = <0x9dc00000>;
+ entry = <0x9dc00000>;
+ blob-ext {
+ filename = "tifsstub.bin_fs";
+ };
+ };
+
+ tifsstub-gp {
+ description = "TIFSSTUB";
+ type = "firmware";
+ arch = "arm32";
+ compression = "none";
+ os = "tifsstub-gp";
+ load = <0x9dc00000>;
+ entry = <0x9dc00000>;
+ blob-ext {
+ filename = "tifsstub.bin_gp";
+ };
+ };
+
dm {
ti-secure {
content = <&dm>;
@@ -189,7 +285,8 @@
conf-0 {
description = "k3-am625-sk";
firmware = "atf";
- loadables = "tee", "dm", "spl";
+ loadables = "tee", "tifsstub-hs", "tifsstub-fs",
+ "tifsstub-gp", "dm", "spl";
fdt = "fdt-0";
};
};
@@ -247,6 +344,45 @@
fit {
images {
+ tifsstub-hs {
+ description = "tifsstub";
+ type = "firmware";
+ arch = "arm32";
+ compression = "none";
+ os = "tifsstub-hs";
+ load = <0x9dc00000>;
+ entry = <0x9dc00000>;
+ blob-ext {
+ filename = "tifsstub.bin_hs";
+ };
+ };
+
+ tifsstub-fs {
+ description = "tifsstub";
+ type = "firmware";
+ arch = "arm32";
+ compression = "none";
+ os = "tifsstub-fs";
+ load = <0x9dc00000>;
+ entry = <0x9dc00000>;
+ blob-ext {
+ filename = "tifsstub.bin_fs";
+ };
+ };
+
+ tifsstub-gp {
+ description = "tifsstub";
+ type = "firmware";
+ arch = "arm32";
+ compression = "none";
+ os = "tifsstub-gp";
+ load = <0x9dc00000>;
+ entry = <0x9dc00000>;
+ blob-ext {
+ filename = "tifsstub.bin_gp";
+ };
+ };
+
dm {
ti-dm {
filename = "ti-dm.bin";
@@ -270,7 +406,8 @@
conf-0 {
description = "k3-am625-sk";
firmware = "atf";
- loadables = "tee", "dm", "spl";
+ loadables = "tee", "tifsstub-hs", "tifsstub-fs",
+ "tifsstub-gp", "dm", "spl";
fdt = "fdt-0";
};
};
diff --git a/arch/arm/dts/k3-am625-verdin-wifi-dev-binman.dtsi b/arch/arm/dts/k3-am625-verdin-wifi-dev-binman.dtsi
index 4e37048..6f58450 100644
--- a/arch/arm/dts/k3-am625-verdin-wifi-dev-binman.dtsi
+++ b/arch/arm/dts/k3-am625-verdin-wifi-dev-binman.dtsi
@@ -140,7 +140,7 @@
#ifdef CONFIG_TARGET_VERDIN_AM62_A53
-#define SPL_VERDIN_AM62_DTB "spl/dts/k3-am625-verdin-wifi-dev.dtb"
+#define SPL_VERDIN_AM62_DTB "spl/dts/ti/k3-am625-verdin-wifi-dev.dtb"
#define VERDIN_AM62_DTB "u-boot.dtb"
&binman {
diff --git a/arch/arm/dts/k3-am625-verdin-wifi-dev-u-boot.dtsi b/arch/arm/dts/k3-am625-verdin-wifi-dev-u-boot.dtsi
index 28b697b..7fe7ae4 100644
--- a/arch/arm/dts/k3-am625-verdin-wifi-dev-u-boot.dtsi
+++ b/arch/arm/dts/k3-am625-verdin-wifi-dev-u-boot.dtsi
@@ -85,13 +85,6 @@
bootph-all;
};
-&dmsc {
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
-};
-
&fss {
bootph-all;
};
diff --git a/arch/arm/dts/k3-am625-verdin-wifi-dev.dts b/arch/arm/dts/k3-am625-verdin-wifi-dev.dts
deleted file mode 100644
index 4b657d6..0000000
--- a/arch/arm/dts/k3-am625-verdin-wifi-dev.dts
+++ /dev/null
@@ -1,22 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
-/*
- * Copyright 2023 Toradex
- *
- * https://www.toradex.com/computer-on-modules/verdin-arm-family/ti-am62
- * https://www.toradex.com/products/carrier-board/verdin-development-board-kit
- */
-
-/dts-v1/;
-
-#include "k3-am625.dtsi"
-#include "k3-am62-verdin.dtsi"
-#include "k3-am62-verdin-wifi.dtsi"
-#include "k3-am62-verdin-dev.dtsi"
-
-/ {
- model = "Toradex Verdin AM62 WB on Verdin Development Board";
- compatible = "toradex,verdin-am62-wifi-dev",
- "toradex,verdin-am62-wifi",
- "toradex,verdin-am62",
- "ti,am625";
-};
diff --git a/arch/arm/dts/k3-am62a7-sk-u-boot.dtsi b/arch/arm/dts/k3-am62a7-sk-u-boot.dtsi
index 31b89b4..c42dec1 100644
--- a/arch/arm/dts/k3-am62a7-sk-u-boot.dtsi
+++ b/arch/arm/dts/k3-am62a7-sk-u-boot.dtsi
@@ -119,10 +119,6 @@
&dmsc {
bootph-all;
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
};
&vdd_mmc1 {
diff --git a/arch/arm/dts/k3-am62p5-sk-u-boot.dtsi b/arch/arm/dts/k3-am62p5-sk-u-boot.dtsi
index c166d65..cf087c6 100644
--- a/arch/arm/dts/k3-am62p5-sk-u-boot.dtsi
+++ b/arch/arm/dts/k3-am62p5-sk-u-boot.dtsi
@@ -15,9 +15,4 @@
&dmsc {
bootph-pre-ram;
-
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-pre-ram;
- };
};
diff --git a/arch/arm/dts/k3-am642-evm-u-boot.dtsi b/arch/arm/dts/k3-am642-evm-u-boot.dtsi
index ee66567..705b3ba 100644
--- a/arch/arm/dts/k3-am642-evm-u-boot.dtsi
+++ b/arch/arm/dts/k3-am642-evm-u-boot.dtsi
@@ -23,13 +23,6 @@
bootph-all;
};
-&dmsc {
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
-};
-
&sdhci0 {
bootph-all;
};
diff --git a/arch/arm/dts/k3-am642-phyboard-electra-rdk-u-boot.dtsi b/arch/arm/dts/k3-am642-phyboard-electra-rdk-u-boot.dtsi
index 5dfc40a..4677c35 100644
--- a/arch/arm/dts/k3-am642-phyboard-electra-rdk-u-boot.dtsi
+++ b/arch/arm/dts/k3-am642-phyboard-electra-rdk-u-boot.dtsi
@@ -29,10 +29,6 @@
&dmsc {
bootph-all;
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
};
&dmss {
diff --git a/arch/arm/dts/k3-am642-sk-u-boot.dtsi b/arch/arm/dts/k3-am642-sk-u-boot.dtsi
index 7e6b298..6fcb11b 100644
--- a/arch/arm/dts/k3-am642-sk-u-boot.dtsi
+++ b/arch/arm/dts/k3-am642-sk-u-boot.dtsi
@@ -15,13 +15,6 @@
clock-frequency = <200000000>;
};
-&dmsc {
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
-};
-
&sdhci0 {
status = "disabled";
};
diff --git a/arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi b/arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi
index d53f133..b6d2c81 100644
--- a/arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi
+++ b/arch/arm/dts/k3-am65-iot2050-common-u-boot.dtsi
@@ -99,10 +99,6 @@
&dmsc {
bootph-all;
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
};
&k3_pds {
diff --git a/arch/arm/dts/k3-am68-sk-base-board-u-boot.dtsi b/arch/arm/dts/k3-am68-sk-base-board-u-boot.dtsi
index 4f34347..b8fc62f 100644
--- a/arch/arm/dts/k3-am68-sk-base-board-u-boot.dtsi
+++ b/arch/arm/dts/k3-am68-sk-base-board-u-boot.dtsi
@@ -51,10 +51,6 @@
&sms {
bootph-all;
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
};
&main_pmx0 {
diff --git a/arch/arm/dts/k3-am69-sk-u-boot.dtsi b/arch/arm/dts/k3-am69-sk-u-boot.dtsi
index bed330e..4a82d2f 100644
--- a/arch/arm/dts/k3-am69-sk-u-boot.dtsi
+++ b/arch/arm/dts/k3-am69-sk-u-boot.dtsi
@@ -23,13 +23,6 @@
bootph-pre-ram;
};
-&sms {
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-pre-ram;
- };
-};
-
#ifdef CONFIG_TARGET_J784S4_A72_EVM
#define SPL_AM69_SK_DTB "spl/dts/ti/k3-am69-sk.dtb"
diff --git a/arch/arm/dts/k3-j7200-common-proc-board-u-boot.dtsi b/arch/arm/dts/k3-j7200-common-proc-board-u-boot.dtsi
index c9fee0e..485f17c 100644
--- a/arch/arm/dts/k3-j7200-common-proc-board-u-boot.dtsi
+++ b/arch/arm/dts/k3-j7200-common-proc-board-u-boot.dtsi
@@ -57,10 +57,6 @@
&dmsc {
bootph-all;
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
};
&k3_pds {
diff --git a/arch/arm/dts/k3-j721e-beagleboneai64-u-boot.dtsi b/arch/arm/dts/k3-j721e-beagleboneai64-u-boot.dtsi
index 116ee37..e202ae1 100644
--- a/arch/arm/dts/k3-j721e-beagleboneai64-u-boot.dtsi
+++ b/arch/arm/dts/k3-j721e-beagleboneai64-u-boot.dtsi
@@ -92,10 +92,6 @@
&dmsc {
bootph-all;
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
};
&k3_pds {
diff --git a/arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi b/arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi
index 9433f3b..aa919b4 100644
--- a/arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi
+++ b/arch/arm/dts/k3-j721e-common-proc-board-u-boot.dtsi
@@ -47,10 +47,6 @@
&dmsc {
bootph-all;
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
};
&k3_pds {
diff --git a/arch/arm/dts/k3-j721e-sk-u-boot.dtsi b/arch/arm/dts/k3-j721e-sk-u-boot.dtsi
index 8b20555..8f4f944 100644
--- a/arch/arm/dts/k3-j721e-sk-u-boot.dtsi
+++ b/arch/arm/dts/k3-j721e-sk-u-boot.dtsi
@@ -47,10 +47,6 @@
&dmsc {
bootph-all;
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
};
&k3_pds {
diff --git a/arch/arm/dts/k3-j721s2-common-proc-board-u-boot.dtsi b/arch/arm/dts/k3-j721s2-common-proc-board-u-boot.dtsi
index a3ebf59..19b2d48 100644
--- a/arch/arm/dts/k3-j721s2-common-proc-board-u-boot.dtsi
+++ b/arch/arm/dts/k3-j721s2-common-proc-board-u-boot.dtsi
@@ -51,10 +51,6 @@
&sms {
bootph-all;
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-all;
- };
};
&main_pmx0 {
diff --git a/arch/arm/dts/k3-j784s4-evm-u-boot.dtsi b/arch/arm/dts/k3-j784s4-evm-u-boot.dtsi
index ac74978..8f03073 100644
--- a/arch/arm/dts/k3-j784s4-evm-u-boot.dtsi
+++ b/arch/arm/dts/k3-j784s4-evm-u-boot.dtsi
@@ -22,10 +22,3 @@
"tchanrt", "rflow";
bootph-pre-ram;
};
-
-&sms {
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- bootph-pre-ram;
- };
-};
diff --git a/arch/arm/dts/zynqmp-mini-nand.dts b/arch/arm/dts/zynqmp-mini-nand.dts
index e0517cf..5889d43 100644
--- a/arch/arm/dts/zynqmp-mini-nand.dts
+++ b/arch/arm/dts/zynqmp-mini-nand.dts
@@ -50,6 +50,12 @@
#size-cells = <1>;
arasan,has-mdma;
num-cs = <2>;
+ nand@0 {
+ reg = <0>;
+ #address-cells = <2>;
+ #size-cells = <1>;
+ nand-ecc-mode = "hw";
+ };
};
};
};
diff --git a/arch/arm/dts/zynqmp-sc-revB.dts b/arch/arm/dts/zynqmp-sc-revB.dts
index 8517bda..c1d713b 100644
--- a/arch/arm/dts/zynqmp-sc-revB.dts
+++ b/arch/arm/dts/zynqmp-sc-revB.dts
@@ -49,7 +49,7 @@
gpio-keys {
compatible = "gpio-keys";
autorepeat;
- fwuen {
+ key-fwuen {
label = "sw16";
gpios = <&gpio 12 GPIO_ACTIVE_LOW>;
linux,code = <BTN_MISC>;
@@ -192,7 +192,7 @@
status = "okay";
/* QSPI should also have PINCTRL setup */
flash@0 {
- compatible = "mt25qu512a", "m25p80", "jedec,spi-nor"; /* mt25qu512abb8e12 512Mib */
+ compatible = "m25p80", "jedec,spi-nor"; /* mt25qu512abb8e12 512Mib */
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
diff --git a/arch/arm/dts/zynqmp-sck-kd-g-revA.dtso b/arch/arm/dts/zynqmp-sck-kd-g-revA.dtso
index 5202b7c..1727a1c 100644
--- a/arch/arm/dts/zynqmp-sck-kd-g-revA.dtso
+++ b/arch/arm/dts/zynqmp-sck-kd-g-revA.dtso
@@ -356,6 +356,8 @@
&uart0 {
status = "okay";
+ rts-gpios = <&gpio 72 GPIO_ACTIVE_HIGH>;
+ linux,rs485-enabled-at-boot-time;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart0_default>;
assigned-clock-rates = <100000000>;
diff --git a/arch/arm/dts/zynqmp-sck-kr-g-revB.dtso b/arch/arm/dts/zynqmp-sck-kr-g-revB.dtso
index 6c29f65..0a0cbd2 100644
--- a/arch/arm/dts/zynqmp-sck-kr-g-revB.dtso
+++ b/arch/arm/dts/zynqmp-sck-kr-g-revB.dtso
@@ -66,6 +66,18 @@
#clock-cells = <0>;
clock-frequency = <74250000>;
};
+
+ dpcon {
+ compatible = "dp-connector";
+ label = "P11";
+ type = "full-size";
+
+ port {
+ dpcon_in: endpoint {
+ remote-endpoint = <&dpsub_dp_out>;
+ };
+ };
+ };
};
&i2c1 { /* I2C_SCK C26/C27 - MIO from SOM */
@@ -130,6 +142,14 @@
phy-names = "dp-phy0";
phys = <&psgtr 1 PHY_TYPE_DP 0 1>;
assigned-clock-rates = <27000000>, <25000000>, <300000000>;
+
+ ports {
+ port@5 {
+ dpsub_dp_out: endpoint {
+ remote-endpoint = <&dpcon_in>;
+ };
+ };
+ };
};
&zynqmp_dpdma {
diff --git a/arch/arm/dts/zynqmp-sck-kv-g-revA.dtso b/arch/arm/dts/zynqmp-sck-kv-g-revA.dtso
index 6d0d5c4..561b546 100644
--- a/arch/arm/dts/zynqmp-sck-kv-g-revA.dtso
+++ b/arch/arm/dts/zynqmp-sck-kv-g-revA.dtso
@@ -342,6 +342,7 @@
slew-rate = <SLEW_RATE_SLOW>;
power-source = <IO_STANDARD_LVCMOS18>;
bias-disable;
+ output-enable;
};
conf-cd {
diff --git a/arch/arm/dts/zynqmp-sck-kv-g-revB.dtso b/arch/arm/dts/zynqmp-sck-kv-g-revB.dtso
index a4b4465..64683e0 100644
--- a/arch/arm/dts/zynqmp-sck-kv-g-revB.dtso
+++ b/arch/arm/dts/zynqmp-sck-kv-g-revB.dtso
@@ -63,6 +63,18 @@
#clock-cells = <0>;
clock-frequency = <27000000>;
};
+
+ dpcon {
+ compatible = "dp-connector";
+ label = "P11";
+ type = "full-size";
+
+ port {
+ dpcon_in: endpoint {
+ remote-endpoint = <&dpsub_dp_out>;
+ };
+ };
+ };
};
&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */
@@ -97,6 +109,14 @@
phy-names = "dp-phy0", "dp-phy1";
phys = <&psgtr 1 PHY_TYPE_DP 0 0>, <&psgtr 0 PHY_TYPE_DP 1 0>;
assigned-clock-rates = <27000000>, <25000000>, <300000000>;
+
+ ports {
+ port@5 {
+ dpsub_dp_out: endpoint {
+ remote-endpoint = <&dpcon_in>;
+ };
+ };
+ };
};
&zynqmp_dpdma {
@@ -329,6 +349,7 @@
slew-rate = <SLEW_RATE_SLOW>;
power-source = <IO_STANDARD_LVCMOS18>;
bias-disable;
+ output-enable;
};
conf-cd {
diff --git a/arch/arm/dts/zynqmp-vp-x-a2785-00-revA.dts b/arch/arm/dts/zynqmp-vp-x-a2785-00-revA.dts
index 2a3bbe1..b626d1a 100644
--- a/arch/arm/dts/zynqmp-vp-x-a2785-00-revA.dts
+++ b/arch/arm/dts/zynqmp-vp-x-a2785-00-revA.dts
@@ -47,7 +47,7 @@
gpio-keys {
compatible = "gpio-keys";
autorepeat;
- j383 {
+ key-j383 {
label = "j383";
gpios = <&gpio 10 GPIO_ACTIVE_HIGH>;
linux,code = <BTN_MISC>;
diff --git a/arch/arm/dts/zynqmp-vpk120-revA.dts b/arch/arm/dts/zynqmp-vpk120-revA.dts
index e0e4f1b..e063288 100644
--- a/arch/arm/dts/zynqmp-vpk120-revA.dts
+++ b/arch/arm/dts/zynqmp-vpk120-revA.dts
@@ -47,7 +47,7 @@
gpio-keys {
compatible = "gpio-keys";
autorepeat;
- sw16 {
+ button-16 {
label = "sw16";
gpios = <&gpio 10 GPIO_ACTIVE_HIGH>;
linux,code = <BTN_MISC>;
diff --git a/arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts b/arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts
index b97f7ee..48ab619 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm017-dc3.dts
@@ -136,8 +136,7 @@
reg = <0x0>;
#address-cells = <0x2>;
#size-cells = <0x1>;
- nand-ecc-mode = "soft";
- nand-ecc-algo = "bch";
+ nand-ecc-mode = "hw";
nand-rb = <0>;
label = "main-storage-0";
nand-ecc-step-size = <1024>;
@@ -173,8 +172,7 @@
reg = <0x1>;
#address-cells = <0x2>;
#size-cells = <0x1>;
- nand-ecc-mode = "soft";
- nand-ecc-algo = "bch";
+ nand-ecc-mode = "hw";
nand-rb = <0>;
label = "main-storage-1";
nand-ecc-step-size = <1024>;
diff --git a/arch/arm/dts/zynqmp-zcu208-revA.dts b/arch/arm/dts/zynqmp-zcu208-revA.dts
index b4e2474..a113e47 100644
--- a/arch/arm/dts/zynqmp-zcu208-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu208-revA.dts
@@ -46,7 +46,7 @@
gpio-keys {
compatible = "gpio-keys";
autorepeat;
- sw19 {
+ switch-19 {
label = "sw19";
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
linux,code = <KEY_DOWN>;
diff --git a/arch/arm/dts/zynqmp-zcu216-revA.dts b/arch/arm/dts/zynqmp-zcu216-revA.dts
index 6f593e8..4d7d5d2 100644
--- a/arch/arm/dts/zynqmp-zcu216-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu216-revA.dts
@@ -46,7 +46,7 @@
gpio-keys {
compatible = "gpio-keys";
autorepeat;
- sw19 {
+ switch-19 {
label = "sw19";
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
linux,code = <KEY_DOWN>;
diff --git a/arch/arm/dts/zynqmp-zcu670-revA.dts b/arch/arm/dts/zynqmp-zcu670-revA.dts
index 7f70904..def3b53 100644
--- a/arch/arm/dts/zynqmp-zcu670-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu670-revA.dts
@@ -49,7 +49,7 @@
gpio-keys {
compatible = "gpio-keys";
autorepeat;
- sw1 {
+ switch-1 {
label = "sw1";
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
linux,code = <BTN_MISC>;
diff --git a/arch/arm/dts/zynqmp-zcu670-revB.dts b/arch/arm/dts/zynqmp-zcu670-revB.dts
index 0adb206..41f9a23 100644
--- a/arch/arm/dts/zynqmp-zcu670-revB.dts
+++ b/arch/arm/dts/zynqmp-zcu670-revB.dts
@@ -49,7 +49,7 @@
gpio-keys {
compatible = "gpio-keys";
autorepeat;
- sw1 {
+ switch-1 {
label = "sw1";
gpios = <&gpio 22 GPIO_ACTIVE_HIGH>;
linux,code = <BTN_MISC>;
diff --git a/arch/arm/dts/zynqmp.dtsi b/arch/arm/dts/zynqmp.dtsi
index b50b83b..53a606c 100644
--- a/arch/arm/dts/zynqmp.dtsi
+++ b/arch/arm/dts/zynqmp.dtsi
@@ -168,7 +168,7 @@
bootph-all;
};
- pmu {
+ pmu: pmu {
compatible = "arm,armv8-pmuv3";
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>,
@@ -1001,14 +1001,14 @@
status = "disabled";
reg = <0x0 0xfe200000 0x0 0x40000>;
interrupt-parent = <&gic>;
- interrupt-names = "host", "peripheral", "otg";
+ interrupt-names = "host", "peripheral", "otg", "wakeup";
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
/* iommus = <&smmu 0x860>; */
snps,quirk-frame-length-adjustment = <0x20>;
clock-names = "ref";
- snps,enable_guctl1_ipd_quirk;
snps,resume-hs-terminations;
/* dma-coherent; */
};
@@ -1033,14 +1033,14 @@
status = "disabled";
reg = <0x0 0xfe300000 0x0 0x40000>;
interrupt-parent = <&gic>;
- interrupt-names = "host", "peripheral", "otg";
+ interrupt-names = "host", "peripheral", "otg", "wakeup";
interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
+ <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
/* iommus = <&smmu 0x861>; */
snps,quirk-frame-length-adjustment = <0x20>;
clock-names = "ref";
- snps,enable_guctl1_ipd_quirk;
snps,resume-hs-terminations;
/* dma-coherent; */
};
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 67275fb..b55167e 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -31,7 +31,7 @@
obj-$(CONFIG_CPU_V7M) += cmd_boot.o
obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o
obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o
else
obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o
diff --git a/arch/arm/mach-k3/Makefile b/arch/arm/mach-k3/Makefile
index 6ee9864..1bd5233 100644
--- a/arch/arm/mach-k3/Makefile
+++ b/arch/arm/mach-k3/Makefile
@@ -25,3 +25,4 @@
obj-$(CONFIG_SOC_K3_AM62P5) += am62p5_init.o
endif
obj-y += common.o security.o
+obj-$(CONFIG_SOC_K3_AM625) += am62x/
diff --git a/arch/arm/mach-k3/am625_init.c b/arch/arm/mach-k3/am625_init.c
index 6c96e88..668f9a5 100644
--- a/arch/arm/mach-k3/am625_init.c
+++ b/arch/arm/mach-k3/am625_init.c
@@ -14,6 +14,7 @@
#include <dm.h>
#include <dm/uclass-internal.h>
#include <dm/pinctrl.h>
+#include <dm/ofnode.h>
#define RTC_BASE_ADDRESS 0x2b1f0000
#define REG_K3RTC_S_CNT_LSW (RTC_BASE_ADDRESS + 0x18)
@@ -24,6 +25,9 @@
#define K3RTC_KICK0_UNLOCK_VALUE 0x83e70b13
#define K3RTC_KICK1_UNLOCK_VALUE 0x95a4f1e0
+/* TISCI DEV ID for A53 Clock */
+#define AM62X_DEV_A53SS0_CORE_0_DEV_ID 135
+
/*
* This uninitialized global variable would normal end up in the .bss section,
* but the .bss is cleared between writing and reading this variable, so move
@@ -111,6 +115,62 @@
writel(K3RTC_KICK0_UNLOCK_VALUE, REG_K3RTC_KICK0);
writel(K3RTC_KICK1_UNLOCK_VALUE, REG_K3RTC_KICK1);
}
+
+#if CONFIG_IS_ENABLED(OF_CONTROL)
+static int get_a53_cpu_clock_index(ofnode node)
+{
+ int count, i;
+ struct ofnode_phandle_args *args;
+ ofnode clknode;
+
+ clknode = ofnode_path("/bus@f0000/system-controller@44043000/clock-controller");
+ if (!ofnode_valid(clknode))
+ return -1;
+
+ count = ofnode_count_phandle_with_args(node, "assigned-clocks", "#clock-cells", 0);
+
+ for (i = 0; i < count; i++) {
+ if (!ofnode_parse_phandle_with_args(node, "assigned-clocks",
+ "#clock-cells", 0, i, args)) {
+ if (ofnode_equal(clknode, args->node) &&
+ args->args[0] == AM62X_DEV_A53SS0_CORE_0_DEV_ID)
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+static void fixup_a53_cpu_freq_by_speed_grade(void)
+{
+ int index, size;
+ u32 *rates;
+ ofnode node;
+
+ node = ofnode_path("/a53@0");
+ if (!ofnode_valid(node))
+ return;
+
+ rates = fdt_getprop_w(ofnode_to_fdt(node), ofnode_to_offset(node),
+ "assigned-clock-rates", &size);
+
+ index = get_a53_cpu_clock_index(node);
+
+ if (!rates || index < 0 || index >= (size / sizeof(u32))) {
+ printf("Wrong A53 assigned-clocks configuration\n");
+ return;
+ }
+
+ rates[index] = cpu_to_fdt32(k3_get_a53_max_frequency());
+
+ printf("Changed A53 CPU frequency to %dHz (%c grade) in DT\n",
+ k3_get_a53_max_frequency(), k3_get_speed_grade());
+}
+#else
+static void fixup_a53_cpu_freq_by_speed_grade(void)
+{
+}
+#endif
void board_init_f(ulong dummy)
{
@@ -176,6 +236,14 @@
}
/*
+ * Relocate boot information to OCRAM (after TIFS has opend this
+ * region for us) so the next bootloader stages can keep access to
+ * primary vs backup bootmodes.
+ */
+ if (IS_ENABLED(CONFIG_CPU_V7R))
+ writel(bootindex, K3_BOOT_PARAM_TABLE_INDEX_OCRAM);
+
+ /*
* Force probe of clk_k3 driver here to ensure basic default clock
* configuration is always done.
*/
@@ -210,6 +278,8 @@
panic("DRAM init failed: %d\n", ret);
}
spl_enable_cache();
+
+ fixup_a53_cpu_freq_by_speed_grade();
}
u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
@@ -235,100 +305,7 @@
}
}
-static u32 __get_backup_bootmedia(u32 devstat)
-{
- u32 bkup_bootmode = (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_MASK) >>
- MAIN_DEVSTAT_BACKUP_BOOTMODE_SHIFT;
- u32 bkup_bootmode_cfg =
- (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_MASK) >>
- MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_SHIFT;
-
- switch (bkup_bootmode) {
- case BACKUP_BOOT_DEVICE_UART:
- return BOOT_DEVICE_UART;
-
- case BACKUP_BOOT_DEVICE_USB:
- return BOOT_DEVICE_USB;
-
- case BACKUP_BOOT_DEVICE_ETHERNET:
- return BOOT_DEVICE_ETHERNET;
-
- case BACKUP_BOOT_DEVICE_MMC:
- if (bkup_bootmode_cfg)
- return BOOT_DEVICE_MMC2;
- return BOOT_DEVICE_MMC1;
-
- case BACKUP_BOOT_DEVICE_SPI:
- return BOOT_DEVICE_SPI;
-
- case BACKUP_BOOT_DEVICE_I2C:
- return BOOT_DEVICE_I2C;
-
- case BACKUP_BOOT_DEVICE_DFU:
- if (bkup_bootmode_cfg & MAIN_DEVSTAT_BACKUP_USB_MODE_MASK)
- return BOOT_DEVICE_USB;
- return BOOT_DEVICE_DFU;
- };
-
- return BOOT_DEVICE_RAM;
-}
-
-static u32 __get_primary_bootmedia(u32 devstat)
-{
- u32 bootmode = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK) >>
- MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT;
- u32 bootmode_cfg = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_MASK) >>
- MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_SHIFT;
-
- switch (bootmode) {
- case BOOT_DEVICE_OSPI:
- fallthrough;
- case BOOT_DEVICE_QSPI:
- fallthrough;
- case BOOT_DEVICE_XSPI:
- fallthrough;
- case BOOT_DEVICE_SPI:
- return BOOT_DEVICE_SPI;
-
- case BOOT_DEVICE_ETHERNET_RGMII:
- fallthrough;
- case BOOT_DEVICE_ETHERNET_RMII:
- return BOOT_DEVICE_ETHERNET;
-
- case BOOT_DEVICE_EMMC:
- return BOOT_DEVICE_MMC1;
-
- case BOOT_DEVICE_MMC:
- if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_PORT_MASK) >>
- MAIN_DEVSTAT_PRIMARY_MMC_PORT_SHIFT)
- return BOOT_DEVICE_MMC2;
- return BOOT_DEVICE_MMC1;
-
- case BOOT_DEVICE_DFU:
- if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_USB_MODE_MASK) >>
- MAIN_DEVSTAT_PRIMARY_USB_MODE_SHIFT)
- return BOOT_DEVICE_USB;
- return BOOT_DEVICE_DFU;
-
- case BOOT_DEVICE_NOBOOT:
- return BOOT_DEVICE_RAM;
- }
-
- return bootmode;
-}
-
u32 spl_boot_device(void)
{
- u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT);
- u32 bootmedia;
-
- if (bootindex == K3_PRIMARY_BOOTMODE)
- bootmedia = __get_primary_bootmedia(devstat);
- else
- bootmedia = __get_backup_bootmedia(devstat);
-
- debug("am625_init: %s: devstat = 0x%x bootmedia = 0x%x bootindex = %d\n",
- __func__, devstat, bootmedia, bootindex);
-
- return bootmedia;
+ return get_boot_device();
}
diff --git a/arch/arm/mach-k3/am62x/Kconfig b/arch/arm/mach-k3/am62x/Kconfig
index 7c9bac2..9786751 100644
--- a/arch/arm/mach-k3/am62x/Kconfig
+++ b/arch/arm/mach-k3/am62x/Kconfig
@@ -48,6 +48,7 @@
select ARM64
select BINMAN
select OF_SYSTEM_SETUP
+ imply OF_UPSTREAM
config TARGET_VERDIN_AM62_R5
bool "Toradex Verdin AM62 running on R5"
diff --git a/arch/arm/mach-k3/am62x/Makefile b/arch/arm/mach-k3/am62x/Makefile
new file mode 100644
index 0000000..acf09c3
--- /dev/null
+++ b/arch/arm/mach-k3/am62x/Makefile
@@ -0,0 +1,2 @@
+# SPDX-License-Identifier: GPL-2.0+
+obj-y += boot.o
diff --git a/arch/arm/mach-k3/am62x/boot.c b/arch/arm/mach-k3/am62x/boot.c
new file mode 100644
index 0000000..132b42f
--- /dev/null
+++ b/arch/arm/mach-k3/am62x/boot.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/am62_spl.h>
+
+static u32 __get_backup_bootmedia(u32 devstat)
+{
+ u32 bkup_bootmode = (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_MASK) >>
+ MAIN_DEVSTAT_BACKUP_BOOTMODE_SHIFT;
+ u32 bkup_bootmode_cfg =
+ (devstat & MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_MASK) >>
+ MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG_SHIFT;
+
+ switch (bkup_bootmode) {
+ case BACKUP_BOOT_DEVICE_UART:
+ return BOOT_DEVICE_UART;
+
+ case BACKUP_BOOT_DEVICE_USB:
+ return BOOT_DEVICE_USB;
+
+ case BACKUP_BOOT_DEVICE_ETHERNET:
+ return BOOT_DEVICE_ETHERNET;
+
+ case BACKUP_BOOT_DEVICE_MMC:
+ if (bkup_bootmode_cfg)
+ return BOOT_DEVICE_MMC2;
+ return BOOT_DEVICE_MMC1;
+
+ case BACKUP_BOOT_DEVICE_SPI:
+ return BOOT_DEVICE_SPI;
+
+ case BACKUP_BOOT_DEVICE_I2C:
+ return BOOT_DEVICE_I2C;
+
+ case BACKUP_BOOT_DEVICE_DFU:
+ if (bkup_bootmode_cfg & MAIN_DEVSTAT_BACKUP_USB_MODE_MASK)
+ return BOOT_DEVICE_USB;
+ return BOOT_DEVICE_DFU;
+ };
+
+ return BOOT_DEVICE_RAM;
+}
+
+static u32 __get_primary_bootmedia(u32 devstat)
+{
+ u32 bootmode = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_MASK) >>
+ MAIN_DEVSTAT_PRIMARY_BOOTMODE_SHIFT;
+ u32 bootmode_cfg = (devstat & MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_MASK) >>
+ MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG_SHIFT;
+
+ switch (bootmode) {
+ case BOOT_DEVICE_OSPI:
+ fallthrough;
+ case BOOT_DEVICE_QSPI:
+ fallthrough;
+ case BOOT_DEVICE_XSPI:
+ fallthrough;
+ case BOOT_DEVICE_SPI:
+ return BOOT_DEVICE_SPI;
+
+ case BOOT_DEVICE_ETHERNET_RGMII:
+ fallthrough;
+ case BOOT_DEVICE_ETHERNET_RMII:
+ return BOOT_DEVICE_ETHERNET;
+
+ case BOOT_DEVICE_EMMC:
+ return BOOT_DEVICE_MMC1;
+
+ case BOOT_DEVICE_MMC:
+ if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_PORT_MASK) >>
+ MAIN_DEVSTAT_PRIMARY_MMC_PORT_SHIFT)
+ return BOOT_DEVICE_MMC2;
+ return BOOT_DEVICE_MMC1;
+
+ case BOOT_DEVICE_DFU:
+ if ((bootmode_cfg & MAIN_DEVSTAT_PRIMARY_USB_MODE_MASK) >>
+ MAIN_DEVSTAT_PRIMARY_USB_MODE_SHIFT)
+ return BOOT_DEVICE_USB;
+ return BOOT_DEVICE_DFU;
+
+ case BOOT_DEVICE_NOBOOT:
+ return BOOT_DEVICE_RAM;
+ }
+
+ return bootmode;
+}
+
+u32 get_boot_device(void)
+{
+ u32 devstat = readl(CTRLMMR_MAIN_DEVSTAT);
+ u32 bootmode = *(u32 *)(K3_BOOT_PARAM_TABLE_INDEX_OCRAM);
+ u32 bootmedia;
+
+ if (bootmode == K3_PRIMARY_BOOTMODE)
+ bootmedia = __get_primary_bootmedia(devstat);
+ else
+ bootmedia = __get_backup_bootmedia(devstat);
+
+ debug("%s: devstat = 0x%x bootmedia = 0x%x bootmode = %d\n",
+ __func__, devstat, bootmedia, bootmode);
+
+ return bootmedia;
+}
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index b0fb87b..1a269d6 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -24,6 +24,7 @@
#include <asm/io.h>
#include <fs_loader.h>
#include <fs.h>
+#include <efi_loader.h>
#include <env.h>
#include <elf.h>
#include <soc.h>
@@ -270,6 +271,17 @@
printf("Failed to probe am65_cpsw_nuss driver\n");
}
+ if (IS_ENABLED(CONFIG_TI_ICSSG_PRUETH)) {
+ struct udevice *dev;
+ int ret;
+
+ ret = uclass_get_device_by_driver(UCLASS_MISC,
+ DM_DRIVER_GET(prueth),
+ &dev);
+ if (ret)
+ printf("Failed to probe prueth driver\n");
+ }
+
/* Default FIT boot on HS-SE devices */
if (get_device_type() == K3_DEVICE_TYPE_HS_SE)
env_set("boot_fit", "1");
@@ -296,3 +308,14 @@
writel(qos_data[i].val, (uintptr_t)qos_data[i].reg);
}
#endif
+
+void efi_add_known_memory(void)
+{
+ if (IS_ENABLED(CONFIG_EFI_LOADER))
+ /*
+ * Memory over ram_top can be used by various firmware
+ * Declare to EFI only memory area below ram_top
+ */
+ efi_add_memory_map(gd->ram_base, gd->ram_top - gd->ram_base,
+ EFI_CONVENTIONAL_MEMORY);
+}
diff --git a/arch/arm/mach-k3/include/mach/am62_hardware.h b/arch/arm/mach-k3/include/mach/am62_hardware.h
index 264f8a4..bcbc482 100644
--- a/arch/arm/mach-k3/include/mach/am62_hardware.h
+++ b/arch/arm/mach-k3/include/mach/am62_hardware.h
@@ -83,6 +83,7 @@
#define CTRLMMR_DBOUNCE_CFG(index) (MCU_CTRL_MMR0_BASE + 0x4080 + (index * 4))
#define ROM_EXTENDED_BOOT_DATA_INFO 0x43c3f1e0
+#define K3_BOOT_PARAM_TABLE_INDEX_OCRAM 0x7000F290
#define TI_SRAM_SCRATCH_BOARD_EEPROM_START 0x43c30000
@@ -122,6 +123,21 @@
}
}
+static inline int k3_get_a53_max_frequency(void)
+{
+ switch (k3_get_speed_grade()) {
+ case 'K':
+ return 800000000;
+ case 'S':
+ return 1000000000;
+ case 'T':
+ return 1250000000;
+ case 'G':
+ default:
+ return 300000000;
+ }
+}
+
static inline int k3_has_pru(void)
{
u32 full_devid = readl(CTRLMMR_WKUP_JTAG_DEVICE_ID);
diff --git a/arch/arm/mach-k3/include/mach/hardware.h b/arch/arm/mach-k3/include/mach/hardware.h
index af982e7..c724450 100644
--- a/arch/arm/mach-k3/include/mach/hardware.h
+++ b/arch/arm/mach-k3/include/mach/hardware.h
@@ -107,4 +107,5 @@
u32 num_components;
};
+u32 get_boot_device(void);
#endif /* _ASM_ARCH_HARDWARE_H_ */
diff --git a/arch/arm/mach-k3/r5/common.c b/arch/arm/mach-k3/r5/common.c
index c02f8d3..0f6c294 100644
--- a/arch/arm/mach-k3/r5/common.c
+++ b/arch/arm/mach-k3/r5/common.c
@@ -24,6 +24,9 @@
IMAGE_ID_OPTEE,
IMAGE_ID_SPL,
IMAGE_ID_DM_FW,
+ IMAGE_ID_TIFSSTUB_HS,
+ IMAGE_ID_TIFSSTUB_FS,
+ IMAGE_ID_T,
IMAGE_AMT,
};
@@ -33,6 +36,9 @@
"tee",
"U-Boot",
"DM",
+ "tifsstub-hs",
+ "tifsstub-fs",
+ "tifsstub-gp",
};
#endif
@@ -314,6 +320,24 @@
break;
}
}
+
+ if (i < IMAGE_AMT && i > IMAGE_ID_DM_FW) {
+ int device_type = get_device_type();
+
+ if ((device_type == K3_DEVICE_TYPE_HS_SE &&
+ strcmp(os, "tifsstub-hs")) ||
+ (device_type == K3_DEVICE_TYPE_HS_FS &&
+ strcmp(os, "tifsstub-fs")) ||
+ (device_type == K3_DEVICE_TYPE_GP &&
+ strcmp(os, "tifsstub-gp"))) {
+ *p_size = 0;
+ } else {
+ debug("tifsstub-type: %s\n", os);
+ }
+
+ return;
+ }
+
/*
* Only DM and the DTBs are being authenticated here,
* rest will be authenticated when A72 cluster is up
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index 1008232..6b6a162 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -90,6 +90,14 @@
imply FPGA_SOCFPGA
imply SPL_USE_TINY_PRINTF
+config SOCFPGA_ARRIA10_ALWAYS_REPROGRAM
+ bool "Always reprogram Arria 10 FPGA"
+ depends on TARGET_SOCFPGA_ARRIA10
+ help
+ Arria 10 FPGA is only programmed during the cold boot.
+ This option forces the FPGA to be reprogrammed every reboot,
+ allowing to change the bitstream and apply it with warm reboot.
+
config TARGET_SOCFPGA_CYCLONE5
bool
select TARGET_SOCFPGA_GEN5
diff --git a/arch/arm/mach-socfpga/spl_a10.c b/arch/arm/mach-socfpga/spl_a10.c
index 9edbbf4..3981d2d 100644
--- a/arch/arm/mach-socfpga/spl_a10.c
+++ b/arch/arm/mach-socfpga/spl_a10.c
@@ -122,7 +122,10 @@
arch_early_init_r();
/* If the full FPGA is already loaded, ie.from EPCQ, config fpga pins */
- if (is_fpgamgr_user_mode()) {
+ if ((IS_ENABLED(CONFIG_SOCFPGA_ARRIA10_ALWAYS_REPROGRAM) &&
+ is_regular_boot_valid()) ||
+ (!IS_ENABLED(CONFIG_SOCFPGA_ARRIA10_ALWAYS_REPROGRAM) &&
+ is_fpgamgr_user_mode())) {
ret = config_pins(gd->fdt_blob, "shared");
if (ret)
return;
@@ -130,7 +133,8 @@
ret = config_pins(gd->fdt_blob, "fpga");
if (ret)
return;
- } else if (!is_fpgamgr_early_user_mode()) {
+ } else if (IS_ENABLED(CONFIG_SOCFPGA_ARRIA10_ALWAYS_REPROGRAM) ||
+ !is_fpgamgr_early_user_mode()) {
/* Program IOSSM(early IO release) or full FPGA */
fpgamgr_program(buf, FPGA_BUFSIZ, 0);
diff --git a/arch/arm/mach-uniphier/dram_init.c b/arch/arm/mach-uniphier/dram_init.c
index 7f27531..e6f1286 100644
--- a/arch/arm/mach-uniphier/dram_init.c
+++ b/arch/arm/mach-uniphier/dram_init.c
@@ -265,14 +265,15 @@
if (uniphier_get_soc_id() == UNIPHIER_LD20_ID)
gd->ram_size -= 64;
+ /* map all the DRAM regions */
+ uniphier_mem_map_init(gd->ram_base, prev_top - gd->ram_base);
+
return 0;
}
int dram_init_banksize(void)
{
struct uniphier_dram_map dram_map[3] = {};
- unsigned long base, top;
- bool valid_bank_found = false;
int ret, i;
ret = uniphier_dram_map_get(dram_map);
@@ -287,18 +288,7 @@
if (!dram_map[i].size)
continue;
-
- if (!valid_bank_found)
- base = dram_map[i].base;
- top = dram_map[i].base + dram_map[i].size;
- valid_bank_found = true;
}
- if (!valid_bank_found)
- return -EINVAL;
-
- /* map all the DRAM regions */
- uniphier_mem_map_init(base, top - base);
-
return 0;
}
diff --git a/arch/arm/mach-zynqmp/Kconfig b/arch/arm/mach-zynqmp/Kconfig
index 6a7be0b..0d2238a 100644
--- a/arch/arm/mach-zynqmp/Kconfig
+++ b/arch/arm/mach-zynqmp/Kconfig
@@ -1,29 +1,5 @@
if ARCH_ZYNQMP
-config SPL_FS_FAT
- default y
-
-config SPL_LIBCOMMON_SUPPORT
- default y
-
-config SPL_LIBDISK_SUPPORT
- default y
-
-config SPL_LIBGENERIC_SUPPORT
- default y
-
-config SPL_MMC
- default y if MMC_SDHCI_ZYNQ
-
-config SPL_SERIAL
- default y
-
-config SPL_SPI_FLASH_SUPPORT
- default y if ZYNQ_QSPI
-
-config SPL_SPI
- default y if ZYNQ_QSPI
-
config SYS_BOARD
string "Board name"
default "zynqmp"
@@ -135,7 +111,8 @@
config SPL_ZYNQMP_PSU_INIT_ENABLED
bool "Include psu_init in SPL"
- default y if SPL
+ depends on SPL
+ default y
select BOARD_EARLY_INIT_F
help
Include psu_init by default in SPL.
diff --git a/arch/arm/mach-zynqmp/spl.c b/arch/arm/mach-zynqmp/spl.c
index a0f35f3..979ff3a 100644
--- a/arch/arm/mach-zynqmp/spl.c
+++ b/arch/arm/mach-zynqmp/spl.c
@@ -9,6 +9,7 @@
#include <image.h>
#include <init.h>
#include <log.h>
+#include <semihosting.h>
#include <spl.h>
#include <linux/delay.h>
@@ -66,6 +67,11 @@
}
#endif
+static u32 jtag_boot_device(void)
+{
+ return semihosting_enabled() ? BOOT_DEVICE_SMH : BOOT_DEVICE_RAM;
+}
+
void board_boot_order(u32 *spl_boot_list)
{
spl_boot_list[0] = spl_boot_device();
@@ -75,7 +81,7 @@
if (spl_boot_list[0] == BOOT_DEVICE_MMC2)
spl_boot_list[1] = BOOT_DEVICE_MMC1;
- spl_boot_list[2] = BOOT_DEVICE_RAM;
+ spl_boot_list[2] = jtag_boot_device();
}
u32 spl_boot_device(void)
@@ -85,19 +91,20 @@
#if defined(CONFIG_SPL_ZYNQMP_ALT_BOOTMODE_ENABLED)
/* Change default boot mode at run-time */
+ reg = CONFIG_SPL_ZYNQMP_ALT_BOOTMODE;
writel(CONFIG_SPL_ZYNQMP_ALT_BOOTMODE << BOOT_MODE_ALT_SHIFT,
&crlapb_base->boot_mode);
-#endif
-
+#else
reg = readl(&crlapb_base->boot_mode);
if (reg >> BOOT_MODE_ALT_SHIFT)
reg >>= BOOT_MODE_ALT_SHIFT;
+#endif
bootmode = reg & BOOT_MODES_MASK;
switch (bootmode) {
case JTAG_MODE:
- return BOOT_DEVICE_RAM;
+ return jtag_boot_device();
#ifdef CONFIG_SPL_MMC
case SD_MODE1:
case SD1_LSHFT_MODE: /* not working on silicon v1 */
diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile
index 6e1fd93..5ccd954 100644
--- a/arch/m68k/lib/Makefile
+++ b/arch/m68k/lib/Makefile
@@ -8,7 +8,7 @@
lib-$(CONFIG_USE_PRIVATE_LIBGCC) += lshrdi3.o muldi3.o ashldi3.o ashrdi3.o
obj-y += bdinfo.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
obj-y += cache.o
obj-y += interrupts.o
obj-y += time.o
diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile
index dfd8135..2f23482 100644
--- a/arch/microblaze/lib/Makefile
+++ b/arch/microblaze/lib/Makefile
@@ -3,6 +3,6 @@
# (C) Copyright 2003-2006
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
obj-$(CONFIG_CMD_BDI) += bdinfo.o
obj-y += muldi3.o
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 1621cc9..4386eb4 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -10,7 +10,7 @@
obj-y += stack.o
obj-y += traps.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
obj-$(CONFIG_CMD_GO) += boot.o
obj-$(CONFIG_SPL_BUILD) += spl.o
diff --git a/arch/nios2/lib/Makefile b/arch/nios2/lib/Makefile
index a9f3c71..68a5ca0 100644
--- a/arch/nios2/lib/Makefile
+++ b/arch/nios2/lib/Makefile
@@ -4,5 +4,5 @@
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
obj-y += cache.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
obj-y += libgcc.o
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index bb819dc..dcce983 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -34,7 +34,7 @@
endif
obj-y += reloc.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
obj-y += cache.o
obj-y += extable.o
obj-y += interrupts.o
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 6c26f91f..7e20ef6 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -22,6 +22,7 @@
config TARGET_QEMU_VIRT
bool "Support QEMU Virt Board"
+ select BOARD_LATE_INIT
config TARGET_SIFIVE_UNLEASHED
bool "Support SiFive Unleashed Board"
@@ -93,6 +94,7 @@
# platform-specific options below
source "arch/riscv/cpu/andesv5/Kconfig"
+source "arch/riscv/cpu/cv1800b/Kconfig"
source "arch/riscv/cpu/fu540/Kconfig"
source "arch/riscv/cpu/fu740/Kconfig"
source "arch/riscv/cpu/generic/Kconfig"
@@ -119,6 +121,26 @@
endchoice
+config FRAMEPOINTER
+ bool "Build with frame pointer for stack unwinding"
+ help
+ Choose this option to use the frame pointer so the stack can be
+ unwound if needed. This is useful for tracing where faults came
+ from as the source may be several functions back
+
+ If you say Y here, then the code size will be increased due to
+ having to store the fp.
+
+config SPL_FRAMEPOINTER
+ bool "Build SPL with frame pointer for stack unwinding"
+ help
+ Choose this option to use the frame pointer so the stack can be
+ unwound if needed. This is useful for tracing where faults came
+ from as the source may be several functions back
+
+ If you say Y here, then the code size will be increased due to
+ having to store the fp.
+
choice
prompt "Code Model"
default CMODEL_MEDLOW
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index b3ef870..c36a853 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -48,6 +48,10 @@
ARCH_FLAGS = -march=$(RISCV_MARCH) -mabi=$(ABI) \
-mcmodel=$(CMODEL)
+ifeq ($(CONFIG_$(SPL_)FRAMEPOINTER),y)
+ ARCH_FLAGS += -fno-omit-frame-pointer
+endif
+
PLATFORM_CPPFLAGS += $(ARCH_FLAGS)
CFLAGS_EFI += $(ARCH_FLAGS)
diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c
index ecfefa1..affe700 100644
--- a/arch/riscv/cpu/cpu.c
+++ b/arch/riscv/cpu/cpu.c
@@ -38,35 +38,51 @@
#if CONFIG_IS_ENABLED(RISCV_MMODE)
return csr_read(CSR_MISA) & (1 << (ext - 'a'));
#elif CONFIG_CPU
+ char sext[2] = {ext};
struct udevice *dev;
- char desc[32];
- int i;
+ const char *isa;
+ int ret, i;
uclass_find_first_device(UCLASS_CPU, &dev);
if (!dev) {
debug("unable to find the RISC-V cpu device\n");
return false;
}
- if (!cpu_get_desc(dev, desc, sizeof(desc))) {
- /*
- * skip the first 4 characters (rv32|rv64)
- */
- for (i = 4; i < sizeof(desc); i++) {
- switch (desc[i]) {
- case 's':
- case 'x':
- case 'z':
- case '_':
- case '\0':
- /*
- * Any of these characters mean the single
- * letter extensions have all been consumed.
- */
- return false;
- default:
- if (desc[i] == ext)
- return true;
- }
+
+ ret = dev_read_stringlist_search(dev, "riscv,isa-extensions", sext);
+ if (ret >= 0)
+ return true;
+
+ /*
+ * Only if the property is not found (ENODATA) is the fallback to
+ * riscv,isa used, otherwise the extension is not present in this
+ * CPU.
+ */
+ if (ret != -ENODATA)
+ return false;
+
+ isa = dev_read_string(dev, "riscv,isa");
+ if (!isa)
+ return false;
+
+ /*
+ * Skip the first 4 characters (rv32|rv64).
+ */
+ for (i = 4; i < sizeof(isa); i++) {
+ switch (isa[i]) {
+ case 's':
+ case 'x':
+ case 'z':
+ case '_':
+ case '\0':
+ /*
+ * Any of these characters mean the single
+ * letter extensions have all been consumed.
+ */
+ return false;
+ default:
+ if (isa[i] == ext)
+ return true;
}
}
diff --git a/arch/riscv/cpu/cv1800b/Kconfig b/arch/riscv/cpu/cv1800b/Kconfig
new file mode 100644
index 0000000..7225b12
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+
+config SOPHGO_CV1800B
+ bool
+ select ARCH_EARLY_INIT_R
+ select SYS_CACHE_SHIFT_6
+ imply CPU
+ imply CPU_RISCV
+ imply RISCV_TIMER
+ imply CMD_CPU
diff --git a/arch/riscv/cpu/cv1800b/Makefile b/arch/riscv/cpu/cv1800b/Makefile
new file mode 100644
index 0000000..95beb34
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+
+obj-y += dram.o
+obj-y += cpu.o
+obj-y += cache.o
diff --git a/arch/riscv/cpu/cv1800b/cache.c b/arch/riscv/cpu/cv1800b/cache.c
new file mode 100644
index 0000000..b8051e2
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/cache.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+ */
+
+#include <cpu_func.h>
+
+/*
+ * dcache.ipa rs1 (invalidate)
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ * 0000001 01010 rs1 000 00000 0001011
+ *
+ * dcache.cpa rs1 (clean)
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ * 0000001 01001 rs1 000 00000 0001011
+ *
+ * dcache.cipa rs1 (clean then invalidate)
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ * 0000001 01011 rs1 000 00000 0001011
+ *
+ * sync.s
+ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
+ * 0000000 11001 00000 000 00000 0001011
+ */
+#define DCACHE_IPA_A0 ".long 0x02a5000b"
+#define DCACHE_CPA_A0 ".long 0x0295000b"
+#define DCACHE_CIPA_A0 ".long 0x02b5000b"
+
+#define SYNC_S ".long 0x0190000b"
+
+void invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+ register unsigned long i asm("a0") = start & ~(CONFIG_SYS_CACHELINE_SIZE - 1);
+ for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
+ __asm__ __volatile__(DCACHE_IPA_A0);
+ __asm__ __volatile__(SYNC_S);
+}
+
+void flush_dcache_range(unsigned long start, unsigned long end)
+{
+ register unsigned long i asm("a0") = start & ~(CONFIG_SYS_CACHELINE_SIZE - 1);
+ for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
+ __asm__ __volatile__(DCACHE_CPA_A0);
+ __asm__ __volatile__(SYNC_S);
+}
diff --git a/arch/riscv/cpu/cv1800b/cpu.c b/arch/riscv/cpu/cv1800b/cpu.c
new file mode 100644
index 0000000..233a6a3
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/cpu.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+ */
+
+int cleanup_before_linux(void)
+{
+ return 0;
+}
diff --git a/arch/riscv/cpu/cv1800b/dram.c b/arch/riscv/cpu/cv1800b/dram.c
new file mode 100644
index 0000000..91007c0
--- /dev/null
+++ b/arch/riscv/cpu/cv1800b/dram.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
+ */
+
+#include <fdtdec.h>
+#include <init.h>
+#include <asm/global_data.h>
+#include <linux/sizes.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ return fdtdec_setup_mem_size_base();
+}
+
+int dram_init_banksize(void)
+{
+ return fdtdec_setup_memory_banksize();
+}
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S
index 6cecadf..a9e1935 100644
--- a/arch/riscv/cpu/start.S
+++ b/arch/riscv/cpu/start.S
@@ -418,6 +418,7 @@
*/
mv a0, s3 /* gd_t */
mv a1, s4 /* dest_addr */
+ mv s0, zero /* fp == NULL */
/*
* jump to it ...
diff --git a/arch/riscv/dts/cv1800b-milkv-duo.dts b/arch/riscv/dts/cv1800b-milkv-duo.dts
index 3af9e34..94e64dd 100644
--- a/arch/riscv/dts/cv1800b-milkv-duo.dts
+++ b/arch/riscv/dts/cv1800b-milkv-duo.dts
@@ -33,6 +33,14 @@
clock-frequency = <25000000>;
};
+&sdhci0 {
+ status = "okay";
+ bus-width = <4>;
+ no-1-8-v;
+ no-mmc;
+ no-sdio;
+};
+
&uart0 {
status = "okay";
};
diff --git a/arch/riscv/dts/cv1800b.dtsi b/arch/riscv/dts/cv1800b.dtsi
index 165e9e3..baf6418 100644
--- a/arch/riscv/dts/cv1800b.dtsi
+++ b/arch/riscv/dts/cv1800b.dtsi
@@ -16,3 +16,7 @@
&clint {
compatible = "sophgo,cv1800b-clint", "thead,c900-clint";
};
+
+&clk {
+ compatible = "sophgo,cv1800-clk";
+};
diff --git a/arch/riscv/dts/cv18xx.dtsi b/arch/riscv/dts/cv18xx.dtsi
index 2d6f4a4..ec99c4d 100644
--- a/arch/riscv/dts/cv18xx.dtsi
+++ b/arch/riscv/dts/cv18xx.dtsi
@@ -45,6 +45,13 @@
#clock-cells = <0>;
};
+ sdhci_clk: sdhci-clock {
+ compatible = "fixed-clock";
+ clock-frequency = <375000000>;
+ clock-output-names = "sdhci_clk";
+ #clock-cells = <0>;
+ };
+
soc {
compatible = "simple-bus";
interrupt-parent = <&plic>;
@@ -53,6 +60,12 @@
dma-noncoherent;
ranges;
+ clk: clock-controller@3002000 {
+ reg = <0x03002000 0x1000>;
+ clocks = <&osc>;
+ #clock-cells = <1>;
+ };
+
gpio0: gpio@3020000 {
compatible = "snps,dw-apb-gpio";
reg = <0x3020000 0x1000>;
@@ -175,6 +188,15 @@
status = "disabled";
};
+ sdhci0: mmc@4310000 {
+ compatible = "sophgo,cv1800b-dwcmshc";
+ reg = <0x4310000 0x1000>;
+ interrupts = <36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sdhci_clk>;
+ clock-names = "core";
+ status = "disabled";
+ };
+
plic: interrupt-controller@70000000 {
reg = <0x70000000 0x4000000>;
interrupts-extended = <&cpu0_intc 11>, <&cpu0_intc 9>;
diff --git a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
index f2c6bec..e11babc 100644
--- a/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
+++ b/arch/riscv/dts/jh7110-starfive-visionfive-2.dtsi
@@ -298,7 +298,7 @@
pinctrl-0 = <&mmc1_pins>;
no-sdio;
no-mmc;
- broken-cd;
+ cd-gpios = <&sysgpio 41 GPIO_ACTIVE_LOW>;
cap-sd-highspeed;
post-power-on-delay-ms = <200>;
status = "okay";
diff --git a/arch/riscv/dts/xilinx-mbv32.dts b/arch/riscv/dts/xilinx-mbv32.dts
index 94e42c2..48ee115 100644
--- a/arch/riscv/dts/xilinx-mbv32.dts
+++ b/arch/riscv/dts/xilinx-mbv32.dts
@@ -8,6 +8,9 @@
*/
/dts-v1/;
+
+#include "binman.dtsi"
+
/ {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/riscv/include/asm/arch-jh7110/eeprom.h b/arch/riscv/include/asm/arch-jh7110/eeprom.h
index d2776d5..62d184a 100644
--- a/arch/riscv/include/asm/arch-jh7110/eeprom.h
+++ b/arch/riscv/include/asm/arch-jh7110/eeprom.h
@@ -12,4 +12,13 @@
u8 get_pcb_revision_from_eeprom(void);
u32 get_ddr_size_from_eeprom(void);
+/**
+ * get_product_id_from_eeprom - get product ID string
+ *
+ * A string like "VF7110A1-2228-D008E000-00000001" is returned.
+ *
+ * Return: product ID string
+ */
+const char *get_product_id_from_eeprom(void);
+
#endif /* _ASM_RISCV_EEPROM_H */
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 9a05b66..0b2c88d 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -6,7 +6,7 @@
# Copyright (C) 2017 Andes Technology Corporation
# Rick Chen, Andes Technology Corporation <rick@andestech.com>
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o
obj-$(CONFIG_CMD_GO) += boot.o
obj-y += cache.o
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index a26ccc7..7350e2c 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -60,6 +60,40 @@
#endif
}
+#if defined(CONFIG_FRAMEPOINTER) || defined(CONFIG_SPL_FRAMEPOINTER)
+static void show_backtrace(struct pt_regs *regs)
+{
+ uintptr_t *fp = (uintptr_t *)regs->s0;
+ unsigned count = 0;
+ ulong ra;
+
+ printf("backtrace:\n");
+
+ /* there are a few entry points where the s0 register is
+ * set to gd, so to avoid changing those, just abort if
+ * the value is the same */
+ while (fp != NULL && fp != (uintptr_t *)gd) {
+ ra = fp[-1];
+ printf("backtrace %2d: FP: " REG_FMT " RA: " REG_FMT,
+ count, (ulong)fp, ra);
+
+ if (gd && gd->flags & GD_FLG_RELOC)
+ printf(" - RA: " REG_FMT " reloc adjusted\n",
+ ra - gd->reloc_off);
+ else
+ printf("\n");
+
+ fp = (uintptr_t *)fp[-2];
+ count++;
+ }
+}
+#else
+static void show_backtrace(struct pt_regs *regs)
+{
+ printf("No backtrace support enabled\n");
+}
+#endif
+
/**
* instr_len() - get instruction length
*
@@ -131,6 +165,7 @@
epc - gd->reloc_off, regs->ra - gd->reloc_off);
show_regs(regs);
+ show_backtrace(regs);
show_code(epc);
show_efi_loaded_images(epc);
panic("\n");
diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
index 0ce77de..1c8353d 100644
--- a/arch/sandbox/Kconfig
+++ b/arch/sandbox/Kconfig
@@ -58,10 +58,15 @@
bool "Reset on crash"
help
If an illegal instruction or an illegal memory access occurs, the
- sandbox by default writes a crash dump and exits. If you set this
- flag, the sandbox is reset instead. This may be useful when running
- test suites like the UEFI self certification test which continue
- with the next test after a crash.
+ sandbox exits with an error by default.
+
+ If the u-boot binary is invoked with --signals (or -S), U-Boot will
+ handle the signal writing a crash dump before exiting.
+
+ If you additionally set the CONFIG_SANDBOX_CRASH_RESET flag, the
+ sandbox is reset after writing the crash dump. This may be useful
+ when running test suites like the UEFI self certification test which
+ continue with the next test after a crash.
config SANDBOX_BITS_PER_LONG
int
diff --git a/arch/sandbox/cpu/eth-raw-os.c b/arch/sandbox/cpu/eth-raw-os.c
index 92c35ae..39ea3b3 100644
--- a/arch/sandbox/cpu/eth-raw-os.c
+++ b/arch/sandbox/cpu/eth-raw-os.c
@@ -105,7 +105,12 @@
/* Make the socket non-blocking */
flags = fcntl(priv->sd, F_GETFL, 0);
- fcntl(priv->sd, F_SETFL, flags | O_NONBLOCK);
+ ret = fcntl(priv->sd, F_SETFL, flags | O_NONBLOCK);
+ if (ret == -1) {
+ printf("Failed to make socket non-blocking: %d %s\n", errno,
+ strerror(errno));
+ return -errno;
+ }
/* Enable promiscuous mode to receive responses meant for us */
mr.mr_ifindex = device->sll_ifindex;
@@ -172,7 +177,12 @@
/* Make the socket non-blocking */
flags = fcntl(priv->sd, F_GETFL, 0);
- fcntl(priv->sd, F_SETFL, flags | O_NONBLOCK);
+ ret = fcntl(priv->sd, F_SETFL, flags | O_NONBLOCK);
+ if (ret == -1) {
+ printf("Failed to make socket non-blocking: %d %s\n", errno,
+ strerror(errno));
+ return -errno;
+ }
/* Include the UDP/IP headers on send and receive */
ret = setsockopt(priv->sd, IPPROTO_IP, IP_HDRINCL, &one,
diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile
index a2bc5a7..c4924b2 100644
--- a/arch/sandbox/lib/Makefile
+++ b/arch/sandbox/lib/Makefile
@@ -7,5 +7,5 @@
obj-y += fdt_fixup.o interrupts.o sections.o
obj-$(CONFIG_PCI) += pci_io.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
obj-$(CONFIG_CMD_BOOTZ) += bootm.o
diff --git a/arch/sandbox/lib/bootm.c b/arch/sandbox/lib/bootm.c
index 8dbcd9f..44ba8b5 100644
--- a/arch/sandbox/lib/bootm.c
+++ b/arch/sandbox/lib/bootm.c
@@ -85,5 +85,7 @@
int booti_setup(ulong image, ulong *relocated_addr, ulong *size,
bool force_reloc)
{
- return 0;
+ log_err("Booting is not supported on the sandbox.\n");
+
+ return 1;
}
diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile
index e7520a3..8c3c302 100644
--- a/arch/sh/lib/Makefile
+++ b/arch/sh/lib/Makefile
@@ -6,7 +6,7 @@
extra-y += start.o
obj-y += board.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
obj-y += time.o
obj-$(CONFIG_CMD_SH_ZIMAGEBOOT) += zimageboot.o
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 99e59d9..23a1e21 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -723,6 +723,14 @@
hex
default 0x10000
+config X86_HARDFP
+ bool "Support hardware floating point"
+ help
+ U-Boot generally does not make use of floating point. Where this is
+ needed, it can be enabled using this option. This adjusts the
+ start-up code for 64-bit mode and changes the compiler options for
+ 64-bit to enable SSE.
+
config HAVE_ITSS
bool "Enable ITSS"
help
@@ -1053,4 +1061,12 @@
display, memory and build information. It is stored in
struct sysinfo_t after parsing by get_coreboot_info().
+config ZBOOT
+ bool "Support the zImage format"
+ default y
+ help
+ Enable this to support booting the x86-specific zImage format. This
+ uses a special, binary format containing information about the Linux
+ format to boot.
+
endmenu
diff --git a/arch/x86/config.mk b/arch/x86/config.mk
index 26ec1af..2e3a711 100644
--- a/arch/x86/config.mk
+++ b/arch/x86/config.mk
@@ -27,9 +27,13 @@
PLATFORM_CPPFLAGS += -march=i386 -m32
else
PLATFORM_CPPFLAGS += $(if $(CONFIG_SPL_BUILD),,-fpic) -fno-common -march=core2 -m64
+
+ifndef CONFIG_X86_HARDFP
PLATFORM_CPPFLAGS += -mno-mmx -mno-sse
endif
+endif # IS_32BIT
+
PLATFORM_RELFLAGS += -fdata-sections -ffunction-sections -fvisibility=hidden
KBUILD_LDFLAGS += -Bsymbolic -Bsymbolic-functions
diff --git a/arch/x86/cpu/x86_64/cpu.c b/arch/x86/cpu/x86_64/cpu.c
index 2647bff..5ea746e 100644
--- a/arch/x86/cpu/x86_64/cpu.c
+++ b/arch/x86/cpu/x86_64/cpu.c
@@ -10,6 +10,7 @@
#include <init.h>
#include <asm/cpu.h>
#include <asm/global_data.h>
+#include <asm/processor-flags.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -39,11 +40,22 @@
return 0;
}
+/* enable SSE features for hardware floating point */
+static void setup_sse_features(void)
+{
+ asm ("mov %%cr4, %%rax\n" \
+ "or %0, %%rax\n" \
+ "mov %%rax, %%cr4\n" \
+ : : "i" (X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT) : "eax");
+}
+
int x86_cpu_reinit_f(void)
{
/* set the vendor to Intel so that native_calibrate_tsc() works */
gd->arch.x86_vendor = X86_VENDOR_INTEL;
gd->arch.has_mtrr = true;
+ if (IS_ENABLED(CONFIG_X86_HARDFP))
+ setup_sse_features();
return 0;
}
diff --git a/arch/x86/dts/coreboot.dts b/arch/x86/dts/coreboot.dts
index dfce7c2..b867468 100644
--- a/arch/x86/dts/coreboot.dts
+++ b/arch/x86/dts/coreboot.dts
@@ -46,6 +46,16 @@
compatible = "coreboot-fb";
};
+ bootstd {
+ compatible = "u-boot,boot-std";
+
+ theme {
+ font-size = <30>;
+ menu-inset = <3>;
+ menuitem-gap-y = <1>;
+ };
+ };
+
sysinfo {
compatible = "coreboot,sysinfo";
};
diff --git a/arch/x86/include/asm/zimage.h b/arch/x86/include/asm/zimage.h
index 655675b..8b54260 100644
--- a/arch/x86/include/asm/zimage.h
+++ b/arch/x86/include/asm/zimage.h
@@ -30,6 +30,78 @@
#define BZIMAGE_LOAD_ADDR 0x100000
#define ZIMAGE_LOAD_ADDR 0x10000
+enum {
+ ZBOOT_STATE_START = BIT(0),
+ ZBOOT_STATE_LOAD = BIT(1),
+ ZBOOT_STATE_SETUP = BIT(2),
+ ZBOOT_STATE_INFO = BIT(3),
+ ZBOOT_STATE_GO = BIT(4),
+
+ /* This one doesn't execute automatically, so stop the count before 5 */
+ ZBOOT_STATE_DUMP = BIT(5),
+ ZBOOT_STATE_COUNT = 5,
+};
+
+/**
+ * struct zboot_state - Current state of the boot
+ *
+ * @bzimage_addr: Address of the bzImage to boot, or 0 if the image has already
+ * been loaded and does not exist (as a cohesive whole) in memory
+ * @bzimage_size: Size of the bzImage, or 0 to detect this
+ * @initrd_addr: Address of the initial ramdisk, or 0 if none
+ * @initrd_size: Size of the initial ramdisk, or 0 if none
+ * @load_address: Address where the bzImage is moved before booting, either
+ * BZIMAGE_LOAD_ADDR or ZIMAGE_LOAD_ADDR
+ * This is set up when loading the zimage
+ * @base_ptr: Pointer to the boot parameters, typically at address
+ * DEFAULT_SETUP_BASE
+ * This is set up when loading the zimage
+ * @cmdline: Environment variable containing the 'override' command line, or
+ * NULL to use the one in the setup block
+ */
+struct zboot_state {
+ ulong bzimage_addr;
+ ulong bzimage_size;
+ ulong initrd_addr;
+ ulong initrd_size;
+ ulong load_address;
+ struct boot_params *base_ptr;
+ const char *cmdline;
+};
+
+extern struct zboot_state state;
+
+/**
+ * zimage_dump() - Dump information about a zimage
+ *
+ * @base_ptr: Pointer to the boot parameters
+ * @show_cmdline: true to show the kernel command line
+ */
+void zimage_dump(struct boot_params *base_ptr, bool show_cmdline);
+
+/**
+ * zboot_load() - Load a zimage
+ *
+ * Load the zimage into the correct place
+ *
+ * Return: 0 if OK, -ve on error
+ */
+int zboot_load(void);
+
+/**
+ * zboot_setup() - Set up the zboot image reeady for booting
+ *
+ * Return: 0 if OK, -ve on error
+ */
+int zboot_setup(void);
+
+/**
+ * zboot_go() - Start the image
+ *
+ * Return: 0 if OK, -ve on error
+ */
+int zboot_go(void);
+
/**
* load_zimage() - Load a zImage or bzImage
*
@@ -62,4 +134,29 @@
int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
ulong initrd_addr, ulong initrd_size, ulong cmdline_force);
+/**
+ * zboot_start() - Prepare to boot a zimage
+ *
+ * Record information about a zimage so it can be booted
+ *
+ * @bzimage_addr: Address of the bzImage to boot
+ * @bzimage_size: Size of the bzImage, or 0 to detect this
+ * @initrd_addr: Address of the initial ramdisk, or 0 if none
+ * @initrd_size: Size of the initial ramdisk, or 0 if none
+ * @base_addr: If non-zero, this indicates that the boot parameters have already
+ * been loaded by the caller to this address, so the load_zimage() call
+ * in zboot_load() will be skipped when booting
+ * @cmdline: Environment variable containing the 'override' command line, or
+ * NULL to use the one in the setup block
+ */
+void zboot_start(ulong bzimage_addr, ulong bzimage_size, ulong initrd_addr,
+ ulong initrd_size, ulong base_addr, const char *cmdline);
+
+/**
+ * zboot_info() - Show simple info about a zimage
+ *
+ * Shows wherer the kernel was loaded and also the setup base
+ */
+void zboot_info(void);
+
#endif
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 90a7618..94aa335 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -16,7 +16,7 @@
endif
ifndef CONFIG_SPL_BUILD
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
endif
obj-y += cmd_boot.o
obj-$(CONFIG_$(SPL_)COREBOOT_SYSINFO) += coreboot/
@@ -48,7 +48,7 @@
endif
obj-y += tables.o
ifndef CONFIG_SPL_BUILD
-obj-$(CONFIG_CMD_ZBOOT) += zimage.o
+obj-$(CONFIG_ZBOOT) += zimage.o
endif
obj-$(CONFIG_USE_HOB) += hob.o
ifndef CONFIG_TPL_BUILD
diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c
index c15f11f..4e4cf18 100644
--- a/arch/x86/lib/spl.c
+++ b/arch/x86/lib/spl.c
@@ -283,7 +283,7 @@
{
int ret;
- printf("Jumping to 64-bit U-Boot: Note many features are missing\n");
+ printf("Jumping to 64-bit U-Boot\n");
ret = cpu_jump_to_64bit_uboot(spl_image->entry_point);
debug("ret=%d\n", ret);
hang();
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index a41e1cc..d740387 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -56,41 +56,8 @@
#define COMMAND_LINE_SIZE 2048
-/**
- * struct zboot_state - Current state of the boot
- *
- * @bzimage_addr: Address of the bzImage to boot
- * @bzimage_size: Size of the bzImage, or 0 to detect this
- * @initrd_addr: Address of the initial ramdisk, or 0 if none
- * @initrd_size: Size of the initial ramdisk, or 0 if none
- * @load_address: Address where the bzImage is moved before booting, either
- * BZIMAGE_LOAD_ADDR or ZIMAGE_LOAD_ADDR
- * @base_ptr: Pointer to the boot parameters, typically at address
- * DEFAULT_SETUP_BASE
- * @cmdline: Environment variable containing the 'override' command line, or
- * NULL to use the one in the setup block
- */
-struct zboot_state {
- ulong bzimage_addr;
- ulong bzimage_size;
- ulong initrd_addr;
- ulong initrd_size;
- ulong load_address;
- struct boot_params *base_ptr;
- char *cmdline;
-} state;
-
-enum {
- ZBOOT_STATE_START = BIT(0),
- ZBOOT_STATE_LOAD = BIT(1),
- ZBOOT_STATE_SETUP = BIT(2),
- ZBOOT_STATE_INFO = BIT(3),
- ZBOOT_STATE_GO = BIT(4),
-
- /* This one doesn't execute automatically, so stop the count before 5 */
- ZBOOT_STATE_DUMP = BIT(5),
- ZBOOT_STATE_COUNT = 5,
-};
+/* Current state of the boot */
+struct zboot_state state;
static void build_command_line(char *command_line, int auto_boot)
{
@@ -400,56 +367,10 @@
return 0;
}
-static int do_zboot_start(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
-{
- const char *s;
-
- memset(&state, '\0', sizeof(state));
- if (argc >= 2) {
- /* argv[1] holds the address of the bzImage */
- s = argv[1];
- } else {
- s = env_get("fileaddr");
- }
-
- if (s)
- state.bzimage_addr = hextoul(s, NULL);
-
- if (argc >= 3) {
- /* argv[2] holds the size of the bzImage */
- state.bzimage_size = hextoul(argv[2], NULL);
- }
-
- if (argc >= 4)
- state.initrd_addr = hextoul(argv[3], NULL);
- if (argc >= 5)
- state.initrd_size = hextoul(argv[4], NULL);
- if (argc >= 6) {
- /*
- * When the base_ptr is passed in, we assume that the image is
- * already loaded at the address given by argv[1] and therefore
- * the original bzImage is somewhere else, or not accessible.
- * In any case, we don't need access to the bzImage since all
- * the processing is assumed to be done.
- *
- * So set the base_ptr to the given address, use this arg as the
- * load address and set bzimage_addr to 0 so we know that it
- * cannot be proceesed (or processed again).
- */
- state.base_ptr = (void *)hextoul(argv[5], NULL);
- state.load_address = state.bzimage_addr;
- state.bzimage_addr = 0;
- }
- if (argc >= 7)
- state.cmdline = env_get(argv[6]);
-
- return 0;
-}
-
-static int zboot_load(void)
+int zboot_load(void)
{
struct boot_params *base_ptr;
+ int ret;
if (state.base_ptr) {
struct boot_params *from = (struct boot_params *)state.base_ptr;
@@ -469,23 +390,16 @@
}
state.base_ptr = base_ptr;
- return 0;
-}
-
-static int do_zboot_load(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
-{
- if (zboot_load())
- return CMD_RET_FAILURE;
-
- if (env_set_hex("zbootbase", map_to_sysmem(state.base_ptr)) ||
- env_set_hex("zbootaddr", state.load_address))
- return CMD_RET_FAILURE;
+ ret = env_set_hex("zbootbase", map_to_sysmem(state.base_ptr));
+ if (!ret)
+ ret = env_set_hex("zbootaddr", state.load_address);
+ if (ret)
+ return ret;
return 0;
}
-static int zboot_setup(void)
+int zboot_setup(void)
{
struct boot_params *base_ptr = state.base_ptr;
int ret;
@@ -499,33 +413,7 @@
return 0;
}
-static int do_zboot_setup(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
-{
- struct boot_params *base_ptr = state.base_ptr;
-
- if (!base_ptr) {
- printf("base is not set: use 'zboot load' first\n");
- return CMD_RET_FAILURE;
- }
- if (zboot_setup()) {
- puts("Setting up boot parameters failed ...\n");
- return CMD_RET_FAILURE;
- }
-
- return 0;
-}
-
-static int do_zboot_info(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
-{
- printf("Kernel loaded at %08lx, setup_base=%p\n",
- state.load_address, state.base_ptr);
-
- return 0;
-}
-
-static int zboot_go(void)
+int zboot_go(void)
{
struct boot_params *params = state.base_ptr;
struct setup_header *hdr = ¶ms->hdr;
@@ -549,35 +437,12 @@
return ret;
}
-static int do_zboot_go(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
+int zboot_run(ulong addr, ulong size, ulong initrd, ulong initrd_size,
+ ulong base, char *cmdline)
{
int ret;
- ret = zboot_go();
- printf("Kernel returned! (err=%d)\n", ret);
-
- return CMD_RET_FAILURE;
-}
-
-int zboot_start(ulong addr, ulong size, ulong initrd, ulong initrd_size,
- ulong base, char *cmdline)
-{
- int ret;
-
- memset(&state, '\0', sizeof(state));
-
- if (base) {
- state.base_ptr = map_sysmem(base, 0);
- state.load_address = addr;
- } else {
- state.bzimage_addr = addr;
- }
- state.bzimage_size = size;
- state.initrd_addr = initrd;
- state.initrd_size = initrd_size;
- state.cmdline = cmdline;
-
+ zboot_start(addr, size, initrd, initrd_size, base, cmdline);
ret = zboot_load();
if (ret)
return log_msg_ret("ld", ret);
@@ -586,7 +451,7 @@
return log_msg_ret("set", ret);
ret = zboot_go();
if (ret)
- return log_msg_ret("set", ret);
+ return log_msg_ret("go", ret);
return -EFAULT;
}
@@ -776,97 +641,25 @@
print_num("Kernel info offset", hdr->kernel_info_offset);
}
-static int do_zboot_dump(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[])
+void zboot_start(ulong bzimage_addr, ulong bzimage_size, ulong initrd_addr,
+ ulong initrd_size, ulong base_addr, const char *cmdline)
{
- struct boot_params *base_ptr = state.base_ptr;
-
- if (argc > 1)
- base_ptr = (void *)hextoul(argv[1], NULL);
- if (!base_ptr) {
- printf("No zboot setup_base\n");
- return CMD_RET_FAILURE;
- }
- zimage_dump(base_ptr, true);
-
- return 0;
-}
-
-/* Note: This defines the complete_zboot() function */
-U_BOOT_SUBCMDS(zboot,
- U_BOOT_CMD_MKENT(start, 8, 1, do_zboot_start, "", ""),
- U_BOOT_CMD_MKENT(load, 1, 1, do_zboot_load, "", ""),
- U_BOOT_CMD_MKENT(setup, 1, 1, do_zboot_setup, "", ""),
- U_BOOT_CMD_MKENT(info, 1, 1, do_zboot_info, "", ""),
- U_BOOT_CMD_MKENT(go, 1, 1, do_zboot_go, "", ""),
- U_BOOT_CMD_MKENT(dump, 2, 1, do_zboot_dump, "", ""),
-)
-
-int do_zboot_states(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[], int state_mask)
-{
- int i;
-
- for (i = 0; i < ZBOOT_STATE_COUNT; i++) {
- struct cmd_tbl *cmd = &zboot_subcmds[i];
- int mask = 1 << i;
- int ret;
+ memset(&state, '\0', sizeof(state));
- if (mask & state_mask) {
- ret = cmd->cmd(cmd, flag, argc, argv);
- if (ret)
- return ret;
- }
+ state.bzimage_size = bzimage_size;
+ state.initrd_addr = initrd_addr;
+ state.initrd_size = initrd_size;
+ if (base_addr) {
+ state.base_ptr = map_sysmem(base_addr, 0);
+ state.load_address = bzimage_addr;
+ } else {
+ state.bzimage_addr = bzimage_addr;
}
-
- return 0;
+ state.cmdline = cmdline;
}
-int do_zboot_parent(struct cmd_tbl *cmdtp, int flag, int argc,
- char *const argv[], int *repeatable)
+void zboot_info(void)
{
- /* determine if we have a sub command */
- if (argc > 1) {
- char *endp;
-
- hextoul(argv[1], &endp);
- /*
- * endp pointing to nul means that argv[1] was just a valid
- * number, so pass it along to the normal processing
- */
- if (*endp)
- return do_zboot(cmdtp, flag, argc, argv, repeatable);
- }
-
- do_zboot_states(cmdtp, flag, argc, argv, ZBOOT_STATE_START |
- ZBOOT_STATE_LOAD | ZBOOT_STATE_SETUP |
- ZBOOT_STATE_INFO | ZBOOT_STATE_GO);
-
- return CMD_RET_FAILURE;
+ printf("Kernel loaded at %08lx, setup_base=%p\n",
+ state.load_address, state.base_ptr);
}
-
-U_BOOT_CMDREP_COMPLETE(
- zboot, 8, do_zboot_parent, "Boot bzImage",
- "[addr] [size] [initrd addr] [initrd size] [setup] [cmdline]\n"
- " addr - The optional starting address of the bzimage.\n"
- " If not set it defaults to the environment\n"
- " variable \"fileaddr\".\n"
- " size - The optional size of the bzimage. Defaults to\n"
- " zero.\n"
- " initrd addr - The address of the initrd image to use, if any.\n"
- " initrd size - The size of the initrd image to use, if any.\n"
- " setup - The address of the kernel setup region, if this\n"
- " is not at addr\n"
- " cmdline - Environment variable containing the kernel\n"
- " command line, to override U-Boot's normal\n"
- " cmdline generation\n"
- "\n"
- "Sub-commands to do part of the zboot sequence:\n"
- "\tstart [addr [arg ...]] - specify arguments\n"
- "\tload - load OS image\n"
- "\tsetup - set up table\n"
- "\tinfo - show summary info\n"
- "\tgo - start OS\n"
- "\tdump [addr] - dump info (optional address of boot params)",
- complete_zboot
-);
diff --git a/arch/xtensa/lib/Makefile b/arch/xtensa/lib/Makefile
index ad4fe32..bb9157f 100644
--- a/arch/xtensa/lib/Makefile
+++ b/arch/xtensa/lib/Makefile
@@ -3,6 +3,6 @@
# (C) Copyright 2007 - 2013 Tensilica Inc.
# (C) Copyright 2014 - 2016 Cadence Design Systems Inc.
-obj-$(CONFIG_CMD_BOOTM) += bootm.o
+obj-$(CONFIG_BOOTM) += bootm.o
obj-y += cache.o misc.o relocate.o time.o
diff --git a/board/emulation/qemu-riscv/qemu-riscv.c b/board/emulation/qemu-riscv/qemu-riscv.c
index 181abbb..173245b 100644
--- a/board/emulation/qemu-riscv/qemu-riscv.c
+++ b/board/emulation/qemu-riscv/qemu-riscv.c
@@ -31,12 +31,6 @@
int board_init(void)
{
- /*
- * Make sure virtio bus is enumerated so that peripherals
- * on the virtio bus can be discovered by their drivers
- */
- virtio_init();
-
return 0;
}
@@ -46,6 +40,12 @@
if (CONFIG_IS_ENABLED(USB_KEYBOARD))
usb_init();
+ /*
+ * Make sure virtio bus is enumerated so that peripherals
+ * on the virtio bus can be discovered by their drivers
+ */
+ virtio_init();
+
return 0;
}
diff --git a/board/emulation/qemu-x86/Kconfig b/board/emulation/qemu-x86/Kconfig
index 9a06118..b2a4e08 100644
--- a/board/emulation/qemu-x86/Kconfig
+++ b/board/emulation/qemu-x86/Kconfig
@@ -18,7 +18,8 @@
select X86_RESET_VECTOR
select QEMU
select QFW_PIO if CMD_QFW
- select BOARD_ROMSIZE_KB_1024
+ select BOARD_ROMSIZE_KB_1024 if TARGET_QEMU_X86
+ select BOARD_ROMSIZE_KB_2048 if TARGET_QEMU_X86_64
imply VIRTIO_PCI
imply VIRTIO_NET
imply VIRTIO_BLK
diff --git a/board/phytec/phycore_am62x/phycore-am62x.c b/board/phytec/phycore_am62x/phycore-am62x.c
index 91a2401..618b4c3 100644
--- a/board/phytec/phycore_am62x/phycore-am62x.c
+++ b/board/phytec/phycore_am62x/phycore-am62x.c
@@ -57,3 +57,67 @@
MCU_CTRL_DEVICE_CLKOUT_32K_CTRL);
}
#endif
+
+#if IS_ENABLED(CONFIG_ENV_IS_IN_FAT) || IS_ENABLED(CONFIG_ENV_IS_IN_MMC)
+int mmc_get_env_dev(void)
+{
+ u32 boot_device = get_boot_device();
+
+ switch (boot_device) {
+ case BOOT_DEVICE_MMC1:
+ return 0;
+ case BOOT_DEVICE_MMC2:
+ return 1;
+ };
+
+ return CONFIG_SYS_MMC_ENV_DEV;
+}
+#endif
+
+enum env_location env_get_location(enum env_operation op, int prio)
+{
+ u32 boot_device = get_boot_device();
+
+ if (prio)
+ return ENVL_UNKNOWN;
+
+ switch (boot_device) {
+ case BOOT_DEVICE_MMC1:
+ case BOOT_DEVICE_MMC2:
+ if (CONFIG_IS_ENABLED(ENV_IS_IN_FAT))
+ return ENVL_FAT;
+ if (CONFIG_IS_ENABLED(ENV_IS_IN_MMC))
+ return ENVL_MMC;
+ case BOOT_DEVICE_SPI:
+ if (CONFIG_IS_ENABLED(ENV_IS_IN_SPI_FLASH))
+ return ENVL_SPI_FLASH;
+ default:
+ return ENVL_NOWHERE;
+ };
+}
+
+#if IS_ENABLED(CONFIG_BOARD_LATE_INIT)
+int board_late_init(void)
+{
+ u32 boot_device = get_boot_device();
+
+ switch (boot_device) {
+ case BOOT_DEVICE_MMC1:
+ env_set_ulong("mmcdev", 0);
+ env_set("boot", "mmc");
+ break;
+ case BOOT_DEVICE_MMC2:
+ env_set_ulong("mmcdev", 1);
+ env_set("boot", "mmc");
+ break;
+ case BOOT_DEVICE_SPI:
+ env_set("boot", "spi");
+ break;
+ case BOOT_DEVICE_ETHERNET:
+ env_set("boot", "net");
+ break;
+ };
+
+ return 0;
+}
+#endif
diff --git a/board/sophgo/milkv_duo/Kconfig b/board/sophgo/milkv_duo/Kconfig
index 2a458f2..040a748 100644
--- a/board/sophgo/milkv_duo/Kconfig
+++ b/board/sophgo/milkv_duo/Kconfig
@@ -7,7 +7,7 @@
default "sophgo"
config SYS_CPU
- default "generic"
+ default "cv1800b"
config SYS_CONFIG_NAME
default "milkv_duo"
@@ -23,6 +23,6 @@
config BOARD_SPECIFIC_OPTIONS
def_bool y
- select GENERIC_RISCV
+ select SOPHGO_CV1800B
endif
diff --git a/board/starfive/visionfive2/spl.c b/board/starfive/visionfive2/spl.c
index 1b49945..45848db 100644
--- a/board/starfive/visionfive2/spl.c
+++ b/board/starfive/visionfive2/spl.c
@@ -4,7 +4,6 @@
* Author: Yanhong Wang<yanhong.wang@starfivetech.com>
*/
-#include <common.h>
#include <asm/arch/eeprom.h>
#include <asm/arch/gpio.h>
#include <asm/arch/regs.h>
@@ -27,6 +26,26 @@
const char *value;
};
+static const struct starfive_vf2_pro milk_v_mars[] = {
+ {"/soc/ethernet@16030000", "starfive,tx-use-rgmii-clk", NULL},
+ {"/soc/ethernet@16040000", "starfive,tx-use-rgmii-clk", NULL},
+
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "motorcomm,tx-clk-adj-enabled", NULL},
+ {"/soc/ethernet@16030000/mdio/ethernet-phy@0",
+ "motorcomm,tx-clk-100-inverted", NULL},
+ {"/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"},
+};
+
static const struct starfive_vf2_pro starfive_vera[] = {
{"/soc/ethernet@16030000/mdio/ethernet-phy@0", "rx-internal-delay-ps",
"1900"},
@@ -67,6 +86,49 @@
"tx-internal-delay-ps", "0"},
};
+void spl_fdt_fixup_mars(void *fdt)
+{
+ static const char compat[] = "milkv,mars\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",
+ "Milk-V Mars");
+
+ /* gmac0 */
+ offset = fdt_path_offset(fdt, "/soc/clock-controller@17000000");
+ phandle = fdt_get_phandle(fdt, offset);
+ offset = fdt_path_offset(fdt, "/soc/ethernet@16030000");
+
+ fdt_setprop_u32(fdt, offset, "assigned-clocks", phandle);
+ fdt_appendprop_u32(fdt, offset, "assigned-clocks", JH7110_AONCLK_GMAC0_TX);
+ fdt_setprop_u32(fdt, offset, "assigned-clock-parents", phandle);
+ fdt_appendprop_u32(fdt, offset, "assigned-clock-parents",
+ JH7110_AONCLK_GMAC0_RMII_RTX);
+
+ /* gmac1 */
+ fdt_setprop_string(fdt, fdt_path_offset(fdt, "/soc/ethernet@16040000"),
+ "status", "disabled");
+
+ for (i = 0; i < ARRAY_SIZE(milk_v_mars); i++) {
+ offset = fdt_path_offset(fdt, milk_v_mars[i].path);
+
+ if (milk_v_mars[i].value)
+ ret = fdt_setprop_u32(fdt, offset, milk_v_mars[i].name,
+ dectoul(milk_v_mars[i].value, NULL));
+ else
+ ret = fdt_setprop_empty(fdt, offset, milk_v_mars[i].name);
+
+ if (ret) {
+ pr_err("%s set prop %s fail.\n", __func__, milk_v_mars[i].name);
+ break;
+ }
+ }
+}
+
void spl_fdt_fixup_version_a(void *fdt)
{
static const char compat[] = "starfive,visionfive-2-v1.2a\0starfive,jh7110";
@@ -167,22 +229,34 @@
void spl_perform_fixups(struct spl_image_info *spl_image)
{
u8 version;
+ const char *product_id;
- version = get_pcb_revision_from_eeprom();
- switch (version) {
- case 'a':
- case 'A':
- spl_fdt_fixup_version_a(spl_image->fdt_addr);
- break;
+ product_id = get_product_id_from_eeprom();
+ if (!product_id) {
+ pr_err("Can't read EEPROM\n");
+ return;
+ }
+ if (!strncmp(product_id, "MARS", 4)) {
+ spl_fdt_fixup_mars(spl_image->fdt_addr);
+ } else if (!strncmp(product_id, "VF7110", 6)) {
+ version = get_pcb_revision_from_eeprom();
+ switch (version) {
+ case 'a':
+ case 'A':
+ spl_fdt_fixup_version_a(spl_image->fdt_addr);
+ break;
- case 'b':
- case 'B':
- default:
- spl_fdt_fixup_version_b(spl_image->fdt_addr);
+ case 'b':
+ case 'B':
+ default:
+ spl_fdt_fixup_version_b(spl_image->fdt_addr);
break;
+ };
+ } else {
+ pr_err("Unknown product %s\n", product_id);
};
- /* Update the memory size which read form eeprom or DT */
+ /* Update the memory size which read from eeprom or DT */
fdt_fixup_memory(spl_image->fdt_addr, 0x40000000, gd->ram_size);
}
diff --git a/board/starfive/visionfive2/starfive_visionfive2.c b/board/starfive/visionfive2/starfive_visionfive2.c
index 78e118d..a86bca5 100644
--- a/board/starfive/visionfive2/starfive_visionfive2.c
+++ b/board/starfive/visionfive2/starfive_visionfive2.c
@@ -4,11 +4,11 @@
* Author: Yanhong Wang<yanhong.wang@starfivetech.com>
*/
-#include <common.h>
#include <cpu_func.h>
#include <dm.h>
#include <fdt_support.h>
#include <env.h>
+#include <log.h>
#include <asm/arch/eeprom.h>
#include <asm/io.h>
#include <asm/sections.h>
@@ -17,6 +17,8 @@
DECLARE_GLOBAL_DATA_PTR;
#define JH7110_L2_PREFETCHER_BASE_ADDR 0x2030000
#define JH7110_L2_PREFETCHER_HART_OFFSET 0x2000
+#define FDTFILE_MILK_V_MARS \
+ "starfive/jh7110-milkv-mars.dtb"
#define FDTFILE_VISIONFIVE2_1_2A \
"starfive/jh7110-starfive-visionfive-2-v1.2a.dtb"
#define FDTFILE_VISIONFIVE2_1_3B \
@@ -48,20 +50,38 @@
{
u8 version;
const char *fdtfile;
+ const char *product_id;
- version = get_pcb_revision_from_eeprom();
- switch (version) {
- case 'a':
- case 'A':
- fdtfile = FDTFILE_VISIONFIVE2_1_2A;
- break;
+ fdtfile = env_get("fdtfile");
+ if (fdtfile)
+ return;
- case 'b':
- case 'B':
- default:
- fdtfile = FDTFILE_VISIONFIVE2_1_3B;
- break;
- };
+ product_id = get_product_id_from_eeprom();
+ if (!product_id) {
+ log_err("Can't read EEPROM\n");
+ return;
+ }
+ if (!strncmp(product_id, "MARS", 4)) {
+ fdtfile = FDTFILE_MILK_V_MARS;
+ } else if (!strncmp(product_id, "VF7110", 6)) {
+ version = get_pcb_revision_from_eeprom();
+
+ switch (version) {
+ case 'a':
+ case 'A':
+ fdtfile = FDTFILE_VISIONFIVE2_1_2A;
+ break;
+
+ case 'b':
+ case 'B':
+ default:
+ fdtfile = FDTFILE_VISIONFIVE2_1_3B;
+ break;
+ }
+ } else {
+ log_err("Unknown product\n");
+ return;
+ }
env_set("fdtfile", fdtfile);
}
diff --git a/board/starfive/visionfive2/visionfive2-i2c-eeprom.c b/board/starfive/visionfive2/visionfive2-i2c-eeprom.c
index c36de1a..ddef7d6 100644
--- a/board/starfive/visionfive2/visionfive2-i2c-eeprom.c
+++ b/board/starfive/visionfive2/visionfive2-i2c-eeprom.c
@@ -4,7 +4,6 @@
* Author: Yanhong Wang<yanhong.wang@starfivetech.com>
*/
-#include <common.h>
#include <command.h>
#include <env.h>
#include <i2c.h>
@@ -405,6 +404,14 @@
update_crc();
}
+const char *get_product_id_from_eeprom(void)
+{
+ if (read_eeprom())
+ return NULL;
+
+ return pbuf.eeprom.atom1.data.pstr;
+}
+
int do_mac(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
char *cmd;
diff --git a/board/toradex/verdin-am62/MAINTAINERS b/board/toradex/verdin-am62/MAINTAINERS
index 4e75980..3e30d1d 100644
--- a/board/toradex/verdin-am62/MAINTAINERS
+++ b/board/toradex/verdin-am62/MAINTAINERS
@@ -1,12 +1,8 @@
Verdin AM62
F: arch/arm/dts/k3-am625-verdin-lpddr4-1600MTs.dtsi
F: arch/arm/dts/k3-am625-verdin-r5.dts
-F: arch/arm/dts/k3-am625-verdin-wifi-dev.dts
F: arch/arm/dts/k3-am625-verdin-wifi-dev-binman.dtsi
F: arch/arm/dts/k3-am625-verdin-wifi-dev-u-boot.dtsi
-F: arch/arm/dts/k3-am62-verdin-dev.dtsi
-F: arch/arm/dts/k3-am62-verdin.dtsi
-F: arch/arm/dts/k3-am62-verdin-wifi.dtsi
F: board/toradex/verdin-am62/
F: configs/verdin-am62_a53_defconfig
F: configs/verdin-am62_r5_defconfig
diff --git a/board/xilinx/Kconfig b/board/xilinx/Kconfig
index 843198f..5c4ad8f 100644
--- a/board/xilinx/Kconfig
+++ b/board/xilinx/Kconfig
@@ -45,6 +45,7 @@
default 0x1000 if ARCH_VERSAL || ARCH_VERSAL_NET
default 0x8000 if MICROBLAZE
default 0x100000 if ARCH_ZYNQ || ARCH_ZYNQMP
+ default 0x23000000 if TARGET_XILINX_MBV
depends on OF_BOARD || OF_SEPARATE
help
Offset in the memory where the board configuration DTB is placed.
diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 9641ed3..b47d2d2 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -12,6 +12,7 @@
#include <env.h>
#include <image.h>
#include <init.h>
+#include <jffs2/load_kernel.h>
#include <lmb.h>
#include <log.h>
#include <asm/global_data.h>
@@ -20,6 +21,7 @@
#include <i2c.h>
#include <linux/sizes.h>
#include <malloc.h>
+#include <mtd_node.h>
#include "board.h"
#include <dm.h>
#include <i2c_eeprom.h>
@@ -43,7 +45,7 @@
.image_index = 1,
},
#endif
-#if defined(XILINX_UBOOT_IMAGE_GUID)
+#if defined(XILINX_UBOOT_IMAGE_GUID) && defined(CONFIG_SPL_FS_LOAD_PAYLOAD_NAME)
{
.image_type_id = XILINX_UBOOT_IMAGE_GUID,
.fw_name = u"XILINX-UBOOT",
@@ -103,10 +105,14 @@
for (i = 0; i < size; i++) {
byte = eeprom[i];
- /* Remove all non printable chars but ignore MAC address */
- if ((i < offsetof(struct xilinx_legacy_format, eth_mac) ||
- i >= offsetof(struct xilinx_legacy_format, unused1)) &&
- (byte < '!' || byte > '~')) {
+ /* Ignore MAC address */
+ if (i >= offsetof(struct xilinx_legacy_format, eth_mac) &&
+ i < offsetof(struct xilinx_legacy_format, unused1)) {
+ continue;
+ }
+
+ /* Remove all non printable chars */
+ if (byte < '!' || byte > '~') {
eeprom[i] = 0;
continue;
}
@@ -358,6 +364,14 @@
void *fdt_blob;
*err = 0;
+
+ if (IS_ENABLED(CONFIG_TARGET_XILINX_MBV)) {
+ fdt_blob = (void *)CONFIG_XILINX_OF_BOARD_DTB_ADDR;
+
+ if (fdt_magic(fdt_blob) == FDT_MAGIC)
+ return fdt_blob;
+ }
+
if (!IS_ENABLED(CONFIG_SPL_BUILD) &&
!IS_ENABLED(CONFIG_VERSAL_NO_DDR) &&
!IS_ENABLED(CONFIG_ZYNQMP_NO_DDR)) {
@@ -693,6 +707,13 @@
u8 buf[MAX_RAND_SIZE];
int nodeoffset, ret;
+ static const struct node_info nodes[] = {
+ { "arm,pl353-nand-r2p1", MTD_DEV_TYPE_NAND, },
+ };
+
+ if (IS_ENABLED(CONFIG_FDT_FIXUP_PARTITIONS) && IS_ENABLED(CONFIG_NAND_ZYNQ))
+ fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
+
if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) {
debug("No RNG device\n");
return 0;
diff --git a/board/xilinx/mbv/Kconfig b/board/xilinx/mbv/Kconfig
index d2dec39..a3a6f21 100644
--- a/board/xilinx/mbv/Kconfig
+++ b/board/xilinx/mbv/Kconfig
@@ -10,15 +10,25 @@
default "generic"
config TEXT_BASE
- default 0x80000000 if !RISCV_SMODE
- default 0x80400000 if RISCV_SMODE && ARCH_RV32I
+ default 0x21200000
+
+config SPL_TEXT_BASE
+ default 0x20000000
+
+config SPL_OPENSBI_LOAD_ADDR
+ hex
+ default 0x20200000
config BOARD_SPECIFIC_OPTIONS
def_bool y
select GENERIC_RISCV
+ select SUPPORT_SPL
imply BOARD_LATE_INIT
+ imply SPL_RAM_SUPPORT
+ imply SPL_RAM_DEVICE
imply CMD_SBI
imply CMD_PING
+ imply OF_HAS_PRIOR_STAGE
source "board/xilinx/Kconfig"
diff --git a/board/xilinx/mbv/board.c b/board/xilinx/mbv/board.c
index ccf4395..c478f7e 100644
--- a/board/xilinx/mbv/board.c
+++ b/board/xilinx/mbv/board.c
@@ -5,7 +5,17 @@
* Michal Simek <michal.simek@amd.com>
*/
+#include <spl.h>
+
int board_init(void)
{
return 0;
}
+
+#ifdef CONFIG_SPL
+u32 spl_boot_device(void)
+{
+ /* RISC-V QEMU only supports RAM as SPL boot device */
+ return BOOT_DEVICE_RAM;
+}
+#endif
diff --git a/board/xilinx/versal-net/board.c b/board/xilinx/versal-net/board.c
index 990ca16..da03024 100644
--- a/board/xilinx/versal-net/board.c
+++ b/board/xilinx/versal-net/board.c
@@ -371,3 +371,35 @@
void reset_cpu(void)
{
}
+
+#if defined(CONFIG_ENV_IS_NOWHERE)
+enum env_location env_get_location(enum env_operation op, int prio)
+{
+ u8 bootmode = versal_net_get_bootmode();
+
+ if (prio)
+ return ENVL_UNKNOWN;
+
+ switch (bootmode) {
+ case EMMC_MODE:
+ case SD_MODE:
+ case SD1_LSHFT_MODE:
+ case SD_MODE1:
+ if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT))
+ return ENVL_FAT;
+ if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4))
+ return ENVL_EXT4;
+ return ENVL_NOWHERE;
+ case OSPI_MODE:
+ case QSPI_MODE_24BIT:
+ case QSPI_MODE_32BIT:
+ if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH))
+ return ENVL_SPI_FLASH;
+ return ENVL_NOWHERE;
+ case JTAG_MODE:
+ case SELECTMAP_MODE:
+ default:
+ return ENVL_NOWHERE;
+ }
+}
+#endif
diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c
index 8c2e614..4f6d561 100644
--- a/board/xilinx/versal/board.c
+++ b/board/xilinx/versal/board.c
@@ -291,6 +291,7 @@
{
}
+#if defined(CONFIG_ENV_IS_NOWHERE)
enum env_location env_get_location(enum env_operation op, int prio)
{
u32 bootmode = versal_get_bootmode();
@@ -320,3 +321,4 @@
return ENVL_NOWHERE;
}
}
+#endif
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index ba49eb7..f370fb7 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -588,6 +588,7 @@
return bootseq;
}
+#if defined(CONFIG_ENV_IS_NOWHERE)
enum env_location env_get_location(enum env_operation op, int prio)
{
u32 bootmode = zynqmp_get_bootmode();
@@ -621,11 +622,37 @@
return ENVL_NOWHERE;
}
}
+#endif
#if defined(CONFIG_SET_DFU_ALT_INFO)
#define DFU_ALT_BUF_LEN SZ_1K
+static void mtd_found_part(u32 *base, u32 *size)
+{
+ struct mtd_info *part, *mtd;
+
+ mtd_probe_devices();
+
+ mtd = get_mtd_device_nm("nor0");
+ if (!IS_ERR_OR_NULL(mtd)) {
+ list_for_each_entry(part, &mtd->partitions, node) {
+ debug("0x%012llx-0x%012llx : \"%s\"\n",
+ part->offset, part->offset + part->size,
+ part->name);
+
+ if (*base >= part->offset &&
+ *base < part->offset + part->size) {
+ debug("Found my partition: %d/%s\n",
+ part->index, part->name);
+ *base = part->offset;
+ *size = part->size;
+ break;
+ }
+ }
+ }
+}
+
void set_dfu_alt_info(char *interface, char *devstr)
{
int multiboot, bootseq = 0, len = 0;
@@ -661,21 +688,38 @@
len += snprintf(buf + len, DFU_ALT_BUF_LEN, ".bin fat %d 1",
bootseq);
#if defined(CONFIG_SPL_FS_LOAD_PAYLOAD_NAME)
- len += snprintf(buf + len, DFU_ALT_BUF_LEN, ";%s fat %d 1",
- CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, bootseq);
+ if (strlen(CONFIG_SPL_FS_LOAD_PAYLOAD_NAME))
+ len += snprintf(buf + len, DFU_ALT_BUF_LEN,
+ ";%s fat %d 1",
+ CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
+ bootseq);
#endif
break;
case QSPI_MODE_24BIT:
case QSPI_MODE_32BIT:
- len += snprintf(buf + len, DFU_ALT_BUF_LEN,
- "sf 0:0=boot.bin raw %x 0x1500000",
- multiboot * SZ_32K);
+ {
+ u32 base = multiboot * SZ_32K;
+ u32 size = 0x1500000;
+ u32 limit = size;
+
+ mtd_found_part(&base, &limit);
+
+#if defined(CONFIG_SYS_SPI_U_BOOT_OFFS)
+ size = limit;
+ limit = CONFIG_SYS_SPI_U_BOOT_OFFS;
+#endif
+
+ len += snprintf(buf + len, DFU_ALT_BUF_LEN,
+ "sf 0:0=boot.bin raw 0x%x 0x%x",
+ base, limit);
#if defined(CONFIG_SPL_FS_LOAD_PAYLOAD_NAME) && defined(CONFIG_SYS_SPI_U_BOOT_OFFS)
- len += snprintf(buf + len, DFU_ALT_BUF_LEN,
- ";%s raw 0x%x 0x500000",
- CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
- multiboot * SZ_32K + CONFIG_SYS_SPI_U_BOOT_OFFS);
+ if (strlen(CONFIG_SPL_FS_LOAD_PAYLOAD_NAME))
+ len += snprintf(buf + len, DFU_ALT_BUF_LEN,
+ ";%s raw 0x%x 0x%x",
+ CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
+ base + limit, size - limit);
#endif
+ }
break;
default:
return;
diff --git a/board/xilinx/zynqmp/zynqmp_kria.env b/board/xilinx/zynqmp/zynqmp_kria.env
index 0f940bd..846eceb 100644
--- a/board/xilinx/zynqmp/zynqmp_kria.env
+++ b/board/xilinx/zynqmp/zynqmp_kria.env
@@ -17,6 +17,7 @@
bootcmd_usb1=devnum=1; run usb_boot
bootcmd_usb2=devnum=2; run usb_boot
bootcmd_usb3=devnum=3; run usb_boot
+bootcmd_usb4=devnum=4; run usb_boot
bootdelay=2
bootfstype=fat
bootm_low=0
@@ -44,7 +45,8 @@
preboot=setenv boot_targets; setenv modeboot; run board_setup
# SOM specific boot methods
-som_cc_boot=if test ${card1_name} = SCK-KV-G; then setenv boot_targets mmc1 usb0 usb1 usb2 usb3 pxe dhcp && run distro_bootcmd; elif test ${card1_name} = SCK-KR-G; then setenv boot_targets usb0 usb1 usb2 usb3 pxe dhcp && run distro_bootcmd; else test ${card1_name} = SCK-KD-G; setenv boot_targets usb0 usb1 usb2 usb3 pxe dhcp && run distro_bootcmd; fi;"
+usb_boot_devices='usb0 usb1 usb2 usb3 usb4'
+som_cc_boot=if test ${card1_name} = SCK-KV-G; then setenv boot_targets mmc1 ${usb_boot_devices} pxe dhcp jtag && run distro_bootcmd; elif test ${card1_name} = SCK-KR-G; then setenv boot_targets ${usb_boot_devices} pxe dhcp jtag && run distro_bootcmd; else test ${card1_name} = SCK-KD-G; setenv boot_targets ${usb_boot_devices} pxe dhcp jtag && run distro_bootcmd; fi;"
som_mmc_boot=setenv boot_targets mmc0 && run distro_bootcmd
k26_starter=SMK-K26-XCL2G
diff --git a/boot/Kconfig b/boot/Kconfig
index d9a6c27..777e408 100644
--- a/boot/Kconfig
+++ b/boot/Kconfig
@@ -2,39 +2,6 @@
menu "Boot images"
-config ANDROID_BOOT_IMAGE
- bool "Android Boot Images"
- default y if FASTBOOT
- help
- This enables support for booting images which use the Android
- image format header.
-
-config TIMESTAMP
- bool "Show image date and time when displaying image information"
- default y if CMD_DATE
- help
- When CONFIG_TIMESTAMP is selected, the timestamp (date and time) of
- an image is printed by image commands like bootm or iminfo. This
- is shown as 'Timestamp: xxx' and 'Created: xxx'. If this option is
- enabled, then U-Boot requires FITs to have a timestamp. If a FIT is
- loaded that does not, the message 'Wrong FIT format: no timestamp'
- is shown.
-
-config BUTTON_CMD
- bool "Support for running a command if a button is held during boot"
- depends on CMDLINE
- depends on BUTTON
- help
- For many embedded devices it's useful to enter a special flashing mode
- such as fastboot mode when a button is held during boot. This option
- allows arbitrary commands to be assigned to specific buttons. These will
- be run after "preboot" if the button is held. Configuration is done via
- the environment variables "button_cmd_N_name" and "button_cmd_N" where n is
- the button number (starting from 0). e.g:
-
- "button_cmd_0_name=vol_down"
- "button_cmd_0=fastboot usb 0"
-
menuconfig FIT
bool "Flattened Image Tree (FIT)"
select HASH
@@ -721,6 +688,100 @@
endif # BOOTSTD
+config BOOTM
+ bool "Support booting an application image from memory"
+ default y
+ help
+ This is the main boot implementation in U-Boot, supporting a wide
+ variety of features including FIT and legacy-image boot, kernel and
+ FDT selection, setting up of the command line for the OS and many
+ other features.
+
+ This option should normally be enabled. It is used to implement the
+ 'bootm' command.
+
+config BOOTM_LINUX
+ bool "Support booting Linux OS images"
+ depends on BOOTM || CMD_BOOTZ || CMD_BOOTI
+ default y
+ help
+ Support booting the Linux kernel directly via a command such as bootm
+ or booti or bootz.
+
+config BOOTM_NETBSD
+ bool "Support booting NetBSD (non-EFI) loader images"
+ depends on BOOTM
+ default y
+ help
+ Support booting NetBSD via the bootm command.
+
+config BOOTM_OPENRTOS
+ bool "Support booting OPENRTOS / FreeRTOS images"
+ depends on BOOTM
+ help
+ Support booting OPENRTOS / FreeRTOS via the bootm command.
+
+config BOOTM_OSE
+ bool "Support booting Enea OSE images"
+ depends on (ARM && (ARM64 || CPU_V7A || CPU_V7R) || SANDBOX || PPC || X86)
+ depends on BOOTM
+ help
+ Support booting Enea OSE images via the bootm command.
+
+config BOOTM_PLAN9
+ bool "Support booting Plan9 OS images"
+ depends on BOOTM
+ default y
+ help
+ Support booting Plan9 images via the bootm command.
+
+config BOOTM_RTEMS
+ bool "Support booting RTEMS OS images"
+ depends on BOOTM
+ default y
+ help
+ Support booting RTEMS images via the bootm command.
+
+config BOOTM_VXWORKS
+ bool "Support booting VxWorks OS images"
+ depends on BOOTM
+ default y
+ help
+ Support booting VxWorks images via the bootm command.
+
+config ANDROID_BOOT_IMAGE
+ bool "Android Boot Images"
+ default y if FASTBOOT
+ help
+ This enables support for booting images which use the Android
+ image format header.
+
+config TIMESTAMP
+ bool "Show image date and time when displaying image information"
+ default y if CMD_DATE
+ help
+ When CONFIG_TIMESTAMP is selected, the timestamp (date and time) of
+ an image is printed by image commands like bootm or iminfo. This
+ is shown as 'Timestamp: xxx' and 'Created: xxx'. If this option is
+ enabled, then U-Boot requires FITs to have a timestamp. If a FIT is
+ loaded that does not, the message 'Wrong FIT format: no timestamp'
+ is shown.
+
+config BUTTON_CMD
+ bool "Support for running a command if a button is held during boot"
+ depends on CMDLINE
+ depends on BUTTON
+ help
+ For many embedded devices it's useful to enter a special flashing mode
+ such as fastboot mode when a button is held during boot. This option
+ allows arbitrary commands to be assigned to specific buttons. These will
+ be run after "preboot" if the button is held. Configuration is done via
+ the environment variables "button_cmd_N_name" and "button_cmd_N" where n is
+ the button number (starting from 0). e.g:
+
+ "button_cmd_0_name=vol_down"
+ "button_cmd_0=fastboot usb 0"
+
config LEGACY_IMAGE_FORMAT
bool "Enable support for the legacy image format"
default y if !FIT_SIGNATURE && !TI_SECURE_DEVICE
@@ -765,7 +826,7 @@
config SYS_BOOTM_LEN
hex "Maximum size of a decompresed OS image"
- depends on CMD_BOOTM || CMD_BOOTI || CMD_BOOTZ || \
+ depends on BOOTM || CMD_BOOTI || CMD_BOOTZ || \
LEGACY_IMAGE_FORMAT || SPL_LEGACY_IMAGE_FORMAT
default 0x4000000 if PPC || ARM64
default 0x1000000 if X86 || ARCH_MX6 || ARCH_MX7
diff --git a/boot/Makefile b/boot/Makefile
index 84ccfea..bf767fd 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -6,7 +6,7 @@
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_BOOT_RETRY) += bootretry.o
-obj-$(CONFIG_CMD_BOOTM) += bootm.o bootm_os.o
+obj-$(CONFIG_BOOTM) += bootm.o bootm_os.o
obj-$(CONFIG_CMD_BOOTZ) += bootm.o bootm_os.o
obj-$(CONFIG_CMD_BOOTI) += bootm.o bootm_os.o
diff --git a/boot/bootm.c b/boot/bootm.c
index d071537..032f5a4 100644
--- a/boot/bootm.c
+++ b/boot/bootm.c
@@ -242,13 +242,13 @@
#ifdef CONFIG_LMB
static void boot_start_lmb(struct bootm_headers *images)
{
- ulong mem_start;
+ phys_addr_t mem_start;
phys_size_t mem_size;
mem_start = env_get_bootm_low();
mem_size = env_get_bootm_size();
- lmb_init_and_reserve_range(&images->lmb, (phys_addr_t)mem_start,
+ lmb_init_and_reserve_range(&images->lmb, mem_start,
mem_size, NULL);
}
#else
diff --git a/boot/bootmeth_cros.c b/boot/bootmeth_cros.c
index cd72db8..f015f2e 100644
--- a/boot/bootmeth_cros.c
+++ b/boot/bootmeth_cros.c
@@ -432,9 +432,9 @@
}
if (IS_ENABLED(CONFIG_X86)) {
- ret = zboot_start(map_to_sysmem(bflow->buf), bflow->size, 0, 0,
- map_to_sysmem(bflow->x86_setup),
- bflow->cmdline);
+ ret = zboot_run(map_to_sysmem(bflow->buf), bflow->size, 0, 0,
+ map_to_sysmem(bflow->x86_setup),
+ bflow->cmdline);
} else {
ret = bootm_boot_start(map_to_sysmem(bflow->buf),
bflow->cmdline);
diff --git a/boot/fdt_support.c b/boot/fdt_support.c
index 090d82e..9844c70 100644
--- a/boot/fdt_support.c
+++ b/boot/fdt_support.c
@@ -17,6 +17,7 @@
#include <linux/ctype.h>
#include <linux/types.h>
#include <asm/global_data.h>
+#include <asm/unaligned.h>
#include <linux/libfdt.h>
#include <fdt_support.h>
#include <exports.h>
@@ -421,13 +422,13 @@
for (i = 0; i < n; i++) {
if (address_cells == 2)
- *(fdt64_t *)p = cpu_to_fdt64(address[i]);
+ put_unaligned_be64(address[i], p);
else
*(fdt32_t *)p = cpu_to_fdt32(address[i]);
p += 4 * address_cells;
if (size_cells == 2)
- *(fdt64_t *)p = cpu_to_fdt64(size[i]);
+ put_unaligned_be64(size[i], p);
else
*(fdt32_t *)p = cpu_to_fdt32(size[i]);
p += 4 * size_cells;
diff --git a/boot/image-board.c b/boot/image-board.c
index 75f6906..09b6e4e 100644
--- a/boot/image-board.c
+++ b/boot/image-board.c
@@ -107,14 +107,12 @@
}
U_BOOT_ENV_CALLBACK(loadaddr, on_loadaddr);
-ulong env_get_bootm_low(void)
+phys_addr_t env_get_bootm_low(void)
{
char *s = env_get("bootm_low");
- if (s) {
- ulong tmp = hextoul(s, NULL);
- return tmp;
- }
+ if (s)
+ return simple_strtoull(s, NULL, 16);
#if defined(CFG_SYS_SDRAM_BASE)
return CFG_SYS_SDRAM_BASE;
@@ -127,14 +125,12 @@
phys_size_t env_get_bootm_size(void)
{
- phys_size_t tmp, size;
- phys_addr_t start;
+ phys_addr_t start, low;
+ phys_size_t size;
char *s = env_get("bootm_size");
- if (s) {
- tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
- return tmp;
- }
+ if (s)
+ return simple_strtoull(s, NULL, 16);
start = gd->ram_base;
size = gd->ram_size;
@@ -144,22 +140,19 @@
s = env_get("bootm_low");
if (s)
- tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
+ low = simple_strtoull(s, NULL, 16);
else
- tmp = start;
+ low = start;
- return size - (tmp - start);
+ return size - (low - start);
}
phys_size_t env_get_bootm_mapsize(void)
{
- phys_size_t tmp;
char *s = env_get("bootm_mapsize");
- if (s) {
- tmp = (phys_size_t)simple_strtoull(s, NULL, 16);
- return tmp;
- }
+ if (s)
+ return simple_strtoull(s, NULL, 16);
#if defined(CFG_SYS_BOOTMAPSZ)
return CFG_SYS_BOOTMAPSZ;
@@ -538,7 +531,7 @@
ulong *initrd_start, ulong *initrd_end)
{
char *s;
- ulong initrd_high;
+ phys_addr_t initrd_high;
int initrd_copy_to_ram = 1;
s = env_get("initrd_high");
@@ -553,8 +546,8 @@
initrd_high = env_get_bootm_mapsize() + env_get_bootm_low();
}
- debug("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
- initrd_high, initrd_copy_to_ram);
+ debug("## initrd_high = 0x%llx, copy_to_ram = %d\n",
+ (u64)initrd_high, initrd_copy_to_ram);
if (rd_data) {
if (!initrd_copy_to_ram) { /* zero-copy ramdisk support */
diff --git a/boot/image-fdt.c b/boot/image-fdt.c
index 5e4aa9d..2b92bda 100644
--- a/boot/image-fdt.c
+++ b/boot/image-fdt.c
@@ -160,9 +160,11 @@
{
void *fdt_blob = *of_flat_tree;
void *of_start = NULL;
- u64 start, size, usable;
+ phys_addr_t start, size, usable;
char *fdt_high;
- ulong mapsize, low;
+ phys_addr_t addr;
+ phys_addr_t low;
+ phys_size_t mapsize;
ulong of_len = 0;
int bank;
int err;
@@ -185,7 +187,6 @@
fdt_high = env_get("fdt_high");
if (fdt_high) {
ulong desired_addr = hextoul(fdt_high, NULL);
- ulong addr;
if (desired_addr == ~0UL) {
/* All ones means use fdt in place */
@@ -217,14 +218,14 @@
if (start + size < low)
continue;
- usable = min(start + size, (u64)(low + mapsize));
-
/*
* At least part of this DRAM bank is usable, try
- * using it for LMB allocation.
+ * using the DRAM bank up to 'usable' address limit
+ * for LMB allocation.
*/
- of_start = map_sysmem((ulong)lmb_alloc_base(lmb,
- of_len, 0x1000, usable), of_len);
+ usable = min(start + size, low + mapsize);
+ addr = lmb_alloc_base(lmb, of_len, 0x1000, usable);
+ of_start = map_sysmem(addr, of_len);
/* Allocation succeeded, use this block. */
if (of_start != NULL)
break;
@@ -233,7 +234,7 @@
* Reduce the mapping size in the next bank
* by the size of attempt in current bank.
*/
- mapsize -= usable - max(start, (u64)low);
+ mapsize -= usable - max(start, low);
if (!mapsize)
break;
}
diff --git a/boot/pxe_utils.c b/boot/pxe_utils.c
index 9620562..d5e1bea 100644
--- a/boot/pxe_utils.c
+++ b/boot/pxe_utils.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <bootm.h>
#include <command.h>
#include <dm.h>
#include <env.h>
@@ -470,6 +471,220 @@
#endif
/**
+ * calc_fdt_fname() - Figure out the filename to use for the FDT
+ *
+ * Determine the path to the FDT filename, based on the "fdtfile" environment
+ * variable. Use <soc>-<board>.dtb as a fallback
+ *
+ * @fdtdir: Directory to use for the FDT file
+ * Return: allocated filename (including directory), or NULL if out of memory
+ */
+static char *calc_fdt_fname(const char *fdtdir)
+{
+ char *fdtfile;
+ char *f1, *f2, *f3, *f4, *slash;
+ int len;
+
+ f1 = env_get("fdtfile");
+ if (f1) {
+ f2 = "";
+ f3 = "";
+ f4 = "";
+ } else {
+ /*
+ * For complex cases where this code doesn't generate the
+ * correct filename, the board code should set $fdtfile during
+ * early boot, or the boot scripts should set $fdtfile before
+ * invoking "pxe" or "sysboot".
+ */
+ f1 = env_get("soc");
+ f2 = "-";
+ f3 = env_get("board");
+ f4 = ".dtb";
+ if (!f1) {
+ f1 = "";
+ f2 = "";
+ }
+ if (!f3) {
+ f2 = "";
+ f3 = "";
+ }
+ }
+
+ len = strlen(fdtdir);
+ if (!len)
+ slash = "./";
+ else if (fdtdir[len - 1] != '/')
+ slash = "/";
+ else
+ slash = "";
+
+ len = strlen(fdtdir) + strlen(slash) + strlen(f1) + strlen(f2) +
+ strlen(f3) + strlen(f4) + 1;
+ fdtfile = malloc(len);
+ if (!fdtfile) {
+ printf("malloc fail (FDT filename)\n");
+ return NULL;
+ }
+
+ snprintf(fdtfile, len, "%s%s%s%s%s%s", fdtdir, slash, f1, f2, f3, f4);
+
+ return fdtfile;
+}
+
+/**
+ * label_run_boot() - Run the correct boot procedure
+ *
+ * fdt usage is optional:
+ * It handles the following scenarios.
+ *
+ * Scenario 1: If fdt_addr_r specified and "fdt" or "fdtdir" label is
+ * defined in pxe file, retrieve fdt blob from server. Pass fdt_addr_r to
+ * bootm, and adjust argc appropriately.
+ *
+ * If retrieve fails and no exact fdt blob is specified in pxe file with
+ * "fdt" label, try Scenario 2.
+ *
+ * Scenario 2: If there is an fdt_addr specified, pass it along to
+ * bootm, and adjust argc appropriately.
+ *
+ * Scenario 3: If there is an fdtcontroladdr specified, pass it along to
+ * bootm, and adjust argc appropriately, unless the image type is fitImage.
+ *
+ * Scenario 4: fdt blob is not available.
+ *
+ * @ctx: PXE context
+ * @label: Label to process
+ * @kernel_addr: string containing the kernel address / config
+ * @initrd_str: string containing the initrd address / size
+ * @initrd_addr_str: initrd address, or NULL if none
+ * @initrd_filesize: initrd size in bytes; only valid if initrd_addr_str is not
+ * NULL
+ * Returns does not return on success, otherwise returns 0 if a localboot
+ * label was processed, or 1 on error
+ */
+static int label_run_boot(struct pxe_context *ctx, struct pxe_label *label,
+ char *kernel_addr, char *initrd_str,
+ char *initrd_addr_str, char *initrd_filesize)
+{
+ struct bootm_info bmi;
+ const char *fdt_addr;
+ ulong kernel_addr_r;
+ void *buf;
+ int ret;
+
+ if (IS_ENABLED(CONFIG_BOOTM))
+ bootm_init(&bmi);
+
+ fdt_addr = env_get("fdt_addr_r");
+
+ /* For FIT, the label can be identical to kernel one */
+ if (label->fdt && !strcmp(label->kernel_label, label->fdt)) {
+ fdt_addr = kernel_addr;
+ /* if fdt label is defined then get fdt from server */
+ } else if (fdt_addr) {
+ char *fdtfile = NULL;
+ char *fdtfilefree = NULL;
+
+ if (label->fdt) {
+ if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
+ if (strcmp("-", label->fdt))
+ fdtfile = label->fdt;
+ } else {
+ fdtfile = label->fdt;
+ }
+ } else if (label->fdtdir) {
+ fdtfilefree = calc_fdt_fname(label->fdtdir);
+ if (!fdtfilefree)
+ return -ENOMEM;
+ fdtfile = fdtfilefree;
+ }
+
+ if (fdtfile) {
+ int err = get_relfile_envaddr(ctx, fdtfile,
+ "fdt_addr_r", NULL);
+
+ free(fdtfilefree);
+ if (err < 0) {
+ fdt_addr = NULL;
+
+ if (label->fdt) {
+ printf("Skipping %s for failure retrieving FDT\n",
+ label->name);
+ return -ENOENT;
+ }
+
+ if (label->fdtdir) {
+ printf("Skipping fdtdir %s for failure retrieving dts\n",
+ label->fdtdir);
+ }
+ }
+
+ if (label->kaslrseed)
+ label_boot_kaslrseed();
+
+#ifdef CONFIG_OF_LIBFDT_OVERLAY
+ if (label->fdtoverlays)
+ label_boot_fdtoverlay(ctx, label);
+#endif
+ } else {
+ fdt_addr = NULL;
+ }
+ }
+
+ bmi.addr_img = kernel_addr;
+
+ if (initrd_addr_str)
+ bmi.conf_ramdisk = initrd_str;
+
+ if (!fdt_addr) {
+ if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
+ if (strcmp("-", label->fdt))
+ fdt_addr = env_get("fdt_addr");
+ } else {
+ fdt_addr = env_get("fdt_addr");
+ }
+ }
+
+ kernel_addr_r = genimg_get_kernel_addr(kernel_addr);
+ buf = map_sysmem(kernel_addr_r, 0);
+
+ if (!fdt_addr && genimg_get_format(buf) != IMAGE_FORMAT_FIT) {
+ if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
+ if (strcmp("-", label->fdt))
+ fdt_addr = env_get("fdtcontroladdr");
+ } else {
+ fdt_addr = env_get("fdtcontroladdr");
+ }
+ }
+
+ bmi.conf_fdt = fdt_addr;
+
+ /* Try bootm for legacy and FIT format image */
+ if (genimg_get_format(buf) != IMAGE_FORMAT_INVALID &&
+ IS_ENABLED(CONFIG_BOOTM))
+ ret = bootm_run(&bmi);
+ /* Try booting an AArch64 Linux kernel image */
+ else if (IS_ENABLED(CONFIG_BOOTM))
+ ret = booti_run(&bmi);
+ /* Try booting a Image */
+ else if (IS_ENABLED(CONFIG_BOOTM))
+ ret = bootz_run(&bmi);
+ /* Try booting an x86_64 Linux kernel image */
+ else if (IS_ENABLED(CONFIG_ZBOOT))
+ ret = zboot_run(hextoul(kernel_addr, NULL), 0,
+ initrd_addr_str ?
+ hextoul(initrd_addr_str, NULL) : 0,
+ initrd_addr_str ?
+ hextoul(initrd_filesize, NULL) : 0,
+ 0, NULL);
+
+ unmap_sysmem(buf);
+
+ return 0;
+}
+
+/**
* label_boot() - Boot according to the contents of a pxe_label
*
* If we can't boot for any reason, we return. A successful boot never
@@ -491,8 +706,6 @@
*/
static int label_boot(struct pxe_context *ctx, struct pxe_label *label)
{
- char *bootm_argv[] = { "bootm", NULL, NULL, NULL, NULL };
- char *zboot_argv[] = { "zboot", NULL, "0", NULL, NULL };
char *kernel_addr = NULL;
char *initrd_addr_str = NULL;
char initrd_filesize[10];
@@ -500,11 +713,7 @@
char mac_str[29] = "";
char ip_str[68] = "";
char *fit_addr = NULL;
- int bootm_argc = 2;
- int zboot_argc = 3;
- int len = 0;
- ulong kernel_addr_r;
- void *buf;
+ int ret;
label_print(label);
@@ -545,9 +754,10 @@
/* For FIT, the label can be identical to kernel one */
if (label->initrd && !strcmp(label->kernel_label, label->initrd)) {
- initrd_addr_str = kernel_addr;
+ initrd_addr_str = kernel_addr;
} else if (label->initrd) {
ulong size;
+
if (get_relfile_envaddr(ctx, label->initrd, "ramdisk_addr_r",
&size) < 0) {
printf("Skipping %s for failure retrieving initrd\n",
@@ -593,7 +803,7 @@
}
if (label->append)
- strncpy(bootargs, label->append, sizeof(bootargs));
+ strlcpy(bootargs, label->append, sizeof(bootargs));
strcat(bootargs, ip_str);
strcat(bootargs, mac_str);
@@ -604,180 +814,8 @@
printf("append: %s\n", finalbootargs);
}
- /*
- * fdt usage is optional:
- * It handles the following scenarios.
- *
- * Scenario 1: If fdt_addr_r specified and "fdt" or "fdtdir" label is
- * defined in pxe file, retrieve fdt blob from server. Pass fdt_addr_r to
- * bootm, and adjust argc appropriately.
- *
- * If retrieve fails and no exact fdt blob is specified in pxe file with
- * "fdt" label, try Scenario 2.
- *
- * Scenario 2: If there is an fdt_addr specified, pass it along to
- * bootm, and adjust argc appropriately.
- *
- * Scenario 3: If there is an fdtcontroladdr specified, pass it along to
- * bootm, and adjust argc appropriately, unless the image type is fitImage.
- *
- * Scenario 4: fdt blob is not available.
- */
- bootm_argv[3] = env_get("fdt_addr_r");
-
- /* For FIT, the label can be identical to kernel one */
- if (label->fdt && !strcmp(label->kernel_label, label->fdt)) {
- bootm_argv[3] = kernel_addr;
- /* if fdt label is defined then get fdt from server */
- } else if (bootm_argv[3]) {
- char *fdtfile = NULL;
- char *fdtfilefree = NULL;
-
- if (label->fdt) {
- if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
- if (strcmp("-", label->fdt))
- fdtfile = label->fdt;
- } else {
- fdtfile = label->fdt;
- }
- } else if (label->fdtdir) {
- char *f1, *f2, *f3, *f4, *slash;
-
- f1 = env_get("fdtfile");
- if (f1) {
- f2 = "";
- f3 = "";
- f4 = "";
- } else {
- /*
- * For complex cases where this code doesn't
- * generate the correct filename, the board
- * code should set $fdtfile during early boot,
- * or the boot scripts should set $fdtfile
- * before invoking "pxe" or "sysboot".
- */
- f1 = env_get("soc");
- f2 = "-";
- f3 = env_get("board");
- f4 = ".dtb";
- if (!f1) {
- f1 = "";
- f2 = "";
- }
- if (!f3) {
- f2 = "";
- f3 = "";
- }
- }
-
- len = strlen(label->fdtdir);
- if (!len)
- slash = "./";
- else if (label->fdtdir[len - 1] != '/')
- slash = "/";
- else
- slash = "";
-
- len = strlen(label->fdtdir) + strlen(slash) +
- strlen(f1) + strlen(f2) + strlen(f3) +
- strlen(f4) + 1;
- fdtfilefree = malloc(len);
- if (!fdtfilefree) {
- printf("malloc fail (FDT filename)\n");
- goto cleanup;
- }
-
- snprintf(fdtfilefree, len, "%s%s%s%s%s%s",
- label->fdtdir, slash, f1, f2, f3, f4);
- fdtfile = fdtfilefree;
- }
-
- if (fdtfile) {
- int err = get_relfile_envaddr(ctx, fdtfile,
- "fdt_addr_r", NULL);
-
- free(fdtfilefree);
- if (err < 0) {
- bootm_argv[3] = NULL;
-
- if (label->fdt) {
- printf("Skipping %s for failure retrieving FDT\n",
- label->name);
- goto cleanup;
- }
-
- if (label->fdtdir) {
- printf("Skipping fdtdir %s for failure retrieving dts\n",
- label->fdtdir);
- }
- }
-
- if (label->kaslrseed)
- label_boot_kaslrseed();
-
-#ifdef CONFIG_OF_LIBFDT_OVERLAY
- if (label->fdtoverlays)
- label_boot_fdtoverlay(ctx, label);
-#endif
- } else {
- bootm_argv[3] = NULL;
- }
- }
-
- bootm_argv[1] = kernel_addr;
- zboot_argv[1] = kernel_addr;
-
- if (initrd_addr_str) {
- bootm_argv[2] = initrd_str;
- bootm_argc = 3;
-
- zboot_argv[3] = initrd_addr_str;
- zboot_argv[4] = initrd_filesize;
- zboot_argc = 5;
- }
-
- if (!bootm_argv[3]) {
- if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
- if (strcmp("-", label->fdt))
- bootm_argv[3] = env_get("fdt_addr");
- } else {
- bootm_argv[3] = env_get("fdt_addr");
- }
- }
-
- kernel_addr_r = genimg_get_kernel_addr(kernel_addr);
- buf = map_sysmem(kernel_addr_r, 0);
-
- if (!bootm_argv[3] && genimg_get_format(buf) != IMAGE_FORMAT_FIT) {
- if (IS_ENABLED(CONFIG_SUPPORT_PASSING_ATAGS)) {
- if (strcmp("-", label->fdt))
- bootm_argv[3] = env_get("fdtcontroladdr");
- } else {
- bootm_argv[3] = env_get("fdtcontroladdr");
- }
- }
-
- if (bootm_argv[3]) {
- if (!bootm_argv[2])
- bootm_argv[2] = "-";
- bootm_argc = 4;
- }
-
- /* Try bootm for legacy and FIT format image */
- if (genimg_get_format(buf) != IMAGE_FORMAT_INVALID &&
- IS_ENABLED(CONFIG_CMD_BOOTM))
- do_bootm(ctx->cmdtp, 0, bootm_argc, bootm_argv);
- /* Try booting an AArch64 Linux kernel image */
- else if (IS_ENABLED(CONFIG_CMD_BOOTI))
- do_booti(ctx->cmdtp, 0, bootm_argc, bootm_argv);
- /* Try booting a Image */
- else if (IS_ENABLED(CONFIG_CMD_BOOTZ))
- do_bootz(ctx->cmdtp, 0, bootm_argc, bootm_argv);
- /* Try booting an x86_64 Linux kernel image */
- else if (IS_ENABLED(CONFIG_CMD_ZBOOT))
- do_zboot_parent(ctx->cmdtp, 0, zboot_argc, zboot_argv, NULL);
-
- unmap_sysmem(buf);
+ ret = label_run_boot(ctx, label, kernel_addr, initrd_str,
+ initrd_addr_str, initrd_filesize);
cleanup:
free(fit_addr);
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 61e280f..8eeb99e 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -262,6 +262,7 @@
config CMD_BOOTM
bool "bootm"
+ depends on BOOTM
default y
help
Boot an application image from the memory.
@@ -333,48 +334,6 @@
help
Boot an AArch64 Linux Kernel image from memory.
-config BOOTM_LINUX
- bool "Support booting Linux OS images"
- depends on CMD_BOOTM || CMD_BOOTZ || CMD_BOOTI
- default y
- help
- Support booting the Linux kernel directly via a command such as bootm
- or booti or bootz.
-
-config BOOTM_NETBSD
- bool "Support booting NetBSD (non-EFI) loader images"
- depends on CMD_BOOTM
- default y
- help
- Support booting NetBSD via the bootm command.
-
-config BOOTM_OPENRTOS
- bool "Support booting OPENRTOS / FreeRTOS images"
- depends on CMD_BOOTM
- help
- Support booting OPENRTOS / FreeRTOS via the bootm command.
-
-config BOOTM_OSE
- bool "Support booting Enea OSE images"
- depends on (ARM && (ARM64 || CPU_V7A || CPU_V7R) || SANDBOX || PPC || X86)
- depends on CMD_BOOTM
- help
- Support booting Enea OSE images via the bootm command.
-
-config BOOTM_PLAN9
- bool "Support booting Plan9 OS images"
- depends on CMD_BOOTM
- default y
- help
- Support booting Plan9 images via the bootm command.
-
-config BOOTM_RTEMS
- bool "Support booting RTEMS OS images"
- depends on CMD_BOOTM
- default y
- help
- Support booting RTEMS images via the bootm command.
-
config CMD_SEAMA
bool "Support read SEAMA NAND images"
depends on MTD_RAW_NAND
@@ -391,13 +350,6 @@
is used to boot. Updating the parameters is not currently
supported.
-config BOOTM_VXWORKS
- bool "Support booting VxWorks OS images"
- depends on CMD_BOOTM
- default y
- help
- Support booting VxWorks images via the bootm command.
-
config CMD_BOOTEFI
bool "bootefi"
depends on EFI_LOADER
@@ -612,6 +564,8 @@
config CMD_ZBOOT
bool "zboot - x86 boot command"
+ depends on ZBOOT
+ default y
help
With x86 machines it is common to boot a bzImage file which
contains both a kernel and a setup.bin file. The latter includes
@@ -1407,6 +1361,13 @@
help
MTD commands support.
+config CMD_MTD_OTP
+ bool "mtd otp"
+ depends on CMD_MTD
+ select HEXDUMP
+ help
+ MTD commands for OTP access.
+
config CMD_MUX
bool "mux"
depends on MULTIPLEXER
@@ -2878,8 +2839,8 @@
Enables a command to control using of function tracing within
U-Boot. This allows recording of call traces including timing
information. The command can write data to memory for exporting
- for analysis (e.g. using bootchart). See doc/README.trace for full
- details.
+ for analysis (e.g. using bootchart). See doc/develop/trace.rst
+ for full details.
config CMD_AVB
bool "avb - Android Verified Boot 2.0 operations"
diff --git a/cmd/booti.c b/cmd/booti.c
index 898df0f..b9637b3 100644
--- a/cmd/booti.c
+++ b/cmd/booti.c
@@ -74,7 +74,7 @@
unmap_sysmem((void *)ld);
ret = booti_setup(ld, &relocated_addr, &image_size, false);
- if (ret || IS_ENABLED(CONFIG_SANDBOX))
+ if (ret)
return 1;
/* Handle BOOTM_STATE_LOADOS */
diff --git a/cmd/fastboot.c b/cmd/fastboot.c
index c3c1923..792e83d 100644
--- a/cmd/fastboot.c
+++ b/cmd/fastboot.c
@@ -159,7 +159,7 @@
return CMD_RET_USAGE;
}
- fastboot_init((void *)buf_addr, buf_size);
+ fastboot_init(buf_addr, buf_size);
if (!strcmp(argv[1], "udp"))
return do_fastboot_udp(argc, argv, buf_addr, buf_size);
diff --git a/cmd/mtd.c b/cmd/mtd.c
index 9083a68..9189f45 100644
--- a/cmd/mtd.c
+++ b/cmd/mtd.c
@@ -11,6 +11,9 @@
#include <command.h>
#include <common.h>
#include <console.h>
+#if CONFIG_IS_ENABLED(CMD_MTD_OTP)
+#include <hexdump.h>
+#endif
#include <malloc.h>
#include <mapmem.h>
#include <mtd.h>
@@ -202,6 +205,221 @@
return true;
}
+#if CONFIG_IS_ENABLED(CMD_MTD_OTP)
+static int do_mtd_otp_read(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct mtd_info *mtd;
+ size_t retlen;
+ off_t from;
+ size_t len;
+ bool user;
+ int ret;
+ u8 *buf;
+
+ if (argc != 5)
+ return CMD_RET_USAGE;
+
+ if (!strcmp(argv[2], "u"))
+ user = true;
+ else if (!strcmp(argv[2], "f"))
+ user = false;
+ else
+ return CMD_RET_USAGE;
+
+ mtd = get_mtd_by_name(argv[1]);
+ if (IS_ERR_OR_NULL(mtd))
+ return CMD_RET_FAILURE;
+
+ from = simple_strtoul(argv[3], NULL, 0);
+ len = simple_strtoul(argv[4], NULL, 0);
+
+ ret = CMD_RET_FAILURE;
+
+ buf = malloc(len);
+ if (!buf)
+ goto put_mtd;
+
+ printf("Reading %s OTP from 0x%lx, %zu bytes\n",
+ user ? "user" : "factory", from, len);
+
+ if (user)
+ ret = mtd_read_user_prot_reg(mtd, from, len, &retlen, buf);
+ else
+ ret = mtd_read_fact_prot_reg(mtd, from, len, &retlen, buf);
+ if (ret) {
+ free(buf);
+ pr_err("OTP read failed: %d\n", ret);
+ ret = CMD_RET_FAILURE;
+ goto put_mtd;
+ }
+
+ if (retlen != len)
+ pr_err("OTP read returns %zu, but %zu expected\n",
+ retlen, len);
+
+ print_hex_dump("", 0, 16, 1, buf, retlen, true);
+
+ free(buf);
+
+ ret = CMD_RET_SUCCESS;
+
+put_mtd:
+ put_mtd_device(mtd);
+
+ return ret;
+}
+
+static int do_mtd_otp_lock(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct mtd_info *mtd;
+ off_t from;
+ size_t len;
+ int ret;
+
+ if (argc != 4)
+ return CMD_RET_USAGE;
+
+ mtd = get_mtd_by_name(argv[1]);
+ if (IS_ERR_OR_NULL(mtd))
+ return CMD_RET_FAILURE;
+
+ from = simple_strtoul(argv[2], NULL, 0);
+ len = simple_strtoul(argv[3], NULL, 0);
+
+ ret = mtd_lock_user_prot_reg(mtd, from, len);
+ if (ret) {
+ pr_err("OTP lock failed: %d\n", ret);
+ ret = CMD_RET_FAILURE;
+ goto put_mtd;
+ }
+
+ ret = CMD_RET_SUCCESS;
+
+put_mtd:
+ put_mtd_device(mtd);
+
+ return ret;
+}
+
+static int do_mtd_otp_write(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct mtd_info *mtd;
+ size_t retlen;
+ size_t binlen;
+ u8 *binbuf;
+ off_t from;
+ int ret;
+
+ if (argc != 4)
+ return CMD_RET_USAGE;
+
+ mtd = get_mtd_by_name(argv[1]);
+ if (IS_ERR_OR_NULL(mtd))
+ return CMD_RET_FAILURE;
+
+ from = simple_strtoul(argv[2], NULL, 0);
+ binlen = strlen(argv[3]) / 2;
+
+ ret = CMD_RET_FAILURE;
+ binbuf = malloc(binlen);
+ if (!binbuf)
+ goto put_mtd;
+
+ hex2bin(binbuf, argv[3], binlen);
+
+ printf("Will write:\n");
+
+ print_hex_dump("", 0, 16, 1, binbuf, binlen, true);
+
+ printf("to 0x%lx\n", from);
+
+ printf("Continue (y/n)?\n");
+
+ if (confirm_yesno() != 1) {
+ pr_err("OTP write canceled\n");
+ ret = CMD_RET_SUCCESS;
+ goto put_mtd;
+ }
+
+ ret = mtd_write_user_prot_reg(mtd, from, binlen, &retlen, binbuf);
+ if (ret) {
+ pr_err("OTP write failed: %d\n", ret);
+ ret = CMD_RET_FAILURE;
+ goto put_mtd;
+ }
+
+ if (retlen != binlen)
+ pr_err("OTP write returns %zu, but %zu expected\n",
+ retlen, binlen);
+
+ ret = CMD_RET_SUCCESS;
+
+put_mtd:
+ free(binbuf);
+ put_mtd_device(mtd);
+
+ return ret;
+}
+
+static int do_mtd_otp_info(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct otp_info otp_info;
+ struct mtd_info *mtd;
+ size_t retlen;
+ bool user;
+ int ret;
+
+ if (argc != 3)
+ return CMD_RET_USAGE;
+
+ if (!strcmp(argv[2], "u"))
+ user = true;
+ else if (!strcmp(argv[2], "f"))
+ user = false;
+ else
+ return CMD_RET_USAGE;
+
+ mtd = get_mtd_by_name(argv[1]);
+ if (IS_ERR_OR_NULL(mtd))
+ return CMD_RET_FAILURE;
+
+ if (user)
+ ret = mtd_get_user_prot_info(mtd, sizeof(otp_info), &retlen,
+ &otp_info);
+ else
+ ret = mtd_get_fact_prot_info(mtd, sizeof(otp_info), &retlen,
+ &otp_info);
+ if (ret) {
+ pr_err("OTP info failed: %d\n", ret);
+ ret = CMD_RET_FAILURE;
+ goto put_mtd;
+ }
+
+ if (retlen != sizeof(otp_info)) {
+ pr_err("OTP info returns %zu, but %zu expected\n",
+ retlen, sizeof(otp_info));
+ ret = CMD_RET_FAILURE;
+ goto put_mtd;
+ }
+
+ printf("%s OTP region info:\n", user ? "User" : "Factory");
+ printf("\tstart: %u\n", otp_info.start);
+ printf("\tlength: %u\n", otp_info.length);
+ printf("\tlocked: %u\n", otp_info.locked);
+
+ ret = CMD_RET_SUCCESS;
+
+put_mtd:
+ put_mtd_device(mtd);
+
+ return ret;
+}
+#endif
+
static int do_mtd_list(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
@@ -551,6 +769,12 @@
"\n"
"Specific functions:\n"
"mtd bad <name>\n"
+#if CONFIG_IS_ENABLED(CMD_MTD_OTP)
+ "mtd otpread <name> [u|f] <off> <size>\n"
+ "mtd otpwrite <name> <off> <hex string>\n"
+ "mtd otplock <name> <off> <size>\n"
+ "mtd otpinfo <name> [u|f]\n"
+#endif
"\n"
"With:\n"
"\t<name>: NAND partition/chip name (or corresponding DM device name or OF path)\n"
@@ -561,10 +785,20 @@
"\t<size>: length of the operation in bytes (default: the entire device)\n"
"\t\t* must be a multiple of a block for erase\n"
"\t\t* must be a multiple of a page otherwise (special case: default is a page with dump)\n"
+#if CONFIG_IS_ENABLED(CMD_MTD_OTP)
+ "\t<hex string>: hex string without '0x' and spaces. Example: ABCD1234\n"
+ "\t[u|f]: user or factory OTP region\n"
+#endif
"\n"
"The .dontskipff option forces writing empty pages, don't use it if unsure.\n");
U_BOOT_CMD_WITH_SUBCMDS(mtd, "MTD utils", mtd_help_text,
+#if CONFIG_IS_ENABLED(CMD_MTD_OTP)
+ U_BOOT_SUBCMD_MKENT(otpread, 5, 1, do_mtd_otp_read),
+ U_BOOT_SUBCMD_MKENT(otpwrite, 4, 1, do_mtd_otp_write),
+ U_BOOT_SUBCMD_MKENT(otplock, 4, 1, do_mtd_otp_lock),
+ U_BOOT_SUBCMD_MKENT(otpinfo, 3, 1, do_mtd_otp_info),
+#endif
U_BOOT_SUBCMD_MKENT(list, 1, 1, do_mtd_list),
U_BOOT_SUBCMD_MKENT_COMPLETE(read, 5, 0, do_mtd_io,
mtd_name_complete),
diff --git a/cmd/sf.c b/cmd/sf.c
index 730996c..e386689 100644
--- a/cmd/sf.c
+++ b/cmd/sf.c
@@ -135,8 +135,9 @@
}
flash = NULL;
if (use_dt) {
- spi_flash_probe_bus_cs(bus, cs, &new);
- flash = dev_get_uclass_priv(new);
+ ret = spi_flash_probe_bus_cs(bus, cs, &new);
+ if (!ret)
+ flash = dev_get_uclass_priv(new);
} else {
flash = spi_flash_probe(bus, cs, speed, mode);
}
diff --git a/cmd/sysboot.c b/cmd/sysboot.c
index 63a7806..d14c570 100644
--- a/cmd/sysboot.c
+++ b/cmd/sysboot.c
@@ -77,6 +77,10 @@
if (argc < 6) {
filename = env_get("bootfile");
+ if (!filename) {
+ printf("Specify a filename or set the ${bootfile} environment variable\n");
+ return 1;
+ }
} else {
filename = argv[5];
env_set("bootfile", filename);
diff --git a/cmd/x86/Makefile b/cmd/x86/Makefile
index 5f82204..b1f39d3 100644
--- a/cmd/x86/Makefile
+++ b/cmd/x86/Makefile
@@ -5,3 +5,4 @@
obj-$(CONFIG_CMD_EXCEPTION) += exception.o
obj-$(CONFIG_USE_HOB) += hob.o
obj-$(CONFIG_HAVE_FSP) += fsp.o
+obj-$(CONFIG_CMD_ZBOOT) += zboot.o
diff --git a/cmd/x86/zboot.c b/cmd/x86/zboot.c
new file mode 100644
index 0000000..addf28c
--- /dev/null
+++ b/cmd/x86/zboot.c
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * (C) Copyright 2002
+ * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
+ */
+
+#include <command.h>
+#include <mapmem.h>
+#include <vsprintf.h>
+#include <asm/zimage.h>
+
+static int do_zboot_start(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ ulong bzimage_addr = 0, bzimage_size, initrd_addr, initrd_size;
+ ulong base_addr;
+ const char *s, *cmdline;
+
+ /* argv[1] holds the address of the bzImage */
+ s = cmd_arg1(argc, argv) ? : env_get("fileaddr");
+ if (s)
+ bzimage_addr = hextoul(s, NULL);
+ bzimage_size = argc > 2 ? hextoul(argv[2], NULL) : 0;
+ initrd_addr = argc > 3 ? hextoul(argv[3], NULL) : 0;
+ initrd_size = argc > 4 ? hextoul(argv[4], NULL) : 0;
+ base_addr = argc > 5 ? hextoul(argv[5], NULL) : 0;
+ cmdline = argc > 6 ? env_get(argv[6]) : NULL;
+
+ zboot_start(bzimage_addr, bzimage_size, initrd_addr, initrd_size,
+ base_addr, cmdline);
+
+ return 0;
+}
+
+static int do_zboot_load(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ int ret;
+
+ ret = zboot_load();
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int do_zboot_setup(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ if (!state.base_ptr) {
+ printf("base is not set: use 'zboot load' first\n");
+ return CMD_RET_FAILURE;
+ }
+ if (zboot_setup()) {
+ puts("Setting up boot parameters failed ...\n");
+ return CMD_RET_FAILURE;
+ }
+
+ if (zboot_setup())
+ return CMD_RET_FAILURE;
+
+ return 0;
+}
+
+static int do_zboot_info(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ zboot_info();
+
+ return 0;
+}
+
+static int do_zboot_go(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ int ret;
+
+ ret = zboot_go();
+ if (ret) {
+ printf("Kernel returned! (err=%d)\n", ret);
+ return CMD_RET_FAILURE;
+ }
+
+ return 0;
+}
+
+static int do_zboot_dump(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[])
+{
+ struct boot_params *base_ptr = state.base_ptr;
+
+ if (argc > 1)
+ base_ptr = (void *)hextoul(argv[1], NULL);
+ if (!base_ptr) {
+ printf("No zboot setup_base\n");
+ return CMD_RET_FAILURE;
+ }
+ zimage_dump(base_ptr, true);
+
+ return 0;
+}
+
+/* Note: This defines the complete_zboot() function */
+U_BOOT_SUBCMDS(zboot,
+ U_BOOT_CMD_MKENT(start, 8, 1, do_zboot_start, "", ""),
+ U_BOOT_CMD_MKENT(load, 1, 1, do_zboot_load, "", ""),
+ U_BOOT_CMD_MKENT(setup, 1, 1, do_zboot_setup, "", ""),
+ U_BOOT_CMD_MKENT(info, 1, 1, do_zboot_info, "", ""),
+ U_BOOT_CMD_MKENT(go, 1, 1, do_zboot_go, "", ""),
+ U_BOOT_CMD_MKENT(dump, 2, 1, do_zboot_dump, "", ""),
+)
+
+int do_zboot_states(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[], int state_mask)
+{
+ int ret;
+
+ if (flag & ZBOOT_STATE_START)
+ ret = do_zboot_start(cmdtp, flag, argc, argv);
+ if (!ret && (flag & ZBOOT_STATE_LOAD))
+ ret = do_zboot_load(cmdtp, flag, argc, argv);
+ if (!ret && (flag & ZBOOT_STATE_SETUP))
+ ret = do_zboot_setup(cmdtp, flag, argc, argv);
+ if (!ret && (flag & ZBOOT_STATE_INFO))
+ ret = do_zboot_info(cmdtp, flag, argc, argv);
+ if (!ret && (flag & ZBOOT_STATE_GO))
+ ret = do_zboot_go(cmdtp, flag, argc, argv);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int do_zboot_parent(struct cmd_tbl *cmdtp, int flag, int argc,
+ char *const argv[], int *repeatable)
+{
+ /* determine if we have a sub command */
+ if (argc > 1) {
+ char *endp;
+
+ hextoul(argv[1], &endp);
+ /*
+ * endp pointing to nul means that argv[1] was just a valid
+ * number, so pass it along to the normal processing
+ */
+ if (*endp)
+ return do_zboot(cmdtp, flag, argc, argv, repeatable);
+ }
+
+ do_zboot_states(cmdtp, flag, argc, argv, ZBOOT_STATE_START |
+ ZBOOT_STATE_LOAD | ZBOOT_STATE_SETUP |
+ ZBOOT_STATE_INFO | ZBOOT_STATE_GO);
+
+ return CMD_RET_FAILURE;
+}
+
+U_BOOT_CMDREP_COMPLETE(
+ zboot, 8, do_zboot_parent, "Boot bzImage",
+ "[addr] [size] [initrd addr] [initrd size] [setup] [cmdline]\n"
+ " addr - The optional starting address of the bzimage.\n"
+ " If not set it defaults to the environment\n"
+ " variable \"fileaddr\".\n"
+ " size - The optional size of the bzimage. Defaults to\n"
+ " zero.\n"
+ " initrd addr - The address of the initrd image to use, if any.\n"
+ " initrd size - The size of the initrd image to use, if any.\n"
+ " setup - The address of the kernel setup region, if this\n"
+ " is not at addr\n"
+ " cmdline - Environment variable containing the kernel\n"
+ " command line, to override U-Boot's normal\n"
+ " cmdline generation\n"
+ "\n"
+ "Sub-commands to do part of the zboot sequence:\n"
+ "\tstart [addr [arg ...]] - specify arguments\n"
+ "\tload - load OS image\n"
+ "\tsetup - set up table\n"
+ "\tinfo - show summary info\n"
+ "\tgo - start OS\n"
+ "\tdump [addr] - dump info (optional address of boot params)",
+ complete_zboot
+);
diff --git a/common/board_f.c b/common/board_f.c
index 8bada6f..039d6d7 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -718,6 +718,7 @@
return 0;
}
+void mcheck_on_ramrelocation(size_t offset);
static int setup_reloc(void)
{
if (!(gd->flags & GD_FLG_SKIP_RELOC)) {
@@ -743,6 +744,9 @@
if (gd->flags & GD_FLG_SKIP_RELOC) {
debug("Skipping relocation due to flag\n");
} else {
+#ifdef MCHECK_HEAP_PROTECTION
+ mcheck_on_ramrelocation(gd->reloc_off);
+#endif
debug("Relocation Offset is: %08lx\n", gd->reloc_off);
debug("Relocating to %08lx, new gd at %08lx, sp at %08lx\n",
gd->relocaddr, (ulong)map_to_sysmem(gd->new_gd),
diff --git a/common/cli.c b/common/cli.c
index a349382..1c33daf 100644
--- a/common/cli.c
+++ b/common/cli.c
@@ -11,6 +11,7 @@
#define pr_fmt(fmt) "cli: %s: " fmt, __func__
#include <common.h>
+#include <ansi.h>
#include <bootstage.h>
#include <cli.h>
#include <cli_hush.h>
@@ -336,4 +337,7 @@
#if defined(CONFIG_HUSH_INIT_VAR)
hush_init_var();
#endif
+
+ if (CONFIG_IS_ENABLED(VIDEO_ANSI))
+ printf(ANSI_CURSOR_SHOW "\n");
}
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index de3f042..a061621 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -32,6 +32,21 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef MCHECK_HEAP_PROTECTION
+ #define STATIC_IF_MCHECK static
+ #undef MALLOC_COPY
+ #undef MALLOC_ZERO
+static inline void MALLOC_ZERO(void *p, size_t sz) { memset(p, 0, sz); }
+static inline void MALLOC_COPY(void *dest, const void *src, size_t sz) { memcpy(dest, src, sz); }
+#else
+ #define STATIC_IF_MCHECK
+ #define mALLOc_impl mALLOc
+ #define fREe_impl fREe
+ #define rEALLOc_impl rEALLOc
+ #define mEMALIGn_impl mEMALIGn
+ #define cALLOc_impl cALLOc
+#endif
+
/*
Emulation of sbrk for WIN32
All code within the ifdef WIN32 is untested by me.
@@ -1270,10 +1285,11 @@
*/
+STATIC_IF_MCHECK
#if __STD_C
-Void_t* mALLOc(size_t bytes)
+Void_t* mALLOc_impl(size_t bytes)
#else
-Void_t* mALLOc(bytes) size_t bytes;
+Void_t* mALLOc_impl(bytes) size_t bytes;
#endif
{
mchunkptr victim; /* inspected/selected chunk */
@@ -1555,10 +1571,11 @@
*/
+STATIC_IF_MCHECK
#if __STD_C
-void fREe(Void_t* mem)
+void fREe_impl(Void_t* mem)
#else
-void fREe(mem) Void_t* mem;
+void fREe_impl(mem) Void_t* mem;
#endif
{
mchunkptr p; /* chunk corresponding to mem */
@@ -1696,10 +1713,11 @@
*/
+STATIC_IF_MCHECK
#if __STD_C
-Void_t* rEALLOc(Void_t* oldmem, size_t bytes)
+Void_t* rEALLOc_impl(Void_t* oldmem, size_t bytes)
#else
-Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
+Void_t* rEALLOc_impl(oldmem, bytes) Void_t* oldmem; size_t bytes;
#endif
{
INTERNAL_SIZE_T nb; /* padded request size */
@@ -1725,7 +1743,7 @@
#ifdef REALLOC_ZERO_BYTES_FREES
if (!bytes) {
- fREe(oldmem);
+ fREe_impl(oldmem);
return NULL;
}
#endif
@@ -1733,7 +1751,7 @@
if ((long)bytes < 0) return NULL;
/* realloc of null is supposed to be same as malloc */
- if (oldmem == NULL) return mALLOc(bytes);
+ if (oldmem == NULL) return mALLOc_impl(bytes);
#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
@@ -1758,7 +1776,7 @@
/* Note the extra SIZE_SZ overhead. */
if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */
/* Must alloc, copy, free. */
- newmem = mALLOc(bytes);
+ newmem = mALLOc_impl(bytes);
if (!newmem)
return NULL; /* propagate failure */
MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
@@ -1869,7 +1887,7 @@
/* Must allocate */
- newmem = mALLOc (bytes);
+ newmem = mALLOc_impl (bytes);
if (newmem == NULL) /* propagate failure */
return NULL;
@@ -1886,7 +1904,7 @@
/* Otherwise copy, free, and exit */
MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
- fREe(oldmem);
+ fREe_impl(oldmem);
return newmem;
} else {
VALGRIND_RESIZEINPLACE_BLOCK(oldmem, 0, bytes, SIZE_SZ);
@@ -1905,7 +1923,7 @@
set_inuse_bit_at_offset(remainder, remainder_size);
VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(remainder), remainder_size, SIZE_SZ,
false);
- fREe(chunk2mem(remainder)); /* let free() deal with it */
+ fREe_impl(chunk2mem(remainder)); /* let free() deal with it */
}
else
{
@@ -1939,10 +1957,11 @@
*/
+STATIC_IF_MCHECK
#if __STD_C
-Void_t* mEMALIGn(size_t alignment, size_t bytes)
+Void_t* mEMALIGn_impl(size_t alignment, size_t bytes)
#else
-Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
+Void_t* mEMALIGn_impl(alignment, bytes) size_t alignment; size_t bytes;
#endif
{
INTERNAL_SIZE_T nb; /* padded request size */
@@ -1965,7 +1984,7 @@
/* If need less alignment than we give anyway, just relay to malloc */
- if (alignment <= MALLOC_ALIGNMENT) return mALLOc(bytes);
+ if (alignment <= MALLOC_ALIGNMENT) return mALLOc_impl(bytes);
/* Otherwise, ensure that it is at least a minimum chunk size */
@@ -1974,7 +1993,7 @@
/* Call malloc with worst case padding to hit alignment. */
nb = request2size(bytes);
- m = (char*)(mALLOc(nb + alignment + MINSIZE));
+ m = (char*)(mALLOc_impl(nb + alignment + MINSIZE));
/*
* The attempt to over-allocate (with a size large enough to guarantee the
@@ -1990,7 +2009,7 @@
* Use bytes not nb, since mALLOc internally calls request2size too, and
* each call increases the size to allocate, to account for the header.
*/
- m = (char*)(mALLOc(bytes));
+ m = (char*)(mALLOc_impl(bytes));
/* Aligned -> return it */
if ((((unsigned long)(m)) % alignment) == 0)
return m;
@@ -1998,10 +2017,10 @@
* Otherwise, try again, requesting enough extra space to be able to
* acquire alignment.
*/
- fREe(m);
+ fREe_impl(m);
/* Add in extra bytes to match misalignment of unexpanded allocation */
extra = alignment - (((unsigned long)(m)) % alignment);
- m = (char*)(mALLOc(bytes + extra));
+ m = (char*)(mALLOc_impl(bytes + extra));
/*
* m might not be the same as before. Validate that the previous value of
* extra still works for the current value of m.
@@ -2010,7 +2029,7 @@
if (m) {
extra2 = alignment - (((unsigned long)(m)) % alignment);
if (extra2 > extra) {
- fREe(m);
+ fREe_impl(m);
m = NULL;
}
}
@@ -2060,7 +2079,7 @@
set_head(newp, newsize | PREV_INUSE);
set_inuse_bit_at_offset(newp, newsize);
set_head_size(p, leadsize);
- fREe(chunk2mem(p));
+ fREe_impl(chunk2mem(p));
p = newp;
VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(p), bytes, SIZE_SZ, false);
@@ -2078,7 +2097,7 @@
set_head_size(p, nb);
VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(remainder), remainder_size, SIZE_SZ,
false);
- fREe(chunk2mem(remainder));
+ fREe_impl(chunk2mem(remainder));
}
check_inuse_chunk(p);
@@ -2126,10 +2145,11 @@
*/
+STATIC_IF_MCHECK
#if __STD_C
-Void_t* cALLOc(size_t n, size_t elem_size)
+Void_t* cALLOc_impl(size_t n, size_t elem_size)
#else
-Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
+Void_t* cALLOc_impl(n, elem_size) size_t n; size_t elem_size;
#endif
{
mchunkptr p;
@@ -2145,7 +2165,7 @@
INTERNAL_SIZE_T oldtopsize = chunksize(top);
#endif
#endif
- Void_t* mem = mALLOc (sz);
+ Void_t* mem = mALLOc_impl (sz);
if ((long)n < 0) return NULL;
@@ -2204,6 +2224,90 @@
}
#endif
+
+#ifdef MCHECK_HEAP_PROTECTION
+ #include "mcheck_core.inc.h"
+ #if !__STD_C
+ #error "must have __STD_C"
+ #endif
+
+Void_t *mALLOc(size_t bytes)
+{
+ mcheck_pedantic_prehook();
+ size_t fullsz = mcheck_alloc_prehook(bytes);
+ void *p = mALLOc_impl(fullsz);
+
+ if (!p)
+ return p;
+ return mcheck_alloc_posthook(p, bytes);
+}
+
+void fREe(Void_t *mem) { fREe_impl(mcheck_free_prehook(mem)); }
+
+Void_t *rEALLOc(Void_t *oldmem, size_t bytes)
+{
+ mcheck_pedantic_prehook();
+ if (bytes == 0) {
+ if (oldmem)
+ fREe(oldmem);
+ return NULL;
+ }
+
+ if (oldmem == NULL)
+ return mALLOc(bytes);
+
+ void *p = mcheck_reallocfree_prehook(oldmem);
+ size_t newsz = mcheck_alloc_prehook(bytes);
+
+ p = rEALLOc_impl(p, newsz);
+ if (!p)
+ return p;
+ return mcheck_alloc_noclean_posthook(p, bytes);
+}
+
+Void_t *mEMALIGn(size_t alignment, size_t bytes)
+{
+ mcheck_pedantic_prehook();
+ size_t fullsz = mcheck_memalign_prehook(alignment, bytes);
+ void *p = mEMALIGn_impl(alignment, fullsz);
+
+ if (!p)
+ return p;
+ return mcheck_memalign_posthook(alignment, p, bytes);
+}
+
+// pvALLOc, vALLOc - redirect to mEMALIGn, defined here, so they need no wrapping.
+
+Void_t *cALLOc(size_t n, size_t elem_size)
+{
+ mcheck_pedantic_prehook();
+ // NB: here is no overflow check.
+ size_t fullsz = mcheck_alloc_prehook(n * elem_size);
+ void *p = cALLOc_impl(1, fullsz);
+
+ if (!p)
+ return p;
+ return mcheck_alloc_noclean_posthook(p, n * elem_size);
+}
+
+// mcheck API {
+int mcheck_pedantic(mcheck_abortfunc_t f)
+{
+ mcheck_initialize(f, 1);
+ return 0;
+}
+
+int mcheck(mcheck_abortfunc_t f)
+{
+ mcheck_initialize(f, 0);
+ return 0;
+}
+
+void mcheck_check_all(void) { mcheck_pedantic_check(); }
+
+enum mcheck_status mprobe(void *__ptr) { return mcheck_mprobe(__ptr); }
+// mcheck API }
+#endif
/*
diff --git a/common/mcheck_core.inc.h b/common/mcheck_core.inc.h
new file mode 100644
index 0000000..6902140
--- /dev/null
+++ b/common/mcheck_core.inc.h
@@ -0,0 +1,304 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2024 Free Software Foundation, Inc.
+ * Written by Eugene Uriev, based on glibc 2.0 prototype of Mike Haertel.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ * <https://www.gnu.org/licenses/>
+ */
+
+/*
+ * TL;DR: this is a porting of glibc mcheck into U-Boot
+ *
+ * This file contains no entities for external linkage.
+ * So mcheck protection may be used in parallel, e.g. for "malloc_simple(..)" and "malloc(..)".
+ * To do so, the file should be shared/include twice, - without linkage conflicts.
+ * I.e. "core"-part is shared as a source, but not as a binary.
+ * Maybe some optimization here make sense, to engage more binary sharing too.
+ * But, currently I strive to keep it as simple, as possible.
+ * And this, programmers'-only, mode don't pretend to be main.
+ *
+ * This library is aware of U-Boot specific. It's also aware of ARM alignment concerns.
+ * Unlike glibc-clients, U-Boot has limited malloc-usage, and only one thread.
+ * So it's better to make the protection heavier.
+ * Thus overflow canary here is greater, than glibc's one. Underflow canary is bigger too.
+ * U-Boot also allows to use fixed-size heap-registry, instead of double-linked list in glibc.
+ *
+ * Heavy canary allows to catch not only memset(..)-errors,
+ * but overflow/underflow of struct-array access:
+ * {
+ * struct mystruct* p = malloc(sizeof(struct mystruct) * N);
+ * p[-1].field1 = 0;
+ * p[N].field2 = 13;
+ * }
+ * TODO: In order to guarantee full coverage of that kind of errors, a user can add variable-size
+ * canaries here. So pre- and post-canary with size >= reqested_size, could be provided
+ * (with the price of 3x heap-usage). Therefore, it would catch 100% of changes beyond
+ * an array, for index(+1/-1) errors.
+ *
+ * U-Boot is a BL, not an OS with a lib. Activity of the library is set not in runtime,
+ * rather in compile-time, by MCHECK_HEAP_PROTECTION macro. That guarantees that
+ * we haven't missed first malloc.
+ */
+
+/*
+ * Testing
+ * This library had been successfully tested for U-Boot @ ARM SoC chip / 64bits.
+ * Proven for both default and pedantic mode: confirms U-Boot to be clean, and catches
+ * intentional/testing corruptions. Working with malloc_trim is not tested.
+ */
+#ifndef _MCHECKCORE_INC_H
+#define _MCHECKCORE_INC_H 1
+#include "mcheck.h"
+
+#if defined(MCHECK_HEAP_PROTECTION)
+#define mcheck_flood memset
+
+// these are from /dev/random:
+#define MAGICWORD 0x99ccf430fa562a05ULL
+#define MAGICFREE 0x4875e63c0c6fc08eULL
+#define MAGICTAIL 0x918dbcd7df78dcd6ULL
+#define MALLOCFLOOD ((char)0xb6)
+#define FREEFLOOD ((char)0xf5)
+#define PADDINGFLOOD ((char)0x58)
+
+// my normal run demands 4427-6449 chunks:
+#define REGISTRY_SZ 6608
+#define CANARY_DEPTH 2
+
+// avoid problems with BSS at early stage:
+static char mcheck_pedantic_flag __section(".data") = 0;
+static void *mcheck_registry[REGISTRY_SZ] __section(".data") = {0};
+static size_t mcheck_chunk_count __section(".data") = 0;
+static size_t mcheck_chunk_count_max __section(".data") = 0;
+
+typedef unsigned long long mcheck_elem;
+typedef struct {
+ mcheck_elem elems[CANARY_DEPTH];
+} mcheck_canary;
+struct mcheck_hdr {
+ size_t size; /* Exact size requested by user. */
+ size_t aln_skip; /* Ignored bytes, before the mcheck_hdr, to fulfill alignment */
+ mcheck_canary canary; /* Magic number to check header integrity. */
+};
+
+static void mcheck_default_abort(enum mcheck_status status, const void *p)
+{
+ const char *msg;
+
+ switch (status) {
+ case MCHECK_OK:
+ msg = "memory is consistent, library is buggy\n";
+ break;
+ case MCHECK_HEAD:
+ msg = "memory clobbered before allocated block\n";
+ break;
+ case MCHECK_TAIL:
+ msg = "memory clobbered past end of allocated block\n";
+ break;
+ case MCHECK_FREE:
+ msg = "block freed twice\n";
+ break;
+ default:
+ msg = "bogus mcheck_status, library is buggy\n";
+ break;
+ }
+ printf("\n\nmcheck: %p:%s!!! [%zu]\n\n", p, msg, mcheck_chunk_count_max);
+}
+
+static mcheck_abortfunc_t mcheck_abortfunc = &mcheck_default_abort;
+
+static inline size_t allign_size_up(size_t sz, size_t grain)
+{
+ return (sz + grain - 1) & ~(grain - 1);
+}
+
+#define mcheck_allign_customer_size(SZ) allign_size_up(SZ, sizeof(mcheck_elem))
+#define mcheck_evaluate_memalign_prefix_size(ALIGN) allign_size_up(sizeof(struct mcheck_hdr), ALIGN)
+
+static enum mcheck_status mcheck_OnNok(enum mcheck_status status, const void *p)
+{
+ (*mcheck_abortfunc)(status, p);
+ return status;
+}
+
+static enum mcheck_status mcheck_checkhdr(const struct mcheck_hdr *hdr)
+{
+ int i;
+
+ for (i = 0; i < CANARY_DEPTH; ++i)
+ if (hdr->canary.elems[i] == MAGICFREE)
+ return mcheck_OnNok(MCHECK_FREE, hdr + 1);
+
+ for (i = 0; i < CANARY_DEPTH; ++i)
+ if (hdr->canary.elems[i] != MAGICWORD)
+ return mcheck_OnNok(MCHECK_HEAD, hdr + 1);
+
+ const size_t payload_size = hdr->size;
+ const size_t payload_size_aligned = mcheck_allign_customer_size(payload_size);
+ const size_t padd_size = payload_size_aligned - hdr->size;
+
+ const char *payload = (const char *)&hdr[1];
+
+ for (i = 0; i < padd_size; ++i)
+ if (payload[payload_size + i] != PADDINGFLOOD)
+ return mcheck_OnNok(MCHECK_TAIL, hdr + 1);
+
+ const mcheck_canary *tail = (const mcheck_canary *)&payload[payload_size_aligned];
+
+ for (i = 0; i < CANARY_DEPTH; ++i)
+ if (tail->elems[i] != MAGICTAIL)
+ return mcheck_OnNok(MCHECK_TAIL, hdr + 1);
+ return MCHECK_OK;
+}
+
+enum { KEEP_CONTENT = 0, CLEAN_CONTENT, ANY_ALIGNMENT = 1 };
+static void *mcheck_free_helper(void *ptr, int clean_content)
+{
+ if (!ptr)
+ return ptr;
+
+ struct mcheck_hdr *hdr = &((struct mcheck_hdr *)ptr)[-1];
+ int i;
+
+ mcheck_checkhdr(hdr);
+ for (i = 0; i < CANARY_DEPTH; ++i)
+ hdr->canary.elems[i] = MAGICFREE;
+
+ if (clean_content)
+ mcheck_flood(ptr, FREEFLOOD, mcheck_allign_customer_size(hdr->size));
+
+ for (i = 0; i < REGISTRY_SZ; ++i)
+ if (mcheck_registry[i] == hdr) {
+ mcheck_registry[i] = 0;
+ break;
+ }
+
+ --mcheck_chunk_count;
+ return (char *)hdr - hdr->aln_skip;
+}
+
+static void *mcheck_free_prehook(void *ptr) { return mcheck_free_helper(ptr, CLEAN_CONTENT); }
+static void *mcheck_reallocfree_prehook(void *ptr) { return mcheck_free_helper(ptr, KEEP_CONTENT); }
+
+static size_t mcheck_alloc_prehook(size_t sz)
+{
+ sz = mcheck_allign_customer_size(sz);
+ return sizeof(struct mcheck_hdr) + sz + sizeof(mcheck_canary);
+}
+
+static void *mcheck_allocated_helper(void *altoghether_ptr, size_t customer_sz,
+ size_t alignment, int clean_content)
+{
+ const size_t slop = alignment ?
+ mcheck_evaluate_memalign_prefix_size(alignment) - sizeof(struct mcheck_hdr) : 0;
+ struct mcheck_hdr *hdr = (struct mcheck_hdr *)((char *)altoghether_ptr + slop);
+ int i;
+
+ hdr->size = customer_sz;
+ hdr->aln_skip = slop;
+ for (i = 0; i < CANARY_DEPTH; ++i)
+ hdr->canary.elems[i] = MAGICWORD;
+
+ char *payload = (char *)&hdr[1];
+
+ if (clean_content)
+ mcheck_flood(payload, MALLOCFLOOD, customer_sz);
+
+ const size_t customer_size_aligned = mcheck_allign_customer_size(customer_sz);
+
+ mcheck_flood(payload + customer_sz, PADDINGFLOOD, customer_size_aligned - customer_sz);
+
+ mcheck_canary *tail = (mcheck_canary *)&payload[customer_size_aligned];
+
+ for (i = 0; i < CANARY_DEPTH; ++i)
+ tail->elems[i] = MAGICTAIL;
+
+ ++mcheck_chunk_count;
+ if (mcheck_chunk_count > mcheck_chunk_count_max)
+ mcheck_chunk_count_max = mcheck_chunk_count;
+
+ for (i = 0; i < REGISTRY_SZ; ++i)
+ if (!mcheck_registry[i]) {
+ mcheck_registry[i] = hdr;
+ return payload; // normal end
+ }
+
+ static char *overflow_msg = "\n\n\nERROR: mcheck registry overflow, pedantic check would be incomplete!!\n\n\n\n";
+
+ printf("%s", overflow_msg);
+ overflow_msg = "(mcheck registry full)";
+ return payload;
+}
+
+static void *mcheck_alloc_posthook(void *altoghether_ptr, size_t customer_sz)
+{
+ return mcheck_allocated_helper(altoghether_ptr, customer_sz, ANY_ALIGNMENT, CLEAN_CONTENT);
+}
+
+static void *mcheck_alloc_noclean_posthook(void *altoghether_ptr, size_t customer_sz)
+{
+ return mcheck_allocated_helper(altoghether_ptr, customer_sz, ANY_ALIGNMENT, KEEP_CONTENT);
+}
+
+static size_t mcheck_memalign_prehook(size_t alig, size_t sz)
+{
+ return mcheck_evaluate_memalign_prefix_size(alig) + sz + sizeof(mcheck_canary);
+}
+
+static void *mcheck_memalign_posthook(size_t alignment, void *altoghether_ptr, size_t customer_sz)
+{
+ return mcheck_allocated_helper(altoghether_ptr, customer_sz, alignment, CLEAN_CONTENT);
+}
+
+static enum mcheck_status mcheck_mprobe(void *ptr)
+{
+ struct mcheck_hdr *hdr = &((struct mcheck_hdr *)ptr)[-1];
+
+ return mcheck_checkhdr(hdr);
+}
+
+static void mcheck_pedantic_check(void)
+{
+ int i;
+
+ for (i = 0; i < REGISTRY_SZ; ++i)
+ if (mcheck_registry[i])
+ mcheck_checkhdr(mcheck_registry[i]);
+}
+
+static void mcheck_pedantic_prehook(void)
+{
+ if (mcheck_pedantic_flag)
+ mcheck_pedantic_check();
+}
+
+static void mcheck_initialize(mcheck_abortfunc_t new_func, char pedantic_flag)
+{
+ mcheck_abortfunc = (new_func) ? new_func : &mcheck_default_abort;
+ mcheck_pedantic_flag = pedantic_flag;
+}
+
+void mcheck_on_ramrelocation(size_t offset)
+{
+ char *p;
+ int i;
+ // Simple, but inaccurate strategy: drop the pre-reloc heap
+ for (i = 0; i < REGISTRY_SZ; ++i)
+ if ((p = mcheck_registry[i]) != NULL ) {
+ printf("mcheck, WRN: forgetting %p chunk\n", p);
+ mcheck_registry[i] = 0;
+ }
+
+ mcheck_chunk_count = 0;
+}
+#endif
+#endif
diff --git a/common/usb.c b/common/usb.c
index 836506d..99e6b85 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -28,6 +28,7 @@
#include <common.h>
#include <command.h>
#include <dm.h>
+#include <dm/device_compat.h>
#include <log.h>
#include <malloc.h>
#include <memalign.h>
@@ -1084,6 +1085,54 @@
return 0;
}
+static int usb_device_is_ignored(u16 id_vendor, u16 id_product)
+{
+ ulong vid, pid;
+ char *end;
+ const char *cur = NULL;
+
+ /* ignore list depends on env support */
+ if (!CONFIG_IS_ENABLED(ENV_SUPPORT))
+ return 0;
+
+ cur = env_get("usb_ignorelist");
+
+ /* parse "usb_ignorelist" strictly */
+ while (cur && cur[0] != '\0') {
+ vid = simple_strtoul(cur, &end, 0);
+ /*
+ * If strtoul did not parse a single digit or the next char is
+ * not ':' the ignore list is malformed.
+ */
+ if (cur == end || end[0] != ':')
+ return -EINVAL;
+
+ cur = end + 1;
+ pid = simple_strtoul(cur, &end, 0);
+ /* Consider '*' as wildcard for the product ID */
+ if (cur == end && end[0] == '*') {
+ pid = U16_MAX + 1;
+ end++;
+ }
+ /*
+ * The ignore list is malformed if no product ID / wildcard was
+ * parsed or entries are not separated by ',' or terminated with
+ * '\0'.
+ */
+ if (cur == end || (end[0] != ',' && end[0] != '\0'))
+ return -EINVAL;
+
+ if (id_vendor == vid && (pid > U16_MAX || id_product == pid))
+ return -ENODEV;
+
+ if (end[0] == '\0')
+ break;
+ cur = end + 1;
+ }
+
+ return 0;
+}
+
int usb_select_config(struct usb_device *dev)
{
unsigned char *tmpbuf = NULL;
@@ -1099,6 +1148,27 @@
le16_to_cpus(&dev->descriptor.idProduct);
le16_to_cpus(&dev->descriptor.bcdDevice);
+ /* ignore devices from usb_ignorelist */
+ err = usb_device_is_ignored(dev->descriptor.idVendor,
+ dev->descriptor.idProduct);
+ if (err == -ENODEV) {
+ debug("Ignoring USB device 0x%x:0x%x\n",
+ dev->descriptor.idVendor, dev->descriptor.idProduct);
+ return err;
+ } else if (err == -EINVAL) {
+ /*
+ * Continue on "usb_ignorelist" parsing errors. The list is
+ * parsed for each device returning the error would result in
+ * ignoring all USB devices.
+ * Since the parsing error is independent of the probed device
+ * report errors with printf instead of dev_err.
+ */
+ printf("usb_ignorelist parse error in \"%s\"\n",
+ env_get("usb_ignorelist"));
+ } else if (err < 0) {
+ return err;
+ }
+
/*
* Kingston DT Ultimate 32GB USB 3.0 seems to be extremely sensitive
* about this first Get Descriptor request. If there are any other
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 4cbc9ac..820f591 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -24,6 +24,18 @@
#include <usb.h>
/*
+ * USB vendor and product IDs used for quirks.
+ */
+#define USB_VENDOR_ID_APPLE 0x05ac
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021 0x029c
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021 0x029a
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f
+
+#define USB_VENDOR_ID_KEYCHRON 0x3434
+
+#define USB_HID_QUIRK_POLL_NO_REPORT_IDLE BIT(0)
+
+/*
* If overwrite_console returns 1, the stdin, stderr and stdout
* are switched to the serial port, else the settings in the
* environment are used
@@ -106,6 +118,8 @@
unsigned long last_report;
struct int_queue *intq;
+ uint32_t ifnum;
+
uint32_t repeat_delay;
uint32_t usb_in_pointer;
@@ -150,8 +164,8 @@
*/
static void usb_kbd_setled(struct usb_device *dev)
{
- struct usb_interface *iface = &dev->config.if_desc[0];
struct usb_kbd_pdata *data = dev->privptr;
+ struct usb_interface *iface = &dev->config.if_desc[data->ifnum];
ALLOC_ALIGN_BUFFER(uint32_t, leds, 1, USB_DMA_MINALIGN);
*leds = data->flags & USB_KBD_LEDMASK;
@@ -365,7 +379,7 @@
#if defined(CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP)
struct usb_interface *iface;
struct usb_kbd_pdata *data = dev->privptr;
- iface = &dev->config.if_desc[0];
+ iface = &dev->config.if_desc[data->ifnum];
usb_get_report(dev, iface->desc.bInterfaceNumber,
1, 0, data->new, USB_KBD_BOOT_REPORT_SIZE);
if (memcmp(data->old, data->new, USB_KBD_BOOT_REPORT_SIZE)) {
@@ -464,6 +478,7 @@
struct usb_interface *iface;
struct usb_endpoint_descriptor *ep;
struct usb_kbd_pdata *data;
+ unsigned int quirks = 0;
int epNum;
if (dev->descriptor.bNumConfigurations != 1)
@@ -496,6 +511,15 @@
debug("USB KBD: found interrupt EP: 0x%x\n", ep->bEndpointAddress);
+ switch (dev->descriptor.idVendor) {
+ case USB_VENDOR_ID_APPLE:
+ case USB_VENDOR_ID_KEYCHRON:
+ quirks |= USB_HID_QUIRK_POLL_NO_REPORT_IDLE;
+ break;
+ default:
+ break;
+ }
+
data = malloc(sizeof(struct usb_kbd_pdata));
if (!data) {
printf("USB KBD: Error allocating private data\n");
@@ -509,6 +533,8 @@
data->new = memalign(USB_DMA_MINALIGN,
roundup(USB_KBD_BOOT_REPORT_SIZE, USB_DMA_MINALIGN));
+ data->ifnum = ifnum;
+
/* Insert private data into USB device structure */
dev->privptr = data;
@@ -534,6 +560,14 @@
usb_set_idle(dev, iface->desc.bInterfaceNumber, 0, 0);
#endif
+ /*
+ * Apple and Keychron keyboards do not report the device state. Reports
+ * are only returned during key presses.
+ */
+ if (quirks & USB_HID_QUIRK_POLL_NO_REPORT_IDLE) {
+ debug("USB KBD: quirk: skip testing device state\n");
+ return 1;
+ }
debug("USB KBD: enable interrupt pipe...\n");
#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
data->intq = create_int_queue(dev, data->intpipe, 1,
@@ -561,10 +595,17 @@
{
char *stdinname;
struct stdio_dev usb_kbd_dev;
+ unsigned int ifnum;
+ unsigned int max_ifnum = min((unsigned int)USB_MAX_ACTIVE_INTERFACES,
+ (unsigned int)dev->config.no_of_if);
int error;
/* Try probing the keyboard */
- if (usb_kbd_probe_dev(dev, 0) != 1)
+ for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
+ if (usb_kbd_probe_dev(dev, ifnum) == 1)
+ break;
+ }
+ if (ifnum >= max_ifnum)
return -ENOENT;
/* Register the keyboard */
@@ -731,6 +772,18 @@
.bInterfaceSubClass = USB_SUB_HID_BOOT,
.bInterfaceProtocol = USB_PROT_HID_KEYBOARD,
},
+ {
+ USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_2021),
+ },
+ {
+ USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_2021),
+ },
+ {
+ USB_DEVICE(USB_VENDOR_ID_APPLE,
+ USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021),
+ },
{ } /* Terminating entry */
};
diff --git a/configs/am62px_evm_a53_defconfig b/configs/am62px_evm_a53_defconfig
index 65dfda1..638d2e9 100644
--- a/configs/am62px_evm_a53_defconfig
+++ b/configs/am62px_evm_a53_defconfig
@@ -70,6 +70,7 @@
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_UBI=y
+CONFIG_MMC_SPEED_MODE_SET=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_OF_UPSTREAM=y
diff --git a/configs/am62x_evm_a53_defconfig b/configs/am62x_evm_a53_defconfig
index d650b85..6b37f8b 100644
--- a/configs/am62x_evm_a53_defconfig
+++ b/configs/am62x_evm_a53_defconfig
@@ -33,7 +33,7 @@
CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000
CONFIG_BOOTSTD_FULL=y
CONFIG_SYS_BOOTM_LEN=0x800000
-CONFIG_BOOTCOMMAND="run envboot; bootflow scan -lb"
+CONFIG_BOOTCOMMAND="run findfdt; run envboot; bootflow scan -lb"
CONFIG_BOARD_LATE_INIT=y
CONFIG_SPL_MAX_SIZE=0x58000
CONFIG_SPL_SYS_REPORT_STACK_F_USAGE=y
@@ -52,6 +52,7 @@
CONFIG_CMD_BOOTEFI_SELFTEST=y
CONFIG_CMD_NVEDIT_EFI=y
CONFIG_CMD_MMC=y
+CONFIG_MMC_SPEED_MODE_SET=y
CONFIG_CMD_EFIDEBUG=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
diff --git a/configs/am64x_evm_a53_defconfig b/configs/am64x_evm_a53_defconfig
index 61b498b..8b0ccba 100644
--- a/configs/am64x_evm_a53_defconfig
+++ b/configs/am64x_evm_a53_defconfig
@@ -75,6 +75,7 @@
CONFIG_CMD_TIME=y
CONFIG_CMD_PMIC=y
CONFIG_CMD_REGULATOR=y
+CONFIG_MMC_SPEED_MODE_SET=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_OF_UPSTREAM=y
diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig
index 500335f..3afa80f 100644
--- a/configs/am65x_evm_a53_defconfig
+++ b/configs/am65x_evm_a53_defconfig
@@ -73,6 +73,7 @@
CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0"
CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),128k(ospi.env),128k(ospi.env.backup),1m(ospi.sysfw),-@8m(ospi.rootfs)"
CONFIG_CMD_UBI=y
+CONFIG_MMC_SPEED_MODE_SET=y
# CONFIG_ISO_PARTITION is not set
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
diff --git a/configs/colibri_vf_defconfig b/configs/colibri_vf_defconfig
index a5e6bcb..0249dc3 100644
--- a/configs/colibri_vf_defconfig
+++ b/configs/colibri_vf_defconfig
@@ -17,6 +17,7 @@
CONFIG_ENV_VARS_UBOOT_CONFIG=y
CONFIG_HAS_BOARD_SIZE_LIMIT=y
CONFIG_BOARD_SIZE_LIMIT=520192
+# CONFIG_BOOTM is not set
CONFIG_BOOTDELAY=1
CONFIG_FDT_FIXUP_PARTITIONS=y
CONFIG_USE_BOOTCOMMAND=y
@@ -33,7 +34,6 @@
# CONFIG_SYS_LONGHELP is not set
CONFIG_SYS_PROMPT="Colibri VFxx # "
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
CONFIG_CMD_BOOTZ=y
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_IMI is not set
diff --git a/configs/coreboot64_defconfig b/configs/coreboot64_defconfig
index dab5eaf..da42ad0 100644
--- a/configs/coreboot64_defconfig
+++ b/configs/coreboot64_defconfig
@@ -16,6 +16,7 @@
CONFIG_SHOW_BOOT_PROGRESS=y
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/sdb3 init=/sbin/init rootwait ro"
+CONFIG_BOOTCOMMAND="bootflow scan -l; if bootflow menu; then cls; bootflow boot; fi"
CONFIG_SYS_PBSIZE=532
CONFIG_PRE_CONSOLE_BUFFER=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
@@ -59,6 +60,7 @@
CONFIG_SOUND=y
CONFIG_SOUND_I8254=y
CONFIG_VIDEO_COPY=y
+CONFIG_CONSOLE_TRUETYPE=y
CONFIG_CONSOLE_SCROLL_LINES=5
CONFIG_SPL_ACPI=y
CONFIG_CMD_DHRYSTONE=y
diff --git a/configs/coreboot_defconfig b/configs/coreboot_defconfig
index c846dfc..0b103ef 100644
--- a/configs/coreboot_defconfig
+++ b/configs/coreboot_defconfig
@@ -14,6 +14,7 @@
CONFIG_SHOW_BOOT_PROGRESS=y
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=/dev/sdb3 init=/sbin/init rootwait ro"
+CONFIG_BOOTCOMMAND="bootflow scan -l; if bootflow menu; then cls; bootflow boot; fi"
CONFIG_PRE_CONSOLE_BUFFER=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_LOG=y
@@ -53,6 +54,7 @@
CONFIG_SOUND=y
CONFIG_SOUND_I8254=y
CONFIG_VIDEO_COPY=y
+CONFIG_CONSOLE_TRUETYPE=y
CONFIG_CONSOLE_SCROLL_LINES=5
CONFIG_CMD_DHRYSTONE=y
# CONFIG_GZIP is not set
diff --git a/configs/iot_devkit_defconfig b/configs/iot_devkit_defconfig
index c492005..d02a28a 100644
--- a/configs/iot_devkit_defconfig
+++ b/configs/iot_devkit_defconfig
@@ -14,12 +14,12 @@
CONFIG_SYS_CLK_FREQ=16000000
CONFIG_SYS_LOAD_ADDR=0x30000000
CONFIG_LOCALVERSION="-iotdk-1.0"
+# CONFIG_BOOTM is not set
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_SYS_CBSIZE=256
CONFIG_SYS_PBSIZE=280
CONFIG_SYS_PROMPT="IoTDK# "
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_XIMG is not set
# CONFIG_CMD_LOADB is not set
diff --git a/configs/milkv_duo_defconfig b/configs/milkv_duo_defconfig
index 548adf1..e8413d7 100644
--- a/configs/milkv_duo_defconfig
+++ b/configs/milkv_duo_defconfig
@@ -17,6 +17,16 @@
CONFIG_SYS_PBSIZE=544
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="milkv_duo# "
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
CONFIG_ENV_OVERWRITE=y
+CONFIG_MMC=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ADMA=y
+CONFIG_MMC_SDHCI_CV1800B=y
CONFIG_SYS_NS16550=y
CONFIG_SYS_NS16550_MEM32=y
diff --git a/configs/mx6memcal_defconfig b/configs/mx6memcal_defconfig
index 7f11e6f..6c5481c 100644
--- a/configs/mx6memcal_defconfig
+++ b/configs/mx6memcal_defconfig
@@ -14,6 +14,7 @@
CONFIG_SPL=y
CONFIG_SYS_MEMTEST_START=0x10000000
CONFIG_SYS_MEMTEST_END=0x20000000
+# CONFIG_BOOTM is not set
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_SYS_PBSIZE=528
CONFIG_SPL_SYS_MALLOC=y
@@ -21,7 +22,6 @@
CONFIG_HUSH_PARSER=y
CONFIG_SYS_MAXARGS=32
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_IMI is not set
# CONFIG_CMD_XIMG is not set
diff --git a/configs/phycore_am62x_a53_defconfig b/configs/phycore_am62x_a53_defconfig
index 552b7e9..08a2532 100644
--- a/configs/phycore_am62x_a53_defconfig
+++ b/configs/phycore_am62x_a53_defconfig
@@ -33,6 +33,7 @@
CONFIG_SYS_BOOTM_LEN=0x800000
CONFIG_BOOTCOMMAND="run mmcboot; bootflow scan -lb"
CONFIG_DEFAULT_FDT_FILE="oftree"
+CONFIG_BOARD_LATE_INIT=y
CONFIG_SPL_MAX_SIZE=0x58000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0x80c80000
diff --git a/configs/qemu-x86_64_defconfig b/configs/qemu-x86_64_defconfig
index 451af0b..008eb46 100644
--- a/configs/qemu-x86_64_defconfig
+++ b/configs/qemu-x86_64_defconfig
@@ -6,7 +6,7 @@
CONFIG_MAX_CPUS=2
CONFIG_SPL_DM_SPI=y
CONFIG_DEFAULT_DEVICE_TREE="qemu-x86_i440fx"
-CONFIG_SPL_TEXT_BASE=0xfffd8000
+CONFIG_SPL_TEXT_BASE=0xfffd4000
CONFIG_SPL_SYS_MALLOC_F_LEN=0x2000
CONFIG_DEBUG_UART_BASE=0x3f8
CONFIG_DEBUG_UART_CLOCK=1843200
@@ -17,7 +17,7 @@
CONFIG_SMP=y
CONFIG_GENERATE_PIRQ_TABLE=y
CONFIG_GENERATE_MP_TABLE=y
-CONFIG_X86_OFFSET_U_BOOT=0xfff00000
+CONFIG_X86_OFFSET_U_BOOT=0xffe00000
CONFIG_SYS_MONITOR_BASE=0x01110000
CONFIG_FIT=y
CONFIG_SPL_LOAD_FIT=y
@@ -80,6 +80,7 @@
CONFIG_SYS_NS16550_PORT_MAPPED=y
CONFIG_SPI=y
CONFIG_USB_KEYBOARD=y
+CONFIG_CONSOLE_TRUETYPE=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_USER=y
CONFIG_FRAMEBUFFER_VESA_MODE=0x144
diff --git a/configs/qemu-x86_defconfig b/configs/qemu-x86_defconfig
index b2a221b..947d15c 100644
--- a/configs/qemu-x86_defconfig
+++ b/configs/qemu-x86_defconfig
@@ -57,6 +57,7 @@
CONFIG_SYS_NS16550_PORT_MAPPED=y
CONFIG_SPI=y
CONFIG_USB_KEYBOARD=y
+CONFIG_CONSOLE_TRUETYPE=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_USER=y
CONFIG_FRAMEBUFFER_VESA_MODE=0x144
diff --git a/configs/socfpga_chameleonv3_defconfig b/configs/socfpga_chameleonv3_defconfig
index 6ea61ca..7506aa8 100644
--- a/configs/socfpga_chameleonv3_defconfig
+++ b/configs/socfpga_chameleonv3_defconfig
@@ -7,6 +7,7 @@
CONFIG_SPL_TEXT_BASE=0xFFE00000
CONFIG_SPL_DRIVERS_MISC=y
CONFIG_TARGET_SOCFPGA_CHAMELEONV3=y
+CONFIG_SOCFPGA_ARRIA10_ALWAYS_REPROGRAM=y
CONFIG_SPL_FS_FAT=y
CONFIG_FIT=y
CONFIG_SPL_FIT=y
diff --git a/configs/starfive_visionfive2_defconfig b/configs/starfive_visionfive2_defconfig
index 7a3f1d4..fa80d48 100644
--- a/configs/starfive_visionfive2_defconfig
+++ b/configs/starfive_visionfive2_defconfig
@@ -40,7 +40,6 @@
CONFIG_BOOTARGS="console=ttyS0,115200 debug rootwait earlycon=sbi"
CONFIG_USE_PREBOOT=y
CONFIG_PREBOOT="nvme scan; usb start; setenv fdt_addr ${fdtcontroladdr}; fdt addr ${fdtcontroladdr};"
-CONFIG_DEFAULT_FDT_FILE="starfive/jh7110-starfive-visionfive-2.dtb"
CONFIG_SYS_CBSIZE=256
CONFIG_SYS_PBSIZE=276
CONFIG_DISPLAY_CPUINFO=y
diff --git a/configs/tools-only_defconfig b/configs/tools-only_defconfig
index b54d2ce..5de482a 100644
--- a/configs/tools-only_defconfig
+++ b/configs/tools-only_defconfig
@@ -12,10 +12,10 @@
# CONFIG_BOOTSTD_FULL is not set
# CONFIG_BOOTMETH_CROS is not set
# CONFIG_BOOTMETH_VBE is not set
+# CONFIG_BOOTM is not set
CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="run distro_bootcmd"
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_EXTENSION is not set
diff --git a/configs/verdin-am62_a53_defconfig b/configs/verdin-am62_a53_defconfig
index 15424fe..633e9c7 100644
--- a/configs/verdin-am62_a53_defconfig
+++ b/configs/verdin-am62_a53_defconfig
@@ -14,7 +14,7 @@
CONFIG_ENV_SIZE=0x2000
CONFIG_ENV_OFFSET=0xFFFFDE00
CONFIG_DM_GPIO=y
-CONFIG_DEFAULT_DEVICE_TREE="k3-am625-verdin-wifi-dev"
+CONFIG_DEFAULT_DEVICE_TREE="ti/k3-am625-verdin-wifi-dev"
CONFIG_SPL_TEXT_BASE=0x80080000
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_DM_RESET=y
diff --git a/configs/xilinx_mbv32_defconfig b/configs/xilinx_mbv32_defconfig
index 2689495..4113409 100644
--- a/configs/xilinx_mbv32_defconfig
+++ b/configs/xilinx_mbv32_defconfig
@@ -1,30 +1,43 @@
CONFIG_RISCV=y
-CONFIG_TEXT_BASE=0x21200000
-CONFIG_SYS_MALLOC_LEN=0x800000
+CONFIG_SYS_MALLOC_LEN=0xe00000
CONFIG_NR_DRAM_BANKS=1
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x20200000
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x21200000
CONFIG_ENV_SIZE=0x20000
CONFIG_DEFAULT_DEVICE_TREE="xilinx-mbv32"
+CONFIG_SPL_STACK=0x20200000
+CONFIG_SPL_SIZE_LIMIT=0x40000
+CONFIG_SPL=y
CONFIG_DEBUG_UART_BASE=0x40600000
CONFIG_DEBUG_UART_CLOCK=1000000
CONFIG_SYS_CLK_FREQ=100000000
CONFIG_BOOT_SCRIPT_OFFSET=0x0
-CONFIG_SYS_LOAD_ADDR=0x80200000
+CONFIG_SYS_LOAD_ADDR=0x20200000
CONFIG_DEBUG_UART=y
CONFIG_TARGET_XILINX_MBV=y
+# CONFIG_SPL_SMP is not set
+CONFIG_REMAKE_ELF=y
CONFIG_FIT=y
+CONFIG_SPL_LOAD_FIT_ADDRESS=0x20200000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_DISPLAY_CPUINFO=y
CONFIG_DISPLAY_BOARDINFO=y
# CONFIG_BOARD_LATE_INIT is not set
+CONFIG_SPL_MAX_SIZE=0x40000
+CONFIG_SPL_BSS_START_ADDR=0x24000000
+CONFIG_SPL_BSS_MAX_SIZE=0x80000
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_SYS_MALLOC=y
+CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
# CONFIG_CMD_MII is not set
CONFIG_CMD_TIMER=y
-CONFIG_OF_EMBED=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_DM_MTD=y
CONFIG_DEBUG_UART_ANNOUNCE=y
CONFIG_DEBUG_UART_SKIP_INIT=y
CONFIG_XILINX_UARTLITE=y
CONFIG_XILINX_TIMER=y
+# CONFIG_BINMAN_FDT is not set
CONFIG_PANIC_HANG=y
+CONFIG_SPL_GZIP=y
diff --git a/configs/xilinx_mbv32_smode_defconfig b/configs/xilinx_mbv32_smode_defconfig
index c724d1b..9938147 100644
--- a/configs/xilinx_mbv32_smode_defconfig
+++ b/configs/xilinx_mbv32_smode_defconfig
@@ -1,27 +1,40 @@
CONFIG_RISCV=y
-CONFIG_TEXT_BASE=0x21200000
-CONFIG_SYS_MALLOC_LEN=0x800000
+CONFIG_SYS_MALLOC_LEN=0xe00000
CONFIG_NR_DRAM_BANKS=1
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
-CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x20200000
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x21200000
CONFIG_ENV_SIZE=0x20000
CONFIG_DEFAULT_DEVICE_TREE="xilinx-mbv32"
+CONFIG_SPL_STACK=0x20200000
+CONFIG_SPL_SIZE_LIMIT=0x40000
+CONFIG_SPL=y
CONFIG_DEBUG_UART_BASE=0x40600000
CONFIG_DEBUG_UART_CLOCK=1000000
CONFIG_SYS_CLK_FREQ=100000000
CONFIG_BOOT_SCRIPT_OFFSET=0x0
-CONFIG_SYS_LOAD_ADDR=0x80200000
+CONFIG_SYS_LOAD_ADDR=0x20200000
CONFIG_TARGET_XILINX_MBV=y
+CONFIG_SPL_OPENSBI_LOAD_ADDR=0x20100000
CONFIG_RISCV_SMODE=y
+# CONFIG_SPL_SMP is not set
+CONFIG_REMAKE_ELF=y
CONFIG_FIT=y
+CONFIG_SPL_LOAD_FIT_ADDRESS=0x20200000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_DISPLAY_CPUINFO=y
CONFIG_DISPLAY_BOARDINFO=y
# CONFIG_BOARD_LATE_INIT is not set
+CONFIG_SPL_MAX_SIZE=0x40000
+CONFIG_SPL_BSS_START_ADDR=0x24000000
+CONFIG_SPL_BSS_MAX_SIZE=0x80000
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_SYS_MALLOC=y
+CONFIG_SPL_SYS_MALLOC_SIZE=0x800000
+CONFIG_SPL_OPENSBI_SCRATCH_OPTIONS=0x2
# CONFIG_CMD_MII is not set
CONFIG_CMD_TIMER=y
-CONFIG_OF_EMBED=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_DM_MTD=y
CONFIG_DEBUG_UART_UARTLITE=y
CONFIG_DEBUG_UART_ANNOUNCE=y
@@ -29,4 +42,6 @@
CONFIG_XILINX_UARTLITE=y
# CONFIG_RISCV_TIMER is not set
CONFIG_XILINX_TIMER=y
+# CONFIG_BINMAN_FDT is not set
CONFIG_PANIC_HANG=y
+CONFIG_SPL_GZIP=y
diff --git a/configs/xilinx_versal_mini_defconfig b/configs/xilinx_versal_mini_defconfig
index 9d3924c..143d262 100644
--- a/configs/xilinx_versal_mini_defconfig
+++ b/configs/xilinx_versal_mini_defconfig
@@ -18,6 +18,7 @@
CONFIG_SYS_MEMTEST_END=0x00001000
# CONFIG_EXPERT is not set
CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
# CONFIG_LEGACY_IMAGE_FORMAT is not set
# CONFIG_AUTOBOOT is not set
CONFIG_SYS_CBSIZE=1024
@@ -33,7 +34,6 @@
CONFIG_SYS_PROMPT="Versal> "
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_mini_emmc0_defconfig b/configs/xilinx_versal_mini_emmc0_defconfig
index 5c949e3..b0e3462 100644
--- a/configs/xilinx_versal_mini_emmc0_defconfig
+++ b/configs/xilinx_versal_mini_emmc0_defconfig
@@ -15,6 +15,7 @@
CONFIG_SYS_LOAD_ADDR=0x8000000
# CONFIG_EXPERT is not set
CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
# CONFIG_AUTOBOOT is not set
CONFIG_SYS_CBSIZE=1024
CONFIG_SYS_PBSIZE=1049
@@ -30,7 +31,6 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_mini_emmc1_defconfig b/configs/xilinx_versal_mini_emmc1_defconfig
index 04cba5b..559b32c 100644
--- a/configs/xilinx_versal_mini_emmc1_defconfig
+++ b/configs/xilinx_versal_mini_emmc1_defconfig
@@ -15,6 +15,7 @@
CONFIG_SYS_LOAD_ADDR=0x8000000
# CONFIG_EXPERT is not set
CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
# CONFIG_AUTOBOOT is not set
CONFIG_SYS_CBSIZE=1024
CONFIG_SYS_PBSIZE=1049
@@ -30,7 +31,6 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_mini_ospi_defconfig b/configs/xilinx_versal_mini_ospi_defconfig
index 7a11035..c02c6ba 100644
--- a/configs/xilinx_versal_mini_ospi_defconfig
+++ b/configs/xilinx_versal_mini_ospi_defconfig
@@ -19,6 +19,7 @@
CONFIG_LTO=y
# CONFIG_EXPERT is not set
CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
# CONFIG_AUTOBOOT is not set
CONFIG_SYS_CONSOLE_INFO_QUIET=y
# CONFIG_DISPLAY_CPUINFO is not set
@@ -31,7 +32,6 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_mini_qspi_defconfig b/configs/xilinx_versal_mini_qspi_defconfig
index 58945a1..4d4b59a 100644
--- a/configs/xilinx_versal_mini_qspi_defconfig
+++ b/configs/xilinx_versal_mini_qspi_defconfig
@@ -17,6 +17,7 @@
CONFIG_LTO=y
# CONFIG_EXPERT is not set
CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
# CONFIG_AUTOBOOT is not set
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_LOGLEVEL=0
@@ -32,7 +33,6 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_net_mini_defconfig b/configs/xilinx_versal_net_mini_defconfig
index 7dac1ec..317fc8e 100644
--- a/configs/xilinx_versal_net_mini_defconfig
+++ b/configs/xilinx_versal_net_mini_defconfig
@@ -20,6 +20,7 @@
CONFIG_SYS_MEMTEST_END=0x00001000
# CONFIG_EXPERT is not set
CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
# CONFIG_LEGACY_IMAGE_FORMAT is not set
# CONFIG_AUTOBOOT is not set
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
@@ -33,7 +34,6 @@
CONFIG_SYS_PROMPT="Versal NET> "
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_net_mini_emmc_defconfig b/configs/xilinx_versal_net_mini_emmc_defconfig
index fc88eee..31c4432 100644
--- a/configs/xilinx_versal_net_mini_emmc_defconfig
+++ b/configs/xilinx_versal_net_mini_emmc_defconfig
@@ -25,7 +25,7 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
+# CONFIG_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_net_mini_ospi_defconfig b/configs/xilinx_versal_net_mini_ospi_defconfig
index d78c9f8..d0d91f9 100644
--- a/configs/xilinx_versal_net_mini_ospi_defconfig
+++ b/configs/xilinx_versal_net_mini_ospi_defconfig
@@ -30,7 +30,7 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
+# CONFIG_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_net_mini_qspi_defconfig b/configs/xilinx_versal_net_mini_qspi_defconfig
index b0567f8..48b6d86 100644
--- a/configs/xilinx_versal_net_mini_qspi_defconfig
+++ b/configs/xilinx_versal_net_mini_qspi_defconfig
@@ -31,7 +31,7 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
+# CONFIG_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_versal_net_virt_defconfig b/configs/xilinx_versal_net_virt_defconfig
index 29cebe2..40c6a29 100644
--- a/configs/xilinx_versal_net_virt_defconfig
+++ b/configs/xilinx_versal_net_virt_defconfig
@@ -60,6 +60,9 @@
CONFIG_OF_BOARD=y
CONFIG_DTB_RESELECT=y
CONFIG_MULTI_DTB_FIT=y
+CONFIG_ENV_IS_NOWHERE=y
+CONFIG_ENV_IS_IN_FAT=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_NET_RANDOM_ETHADDR=y
diff --git a/configs/xilinx_zynqmp_kria_defconfig b/configs/xilinx_zynqmp_kria_defconfig
index 7cb8b62..7af8b27 100644
--- a/configs/xilinx_zynqmp_kria_defconfig
+++ b/configs/xilinx_zynqmp_kria_defconfig
@@ -155,7 +155,6 @@
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ZYNQ=y
CONFIG_DM_MTD=y
-CONFIG_SPI_FLASH_BAR=y
CONFIG_SPI_FLASH_STMICRO=y
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
CONFIG_SPI_FLASH_MTD=y
diff --git a/configs/xilinx_zynqmp_mini_defconfig b/configs/xilinx_zynqmp_mini_defconfig
index 7fdd2ee..40d4a4a 100644
--- a/configs/xilinx_zynqmp_mini_defconfig
+++ b/configs/xilinx_zynqmp_mini_defconfig
@@ -13,6 +13,7 @@
CONFIG_SYS_MEMTEST_START=0x00000000
CONFIG_SYS_MEMTEST_END=0x00001000
CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
# CONFIG_LEGACY_IMAGE_FORMAT is not set
# CONFIG_AUTOBOOT is not set
CONFIG_SYS_CBSIZE=1024
@@ -26,7 +27,6 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_zynqmp_mini_emmc0_defconfig b/configs/xilinx_zynqmp_mini_emmc0_defconfig
index bf34832..9cccf5d 100644
--- a/configs/xilinx_zynqmp_mini_emmc0_defconfig
+++ b/configs/xilinx_zynqmp_mini_emmc0_defconfig
@@ -17,6 +17,7 @@
CONFIG_REMAKE_ELF=y
# CONFIG_MP is not set
CONFIG_FIT=y
+# CONFIG_BOOTM is not set
CONFIG_SUPPORT_RAW_INITRD=y
# CONFIG_AUTOBOOT is not set
CONFIG_SYS_CBSIZE=1024
@@ -37,7 +38,6 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_zynqmp_mini_emmc1_defconfig b/configs/xilinx_zynqmp_mini_emmc1_defconfig
index af70ccf..3919e23 100644
--- a/configs/xilinx_zynqmp_mini_emmc1_defconfig
+++ b/configs/xilinx_zynqmp_mini_emmc1_defconfig
@@ -17,6 +17,7 @@
CONFIG_REMAKE_ELF=y
# CONFIG_MP is not set
CONFIG_FIT=y
+# CONFIG_BOOTM is not set
CONFIG_SUPPORT_RAW_INITRD=y
# CONFIG_AUTOBOOT is not set
CONFIG_SYS_CBSIZE=1024
@@ -37,7 +38,6 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
diff --git a/configs/xilinx_zynqmp_mini_nand_defconfig b/configs/xilinx_zynqmp_mini_nand_defconfig
index d2e920f..ae0c3ae 100644
--- a/configs/xilinx_zynqmp_mini_nand_defconfig
+++ b/configs/xilinx_zynqmp_mini_nand_defconfig
@@ -13,6 +13,7 @@
CONFIG_REMAKE_ELF=y
# CONFIG_MP is not set
CONFIG_FIT=y
+# CONFIG_BOOTM is not set
CONFIG_SUPPORT_RAW_INITRD=y
# CONFIG_AUTOBOOT is not set
CONFIG_SYS_CBSIZE=1024
@@ -27,7 +28,6 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_GO is not set
# CONFIG_CMD_RUN is not set
diff --git a/configs/xilinx_zynqmp_mini_nand_single_defconfig b/configs/xilinx_zynqmp_mini_nand_single_defconfig
index 31f6473..15d471c 100644
--- a/configs/xilinx_zynqmp_mini_nand_single_defconfig
+++ b/configs/xilinx_zynqmp_mini_nand_single_defconfig
@@ -13,6 +13,7 @@
CONFIG_REMAKE_ELF=y
# CONFIG_MP is not set
CONFIG_FIT=y
+# CONFIG_BOOTM is not set
CONFIG_SUPPORT_RAW_INITRD=y
# CONFIG_AUTOBOOT is not set
CONFIG_SYS_CBSIZE=1024
@@ -27,7 +28,6 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_GO is not set
# CONFIG_CMD_RUN is not set
diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig
index 096feeb..071784c 100644
--- a/configs/xilinx_zynqmp_mini_qspi_defconfig
+++ b/configs/xilinx_zynqmp_mini_qspi_defconfig
@@ -19,6 +19,7 @@
CONFIG_SYS_LOAD_ADDR=0x8000000
# CONFIG_EXPERT is not set
CONFIG_REMAKE_ELF=y
+# CONFIG_BOOTM is not set
# CONFIG_LEGACY_IMAGE_FORMAT is not set
# CONFIG_AUTOBOOT is not set
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
@@ -41,7 +42,6 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_BOOTI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
diff --git a/configs/zynq_cse_nand_defconfig b/configs/zynq_cse_nand_defconfig
index 0dbc804..982777b 100644
--- a/configs/zynq_cse_nand_defconfig
+++ b/configs/zynq_cse_nand_defconfig
@@ -19,6 +19,7 @@
CONFIG_REMAKE_ELF=y
CONFIG_SYS_CUSTOM_LDSCRIPT=y
CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
+# CONFIG_BOOTM is not set
# CONFIG_AUTOBOOT is not set
CONFIG_USE_PREBOOT=y
CONFIG_SYS_CBSIZE=1024
@@ -43,7 +44,6 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
# CONFIG_CMD_GO is not set
diff --git a/configs/zynq_cse_nor_defconfig b/configs/zynq_cse_nor_defconfig
index d95f760..7d70dae 100644
--- a/configs/zynq_cse_nor_defconfig
+++ b/configs/zynq_cse_nor_defconfig
@@ -19,6 +19,7 @@
CONFIG_REMAKE_ELF=y
CONFIG_SYS_CUSTOM_LDSCRIPT=y
CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
+# CONFIG_BOOTM is not set
# CONFIG_AUTOBOOT is not set
CONFIG_USE_PREBOOT=y
CONFIG_SYS_CBSIZE=1024
@@ -43,7 +44,6 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
# CONFIG_CMD_GO is not set
diff --git a/configs/zynq_cse_qspi_defconfig b/configs/zynq_cse_qspi_defconfig
index dd7f978..c7477aa 100644
--- a/configs/zynq_cse_qspi_defconfig
+++ b/configs/zynq_cse_qspi_defconfig
@@ -25,6 +25,7 @@
CONFIG_REMAKE_ELF=y
CONFIG_SYS_CUSTOM_LDSCRIPT=y
CONFIG_SYS_LDSCRIPT="arch/arm/mach-zynq/u-boot.lds"
+# CONFIG_BOOTM is not set
# CONFIG_AUTOBOOT is not set
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_USE_PREBOOT=y
@@ -52,7 +53,6 @@
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_BOOTD is not set
-# CONFIG_CMD_BOOTM is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_FDT is not set
# CONFIG_CMD_GO is not set
diff --git a/disk/part.c b/disk/part.c
index 36b8820..2bee669 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -14,6 +14,7 @@
#include <malloc.h>
#include <part.h>
#include <ubifs_uboot.h>
+#include <dm/uclass.h>
#undef PART_DEBUG
@@ -305,50 +306,8 @@
CONFIG_IS_ENABLED(ISO_PARTITION) || \
CONFIG_IS_ENABLED(AMIGA_PARTITION) || \
CONFIG_IS_ENABLED(EFI_PARTITION)
- puts ("\nPartition Map for ");
- switch (desc->uclass_id) {
- case UCLASS_IDE:
- puts ("IDE");
- break;
- case UCLASS_AHCI:
- puts ("SATA");
- break;
- case UCLASS_SCSI:
- puts ("SCSI");
- break;
- case UCLASS_USB:
- puts ("USB");
- break;
- case UCLASS_MMC:
- puts ("MMC");
- break;
- case UCLASS_HOST:
- puts ("HOST");
- break;
- case UCLASS_NVME:
- puts ("NVMe");
- break;
- case UCLASS_PVBLOCK:
- puts("PV BLOCK");
- break;
- case UCLASS_RKMTD:
- puts("RKMTD");
- break;
- case UCLASS_VIRTIO:
- puts("VirtIO");
- break;
- case UCLASS_EFI_MEDIA:
- puts("EFI");
- break;
- case UCLASS_BLKMAP:
- puts("BLKMAP");
- break;
- default:
- printf("UNKNOWN(%d)", desc->uclass_id);
- break;
- }
- printf (" device %d -- Partition Type: %s\n\n",
- desc->devnum, type);
+ printf("\nPartition Map for %s device %d -- Partition Type: %s\n\n",
+ uclass_get_name(desc->uclass_id), desc->devnum, type);
#endif /* any CONFIG_..._PARTITION */
}
@@ -717,8 +676,11 @@
for (i = 1; i < part_drv->max_entries; i++) {
ret = part_drv->get_info(desc, i, info);
if (ret != 0) {
- /* no more entries in table */
- break;
+ /*
+ * Partition with this index can't be obtained, but
+ * further partitions might be, so keep checking.
+ */
+ continue;
}
if (strcmp(name, (const char *)info->name) == 0) {
/* matched */
diff --git a/doc/android/fastboot.rst b/doc/android/fastboot.rst
index 05d8f77..9e337ca 100644
--- a/doc/android/fastboot.rst
+++ b/doc/android/fastboot.rst
@@ -128,6 +128,7 @@
When executing the fastboot ``boot`` command, if ``fastboot_bootcmd`` is set
then that will be executed in place of ``bootm <CONFIG_FASTBOOT_BUF_ADDR>``.
+This is supported if CONFIG_CMDLINE is enabled, which it normally is.
Partition Names
---------------
diff --git a/doc/board/emulation/qemu-x86.rst b/doc/board/emulation/qemu-x86.rst
index c604e42..4eeba46 100644
--- a/doc/board/emulation/qemu-x86.rst
+++ b/doc/board/emulation/qemu-x86.rst
@@ -134,7 +134,7 @@
U-Boot SPL 2023.07 (Jul 23 2023 - 08:00:12 -0600)
Trying to boot from SPI
- Jumping to 64-bit U-Boot: Note many features are missing
+ Jumping to 64-bit U-Boot
U-Boot 2023.07 (Jul 23 2023 - 08:00:12 -0600)
diff --git a/doc/board/starfive/index.rst b/doc/board/starfive/index.rst
index 0c52dc7..2762bf7 100644
--- a/doc/board/starfive/index.rst
+++ b/doc/board/starfive/index.rst
@@ -6,4 +6,5 @@
.. toctree::
:maxdepth: 1
+ milk-v_mars.rst
visionfive2
diff --git a/doc/board/starfive/milk-v_mars.rst b/doc/board/starfive/milk-v_mars.rst
new file mode 100644
index 0000000..554932e
--- /dev/null
+++ b/doc/board/starfive/milk-v_mars.rst
@@ -0,0 +1,111 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Milk-V Mars
+===========
+
+U-Boot for the Milk-V Mars uses the same U-Boot binaries as the VisionFive 2
+board. In U-Boot SPL the actual board is detected and the device-tree patched
+accordingly.
+
+Building
+~~~~~~~~
+
+1. Add the RISC-V toolchain to your PATH.
+2. Setup ARCH & cross compilation environment variable:
+
+.. code-block:: none
+
+ export CROSS_COMPILE=<riscv64 toolchain prefix>
+
+The M-mode software OpenSBI provides the supervisor binary interface (SBI) and
+is responsible for the switch to S-Mode. It is a prerequisite to build U-Boot.
+Support for the JH7110 was introduced in OpenSBI 1.2. It is recommended to use
+a current release.
+
+.. code-block:: console
+
+ git clone https://github.com/riscv/opensbi.git
+ cd opensbi
+ make PLATFORM=generic FW_TEXT_START=0x40000000 FW_OPTIONS=0
+
+Now build the U-Boot SPL and U-Boot proper.
+
+.. code-block:: console
+
+ cd <U-Boot-dir>
+ make starfive_visionfive2_defconfig
+ make OPENSBI=$(opensbi_dir)/build/platform/generic/firmware/fw_dynamic.bin
+
+This will generate the U-Boot SPL image (spl/u-boot-spl.bin.normal.out) as well
+as the FIT image (u-boot.itb) with OpenSBI and U-Boot.
+
+Device-tree selection
+~~~~~~~~~~~~~~~~~~~~~
+
+Depending on the board version U-Boot set variable $fdtfile to either
+starfive/jh7110-starfive-visionfive-2-v1.2a.dtb or
+starfive/jh7110-starfive-visionfive-2-v1.3b.dtb.
+
+To overrule this selection the variable can be set manually and saved in the
+environment
+
+::
+
+ setenv fdtfile my_device-tree.dtb
+ env save
+
+or the configuration variable CONFIG_DEFAULT_FDT_FILE can be used to set to
+provide a default value.
+
+Boot source selection
+~~~~~~~~~~~~~~~~~~~~~
+
+The board provides the DIP switches MSEL[1:0] to select the boot device out of
+SPI flash, eMMC, SD-card, UART. To select booting from SD-card set the DIP
+switches MSEL[1:0] to 10.
+
+Preparing the SD-Card
+~~~~~~~~~~~~~~~~~~~~~
+
+The device firmware loads U-Boot SPL (u-boot-spl.bin.normal.out) from the
+partition with type GUID 2E54B353-1271-4842-806F-E436D6AF6985. You are free
+to choose any partition number.
+
+With the default configuration U-Boot SPL loads the U-Boot FIT image
+(u-boot.itb) from partition 2 (CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=0x2).
+When formatting it is recommended to use GUID
+BC13C2FF-59E6-4262-A352-B275FD6F7172 for this partition.
+
+The FIT image (u-boot.itb) is a combination of OpenSBI's fw_dynamic.bin,
+u-boot-nodtb.bin and the device tree blob.
+
+Format the SD card (make sure the disk has GPT, otherwise use gdisk to switch)
+
+.. code-block:: bash
+
+ sudo sgdisk --clear \
+ --set-alignment=2 \
+ --new=1:4096:8191 --change-name=1:spl --typecode=1:2E54B353-1271-4842-806F-E436D6AF6985\
+ --new=2:8192:16383 --change-name=2:uboot --typecode=2:BC13C2FF-59E6-4262-A352-B275FD6F7172 \
+ --new=3:16384:1654784 --change-name=3:system --typecode=3:EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 \
+ /dev/sdb
+
+Copy U-Boot to the SD card
+
+.. code-block:: bash
+
+ sudo dd if=u-boot-spl.bin.normal.out of=/dev/sdb1
+ sudo dd if=u-boot.itb of=/dev/sdb2
+
+ sudo mount /dev/sdb3 /mnt/
+ sudo cp u-boot-spl.bin.normal.out /mnt/
+ sudo cp u-boot.itb /mnt/
+ sudo cp Image.gz /mnt/
+ sudo cp initramfs.cpio.gz /mnt/
+ sudo cp jh7110-starfive-visionfive-2.dtb /mnt/
+ sudo umount /mnt
+
+Booting
+~~~~~~~
+
+Once you plugin the sdcard and power up, you should see the U-Boot prompt.
diff --git a/doc/board/starfive/visionfive2.rst b/doc/board/starfive/visionfive2.rst
index abda8ac..2c68df3 100644
--- a/doc/board/starfive/visionfive2.rst
+++ b/doc/board/starfive/visionfive2.rst
@@ -71,6 +71,24 @@
This will generate the U-Boot SPL image (spl/u-boot-spl.bin.normal.out) as well
as the FIT image (u-boot.itb) with OpenSBI and U-Boot.
+Device-tree selection
+~~~~~~~~~~~~~~~~~~~~~
+
+Depending on the board version U-Boot set variable $fdtfile to either
+starfive/jh7110-starfive-visionfive-2-v1.2a.dtb or
+starfive/jh7110-starfive-visionfive-2-v1.3b.dtb.
+
+To overrule this selection the variable can be set manually and saved in the
+environment
+
+::
+
+ setenv fdtfile my_device-tree.dtb
+ env save
+
+or the configuration variable CONFIG_DEFAULT_FDT_FILE can be used to provide
+a default value.
+
Flashing
~~~~~~~~
diff --git a/doc/build/docker.rst b/doc/build/docker.rst
index 953d1b2..45659b3 100644
--- a/doc/build/docker.rst
+++ b/doc/build/docker.rst
@@ -11,4 +11,4 @@
.. code-block:: bash
- sudo docker pull trini/u-boot-gitlab-ci-runner:bionic-20200807-02Sep2020
+ sudo docker pull trini/u-boot-gitlab-ci-runner:jammy-20240227-14Mar2024
diff --git a/doc/build/gen_compile_commands.rst b/doc/build/gen_compile_commands.rst
index 50305ce..d503764 100644
--- a/doc/build/gen_compile_commands.rst
+++ b/doc/build/gen_compile_commands.rst
@@ -42,7 +42,7 @@
other than it's default one (compile_commands.json).
Compatible IDEs
-===============
+---------------
Several popular integrated development environments (IDEs) support the use
of JSON compilation databases for C/C++ development, making it easier to
@@ -73,7 +73,7 @@
code navigation.
Usage
-=====
+-----
For further details on the script's options, please refer to its help message,
as in the example below.
diff --git a/doc/develop/tests_sandbox.rst b/doc/develop/tests_sandbox.rst
index bfd3bdb..7292307 100644
--- a/doc/develop/tests_sandbox.rst
+++ b/doc/develop/tests_sandbox.rst
@@ -28,8 +28,8 @@
- test/image/test-imagetools.sh - multi-file images
- test/py/tests/test-fit.py - FIT images
- - tracing: test/trace/test-trace.sh tests the tracing system (see
- README.trace)
+ - tracing: test/trace/test-trace.sh tests the tracing system
+ (see :doc:`trace`).
- verified boot: test/py/tests/test_vboot.py
If you change or enhance any U-Boot subsystem, you should write or expand a
diff --git a/doc/device-tree-bindings/sysreset/ti,sci-sysreset.txt b/doc/device-tree-bindings/sysreset/ti,sci-sysreset.txt
deleted file mode 100644
index 02704c6..0000000
--- a/doc/device-tree-bindings/sysreset/ti,sci-sysreset.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-Texas Instruments TI SCI System Reset Controller
-================================================
-
-Some TI SoCs contain a system controller (like the SYSFW, etc...) that is
-responsible for controlling the state of the IPs that are present.
-Communication between the host processor running an OS and the system
-controller happens through a protocol known as TI SCI [1].
-
-[1] http://processors.wiki.ti.com/index.php/TISCI
-
-System Reset Controller Node
-============================
-The sysreset controller node represents the reset for the overall SoC
-which is managed by the SYSFW. Because this relies on the TI SCI protocol
-to communicate with the SYSFW it must be a child of the sysfw node.
-
-Required Properties:
---------------------
- - compatible: Must be "ti,sci-sysreset"
-
-Example (AM65x):
-----------------
- sysfw: sysfw {
- compatible = "ti,am654-system-controller";
- ...
- k3_sysreset: sysreset-controller {
- compatible = "ti,sci-sysreset";
- };
- };
diff --git a/doc/sphinx/requirements.txt b/doc/sphinx/requirements.txt
index 840c6ce..5b4df36 100644
--- a/doc/sphinx/requirements.txt
+++ b/doc/sphinx/requirements.txt
@@ -3,7 +3,7 @@
certifi==2023.11.17
charset-normalizer==3.3.2
docutils==0.20.1
-idna==3.6
+idna==3.7
imagesize==1.4.1
Jinja2==3.1.3
MarkupSafe==2.1.3
diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst
index ebf75fa..7d4b448 100644
--- a/doc/usage/environment.rst
+++ b/doc/usage/environment.rst
@@ -366,6 +366,19 @@
This means the count of blocks we can receive before
sending ack to server.
+usb_ignorelist
+ Ignore USB devices to prevent binding them to an USB device driver. This can
+ be used to ignore devices are for some reason undesirable or causes crashes
+ u-boot's USB stack.
+ An example for undesired behavior is the keyboard emulation of security keys
+ like Yubikeys. U-boot currently supports only a single USB keyboard device
+ so try to probe an useful keyboard device. The default environment blocks
+ Yubico devices as common devices emulating keyboards.
+ Devices are matched by idVendor and idProduct. The variable contains a comma
+ separated list of idVendor:idProduct pairs as hexadecimal numbers joined
+ by a colon. '*' functions as a wildcard for idProduct to block all devices
+ with the specified idVendor.
+
vlan
When set to a value < 4095 the traffic over
Ethernet is encapsulated/received over 802.1q
diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c
index ce10d79..f0cb797 100644
--- a/drivers/clk/imx/clk-imx93.c
+++ b/drivers/clk/imx/clk-imx93.c
@@ -289,7 +289,7 @@
clk_dm(IMX93_CLK_SYS_PLL_PFD2_DIV2,
imx_clk_fixed_factor("sys_pll_pfd2_div2", "sys_pll_pfd2", 1, 2));
- base = (void *)ANATOP_BASE_ADDR;
+ anatop_base = (void *)ANATOP_BASE_ADDR;
clk_dm(IMX93_CLK_ARM_PLL,
imx_clk_fracn_gppll_integer("arm_pll", "clock-osc-24m",
diff --git a/drivers/cpu/imx9_cpu.c b/drivers/cpu/imx9_cpu.c
deleted file mode 100644
index 66534fe..0000000
--- a/drivers/cpu/imx9_cpu.c
+++ /dev/null
@@ -1,224 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright 2019 NXP
- */
-
-#include <common.h>
-#include <cpu.h>
-#include <dm.h>
-#include <thermal.h>
-#include <asm/global_data.h>
-#include <asm/system.h>
-#include <firmware/linux/imx/sci/sci.h>
-#include <asm/arch/sys_proto.h>
-#include <asm/arch-imx/cpu.h>
-#include <asm/armv8/cpu.h>
-#include <linux/bitops.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-struct cpu_imx_plat {
- const char *name;
- const char *rev;
- const char *type;
- u32 cpu_rsrc;
- u32 cpurev;
- u32 freq_mhz;
- u32 mpidr;
-};
-
-const char *get_imx9_type(u32 imxtype)
-{
- switch (imxtype) {
- case MXC_CPU_IMX93:
- return "93";
- default:
- return "??";
- }
-}
-
-const char *get_imx9_rev(u32 rev)
-{
- switch (rev) {
- case CHIP_REV_1_0:
- return "1.";
- case CHIP_REV_B:
- return "B";
- case CHIP_REV_C:
- return "C";
- default:
- return "?";
- }
-}
-
-static void set_core_data(struct udevice *dev)
-{
- struct cpu_imx_plat *plat = dev_get_plat(dev);
-
- if (device_is_compatible(dev, "arm,cortex-a35"))
- plat->name = "A35";
- else
- plat->name = "?";
-}
-
-#if IS_ENABLED(CONFIG_IMX_SCU_THERMAL)
-static int cpu_imx_get_temp(struct cpu_imx_plat *plat)
-{
- struct udevice *thermal_dev;
- int cpu_tmp, ret;
- int idx = 1; /* use "cpu-thermal0" device */
-
- if (plat->cpu_rsrc == SC_R_A72)
- idx = 2; /* use "cpu-thermal1" device */
-
- ret = uclass_get_device(UCLASS_THERMAL, idx, &thermal_dev);
- if (!ret) {
- ret = thermal_get_temp(thermal_dev, &cpu_tmp);
- if (ret)
- return 0xdeadbeef;
- } else {
- return 0xdeadbeef;
- }
-
- return cpu_tmp;
-}
-#else
-static int cpu_imx_get_temp(struct cpu_imx_plat *plat)
-{
- return 0;
-}
-#endif
-
-int cpu_imx_get_desc(const struct udevice *dev, char *buf, int size)
-{
- struct cpu_imx_plat *plat = dev_get_plat(dev);
- int ret, temp;
-
- if (size < 100)
- return -ENOSPC;
-
- ret = snprintf(buf, size, "NXP i.MX8%s Rev%s %s at %u MHz",
- plat->type, plat->rev, plat->name, plat->freq_mhz);
-
- if (IS_ENABLED(CONFIG_IMX_SCU_THERMAL)) {
- temp = cpu_imx_get_temp(plat);
- buf = buf + ret;
- size = size - ret;
- if (temp != 0xdeadbeef)
- ret = snprintf(buf, size, " at %dC", temp);
- else
- ret = snprintf(buf, size, " - invalid sensor data");
- }
-
- snprintf(buf + ret, size - ret, "\n");
-
- return 0;
-}
-
-static int cpu_imx_get_info(const struct udevice *dev, struct cpu_info *info)
-{
- struct cpu_imx_plat *plat = dev_get_plat(dev);
-
- info->cpu_freq = plat->freq_mhz * 1000;
- info->features = BIT(CPU_FEAT_L1_CACHE) | BIT(CPU_FEAT_MMU);
- return 0;
-}
-
-static int cpu_imx_get_count(const struct udevice *dev)
-{
- ofnode node;
- int num = 0;
-
- ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) {
- const char *device_type;
-
- if (!ofnode_is_enabled(node))
- continue;
-
- device_type = ofnode_read_string(node, "device_type");
- if (!device_type)
- continue;
-
- if (!strcmp(device_type, "cpu"))
- num++;
- }
-
- return num;
-}
-
-static int cpu_imx_get_vendor(const struct udevice *dev, char *buf, int size)
-{
- snprintf(buf, size, "NXP");
- return 0;
-}
-
-static int cpu_imx_is_current(struct udevice *dev)
-{
- struct cpu_imx_plat *plat = dev_get_plat(dev);
-
- if (plat->mpidr == (read_mpidr() & 0xffff))
- return 1;
-
- return 0;
-}
-
-static const struct cpu_ops cpu_imx9_ops = {
- .get_desc = cpu_imx_get_desc,
- .get_info = cpu_imx_get_info,
- .get_count = cpu_imx_get_count,
- .get_vendor = cpu_imx_get_vendor,
- .is_current = cpu_imx_is_current,
-};
-
-static const struct udevice_id cpu_imx9_ids[] = {
- { .compatible = "arm,cortex-a35" },
- { .compatible = "arm,cortex-a53" },
- { .compatible = "arm,cortex-a72" },
- { }
-};
-
-static ulong imx9_get_cpu_rate(struct udevice *dev)
-{
- struct cpu_imx_plat *plat = dev_get_plat(dev);
- ulong rate;
- int ret;
-
- ret = sc_pm_get_clock_rate(-1, plat->cpu_rsrc, SC_PM_CLK_CPU,
- (sc_pm_clock_rate_t *)&rate);
- if (ret) {
- printf("Could not read CPU frequency: %d\n", ret);
- return 0;
- }
-
- return rate;
-}
-
-static int imx9_cpu_probe(struct udevice *dev)
-{
- struct cpu_imx_plat *plat = dev_get_plat(dev);
- u32 cpurev;
-
- set_core_data(dev);
- cpurev = get_cpu_rev();
- plat->cpurev = cpurev;
- plat->rev = get_imx9_rev(cpurev & 0xFFF);
- plat->type = get_imx9_type((cpurev & 0xFF000) >> 12);
- plat->freq_mhz = imx9_get_cpu_rate(dev) / 1000000;
- plat->mpidr = dev_read_addr(dev);
- if (plat->mpidr == FDT_ADDR_T_NONE) {
- printf("%s: Failed to get CPU reg property\n", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-U_BOOT_DRIVER(cpu_imx9_drv) = {
- .name = "imx9x_cpu",
- .id = UCLASS_CPU,
- .of_match = cpu_imx9_ids,
- .ops = &cpu_imx9_ops,
- .probe = imx9_cpu_probe,
- .plat_auto = sizeof(struct cpu_imx_plat),
- .flags = DM_FLAG_PRE_RELOC,
-};
diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c
index 5d1026b..9b1950e 100644
--- a/drivers/cpu/riscv_cpu.c
+++ b/drivers/cpu/riscv_cpu.c
@@ -21,13 +21,13 @@
static int riscv_cpu_get_desc(const struct udevice *dev, char *buf, int size)
{
- const char *isa;
+ const char *cpu;
- isa = dev_read_string(dev, "riscv,isa");
- if (size < (strlen(isa) + 1))
+ cpu = dev_read_string(dev, "compatible");
+ if (size < (strlen(cpu) + 1))
return -ENOSPC;
- strcpy(buf, isa);
+ strcpy(buf, cpu);
return 0;
}
diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
index 5e5855a..d6e2be0 100644
--- a/drivers/fastboot/Kconfig
+++ b/drivers/fastboot/Kconfig
@@ -1,5 +1,4 @@
menu "Fastboot support"
- depends on CMDLINE
config FASTBOOT
bool
@@ -13,6 +12,10 @@
More information about the protocol and usecases:
https://android.googlesource.com/platform/system/core/+/refs/heads/master/fastboot/
+ Note that enabling CMDLINE is recommended since fastboot allows U-Boot
+ commands to be executed on request. The CMDLINE option is required
+ for anything other than simply booting the OS.
+
config USB_FUNCTION_FASTBOOT
bool "Enable USB fastboot gadget"
depends on USB_GADGET
diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
index f95f4e4..b8782bf 100644
--- a/drivers/fastboot/fb_command.c
+++ b/drivers/fastboot/fb_command.c
@@ -11,6 +11,7 @@
#include <fastboot-internal.h>
#include <fb_mmc.h>
#include <fb_nand.h>
+#include <mapmem.h>
#include <part.h>
#include <stdlib.h>
#include <linux/printk.h>
@@ -278,6 +279,7 @@
{
#define BYTES_PER_DOT 0x20000
u32 pre_dot_num, now_dot_num;
+ void *buf;
if (fastboot_data_len == 0 ||
(fastboot_bytes_received + fastboot_data_len) >
@@ -287,8 +289,10 @@
return;
}
/* Download data to fastboot_buf_addr */
- memcpy(fastboot_buf_addr + fastboot_bytes_received,
+ buf = map_sysmem(fastboot_buf_addr, 0);
+ memcpy(buf + fastboot_bytes_received,
fastboot_data, fastboot_data_len);
+ unmap_sysmem(buf);
pre_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
fastboot_bytes_received += fastboot_data_len;
@@ -331,13 +335,16 @@
*/
static void __maybe_unused flash(char *cmd_parameter, char *response)
{
+ void *buf = map_sysmem(fastboot_buf_addr, 0);
+
if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_MMC))
- fastboot_mmc_flash_write(cmd_parameter, fastboot_buf_addr,
- image_size, response);
+ fastboot_mmc_flash_write(cmd_parameter, buf, image_size,
+ response);
if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_NAND))
- fastboot_nand_flash_write(cmd_parameter, fastboot_buf_addr,
- image_size, response);
+ fastboot_nand_flash_write(cmd_parameter, buf, image_size,
+ response);
+ unmap_sysmem(buf);
}
/**
diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c
index 3576b06..5959545 100644
--- a/drivers/fastboot/fb_common.c
+++ b/drivers/fastboot/fb_common.c
@@ -11,6 +11,7 @@
*/
#include <bcb.h>
+#include <bootm.h>
#include <common.h>
#include <command.h>
#include <env.h>
@@ -20,7 +21,7 @@
/**
* fastboot_buf_addr - base address of the fastboot download buffer
*/
-void *fastboot_buf_addr;
+ulong fastboot_buf_addr;
/**
* fastboot_buf_size - size of the fastboot download buffer
@@ -142,22 +143,19 @@
*/
void fastboot_boot(void)
{
- char *s;
+ char *s = NULL;
- s = env_get("fastboot_bootcmd");
- if (s) {
- run_command(s, CMD_FLAG_ENV);
- } else if (IS_ENABLED(CONFIG_CMD_BOOTM)) {
- static char boot_addr_start[20];
- static char *const bootm_args[] = {
- "bootm", boot_addr_start, NULL
- };
+ if (IS_ENABLED(CONFIG_CMDLINE)) {
+ s = env_get("fastboot_bootcmd");
+ if (s)
+ run_command(s, CMD_FLAG_ENV);
+ }
- snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
- "0x%p", fastboot_buf_addr);
- printf("Booting kernel at %s...\n\n\n", boot_addr_start);
+ if (!s && IS_ENABLED(CONFIG_BOOTM)) {
+ int ret;
- do_bootm(NULL, 0, 2, bootm_args);
+ printf("Booting kernel at %lx...\n\n\n", fastboot_buf_addr);
+ ret = bootm_boot_start(fastboot_buf_addr, NULL);
/*
* This only happens if image is somehow faulty so we start
@@ -214,16 +212,9 @@
fastboot_progress_callback = progress;
}
-/*
- * fastboot_init() - initialise new fastboot protocol session
- *
- * @buf_addr: Pointer to download buffer, or NULL for default
- * @buf_size: Size of download buffer, or zero for default
- */
-void fastboot_init(void *buf_addr, u32 buf_size)
+void fastboot_init(ulong buf_addr, u32 buf_size)
{
- fastboot_buf_addr = buf_addr ? buf_addr :
- (void *)CONFIG_FASTBOOT_BUF_ADDR;
+ fastboot_buf_addr = buf_addr ? buf_addr : CONFIG_FASTBOOT_BUF_ADDR;
fastboot_buf_size = buf_size ? buf_size : CONFIG_FASTBOOT_BUF_SIZE;
fastboot_set_progress_callback(NULL);
}
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c
index ee09218..6c581b9 100644
--- a/drivers/firmware/ti_sci.c
+++ b/drivers/firmware/ti_sci.c
@@ -16,6 +16,7 @@
#include <dm/device.h>
#include <dm/device_compat.h>
#include <dm/devres.h>
+#include <dm/lists.h>
#include <linux/bitops.h>
#include <linux/compat.h>
#include <linux/err.h>
@@ -2840,6 +2841,12 @@
INIT_LIST_HEAD(&info->dev_list);
+ if (IS_ENABLED(CONFIG_SYSRESET_TI_SCI)) {
+ ret = device_bind_driver(dev, "ti-sci-sysreset", "sysreset", NULL);
+ if (ret)
+ dev_warn(dev, "cannot bind SYSRESET (ret = %d)\n", ret);
+ }
+
return 0;
}
diff --git a/drivers/gpio/imx_rgpio2p.c b/drivers/gpio/imx_rgpio2p.c
index 175e460..3227a8d 100644
--- a/drivers/gpio/imx_rgpio2p.c
+++ b/drivers/gpio/imx_rgpio2p.c
@@ -21,6 +21,12 @@
#define GPIO_PER_BANK 32
+struct imx_rgpio2p_soc_data {
+ bool have_dual_base;
+};
+
+#define IMX8ULP_GPIO_BASE_OFF 0x40
+
struct imx_rgpio2p_data {
struct gpio_regs *regs;
};
@@ -165,6 +171,9 @@
static int imx_rgpio2p_bind(struct udevice *dev)
{
struct imx_rgpio2p_plat *plat = dev_get_plat(dev);
+ struct imx_rgpio2p_soc_data *data =
+ (struct imx_rgpio2p_soc_data *)dev_get_driver_data(dev);
+ bool dual_base = data->have_dual_base;
fdt_addr_t addr;
/*
@@ -176,9 +185,26 @@
if (plat)
return 0;
- addr = devfdt_get_addr_index(dev, 1);
- if (addr == FDT_ADDR_T_NONE)
- return -EINVAL;
+ /*
+ * Handle legacy compatible combinations which used two reg values
+ * for the i.MX8ULP and i.MX93.
+ */
+ if (device_is_compatible(dev, "fsl,imx7ulp-gpio") &&
+ (device_is_compatible(dev, "fsl,imx93-gpio") ||
+ (device_is_compatible(dev, "fsl,imx8ulp-gpio"))))
+ dual_base = true;
+
+ if (dual_base) {
+ addr = devfdt_get_addr_index(dev, 1);
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+ } else {
+ addr = devfdt_get_addr_index(dev, 0);
+ if (addr == FDT_ADDR_T_NONE)
+ return -EINVAL;
+
+ addr += IMX8ULP_GPIO_BASE_OFF;
+ }
/*
* TODO:
@@ -202,9 +228,17 @@
return 0;
}
+static struct imx_rgpio2p_soc_data imx7ulp_data = {
+ .have_dual_base = true,
+};
+
+static struct imx_rgpio2p_soc_data imx8ulp_data = {
+ .have_dual_base = false,
+};
static const struct udevice_id imx_rgpio2p_ids[] = {
- { .compatible = "fsl,imx7ulp-gpio" },
+ { .compatible = "fsl,imx7ulp-gpio", .data = (ulong)&imx7ulp_data },
+ { .compatible = "fsl,imx8ulp-gpio", .data = (ulong)&imx8ulp_data },
{ }
};
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 9e82990..e53d52c 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -91,4 +91,4 @@
obj-$(CONFIG_ESM_K3) += k3_esm.o
obj-$(CONFIG_ESM_PMIC) += esm_pmic.o
obj-$(CONFIG_SL28CPLD) += sl28cpld.o
-obj-$(CONFIG_SPL_SOCFPGA_SEC_REG) += socfpga_dtreg.o
+obj-$(CONFIG_SPL_SOCFPGA_DT_REG) += socfpga_dtreg.o
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index cef0579..06e32e7 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -20,11 +20,19 @@
config MMC_PWRSEQ
bool "HW reset support for eMMC"
- depends on PWRSEQ
+ depends on PWRSEQ && DM_GPIO
help
- Ths select Hardware reset support aka pwrseq-emmc for eMMC
+ This select Hardware reset support aka pwrseq-emmc for eMMC
devices.
+config SPL_MMC_PWRSEQ
+ bool "HW reset support for eMMC in SPL"
+ depends on SPL_PWRSEQ && SPL_DM_GPIO
+ default y if MMC_PWRSEQ
+ help
+ This select Hardware reset support aka pwrseq-emmc for eMMC
+ devices in SPL.
+
config MMC_BROKEN_CD
bool "Poll for broken card detection case"
help
@@ -79,11 +87,12 @@
config ARM_PL180_MMCI
bool "ARM AMBA Multimedia Card Interface and compatible support"
+ depends on DM_MMC
help
This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card
Interface (PL180, PL181 and compatible) support.
If you have an ARM(R) platform with a Multimedia Card slot,
- say Y or M here.
+ say Y here.
config MMC_QUIRKS
bool "Enable quirks"
@@ -568,6 +577,19 @@
If unsure, say N.
+config MMC_SDHCI_CV1800B
+ bool "SDHCI support for the CV1800B SD/SDIO/eMMC controller"
+ depends on BLK && DM_MMC
+ depends on MMC_SDHCI
+ depends on OF_CONTROL
+ help
+ This selects the CV1800B SD/SDIO/eMMC driver.
+
+ If you have a controller with this interface,
+ say Y here.
+
+ If unsure, say N.
+
config MMC_SDHCI_AM654
bool "SDHCI Controller on TI's Am654 devices"
depends on ARCH_K3
@@ -586,7 +608,7 @@
This selects the iProc SD/MMC controller.
If you have a Broadcom IPROC platform with SD or MMC devices,
- say Y or M here.
+ say Y here.
If unsure, say N.
@@ -597,7 +619,7 @@
help
This selects the Secure Digital Host Controller Interface (SDHCI)
Needed by some Fujitsu/Socionext SoC for MMC / SD / SDIO support.
- If you have a controller with this interface, say Y or M here.
+ If you have a controller with this interface, say Y here.
If unsure, say N.
config MMC_SDHCI_KONA
@@ -791,7 +813,7 @@
help
This selects support for the SD/MMC controller on STM32H7 SoCs.
If you have a board based on such a SoC and with a SD/MMC slot,
- say Y or M here.
+ say Y here.
config FTSDC010
bool "Ftsdc010 SD/MMC controller Support"
@@ -811,7 +833,7 @@
depends on OF_CONTROL
help
This selects the MediaTek(R) Secure digital and Multimedia card Interface.
- If you have a machine with a integrated SD/MMC card reader, say Y or M here.
+ If you have a machine with a integrated SD/MMC card reader, say Y here.
This is needed if support for any SD/SDIO/MMC devices is required.
If unsure, say N.
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index e9cf1fc..72c3fb6 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -11,7 +11,7 @@
endif
obj-$(CONFIG_$(SPL_TPL_)MMC_WRITE) += mmc_write.o
-obj-$(CONFIG_MMC_PWRSEQ) += mmc-pwrseq.o
+obj-$(CONFIG_$(SPL_)MMC_PWRSEQ) += mmc-pwrseq.o
obj-$(CONFIG_MMC_SDHCI_ADMA_HELPERS) += sdhci-adma.o
ifndef CONFIG_$(SPL_)BLK
@@ -60,6 +60,7 @@
obj-$(CONFIG_MMC_SDHCI_BCM2835) += bcm2835_sdhci.o
obj-$(CONFIG_MMC_SDHCI_BCMSTB) += bcmstb_sdhci.o
obj-$(CONFIG_MMC_SDHCI_CADENCE) += sdhci-cadence.o
+obj-$(CONFIG_MMC_SDHCI_CV1800B) += cv1800b_sdhci.o
obj-$(CONFIG_MMC_SDHCI_AM654) += am654_sdhci.o
obj-$(CONFIG_MMC_SDHCI_IPROC) += iproc_sdhci.o
obj-$(CONFIG_MMC_SDHCI_KONA) += kona_sdhci.o
diff --git a/drivers/mmc/am654_sdhci.c b/drivers/mmc/am654_sdhci.c
index 05595bd..2139fea 100644
--- a/drivers/mmc/am654_sdhci.c
+++ b/drivers/mmc/am654_sdhci.c
@@ -390,7 +390,7 @@
for (itap = 0; itap < ITAP_MAX; itap++) {
am654_sdhci_write_itapdly(plat, itap);
- cur_val = !mmc_send_tuning(mmc, opcode, NULL);
+ cur_val = !mmc_send_tuning(mmc, opcode);
if (cur_val && !prev_val)
pass_window = itap;
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c
index 5cf5502..2666b65 100644
--- a/drivers/mmc/arm_pl180_mmci.c
+++ b/drivers/mmc/arm_pl180_mmci.c
@@ -18,6 +18,7 @@
#include <malloc.h>
#include <mmc.h>
#include <dm/device_compat.h>
+#include <dm.h>
#include <asm/io.h>
#include <asm-generic/gpio.h>
@@ -25,8 +26,6 @@
#include "arm_pl180_mmci.h"
#include <linux/delay.h>
-#ifdef CONFIG_DM_MMC
-#include <dm.h>
#define MMC_CLOCK_MAX 48000000
#define MMC_CLOCK_MIN 400000
@@ -34,7 +33,6 @@
struct mmc_config cfg;
struct mmc mmc;
};
-#endif
static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd)
{
@@ -355,68 +353,9 @@
writel(sdi_clkcr, &host->base->clock);
udelay(CLK_CHANGE_DELAY);
- return 0;
-}
-
-#ifndef CONFIG_DM_MMC
-/* MMC uses open drain drivers in the enumeration phase */
-static int mmc_host_reset(struct mmc *dev)
-{
- struct pl180_mmc_host *host = dev->priv;
-
- writel(host->pwr_init, &host->base->power);
-
- return 0;
-}
-
-static const struct mmc_ops arm_pl180_mmci_ops = {
- .send_cmd = host_request,
- .set_ios = host_set_ios,
- .init = mmc_host_reset,
-};
-
-/*
- * mmc_host_init - initialize the mmc controller.
- * Set initial clock and power for mmc slot.
- * Initialize mmc struct and register with mmc framework.
- */
-
-int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc)
-{
- u32 sdi_u32;
-
- writel(host->pwr_init, &host->base->power);
- writel(host->clkdiv_init, &host->base->clock);
- udelay(CLK_CHANGE_DELAY);
-
- /* Disable mmc interrupts */
- sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK;
- writel(sdi_u32, &host->base->mask0);
-
- host->cfg.name = host->name;
- host->cfg.ops = &arm_pl180_mmci_ops;
-
- /* TODO remove the duplicates */
- host->cfg.host_caps = host->caps;
- host->cfg.voltages = host->voltages;
- host->cfg.f_min = host->clock_min;
- host->cfg.f_max = host->clock_max;
- if (host->b_max != 0)
- host->cfg.b_max = host->b_max;
- else
- host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
-
- *mmc = mmc_create(&host->cfg, host);
- if (!*mmc)
- return -1;
- debug("registered mmc interface number is:%d\n",
- (*mmc)->block_dev.devnum);
-
return 0;
}
-#endif
-#ifdef CONFIG_DM_MMC
static void arm_pl180_mmc_init(struct pl180_mmc_host *host)
{
u32 sdi_u32;
@@ -477,7 +416,7 @@
host->version2 = true;
break;
default:
- host->version2 = true;
+ host->version2 = false; /* ARM variant */
}
gpio_request_by_name(dev, "cd-gpios", 0, &host->cd_gpio, GPIOD_IS_IN);
@@ -561,4 +500,3 @@
.priv_auto = sizeof(struct pl180_mmc_host),
.plat_auto = sizeof(struct arm_pl180_mmc_plat),
};
-#endif
diff --git a/drivers/mmc/cv1800b_sdhci.c b/drivers/mmc/cv1800b_sdhci.c
new file mode 100644
index 0000000..9af6b97
--- /dev/null
+++ b/drivers/mmc/cv1800b_sdhci.c
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com>
+ */
+
+#include <dm.h>
+#include <mmc.h>
+#include <sdhci.h>
+#include <linux/delay.h>
+
+#define SDHCI_PHY_TX_RX_DLY 0x240
+#define MMC_MAX_CLOCK 375000000
+#define TUNE_MAX_PHCODE 128
+
+struct cv1800b_sdhci_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+
+static void cv1800b_set_tap_delay(struct sdhci_host *host, u16 tap)
+{
+ sdhci_writel(host, tap << 16, SDHCI_PHY_TX_RX_DLY);
+}
+
+static void cv1800b_sdhci_reset(struct sdhci_host *host, u8 mask)
+{
+ sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
+ while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask)
+ udelay(10);
+}
+
+static int cv1800b_execute_tuning(struct mmc *mmc, u8 opcode)
+{
+ struct sdhci_host *host = dev_get_priv(mmc->dev);
+
+ u16 tap;
+
+ int current_size = 0;
+ int max_size = 0;
+ int max_window = 0;
+
+ for (tap = 0; tap < TUNE_MAX_PHCODE; tap++) {
+ cv1800b_set_tap_delay(host, tap);
+
+ if (mmc_send_tuning(host->mmc, opcode)) {
+ current_size = 0;
+ } else {
+ current_size++;
+ if (current_size > max_size) {
+ max_size = current_size;
+ max_window = tap;
+ }
+ }
+ }
+
+ cv1800b_sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
+
+ cv1800b_set_tap_delay(host, max_window - max_size / 2);
+
+ return 0;
+}
+
+const struct sdhci_ops cv1800b_sdhci_sd_ops = {
+ .platform_execute_tuning = cv1800b_execute_tuning,
+};
+
+static int cv1800b_sdhci_bind(struct udevice *dev)
+{
+ struct cv1800b_sdhci_plat *plat = dev_get_plat(dev);
+
+ return sdhci_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static int cv1800b_sdhci_probe(struct udevice *dev)
+{
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct cv1800b_sdhci_plat *plat = dev_get_plat(dev);
+ struct sdhci_host *host = dev_get_priv(dev);
+ int ret;
+
+ host->name = dev->name;
+ host->ioaddr = devfdt_get_addr_ptr(dev);
+
+ upriv->mmc = &plat->mmc;
+ host->mmc = &plat->mmc;
+ host->mmc->priv = host;
+ host->mmc->dev = dev;
+ host->ops = &cv1800b_sdhci_sd_ops;
+ host->max_clk = MMC_MAX_CLOCK;
+
+ ret = mmc_of_parse(dev, &plat->cfg);
+ if (ret)
+ return ret;
+
+ ret = sdhci_setup_cfg(&plat->cfg, host, 0, 200000);
+ if (ret)
+ return ret;
+
+ return sdhci_probe(dev);
+}
+
+static const struct udevice_id cv1800b_sdhci_match[] = {
+ { .compatible = "sophgo,cv1800b-dwcmshc" },
+ { }
+};
+
+U_BOOT_DRIVER(cv1800b_sdhci) = {
+ .name = "sdhci-cv1800b",
+ .id = UCLASS_MMC,
+ .of_match = cv1800b_sdhci_match,
+ .bind = cv1800b_sdhci_bind,
+ .probe = cv1800b_sdhci_probe,
+ .priv_auto = sizeof(struct sdhci_host),
+ .plat_auto = sizeof(struct cv1800b_sdhci_plat),
+ .ops = &sdhci_ops,
+};
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 400066f..e103664 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -262,8 +262,8 @@
while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) {
if (get_timer(start) > timeout) {
- debug("%s: Timeout on data busy\n", __func__);
- return -ETIMEDOUT;
+ debug("%s: Timeout on data busy, continue anyway\n", __func__);
+ break;
}
}
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index d506666..d44dfa5 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -1123,7 +1123,7 @@
esdhc_write32(®s->irqstaten, IRQSTATEN_BRR);
for (i = 0; i < MAX_TUNING_LOOP; i++) {
- mmc_send_tuning(mmc, opcode, NULL);
+ mmc_send_tuning(mmc, opcode);
mdelay(1);
val = esdhc_read32(®s->autoc12err);
diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c
index 7c39c86..b74c014 100644
--- a/drivers/mmc/fsl_esdhc_imx.c
+++ b/drivers/mmc/fsl_esdhc_imx.c
@@ -882,7 +882,7 @@
esdhc_write32(®s->mixctrl, val);
/* We are using STD tuning, no need to check return value */
- mmc_send_tuning(mmc, opcode, NULL);
+ mmc_send_tuning(mmc, opcode);
ctrl = esdhc_read32(®s->autoc12err);
if ((!(ctrl & MIX_CTRL_EXE_TUNE)) &&
diff --git a/drivers/mmc/hi6220_dw_mmc.c b/drivers/mmc/hi6220_dw_mmc.c
index 71962cd..dc02104 100644
--- a/drivers/mmc/hi6220_dw_mmc.c
+++ b/drivers/mmc/hi6220_dw_mmc.c
@@ -5,15 +5,24 @@
*/
#include <common.h>
+#include <clk.h>
#include <dm.h>
#include <dwmmc.h>
#include <errno.h>
#include <fdtdec.h>
#include <malloc.h>
+#include <reset.h>
#include <asm/global_data.h>
+#include <dm/device_compat.h>
DECLARE_GLOBAL_DATA_PTR;
+enum hi6220_dwmmc_clk_type {
+ HI6220_DWMMC_CLK_BIU,
+ HI6220_DWMMC_CLK_CIU,
+ HI6220_DWMMC_CLK_CNT,
+};
+
struct hi6220_dwmmc_plat {
struct mmc_config cfg;
struct mmc mmc;
@@ -21,18 +30,43 @@
struct hi6220_dwmmc_priv_data {
struct dwmci_host host;
+ struct clk *clks[HI6220_DWMMC_CLK_CNT];
+ struct reset_ctl_bulk rsts;
};
struct hisi_mmc_data {
unsigned int clock;
bool use_fifo;
+ u32 fifoth_val;
};
static int hi6220_dwmmc_of_to_plat(struct udevice *dev)
{
struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev);
struct dwmci_host *host = &priv->host;
+ int ret;
+
+ if (CONFIG_IS_ENABLED(CLK) && CONFIG_IS_ENABLED(DM_RESET)) {
+ priv->clks[HI6220_DWMMC_CLK_BIU] = devm_clk_get(dev, "biu");
+ if (IS_ERR(priv->clks[HI6220_DWMMC_CLK_BIU])) {
+ ret = PTR_ERR(priv->clks[HI6220_DWMMC_CLK_BIU]);
+ dev_err(dev, "Failed to get BIU clock(ret = %d).\n", ret);
+ return log_msg_ret("clk", ret);
+ }
+ priv->clks[HI6220_DWMMC_CLK_CIU] = devm_clk_get(dev, "ciu");
+ if (IS_ERR(priv->clks[HI6220_DWMMC_CLK_CIU])) {
+ ret = PTR_ERR(priv->clks[HI6220_DWMMC_CLK_CIU]);
+ dev_err(dev, "Failed to get CIU clock(ret = %d).\n", ret);
+ return log_msg_ret("clk", ret);
+ }
+
+ ret = reset_get_bulk(dev, &priv->rsts);
+ if (ret) {
+ dev_err(dev, "Failed to get resets(ret = %d)", ret);
+ return log_msg_ret("rst", ret);
+ }
+ }
host->name = dev->name;
host->ioaddr = dev_read_addr_ptr(dev);
host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
@@ -56,16 +90,43 @@
struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev);
struct dwmci_host *host = &priv->host;
struct hisi_mmc_data *mmc_data;
+ int ret;
mmc_data = (struct hisi_mmc_data *)dev_get_driver_data(dev);
- /* Use default bus speed due to absence of clk driver */
host->bus_hz = mmc_data->clock;
+ if (CONFIG_IS_ENABLED(CLK) && CONFIG_IS_ENABLED(DM_RESET)) {
+ ret = clk_prepare_enable(priv->clks[HI6220_DWMMC_CLK_BIU]);
+ if (ret) {
+ dev_err(dev, "Failed to enable biu clock(ret = %d).\n", ret);
+ return log_msg_ret("clk", ret);
+ }
+
+ ret = clk_prepare_enable(priv->clks[HI6220_DWMMC_CLK_CIU]);
+ if (ret) {
+ dev_err(dev, "Failed to enable ciu clock(ret = %d).\n", ret);
+ return log_msg_ret("clk", ret);
+ }
+
+ ret = reset_deassert_bulk(&priv->rsts);
+ if (ret) {
+ dev_err(dev, "Failed to deassert resets(ret = %d).\n", ret);
+ return log_msg_ret("rst", ret);
+ }
+
+ host->bus_hz = clk_get_rate(priv->clks[HI6220_DWMMC_CLK_CIU]);
+ if (host->bus_hz <= 0) {
+ dev_err(dev, "Failed to get ciu clock rate(ret = %d).\n", ret);
+ return log_msg_ret("clk", ret);
+ }
+ }
+ dev_dbg(dev, "bus clock rate: %d.\n", host->bus_hz);
dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, 400000);
host->mmc = &plat->mmc;
host->fifo_mode = mmc_data->use_fifo;
+ host->fifoth_val = mmc_data->fifoth_val;
host->mmc->priv = &priv->host;
upriv->mmc = host->mmc;
host->mmc->dev = dev;
@@ -95,13 +156,20 @@
.use_fifo = false,
};
+static const struct hisi_mmc_data hi3798mv2x_mmc_data = {
+ .clock = 50000000,
+ .use_fifo = false,
+ // FIFO depth is 256
+ .fifoth_val = MSIZE(4) | RX_WMARK(0x7f) | TX_WMARK(0x80),
+};
+
static const struct udevice_id hi6220_dwmmc_ids[] = {
{ .compatible = "hisilicon,hi6220-dw-mshc",
.data = (ulong)&hi6220_mmc_data },
{ .compatible = "hisilicon,hi3798cv200-dw-mshc",
.data = (ulong)&hi6220_mmc_data },
{ .compatible = "hisilicon,hi3798mv200-dw-mshc",
- .data = (ulong)&hi6220_mmc_data },
+ .data = (ulong)&hi3798mv2x_mmc_data },
{ .compatible = "hisilicon,hi3660-dw-mshc",
.data = (ulong)&hi3660_mmc_data },
{ }
diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c
index fcf4f03..0825c0a 100644
--- a/drivers/mmc/meson_gx_mmc.c
+++ b/drivers/mmc/meson_gx_mmc.c
@@ -288,7 +288,7 @@
mmc_set_clock(mmc, cfg->f_min, MMC_CLK_ENABLE);
-#ifdef CONFIG_MMC_PWRSEQ
+#if CONFIG_IS_ENABLED(MMC_PWRSEQ)
/* Enable power if needed */
ret = mmc_pwrseq_get_power(dev, cfg);
if (!ret) {
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 3284568..1e03901 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -124,7 +124,13 @@
int mmc_execute_tuning(struct mmc *mmc, uint opcode)
{
- return dm_mmc_execute_tuning(mmc->dev, opcode);
+ int ret;
+
+ mmc->tuning = true;
+ ret = dm_mmc_execute_tuning(mmc->dev, opcode);
+ mmc->tuning = false;
+
+ return ret;
}
#endif
@@ -494,10 +500,7 @@
if (ret) {
debug("Probing %s failed (err=%d)\n", dev->name, ret);
- if (CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) ||
- CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) ||
- CONFIG_IS_ENABLED(MMC_HS400_SUPPORT))
- mmc_deinit(mmc);
+ mmc_deinit(mmc);
return ret;
}
@@ -505,9 +508,6 @@
return 0;
}
-#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
- CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
- CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
static int mmc_blk_remove(struct udevice *dev)
{
struct udevice *mmc_dev = dev_get_parent(dev);
@@ -516,7 +516,6 @@
return mmc_deinit(mmc);
}
-#endif
static const struct blk_ops mmc_blk_ops = {
.read = mmc_bread,
@@ -532,12 +531,8 @@
.id = UCLASS_BLK,
.ops = &mmc_blk_ops,
.probe = mmc_blk_probe,
-#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
- CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
- CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
.remove = mmc_blk_remove,
.flags = DM_FLAG_OS_PREPARE,
-#endif
};
#endif /* CONFIG_BLK */
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index d96db7a..7b068c7 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -360,7 +360,7 @@
0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
};
-int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error)
+int mmc_send_tuning(struct mmc *mmc, u32 opcode)
{
struct mmc_cmd cmd;
struct mmc_data data;
@@ -1570,13 +1570,20 @@
return 0;
}
#endif
-/* frequency bases */
-/* divided by 10 to be nice to platforms without floating point */
+/*
+ * TRAN_SPEED bits 0:2 encode the frequency unit:
+ * 0 = 100KHz, 1 = 1MHz, 2 = 10MHz, 3 = 100MHz, values 4 - 7 are reserved.
+ * The values in fbase[] are divided by 10 to avoid floats in multiplier[].
+ */
static const int fbase[] = {
10000,
100000,
1000000,
10000000,
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
+ 0, /* reserved */
};
/* Multiplier values for TRAN_SPEED. Multiplied by 10 to be nice
@@ -2027,9 +2034,9 @@
mmc_set_clock(mmc, mmc->tran_speed, false);
/* execute tuning if needed */
- mmc->hs400_tuning = 1;
+ mmc->hs400_tuning = true;
err = mmc_execute_tuning(mmc, MMC_CMD_SEND_TUNING_BLOCK_HS200);
- mmc->hs400_tuning = 0;
+ mmc->hs400_tuning = false;
if (err) {
debug("tuning failed\n");
return err;
@@ -2250,6 +2257,16 @@
return -ENOTSUPP;
}
+#else
+static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps)
+{
+ return 0;
+};
+
+static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
+{
+ return 0;
+};
#endif
#if CONFIG_IS_ENABLED(MMC_TINY)
@@ -2560,6 +2577,8 @@
mult = multipliers[((cmd.response[0] >> 3) & 0xf)];
mmc->legacy_speed = freq * mult;
+ if (!mmc->legacy_speed)
+ log_debug("TRAN_SPEED: reserved value");
mmc_select_mode(mmc, MMC_LEGACY);
mmc->dsr_imp = ((cmd.response[1] >> 12) & 0x1);
@@ -3010,13 +3029,15 @@
return err;
}
-#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
- CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
- CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
int mmc_deinit(struct mmc *mmc)
{
u32 caps_filtered;
+ if (!CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) &&
+ !CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) &&
+ !CONFIG_IS_ENABLED(MMC_HS400_SUPPORT))
+ return 0;
+
if (!mmc->has_init)
return 0;
@@ -3034,7 +3055,6 @@
return mmc_select_mode_and_width(mmc, caps_filtered);
}
}
-#endif
int mmc_set_dsr(struct mmc *mmc, u16 val)
{
diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c
index 5a0c61d..296aaee 100644
--- a/drivers/mmc/mtk-sd.c
+++ b/drivers/mmc/mtk-sd.c
@@ -1131,7 +1131,7 @@
i << PAD_CMD_TUNE_RX_DLY3_S);
for (j = 0; j < 3; j++) {
- mmc_send_tuning(mmc, opcode, &cmd_err);
+ cmd_err = mmc_send_tuning(mmc, opcode);
if (!cmd_err) {
cmd_delay |= (1 << i);
} else {
@@ -1181,7 +1181,7 @@
i << MSDC_PAD_TUNE_CMDRDLY_S);
for (j = 0; j < 3; j++) {
- mmc_send_tuning(mmc, opcode, &cmd_err);
+ cmd_err = mmc_send_tuning(mmc, opcode);
if (!cmd_err) {
rise_delay |= (1 << i);
} else {
@@ -1203,7 +1203,7 @@
i << MSDC_PAD_TUNE_CMDRDLY_S);
for (j = 0; j < 3; j++) {
- mmc_send_tuning(mmc, opcode, &cmd_err);
+ cmd_err = mmc_send_tuning(mmc, opcode);
if (!cmd_err) {
fall_delay |= (1 << i);
} else {
@@ -1238,7 +1238,7 @@
clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_CMDRRDLY_M,
i << MSDC_PAD_TUNE_CMDRRDLY_S);
- mmc_send_tuning(mmc, opcode, &cmd_err);
+ cmd_err = mmc_send_tuning(mmc, opcode);
if (!cmd_err)
internal_delay |= (1 << i);
}
@@ -1264,7 +1264,6 @@
struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0, };
u8 final_delay, final_maxlen;
void __iomem *tune_reg = &host->base->pad_tune;
- int cmd_err;
int i, ret;
if (host->dev_comp->pad_tune0)
@@ -1277,10 +1276,10 @@
clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
i << MSDC_PAD_TUNE_DATRRDLY_S);
- ret = mmc_send_tuning(mmc, opcode, &cmd_err);
+ ret = mmc_send_tuning(mmc, opcode);
if (!ret) {
rise_delay |= (1 << i);
- } else if (cmd_err) {
+ } else {
/* in this case, retune response is needed */
ret = msdc_tune_response(dev, opcode);
if (ret)
@@ -1300,10 +1299,10 @@
clrsetbits_le32(tune_reg, MSDC_PAD_TUNE_DATRRDLY_M,
i << MSDC_PAD_TUNE_DATRRDLY_S);
- ret = mmc_send_tuning(mmc, opcode, &cmd_err);
+ ret = mmc_send_tuning(mmc, opcode);
if (!ret) {
fall_delay |= (1 << i);
- } else if (cmd_err) {
+ } else {
/* in this case, retune response is needed */
ret = msdc_tune_response(dev, opcode);
if (ret)
@@ -1362,7 +1361,7 @@
for (i = 0; i < PAD_DELAY_MAX; i++) {
msdc_set_cmd_delay(host, i);
msdc_set_data_delay(host, i);
- ret = mmc_send_tuning(mmc, opcode, NULL);
+ ret = mmc_send_tuning(mmc, opcode);
if (!ret)
rise_delay |= (1 << i);
}
@@ -1378,7 +1377,7 @@
for (i = 0; i < PAD_DELAY_MAX; i++) {
msdc_set_cmd_delay(host, i);
msdc_set_data_delay(host, i);
- ret = mmc_send_tuning(mmc, opcode, NULL);
+ ret = mmc_send_tuning(mmc, opcode);
if (!ret)
fall_delay |= (1 << i);
}
diff --git a/drivers/mmc/octeontx_hsmmc.c b/drivers/mmc/octeontx_hsmmc.c
index 4ee62df..7f9c4f4 100644
--- a/drivers/mmc/octeontx_hsmmc.c
+++ b/drivers/mmc/octeontx_hsmmc.c
@@ -1653,6 +1653,12 @@
return err;
}
+static int octeontx_mmc_send_tuning(struct mmc *mmc, u32 opcode, int *error)
+{
+ *error = 0;
+ return mmc_send_tuning(mmc, opcode);
+}
+
static int octeontx_mmc_test_get_ext_csd(struct mmc *mmc, u32 opcode,
int *statp)
{
@@ -2006,7 +2012,7 @@
{ "CMD_IN", 48, octeontx_mmc_test_cmd, MMC_CMD_SEND_STATUS,
false, false, false, 2, },
/* { "CMD_OUT", 32, octeontx_mmc_test_cmd, MMC_CMD_SEND_STATUS, },*/
- { "DATA_IN(HS200)", 16, mmc_send_tuning,
+ { "DATA_IN(HS200)", 16, octeontx_mmc_send_tuning,
MMC_CMD_SEND_TUNING_BLOCK_HS200, false, true, false, 2, },
{ "DATA_IN", 16, octeontx_mmc_test_get_ext_csd, 0, false, false,
true, 2, },
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index a2595d1..99f21b2 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -666,7 +666,7 @@
while (phase_delay <= MAX_PHASE_DELAY) {
omap_hsmmc_set_dll(mmc, phase_delay);
- cur_match = !mmc_send_tuning(mmc, opcode, NULL);
+ cur_match = !mmc_send_tuning(mmc, opcode);
if (cur_match) {
if (prev_match) {
@@ -731,7 +731,7 @@
*/
for (i = 3; i <= 10; i++) {
omap_hsmmc_set_dll(mmc, phase_delay + i);
- if (mmc_send_tuning(mmc, opcode, NULL)) {
+ if (mmc_send_tuning(mmc, opcode)) {
if (temperature < 10000)
phase_delay += i + 6;
else if (temperature < 20000)
@@ -749,7 +749,7 @@
for (i = 2; i >= -10; i--) {
omap_hsmmc_set_dll(mmc, phase_delay + i);
- if (mmc_send_tuning(mmc, opcode, NULL)) {
+ if (mmc_send_tuning(mmc, opcode)) {
if (temperature < 10000)
phase_delay += i + 12;
else if (temperature < 20000)
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index 20b1e92..23db2a7 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -568,8 +568,8 @@
struct mmc *mmc = upriv->mmc;
unsigned int tap_num;
unsigned int taps = 0;
- int i, ret = 0;
- u32 caps;
+ int i, ret = 0, sret;
+ u32 caps, reg;
/* Only supported on Renesas RCar */
if (!(priv->caps & TMIO_SD_CAP_RCAR_UHS))
@@ -605,15 +605,15 @@
caps = priv->caps;
priv->caps &= ~TMIO_SD_CAP_DMA_INTERNAL;
- ret = mmc_send_tuning(mmc, opcode, NULL);
+ ret = mmc_send_tuning(mmc, opcode);
priv->caps = caps;
if (ret == 0)
taps |= BIT(i);
- ret = renesas_sdhi_compare_scc_data(priv);
- if (ret == 0)
+ reg = renesas_sdhi_compare_scc_data(priv);
+ if (reg == 0)
priv->smpcmp |= BIT(i);
mdelay(1);
@@ -624,9 +624,9 @@
* eMMC.
*/
if (ret && (opcode == MMC_CMD_SEND_TUNING_BLOCK_HS200)) {
- ret = mmc_send_stop_transmission(mmc, false);
- if (ret < 0)
- dev_dbg(dev, "Tuning abort fail (%d)\n", ret);
+ sret = mmc_send_stop_transmission(mmc, false);
+ if (sret < 0)
+ dev_dbg(dev, "Tuning abort fail (%d)\n", sret);
}
}
@@ -798,9 +798,12 @@
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) || \
CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
struct tmio_sd_priv *priv = dev_get_priv(dev);
+ struct mmc *mmc = upriv->mmc;
- renesas_sdhi_check_scc_error(dev);
+ if (!mmc->tuning)
+ renesas_sdhi_check_scc_error(dev);
if (cmd->cmdidx == MMC_CMD_SEND_STATUS)
renesas_sdhi_adjust_hs400_mode_enable(priv);
diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c
index 72c820e..ad4529d 100644
--- a/drivers/mmc/rockchip_dw_mmc.c
+++ b/drivers/mmc/rockchip_dw_mmc.c
@@ -145,7 +145,7 @@
host->fifo_mode = priv->fifo_mode;
-#ifdef CONFIG_MMC_PWRSEQ
+#if CONFIG_IS_ENABLED(MMC_PWRSEQ)
/* Enable power if needed */
ret = mmc_pwrseq_get_power(dev, &plat->cfg);
if (!ret) {
diff --git a/drivers/mmc/sdhci-cadence.c b/drivers/mmc/sdhci-cadence.c
index 327a05a..c0a9f60 100644
--- a/drivers/mmc/sdhci-cadence.c
+++ b/drivers/mmc/sdhci-cadence.c
@@ -224,7 +224,7 @@
for (i = 0; i < SDHCI_CDNS_MAX_TUNING_LOOP; i++) {
if (sdhci_cdns_set_tune_val(plat, i) ||
- mmc_send_tuning(mmc, opcode, NULL)) { /* bad */
+ mmc_send_tuning(mmc, opcode)) { /* bad */
cur_streak = 0;
} else { /* good */
cur_streak++;
diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c
index 890c496..719c483 100644
--- a/drivers/mmc/tmio-common.c
+++ b/drivers/mmc/tmio-common.c
@@ -299,7 +299,13 @@
struct tmio_sd_priv *priv = dev_get_priv(dev);
long wait = 1000000 + 10 * blocks;
- while (!(tmio_sd_readl(priv, TMIO_SD_DMA_INFO1) & flag)) {
+ for (;;) {
+ if (tmio_sd_readl(priv, TMIO_SD_DMA_INFO1) & flag)
+ break;
+
+ if (tmio_sd_readl(priv, TMIO_SD_INFO1) & TMIO_SD_INFO1_CMP)
+ break;
+
if (wait-- < 0) {
dev_err(dev, "timeout during DMA\n");
return -ETIMEDOUT;
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index bb9994b..9f3f126 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -1,6 +1,6 @@
-
menuconfig MTD_RAW_NAND
bool "Raw NAND Device Support"
+
if MTD_RAW_NAND
config SYS_NAND_SELF_INIT
@@ -49,12 +49,12 @@
depends on NAND_ARASAN || NAND_DAVINCI || NAND_KIRKWOOD
config DM_NAND_ATMEL
- bool "Support Atmel NAND controller with DM support"
- select SYS_NAND_SELF_INIT
- imply SYS_NAND_USE_FLASH_BBT
- help
- Enable this driver for NAND flash platforms using an Atmel NAND
- controller.
+ bool "Support Atmel NAND controller with DM support"
+ select SYS_NAND_SELF_INIT
+ imply SYS_NAND_USE_FLASH_BBT
+ help
+ Enable this driver for NAND flash platforms using an Atmel NAND
+ controller.
config NAND_ATMEL
bool "Support Atmel NAND controller"
@@ -133,35 +133,35 @@
Enable support for broadcom nand driver on bcm6753.
config NAND_BRCMNAND_68360
- bool "Support Broadcom NAND controller on bcm68360"
- depends on NAND_BRCMNAND && BCM6856
- help
- Enable support for broadcom nand driver on bcm68360.
+ bool "Support Broadcom NAND controller on bcm68360"
+ depends on NAND_BRCMNAND && BCM6856
+ help
+ Enable support for broadcom nand driver on bcm68360.
config NAND_BRCMNAND_6838
- bool "Support Broadcom NAND controller on bcm6838"
- depends on NAND_BRCMNAND && ARCH_BMIPS && SOC_BMIPS_BCM6838
- help
- Enable support for broadcom nand driver on bcm6838.
+ bool "Support Broadcom NAND controller on bcm6838"
+ depends on NAND_BRCMNAND && ARCH_BMIPS && SOC_BMIPS_BCM6838
+ help
+ Enable support for broadcom nand driver on bcm6838.
config NAND_BRCMNAND_6858
- bool "Support Broadcom NAND controller on bcm6858"
- depends on NAND_BRCMNAND && BCM6858
- help
- Enable support for broadcom nand driver on bcm6858.
+ bool "Support Broadcom NAND controller on bcm6858"
+ depends on NAND_BRCMNAND && BCM6858
+ help
+ Enable support for broadcom nand driver on bcm6858.
config NAND_BRCMNAND_63158
- bool "Support Broadcom NAND controller on bcm63158"
- depends on NAND_BRCMNAND && BCM63158
- help
- Enable support for broadcom nand driver on bcm63158.
+ bool "Support Broadcom NAND controller on bcm63158"
+ depends on NAND_BRCMNAND && BCM63158
+ help
+ Enable support for broadcom nand driver on bcm63158.
config NAND_BRCMNAND_IPROC
- bool "Support Broadcom NAND controller on the iproc family"
- depends on NAND_BRCMNAND
- help
- Enable support for broadcom nand driver on the Broadcom
- iproc family such as Northstar (BCM5301x, BCM4708...)
+ bool "Support Broadcom NAND controller on the iproc family"
+ depends on NAND_BRCMNAND
+ help
+ Enable support for broadcom nand driver on the Broadcom
+ iproc family such as Northstar (BCM5301x, BCM4708...)
config NAND_DAVINCI
bool "Support TI Davinci NAND controller"
@@ -413,10 +413,10 @@
if NAND_VF610_NFC
config NAND_VF610_NFC_DT
- bool "Support Vybrid's vf610 NAND controller as a DT device"
- depends on OF_CONTROL && DM_MTD
- help
- Enable the driver for Vybrid's vf610 NAND flash on platforms
+ bool "Support Vybrid's vf610 NAND controller as a DT device"
+ depends on OF_CONTROL && DM_MTD
+ help
+ Enable the driver for Vybrid's vf610 NAND flash on platforms
using device tree.
choice
@@ -472,11 +472,11 @@
select SPL_NAND_SUPPORT
select SPL_SYS_NAND_SELF_INIT
imply CMD_NAND
- ---help---
- Enable support for NAND. This option enables the standard and
- SPL drivers.
- The SPL driver only supports reading from the NAND using DMA
- transfers.
+ help
+ Enable support for NAND. This option enables the standard and
+ SPL drivers.
+ The SPL driver only supports reading from the NAND using DMA
+ transfers.
if NAND_SUNXI
@@ -504,6 +504,15 @@
controller. This uses the hardware ECC for read and
write operations.
+config NAND_MESON
+ bool "Meson NAND support"
+ select SYS_NAND_SELF_INIT
+ depends on DM_MTD && ARCH_MESON
+ imply CMD_NAND
+ help
+ This enables Nand driver support for Meson raw NAND flash
+ controller.
+
config NAND_MXC
bool "MXC NAND support"
depends on CPU_ARM926EJS || CPU_ARM1136 || MX5
@@ -577,16 +586,16 @@
select SYS_NAND_SELF_INIT
imply CMD_NAND
help
- This enables Nand flash controller hardware found on the OcteonTX
- processors.
+ This enables Nand flash controller hardware found on the OcteonTX
+ processors.
config NAND_OCTEONTX_HW_ECC
bool "Support Hardware ECC for OcteonTX NAND controller"
depends on NAND_OCTEONTX
default y
help
- This enables Hardware BCH engine found on the OcteonTX processors to
- support ECC for NAND flash controller.
+ This enables Hardware BCH engine found on the OcteonTX processors to
+ support ECC for NAND flash controller.
config NAND_STM32_FMC2
bool "Support for NAND controller on STM32MP SoCs"
@@ -751,37 +760,37 @@
config SYS_NAND_U_BOOT_LOCATIONS
bool "Define U-Boot binaries locations in NAND"
help
- Enable CONFIG_SYS_NAND_U_BOOT_OFFS though Kconfig.
- This option should not be enabled when compiling U-Boot for boards
- defining CONFIG_SYS_NAND_U_BOOT_OFFS in their include/configs/<board>.h
- file.
+ Enable CONFIG_SYS_NAND_U_BOOT_OFFS though Kconfig.
+ This option should not be enabled when compiling U-Boot for boards
+ defining CONFIG_SYS_NAND_U_BOOT_OFFS in their include/configs/<board>.h
+ file.
config SYS_NAND_U_BOOT_OFFS
hex "Location in NAND to read U-Boot from"
default 0x800000 if NAND_SUNXI
depends on SYS_NAND_U_BOOT_LOCATIONS
help
- Set the offset from the start of the nand where u-boot should be
- loaded from.
+ Set the offset from the start of the nand where u-boot should be
+ loaded from.
config SYS_NAND_U_BOOT_OFFS_REDUND
hex "Location in NAND to read U-Boot from"
default SYS_NAND_U_BOOT_OFFS
depends on SYS_NAND_U_BOOT_LOCATIONS
help
- Set the offset from the start of the nand where the redundant u-boot
- should be loaded from.
+ Set the offset from the start of the nand where the redundant u-boot
+ should be loaded from.
config SPL_NAND_AM33XX_BCH
bool "Enables SPL-NAND driver which supports ELM based"
depends on SPL_NAND_SUPPORT && NAND_OMAP_GPMC && !OMAP34XX
default y
- help
+ help
Hardware ECC correction. This is useful for platforms which have ELM
hardware engine and use NAND boot mode.
Some legacy platforms like OMAP3xx do not have in-built ELM h/w engine,
so those platforms should use CONFIG_SPL_NAND_SIMPLE for enabling
- SPL-NAND driver with software ECC correction support.
+ SPL-NAND driver with software ECC correction support.
config SPL_NAND_DENALI
bool "Support Denali NAND controller for SPL"
@@ -810,6 +819,6 @@
bool "In SPL, read the OOB first and then the data from NAND"
depends on SPL_NAND_SIMPLE
-endif
+endif # if SPL
-endif # if NAND
+endif # if MTD_RAW_NAND
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
index ddbba89..46fead6 100644
--- a/drivers/mtd/nand/raw/Makefile
+++ b/drivers/mtd/nand/raw/Makefile
@@ -61,6 +61,7 @@
obj-$(CONFIG_NAND_LPC32XX_MLC) += lpc32xx_nand_mlc.o
obj-$(CONFIG_NAND_LPC32XX_SLC) += lpc32xx_nand_slc.o
obj-$(CONFIG_NAND_VF610_NFC) += vf610_nfc.o
+obj-$(CONFIG_NAND_MESON) += meson_nand.o
obj-$(CONFIG_NAND_MXC) += mxc_nand.o
obj-$(CONFIG_NAND_MXS) += mxs_nand.o
obj-$(CONFIG_NAND_MXS_DT) += mxs_nand_dt.o
diff --git a/drivers/mtd/nand/raw/arasan_nfc.c b/drivers/mtd/nand/raw/arasan_nfc.c
index 1476640..ffcd963 100644
--- a/drivers/mtd/nand/raw/arasan_nfc.c
+++ b/drivers/mtd/nand/raw/arasan_nfc.c
@@ -1232,7 +1232,8 @@
struct nand_config *nand = &info->config;
struct mtd_info *mtd;
ofnode child;
- int err = -1;
+ int ret;
+ const char *str;
info->reg = dev_read_addr_ptr(dev);
mtd = nand_to_mtd(nand_chip);
@@ -1258,11 +1259,18 @@
writel(0x0, &info->reg->pgm_reg);
/* first scan to find the device and get the page size */
- if (nand_scan_ident(mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL)) {
+ ret = nand_scan_ident(mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL);
+ if (ret) {
printf("%s: nand_scan_ident failed\n", __func__);
- goto fail;
+ return ret;
}
+ str = ofnode_read_string(nand_chip->flash_node, "nand-ecc-mode");
+ if (!str || strcmp(str, "hw") != 0) {
+ printf("%s ecc mode is not supported\n", str);
+ return -EINVAL;
+ }
+
nand_chip->ecc.mode = NAND_ECC_HW;
nand_chip->ecc.hwctl = NULL;
nand_chip->ecc.read_page = arasan_nand_read_page_hwecc;
@@ -1282,26 +1290,26 @@
nand_chip->ecc.bytes = 0;
nand_chip->ecc.layout = &ondie_nand_oob_64;
} else {
- if (arasan_nand_ecc_init(mtd)) {
+ ret = arasan_nand_ecc_init(mtd);
+ if (ret) {
printf("%s: nand_ecc_init failed\n", __func__);
- goto fail;
+ return ret;
}
}
- if (nand_scan_tail(mtd)) {
+ ret = nand_scan_tail(mtd);
+ if (ret) {
printf("%s: nand_scan_tail failed\n", __func__);
- goto fail;
+ return ret;
}
- if (nand_register(0, mtd)) {
+ ret = nand_register(0, mtd);
+ if (ret) {
printf("Nand Register Fail\n");
- goto fail;
+ return ret;
}
- return 0;
-fail:
- free(nand);
- return err;
+ return ret;
}
static const struct udevice_id arasan_nand_dt_ids[] = {
diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index 0e04414..ee4ec6d 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -1267,7 +1267,7 @@
return ret;
/*
- * The write cycle timing is directly matching tWC, but is also
+ * The read cycle timing is directly matching tRC, but is also
* dependent on the setup and hold timings we calculated earlier,
* which gives:
*
@@ -1429,8 +1429,6 @@
return nc->caps->ops->setup_data_interface(nand, csline, conf);
}
-#define NAND_KEEP_TIMINGS 0x00800000
-
static void atmel_nand_init(struct atmel_nand_controller *nc,
struct atmel_nand *nand)
{
diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c
new file mode 100644
index 0000000..12499a7
--- /dev/null
+++ b/drivers/mtd/nand/raw/meson_nand.c
@@ -0,0 +1,1247 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Amlogic Meson Nand Flash Controller Driver
+ *
+ * Copyright (c) 2018 Amlogic, inc.
+ * Author: Liang Yang <liang.yang@amlogic.com>
+ *
+ * Copyright (c) 2023 SaluteDevices, Inc.
+ * Author: Arseniy Krasnov <avkrasnov@salutedevices.com>
+ */
+
+#include <nand.h>
+#include <asm/io.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <dm/ofnode.h>
+#include <dm/uclass.h>
+#include <linux/bug.h>
+#include <linux/clk-provider.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/iopoll.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/rawnand.h>
+#include <linux/sizes.h>
+
+#define NFC_CMD_IDLE (0xc << 14)
+#define NFC_CMD_CLE (0x5 << 14)
+#define NFC_CMD_ALE (0x6 << 14)
+#define NFC_CMD_DWR (0x4 << 14)
+#define NFC_CMD_DRD (0x8 << 14)
+#define NFC_CMD_ADL ((0 << 16) | (3 << 20))
+#define NFC_CMD_ADH ((1 << 16) | (3 << 20))
+#define NFC_CMD_AIL ((2 << 16) | (3 << 20))
+#define NFC_CMD_AIH ((3 << 16) | (3 << 20))
+#define NFC_CMD_SEED ((8 << 16) | (3 << 20))
+#define NFC_CMD_M2N ((0 << 17) | (2 << 20))
+#define NFC_CMD_N2M ((1 << 17) | (2 << 20))
+#define NFC_CMD_RB BIT(20)
+#define NFC_CMD_SCRAMBLER_ENABLE BIT(19)
+#define NFC_CMD_SCRAMBLER_DISABLE 0
+#define NFC_CMD_SHORTMODE_DISABLE 0
+#define NFC_CMD_RB_INT BIT(14)
+#define NFC_CMD_RB_INT_NO_PIN ((0xb << 10) | BIT(18) | BIT(16))
+
+#define NFC_CMD_GET_SIZE(x) (((x) >> 22) & GENMASK(4, 0))
+
+#define NFC_REG_CMD 0x00
+#define NFC_REG_CFG 0x04
+#define NFC_REG_DADR 0x08
+#define NFC_REG_IADR 0x0c
+#define NFC_REG_BUF 0x10
+#define NFC_REG_INFO 0x14
+#define NFC_REG_DC 0x18
+#define NFC_REG_ADR 0x1c
+#define NFC_REG_DL 0x20
+#define NFC_REG_DH 0x24
+#define NFC_REG_CADR 0x28
+#define NFC_REG_SADR 0x2c
+#define NFC_REG_PINS 0x30
+#define NFC_REG_VER 0x38
+
+#define CMDRWGEN(cmd_dir, ran, bch, short_mode, page_size, pages) \
+ ( \
+ (cmd_dir) | \
+ (ran) | \
+ ((bch) << 14) | \
+ ((short_mode) << 13) | \
+ (((page_size) & 0x7f) << 6) | \
+ ((pages) & 0x3f) \
+ )
+
+#define GENCMDDADDRL(adl, addr) ((adl) | ((addr) & 0xffff))
+#define GENCMDDADDRH(adh, addr) ((adh) | (((addr) >> 16) & 0xffff))
+#define GENCMDIADDRL(ail, addr) ((ail) | ((addr) & 0xffff))
+#define GENCMDIADDRH(aih, addr) ((aih) | (((addr) >> 16) & 0xffff))
+
+#define DMA_DIR(dir) ((dir) ? NFC_CMD_N2M : NFC_CMD_M2N)
+
+#define ECC_CHECK_RETURN_FF -1
+
+#define NAND_CE0 (0xe << 10)
+#define NAND_CE1 (0xd << 10)
+
+#define DMA_BUSY_TIMEOUT_US 1000000
+#define CMD_DRAIN_TIMEOUT_US 1000
+#define ECC_POLL_TIMEOUT_US 15
+
+#define MAX_CE_NUM 2
+
+/* eMMC clock register, misc control */
+#define CLK_SELECT_NAND BIT(31)
+#define CLK_ALWAYS_ON_NAND BIT(24)
+#define CLK_ENABLE_VALUE 0x245
+
+#define DIRREAD 1
+#define DIRWRITE 0
+
+#define ECC_PARITY_BCH8_512B 14
+#define ECC_COMPLETE BIT(31)
+#define ECC_ERR_CNT(x) (((x) >> 24) & GENMASK(5, 0))
+#define ECC_ZERO_CNT(x) (((x) >> 16) & GENMASK(5, 0))
+#define ECC_UNCORRECTABLE 0x3f
+
+#define PER_INFO_BYTE 8
+
+#define NFC_SEND_CMD(host, cmd) \
+ (writel((cmd), (host)->reg_base + NFC_REG_CMD))
+
+#define NFC_GET_CMD(host) \
+ (readl((host)->reg_base + NFC_REG_CMD))
+
+#define NFC_CMDFIFO_SIZE(host) ((NFC_GET_CMD((host)) >> 22) & GENMASK(4, 0))
+
+#define NFC_CMD_MAKE_IDLE(ce, delay) ((ce) | NFC_CMD_IDLE | ((delay) & 0x3ff))
+#define NFC_CMD_MAKE_DRD(ce, size) ((ce) | NFC_CMD_DRD | (size))
+#define NFC_CMD_MAKE_DWR(ce, data) ((ce) | NFC_CMD_DWR | ((data) & 0xff))
+#define NFC_CMD_MAKE_CLE(ce, cmd_val) ((ce) | NFC_CMD_CLE | ((cmd_val) & 0xff))
+#define NFC_CMD_MAKE_ALE(ce, addr) ((ce) | NFC_CMD_ALE | ((addr) & 0xff))
+
+#define NAND_TWB_TIME_CYCLE 10
+
+#define NFC_DEV_READY_TICK_MAX 5000
+
+/* Both values are recommended by vendor, as the most
+ * tested with almost all SLC NAND flash. Second value
+ * could be calculated dynamically from timing parameters,
+ * but we need both values for initial start of the NAND
+ * controller (e.g. before NAND subsystem processes timings),
+ * so use hardcoded constants.
+ */
+#define NFC_DEFAULT_BUS_CYCLE 6
+#define NFC_DEFAULT_BUS_TIMING 7
+
+#define NFC_SEED_OFFSET 0xc2
+#define NFC_SEED_MASK 0x7fff
+
+#define DMA_ADDR_ALIGN 8
+
+struct meson_nfc_nand_chip {
+ struct list_head node;
+ struct nand_chip nand;
+
+ u32 bch_mode;
+ u8 *data_buf;
+ __le64 *info_buf;
+ u32 nsels;
+ u8 sels[];
+};
+
+struct meson_nfc_param {
+ u32 chip_select;
+ u32 rb_select;
+};
+
+struct meson_nfc {
+ void __iomem *reg_base;
+ void __iomem *reg_clk;
+ struct list_head chips;
+ struct meson_nfc_param param;
+ struct udevice *dev;
+ dma_addr_t daddr;
+ dma_addr_t iaddr;
+ u32 data_bytes;
+ u32 info_bytes;
+ u64 assigned_cs;
+};
+
+struct meson_nand_ecc {
+ u32 bch;
+ u32 strength;
+ u32 size;
+};
+
+enum {
+ NFC_ECC_BCH8_512 = 1,
+ NFC_ECC_BCH8_1K,
+ NFC_ECC_BCH24_1K,
+ NFC_ECC_BCH30_1K,
+ NFC_ECC_BCH40_1K,
+ NFC_ECC_BCH50_1K,
+ NFC_ECC_BCH60_1K,
+};
+
+#define MESON_ECC_DATA(b, s, sz) { .bch = (b), .strength = (s), .size = (sz) }
+
+static struct meson_nand_ecc meson_ecc[] = {
+ MESON_ECC_DATA(NFC_ECC_BCH8_512, 8, 512),
+ MESON_ECC_DATA(NFC_ECC_BCH8_1K, 8, 1024),
+};
+
+static int meson_nand_calc_ecc_bytes(int step_size, int strength)
+{
+ int ecc_bytes;
+
+ if (step_size == 512 && strength == 8)
+ return ECC_PARITY_BCH8_512B;
+
+ ecc_bytes = DIV_ROUND_UP(strength * fls(step_size * 8), 8);
+ ecc_bytes = ALIGN(ecc_bytes, 2);
+
+ return ecc_bytes;
+}
+
+static struct meson_nfc_nand_chip *to_meson_nand(struct nand_chip *nand)
+{
+ return container_of(nand, struct meson_nfc_nand_chip, nand);
+}
+
+static void meson_nfc_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+
+ nfc->param.chip_select = meson_chip->sels[chip] ? NAND_CE1 : NAND_CE0;
+}
+
+static void meson_nfc_cmd_idle(struct meson_nfc *nfc, u32 time)
+{
+ writel(NFC_CMD_MAKE_IDLE(nfc->param.chip_select, time),
+ nfc->reg_base + NFC_REG_CMD);
+}
+
+static void meson_nfc_cmd_seed(const struct meson_nfc *nfc, u32 seed)
+{
+ writel(NFC_CMD_SEED | (NFC_SEED_OFFSET + (seed & NFC_SEED_MASK)),
+ nfc->reg_base + NFC_REG_CMD);
+}
+
+static void meson_nfc_cmd_access(struct nand_chip *nand, bool raw, bool dir,
+ int scrambler)
+{
+ struct mtd_info *mtd = nand_to_mtd(nand);
+ const struct meson_nfc *nfc = nand_get_controller_data(mtd_to_nand(mtd));
+ const struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ u32 bch = meson_chip->bch_mode, cmd;
+ int len = mtd->writesize, pagesize, pages;
+
+ pagesize = nand->ecc.size;
+
+ if (raw) {
+ len = mtd->writesize + mtd->oobsize;
+ cmd = len | scrambler | DMA_DIR(dir);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+ return;
+ }
+
+ pages = len / nand->ecc.size;
+
+ cmd = CMDRWGEN(DMA_DIR(dir), scrambler, bch,
+ NFC_CMD_SHORTMODE_DISABLE, pagesize, pages);
+
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+}
+
+static void meson_nfc_drain_cmd(struct meson_nfc *nfc)
+{
+ /*
+ * Insert two commands to make sure all valid commands are finished.
+ *
+ * The Nand flash controller is designed as two stages pipleline -
+ * a) fetch and b) execute.
+ * There might be cases when the driver see command queue is empty,
+ * but the Nand flash controller still has two commands buffered,
+ * one is fetched into NFC request queue (ready to run), and another
+ * is actively executing. So pushing 2 "IDLE" commands guarantees that
+ * the pipeline is emptied.
+ */
+ meson_nfc_cmd_idle(nfc, 0);
+ meson_nfc_cmd_idle(nfc, 0);
+}
+
+static int meson_nfc_wait_cmd_finish(const struct meson_nfc *nfc,
+ unsigned int timeout_us)
+{
+ u32 cmd_size = 0;
+
+ /* wait cmd fifo is empty */
+ return readl_relaxed_poll_timeout(nfc->reg_base + NFC_REG_CMD, cmd_size,
+ !NFC_CMD_GET_SIZE(cmd_size),
+ timeout_us);
+}
+
+static int meson_nfc_wait_dma_finish(struct meson_nfc *nfc)
+{
+ meson_nfc_drain_cmd(nfc);
+
+ return meson_nfc_wait_cmd_finish(nfc, DMA_BUSY_TIMEOUT_US);
+}
+
+static u8 *meson_nfc_oob_ptr(struct nand_chip *nand, int i)
+{
+ const struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ int len;
+
+ len = nand->ecc.size * (i + 1) + (nand->ecc.bytes + 2) * i;
+
+ return meson_chip->data_buf + len;
+}
+
+static u8 *meson_nfc_data_ptr(struct nand_chip *nand, int i)
+{
+ const struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ int len, temp;
+
+ temp = nand->ecc.size + nand->ecc.bytes;
+ len = (temp + 2) * i;
+
+ return meson_chip->data_buf + len;
+}
+
+static void meson_nfc_get_data_oob(struct nand_chip *nand,
+ u8 *buf, u8 *oobbuf)
+{
+ u8 *dsrc, *osrc;
+ int i, oob_len;
+
+ oob_len = nand->ecc.bytes + 2;
+ for (i = 0; i < nand->ecc.steps; i++) {
+ if (buf) {
+ dsrc = meson_nfc_data_ptr(nand, i);
+ memcpy(buf, dsrc, nand->ecc.size);
+ buf += nand->ecc.size;
+ }
+
+ if (oobbuf) {
+ osrc = meson_nfc_oob_ptr(nand, i);
+ memcpy(oobbuf, osrc, oob_len);
+ oobbuf += oob_len;
+ }
+ }
+}
+
+static void meson_nfc_set_data_oob(struct nand_chip *nand,
+ const u8 *buf, u8 *oobbuf)
+{
+ int i, oob_len;
+
+ oob_len = nand->ecc.bytes + 2;
+ for (i = 0; i < nand->ecc.steps; i++) {
+ u8 *osrc;
+
+ if (buf) {
+ u8 *dsrc;
+
+ dsrc = meson_nfc_data_ptr(nand, i);
+ memcpy(dsrc, buf, nand->ecc.size);
+ buf += nand->ecc.size;
+ }
+
+ osrc = meson_nfc_oob_ptr(nand, i);
+ memcpy(osrc, oobbuf, oob_len);
+ oobbuf += oob_len;
+ }
+}
+
+static void meson_nfc_set_user_byte(struct nand_chip *nand, const u8 *oob_buf)
+{
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ int i, count;
+
+ for (i = 0, count = 0; i < nand->ecc.steps; i++, count += (2 + nand->ecc.bytes)) {
+ __le64 *info = &meson_chip->info_buf[i];
+
+ *info |= oob_buf[count];
+ *info |= oob_buf[count + 1] << 8;
+ }
+}
+
+static void meson_nfc_get_user_byte(struct nand_chip *nand, u8 *oob_buf)
+{
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ int i, count;
+
+ for (i = 0, count = 0; i < nand->ecc.steps; i++, count += (2 + nand->ecc.bytes)) {
+ const __le64 *info = &meson_chip->info_buf[i];
+
+ oob_buf[count] = *info;
+ oob_buf[count + 1] = *info >> 8;
+ }
+}
+
+static int meson_nfc_ecc_correct(struct nand_chip *nand, u32 *bitflips,
+ u64 *correct_bitmap)
+{
+ struct mtd_info *mtd = nand_to_mtd(nand);
+ int ret = 0, i;
+
+ for (i = 0; i < nand->ecc.steps; i++) {
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ const __le64 *info = &meson_chip->info_buf[i];
+
+ if (ECC_ERR_CNT(*info) != ECC_UNCORRECTABLE) {
+ mtd->ecc_stats.corrected += ECC_ERR_CNT(*info);
+ *bitflips = max_t(u32, *bitflips, ECC_ERR_CNT(*info));
+ *correct_bitmap |= BIT_ULL(i);
+ continue;
+ }
+
+ if ((nand->options & NAND_NEED_SCRAMBLING) &&
+ ECC_ZERO_CNT(*info) < nand->ecc.strength) {
+ mtd->ecc_stats.corrected += ECC_ZERO_CNT(*info);
+ *bitflips = max_t(u32, *bitflips,
+ ECC_ZERO_CNT(*info));
+ ret = ECC_CHECK_RETURN_FF;
+ } else {
+ ret = -EBADMSG;
+ }
+ }
+
+ return ret;
+}
+
+static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf,
+ int datalen, void *infobuf, int infolen,
+ enum dma_data_direction dir)
+{
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+ int ret;
+ u32 cmd;
+
+ nfc->daddr = dma_map_single(databuf, datalen, DMA_BIDIRECTIONAL);
+ ret = dma_mapping_error(nfc->dev, nfc->daddr);
+ if (ret)
+ return ret;
+
+ cmd = GENCMDDADDRL(NFC_CMD_ADL, nfc->daddr);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+
+ cmd = GENCMDDADDRH(NFC_CMD_ADH, nfc->daddr);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+
+ if (infobuf) {
+ nfc->iaddr = dma_map_single(infobuf, infolen,
+ DMA_BIDIRECTIONAL);
+ ret = dma_mapping_error(nfc->dev, nfc->iaddr);
+ if (ret) {
+ dma_unmap_single(nfc->daddr, datalen, dir);
+ return ret;
+ }
+
+ nfc->info_bytes = infolen;
+ cmd = GENCMDIADDRL(NFC_CMD_AIL, nfc->iaddr);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+
+ cmd = GENCMDIADDRH(NFC_CMD_AIH, nfc->iaddr);
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+ }
+
+ return 0;
+}
+
+static void meson_nfc_dma_buffer_release(struct nand_chip *nand,
+ int datalen, int infolen,
+ enum dma_data_direction dir)
+{
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+
+ dma_unmap_single(nfc->daddr, datalen, dir);
+
+ if (infolen) {
+ dma_unmap_single(nfc->iaddr, infolen, dir);
+ nfc->info_bytes = 0;
+ }
+}
+
+static void meson_nfc_read_buf(struct mtd_info *mtd, u8 *buf, int size)
+{
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ u8 *dma_buf;
+ int ret;
+ u32 cmd;
+
+ if ((uintptr_t)buf % DMA_ADDR_ALIGN) {
+ unsigned long tmp_addr;
+
+ dma_buf = dma_alloc_coherent(size, &tmp_addr);
+ if (!dma_buf)
+ return;
+ } else {
+ dma_buf = buf;
+ }
+
+ ret = meson_nfc_dma_buffer_setup(nand, dma_buf, size, meson_chip->info_buf,
+ PER_INFO_BYTE, DMA_FROM_DEVICE);
+ if (ret) {
+ pr_err("Failed to setup DMA buffer %p/%p\n", dma_buf,
+ meson_chip->info_buf);
+ return;
+ }
+
+ cmd = NFC_CMD_N2M | size;
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+
+ meson_nfc_drain_cmd(nfc);
+ meson_nfc_wait_cmd_finish(nfc, CMD_DRAIN_TIMEOUT_US);
+ meson_nfc_dma_buffer_release(nand, size, PER_INFO_BYTE, DMA_FROM_DEVICE);
+
+ if (buf != dma_buf) {
+ memcpy(buf, dma_buf, size);
+ dma_free_coherent(dma_buf);
+ }
+}
+
+static void meson_nfc_write_buf(struct mtd_info *mtd, const u8 *buf, int size)
+{
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+ u8 *dma_buf;
+ int ret;
+ u32 cmd;
+
+ if ((uintptr_t)buf % DMA_ADDR_ALIGN) {
+ unsigned long tmp_addr;
+
+ dma_buf = dma_alloc_coherent(size, &tmp_addr);
+ if (!dma_buf)
+ return;
+
+ memcpy(dma_buf, buf, size);
+ } else {
+ dma_buf = (u8 *)buf;
+ }
+
+ ret = meson_nfc_dma_buffer_setup(nand, (void *)dma_buf, size, NULL,
+ 0, DMA_TO_DEVICE);
+ if (ret) {
+ pr_err("Failed to setup DMA buffer %p\n", dma_buf);
+ return;
+ }
+
+ cmd = NFC_CMD_M2N | size;
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+
+ meson_nfc_drain_cmd(nfc);
+ meson_nfc_wait_cmd_finish(nfc, CMD_DRAIN_TIMEOUT_US);
+ meson_nfc_dma_buffer_release(nand, size, 0, DMA_TO_DEVICE);
+
+ if (buf != dma_buf)
+ dma_free_coherent(dma_buf);
+}
+
+static int meson_nfc_write_page_sub(struct nand_chip *nand,
+ int page, bool raw)
+{
+ const struct mtd_info *mtd = nand_to_mtd(nand);
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+ int data_len, info_len;
+ int ret;
+ u32 cmd;
+
+ data_len = mtd->writesize + mtd->oobsize;
+ info_len = nand->ecc.steps * PER_INFO_BYTE;
+
+ ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf,
+ data_len, meson_chip->info_buf,
+ info_len, DMA_TO_DEVICE);
+ if (ret) {
+ pr_err("Failed to setup DMA buffer %p/%p\n",
+ meson_chip->data_buf, meson_chip->info_buf);
+ return ret;
+ }
+
+ if (nand->options & NAND_NEED_SCRAMBLING) {
+ meson_nfc_cmd_seed(nfc, page);
+ meson_nfc_cmd_access(nand, raw, DIRWRITE,
+ NFC_CMD_SCRAMBLER_ENABLE);
+ } else {
+ meson_nfc_cmd_access(nand, raw, DIRWRITE,
+ NFC_CMD_SCRAMBLER_DISABLE);
+ }
+
+ cmd = nfc->param.chip_select | NFC_CMD_CLE | NAND_CMD_PAGEPROG;
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+
+ meson_nfc_dma_buffer_release(nand, data_len, info_len, DMA_TO_DEVICE);
+
+ return 0;
+}
+
+static int meson_nfc_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+ const u8 *buf, int oob_required, int page)
+{
+ meson_nfc_set_data_oob(chip, buf, oob_required ? chip->oob_poi : NULL);
+
+ return meson_nfc_write_page_sub(chip, page, true);
+}
+
+static int meson_nfc_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+ const u8 *buf, int oob_required, int page)
+{
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(chip);
+
+ if (buf)
+ memcpy(meson_chip->data_buf, buf, mtd->writesize);
+
+ memset(meson_chip->info_buf, 0, chip->ecc.steps * PER_INFO_BYTE);
+
+ if (oob_required)
+ meson_nfc_set_user_byte(chip, chip->oob_poi);
+
+ return meson_nfc_write_page_sub(chip, page, false);
+}
+
+static void meson_nfc_check_ecc_pages_valid(struct meson_nfc *nfc,
+ struct nand_chip *nand, bool raw)
+{
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ __le64 *info;
+ u32 neccpages;
+ int ret;
+
+ neccpages = raw ? 1 : nand->ecc.steps;
+ info = &meson_chip->info_buf[neccpages - 1];
+ do {
+ udelay(ECC_POLL_TIMEOUT_US);
+ /* info is updated by nfc dma engine*/
+ rmb();
+ invalidate_dcache_range(nfc->iaddr, nfc->iaddr + nfc->info_bytes);
+ ret = *info & ECC_COMPLETE;
+ } while (!ret);
+}
+
+static int meson_nfc_read_page_sub(struct nand_chip *nand,
+ int page, bool raw)
+{
+ struct mtd_info *mtd = nand_to_mtd(nand);
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ u32 data_len, info_len;
+ int ret;
+
+ data_len = mtd->writesize + mtd->oobsize;
+ info_len = nand->ecc.steps * PER_INFO_BYTE;
+
+ ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, data_len,
+ meson_chip->info_buf, info_len,
+ DMA_FROM_DEVICE);
+ if (ret)
+ return ret;
+
+ if (nand->options & NAND_NEED_SCRAMBLING) {
+ meson_nfc_cmd_seed(nfc, page);
+ meson_nfc_cmd_access(nand, raw, DIRREAD,
+ NFC_CMD_SCRAMBLER_ENABLE);
+ } else {
+ meson_nfc_cmd_access(nand, raw, DIRREAD,
+ NFC_CMD_SCRAMBLER_DISABLE);
+ }
+
+ meson_nfc_wait_dma_finish(nfc);
+ meson_nfc_check_ecc_pages_valid(nfc, nand, raw);
+
+ meson_nfc_dma_buffer_release(nand, data_len, info_len,
+ DMA_FROM_DEVICE);
+
+ return 0;
+}
+
+static int meson_nfc_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
+ u8 *buf, int oob_required, int page)
+{
+ int ret;
+
+ ret = meson_nfc_read_page_sub(chip, page, true);
+ if (ret)
+ return ret;
+
+ meson_nfc_get_data_oob(chip, buf, oob_required ? chip->oob_poi : NULL);
+
+ return 0;
+}
+
+static int meson_nfc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
+ u8 *buf, int oob_required, int page)
+{
+ const struct meson_nfc_nand_chip *meson_chip = to_meson_nand(chip);
+ u64 correct_bitmap = 0;
+ u32 bitflips = 0;
+ int ret;
+
+ ret = meson_nfc_read_page_sub(chip, page, false);
+ if (ret)
+ return ret;
+
+ if (oob_required)
+ meson_nfc_get_user_byte(chip, chip->oob_poi);
+
+ ret = meson_nfc_ecc_correct(chip, &bitflips, &correct_bitmap);
+
+ if (ret == ECC_CHECK_RETURN_FF) {
+ if (buf)
+ memset(buf, 0xff, mtd->writesize);
+
+ if (oob_required)
+ memset(chip->oob_poi, 0xff, mtd->oobsize);
+ } else if (ret < 0) {
+ struct nand_ecc_ctrl *ecc;
+ int i;
+
+ if ((chip->options & NAND_NEED_SCRAMBLING) || !buf) {
+ mtd->ecc_stats.failed++;
+ return bitflips;
+ }
+
+ chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page);
+
+ ret = meson_nfc_read_page_raw(mtd, chip, buf, 1, page);
+ if (ret)
+ return ret;
+
+ ecc = &chip->ecc;
+
+ for (i = 0; i < chip->ecc.steps ; i++) {
+ u8 *data = buf + i * ecc->size;
+ u8 *oob = chip->oob_poi + i * (ecc->bytes + 2);
+
+ if (correct_bitmap & BIT_ULL(i))
+ continue;
+
+ ret = nand_check_erased_ecc_chunk(data, ecc->size,
+ oob, ecc->bytes + 2,
+ NULL, 0,
+ ecc->strength);
+ if (ret < 0) {
+ mtd->ecc_stats.failed++;
+ } else {
+ mtd->ecc_stats.corrected += ret;
+ bitflips = max_t(u32, bitflips, ret);
+ }
+ }
+ } else if (buf && buf != meson_chip->data_buf) {
+ memcpy(buf, meson_chip->data_buf, mtd->writesize);
+ }
+
+ return bitflips;
+}
+
+static int meson_nfc_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip,
+ int page)
+{
+ int ret;
+
+ ret = nand_read_page_op(chip, page, 0, NULL, 0);
+ if (ret)
+ return ret;
+
+ return meson_nfc_read_page_raw(mtd, chip, NULL, 1, page);
+}
+
+static int meson_nfc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
+ int page)
+{
+ int ret;
+
+ ret = nand_read_page_op(chip, page, 0, NULL, 0);
+ if (ret)
+ return ret;
+
+ return meson_nfc_read_page_hwecc(mtd, chip, NULL, 1, page);
+}
+
+static int meson_nfc_write_oob_raw(struct mtd_info *mtd, struct nand_chip *chip,
+ int page)
+{
+ int ret;
+
+ ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+ if (ret)
+ return ret;
+
+ ret = meson_nfc_write_page_raw(mtd, chip, NULL, 1, page);
+ if (ret)
+ return ret;
+
+ return nand_prog_page_end_op(chip);
+}
+
+static int meson_nfc_write_oob(struct mtd_info *mtd, struct nand_chip *chip,
+ int page)
+{
+ int ret;
+
+ ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0);
+ if (ret)
+ return ret;
+
+ ret = meson_nfc_write_page_hwecc(mtd, chip, NULL, 1, page);
+ if (ret)
+ return ret;
+
+ return nand_prog_page_end_op(chip);
+}
+
+static void meson_nfc_nand_cmd_function(struct mtd_info *mtd, unsigned int command,
+ int column, int page_addr)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+
+ chip->cmd_ctrl(mtd, command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
+
+ if (column != -1 || page_addr != -1) {
+ int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE;
+
+ /* Serially input address */
+ if (column != -1) {
+ /* Adjust columns for 16 bit buswidth */
+ if (chip->options & NAND_BUSWIDTH_16 &&
+ !nand_opcode_8bits(command))
+ column >>= 1;
+
+ chip->cmd_ctrl(mtd, column, ctrl);
+ ctrl &= ~NAND_CTRL_CHANGE;
+ /* Only output a single addr cycle for 8bits
+ * opcodes.
+ */
+ if (!nand_opcode_8bits(command))
+ chip->cmd_ctrl(mtd, column >> 8, ctrl);
+ }
+
+ if (page_addr != -1) {
+ chip->cmd_ctrl(mtd, page_addr, ctrl);
+ chip->cmd_ctrl(mtd, page_addr >> 8, NAND_NCE |
+ NAND_ALE);
+ /* One more address cycle for devices > 128MiB */
+ if (chip->chipsize > SZ_128M)
+ chip->cmd_ctrl(mtd, page_addr >> 16,
+ NAND_NCE | NAND_ALE);
+ }
+
+ switch (command) {
+ case NAND_CMD_READ0:
+ chip->cmd_ctrl(mtd, NAND_CMD_READSTART,
+ NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE);
+ fallthrough;
+ case NAND_CMD_PARAM:
+ nand_wait_ready(mtd);
+ nand_exit_status_op(chip);
+ }
+ }
+}
+
+static void meson_nfc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ if (ctrl & NAND_CLE)
+ cmd = NFC_CMD_MAKE_CLE(nfc->param.chip_select, cmd);
+ else
+ cmd = NFC_CMD_MAKE_ALE(nfc->param.chip_select, cmd);
+
+ writel(cmd, nfc->reg_base + NFC_REG_CMD);
+}
+
+static void meson_nfc_wait_cmd_fifo(struct meson_nfc *nfc)
+{
+ while ((NFC_GET_CMD(nfc) >> 22) & GENMASK(4, 0))
+ ;
+}
+
+static u8 meson_nfc_nand_read_byte(struct mtd_info *mtd)
+{
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+
+ writel(NFC_CMD_MAKE_DRD(nfc->param.chip_select, 0), nfc->reg_base + NFC_REG_CMD);
+
+ meson_nfc_cmd_idle(nfc, NAND_TWB_TIME_CYCLE);
+ meson_nfc_cmd_idle(nfc, 0);
+ meson_nfc_cmd_idle(nfc, 0);
+
+ meson_nfc_wait_cmd_fifo(nfc);
+
+ return readl(nfc->reg_base + NFC_REG_BUF);
+}
+
+static void meson_nfc_nand_write_byte(struct mtd_info *mtd, u8 val)
+{
+ struct nand_chip *nand = mtd_to_nand(mtd);
+ struct meson_nfc *nfc = nand_get_controller_data(nand);
+
+ meson_nfc_cmd_idle(nfc, NAND_TWB_TIME_CYCLE);
+
+ writel(NFC_CMD_MAKE_DWR(nfc->param.chip_select, val), nfc->reg_base + NFC_REG_CMD);
+
+ meson_nfc_cmd_idle(nfc, NAND_TWB_TIME_CYCLE);
+ meson_nfc_cmd_idle(nfc, 0);
+ meson_nfc_cmd_idle(nfc, 0);
+
+ meson_nfc_wait_cmd_fifo(nfc);
+}
+
+static int meson_nfc_dev_ready(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd_to_nand(mtd);
+ unsigned int time_out_cnt = 0;
+
+ chip->select_chip(mtd, 0);
+
+ chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
+
+ do {
+ int status;
+
+ status = (int)chip->read_byte(mtd);
+ if (status & NAND_STATUS_READY)
+ break;
+ } while (time_out_cnt++ < NFC_DEV_READY_TICK_MAX);
+
+ return time_out_cnt != NFC_DEV_READY_TICK_MAX;
+}
+
+static int meson_chip_buffer_init(struct nand_chip *nand)
+{
+ const struct mtd_info *mtd = nand_to_mtd(nand);
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+ u32 page_bytes, info_bytes, nsectors;
+ unsigned long tmp_addr;
+
+ nsectors = mtd->writesize / nand->ecc.size;
+
+ page_bytes = mtd->writesize + mtd->oobsize;
+ info_bytes = nsectors * PER_INFO_BYTE;
+
+ meson_chip->data_buf = dma_alloc_coherent(page_bytes, &tmp_addr);
+ if (!meson_chip->data_buf)
+ return -ENOMEM;
+
+ meson_chip->info_buf = dma_alloc_coherent(info_bytes, &tmp_addr);
+ if (!meson_chip->info_buf) {
+ dma_free_coherent(meson_chip->data_buf);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static const int axg_stepinfo_strengths[] = { 8 };
+static const struct nand_ecc_step_info axg_stepinfo_1024 = {
+ .stepsize = 1024,
+ .strengths = axg_stepinfo_strengths,
+ .nstrengths = ARRAY_SIZE(axg_stepinfo_strengths)
+};
+
+static const struct nand_ecc_step_info axg_stepinfo_512 = {
+ .stepsize = 512,
+ .strengths = axg_stepinfo_strengths,
+ .nstrengths = ARRAY_SIZE(axg_stepinfo_strengths)
+};
+
+static const struct nand_ecc_step_info axg_stepinfo[] = { axg_stepinfo_1024, axg_stepinfo_512 };
+
+static const struct nand_ecc_caps meson_axg_ecc_caps = {
+ .stepinfos = axg_stepinfo,
+ .nstepinfos = ARRAY_SIZE(axg_stepinfo),
+ .calc_ecc_bytes = meson_nand_calc_ecc_bytes,
+};
+
+/*
+ * OOB layout:
+ *
+ * For ECC with 512 bytes step size:
+ * 0x00: AA AA BB BB BB BB BB BB BB BB BB BB BB BB BB BB
+ * 0x10: AA AA CC CC CC CC CC CC CC CC CC CC CC CC CC CC
+ * 0x20:
+ * 0x30:
+ *
+ * For ECC with 1024 bytes step size:
+ * 0x00: AA AA BB BB BB BB BB BB BB BB BB BB BB BB BB BB
+ * 0x10: AA AA CC CC CC CC CC CC CC CC CC CC CC CC CC CC
+ * 0x20: AA AA DD DD DD DD DD DD DD DD DD DD DD DD DD DD
+ * 0x30: AA AA EE EE EE EE EE EE EE EE EE EE EE EE EE EE
+ *
+ * AA - user bytes.
+ * BB, CC, DD, EE - ECC code bytes for each step.
+ */
+static struct nand_ecclayout nand_oob;
+
+static void meson_nfc_init_nand_oob(struct nand_chip *nand)
+{
+ int section_size = 2 + nand->ecc.bytes;
+ int i;
+ int k;
+
+ nand_oob.eccbytes = nand->ecc.steps * nand->ecc.bytes;
+ k = 0;
+
+ for (i = 0; i < nand->ecc.steps; i++) {
+ int j;
+
+ for (j = 0; j < nand->ecc.bytes; j++)
+ nand_oob.eccpos[k++] = (i * section_size) + 2 + j;
+
+ nand_oob.oobfree[i].offset = (i * section_size);
+ nand_oob.oobfree[i].length = 2;
+ }
+
+ nand_oob.oobavail = 2 * nand->ecc.steps;
+ nand->ecc.layout = &nand_oob;
+}
+
+static int meson_nfc_init_ecc(struct nand_chip *nand, ofnode node)
+{
+ const struct mtd_info *mtd = nand_to_mtd(nand);
+ int ret;
+ int i;
+
+ ret = nand_check_ecc_caps(nand, &meson_axg_ecc_caps, mtd->oobsize - 2);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < ARRAY_SIZE(meson_ecc); i++) {
+ if (meson_ecc[i].strength == nand->ecc.strength &&
+ meson_ecc[i].size == nand->ecc.size) {
+ struct meson_nfc_nand_chip *meson_chip = to_meson_nand(nand);
+
+ nand->ecc.steps = mtd->writesize / nand->ecc.size;
+ meson_chip->bch_mode = meson_ecc[i].bch;
+
+ meson_nfc_init_nand_oob(nand);
+
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int meson_nfc_nand_chip_init(struct udevice *dev, struct meson_nfc *nfc,
+ ofnode node)
+{
+ struct meson_nfc_nand_chip *meson_chip;
+ struct nand_chip *nand;
+ struct mtd_info *mtd;
+ u32 cs[MAX_CE_NUM];
+ u32 nsels;
+ int ret;
+ int i;
+
+ if (!ofnode_get_property(node, "reg", &nsels)) {
+ dev_err(dev, "\"reg\" property is not found\n");
+ return -ENODEV;
+ }
+
+ nsels /= sizeof(u32);
+ if (nsels >= MAX_CE_NUM) {
+ dev_err(dev, "invalid size of CS array, max is %d\n",
+ MAX_CE_NUM);
+ return -EINVAL;
+ }
+
+ ret = ofnode_read_u32_array(node, "reg", cs, nsels);
+ if (ret < 0) {
+ dev_err(dev, "failed to read \"reg\" property\n");
+ return ret;
+ }
+
+ for (i = 0; i < nsels; i++) {
+ if (test_and_set_bit(cs[i], &nfc->assigned_cs)) {
+ dev_err(dev, "CS %d already assigned\n", cs[i]);
+ return -EINVAL;
+ }
+ }
+
+ meson_chip = malloc(sizeof(*meson_chip) + nsels * sizeof(meson_chip->sels[0]));
+ if (!meson_chip) {
+ dev_err(dev, "failed to allocate memory for chip\n");
+ return -ENOMEM;
+ }
+
+ meson_chip->nsels = nsels;
+ nand = &meson_chip->nand;
+
+ nand->flash_node = node;
+ nand_set_controller_data(nand, nfc);
+ /* Set the driver entry points for MTD */
+ nand->cmdfunc = meson_nfc_nand_cmd_function;
+ nand->cmd_ctrl = meson_nfc_cmd_ctrl;
+ nand->select_chip = meson_nfc_nand_select_chip;
+ nand->read_byte = meson_nfc_nand_read_byte;
+ nand->write_byte = meson_nfc_nand_write_byte;
+ nand->dev_ready = meson_nfc_dev_ready;
+
+ /* Buffer read/write routines */
+ nand->read_buf = meson_nfc_read_buf;
+ nand->write_buf = meson_nfc_write_buf;
+ nand->options |= NAND_NO_SUBPAGE_WRITE;
+
+ nand->ecc.mode = NAND_ECC_HW;
+ nand->ecc.hwctl = NULL;
+ nand->ecc.read_page = meson_nfc_read_page_hwecc;
+ nand->ecc.write_page = meson_nfc_write_page_hwecc;
+ nand->ecc.read_page_raw = meson_nfc_read_page_raw;
+ nand->ecc.write_page_raw = meson_nfc_write_page_raw;
+
+ nand->ecc.read_oob = meson_nfc_read_oob;
+ nand->ecc.write_oob = meson_nfc_write_oob;
+ nand->ecc.read_oob_raw = meson_nfc_read_oob_raw;
+ nand->ecc.write_oob_raw = meson_nfc_write_oob_raw;
+
+ nand->ecc.algo = NAND_ECC_BCH;
+
+ mtd = nand_to_mtd(nand);
+
+ ret = nand_scan_ident(mtd, 1, NULL);
+ if (ret) {
+ dev_err(dev, "'nand_scan_ident()' failed: %d\n", ret);
+ goto err_chip_free;
+ }
+
+ ret = meson_nfc_init_ecc(nand, node);
+ if (ret) {
+ dev_err(dev, "failed to init ECC settings: %d\n", ret);
+ goto err_chip_free;
+ }
+
+ ret = meson_chip_buffer_init(nand);
+ if (ret) {
+ dev_err(dev, "failed to init DMA buffers: %d\n", ret);
+ goto err_chip_free;
+ }
+
+ /* 'nand_scan_tail()' needs ECC parameters to be already
+ * set and correct.
+ */
+ ret = nand_scan_tail(mtd);
+ if (ret) {
+ dev_err(dev, "'nand_scan_tail()' failed: %d\n", ret);
+ goto err_chip_buf_free;
+ }
+
+ ret = nand_register(0, mtd);
+ if (ret) {
+ dev_err(dev, "'nand_register()' failed: %d\n", ret);
+ goto err_chip_buf_free;
+ }
+
+ list_add_tail(&meson_chip->node, &nfc->chips);
+
+ return 0;
+
+err_chip_buf_free:
+ dma_free_coherent(meson_chip->info_buf);
+ dma_free_coherent(meson_chip->data_buf);
+
+err_chip_free:
+ free(meson_chip);
+
+ return ret;
+}
+
+static int meson_nfc_nand_chips_init(struct udevice *dev,
+ struct meson_nfc *nfc)
+{
+ ofnode parent = dev_ofnode(dev);
+ ofnode node;
+
+ ofnode_for_each_subnode(node, parent) {
+ int ret = meson_nfc_nand_chip_init(dev, nfc, node);
+
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static void meson_nfc_clk_init(struct meson_nfc *nfc)
+{
+ u32 bus_cycle = NFC_DEFAULT_BUS_CYCLE;
+ u32 bus_timing = NFC_DEFAULT_BUS_TIMING;
+ u32 bus_cfg_val;
+
+ writel(CLK_ALWAYS_ON_NAND | CLK_SELECT_NAND | CLK_ENABLE_VALUE, nfc->reg_clk);
+ writel(0, nfc->reg_base + NFC_REG_CFG);
+
+ bus_cfg_val = (((bus_cycle - 1) & 31) | ((bus_timing & 31) << 5));
+ writel(bus_cfg_val, nfc->reg_base + NFC_REG_CFG);
+ writel(BIT(31), nfc->reg_base + NFC_REG_CMD);
+}
+
+static int meson_probe(struct udevice *dev)
+{
+ struct meson_nfc *nfc = dev_get_priv(dev);
+ void *addr;
+ int ret;
+
+ addr = dev_read_addr_ptr(dev);
+ if (!addr) {
+ dev_err(dev, "base register address not found\n");
+ return -EINVAL;
+ }
+
+ nfc->reg_base = addr;
+
+ addr = dev_read_addr_index_ptr(dev, 1);
+ if (!addr) {
+ dev_err(dev, "clk register address not found\n");
+ return -EINVAL;
+ }
+
+ nfc->reg_clk = addr;
+ nfc->dev = dev;
+
+ meson_nfc_clk_init(nfc);
+
+ ret = meson_nfc_nand_chips_init(dev, nfc);
+ if (ret) {
+ dev_err(nfc->dev, "failed to init chips\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id meson_nand_dt_ids[] = {
+ {.compatible = "amlogic,meson-axg-nfc",},
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(meson_nand) = {
+ .name = "meson_nand",
+ .id = UCLASS_MTD,
+ .of_match = meson_nand_dt_ids,
+ .probe = meson_probe,
+ .priv_auto = sizeof(struct meson_nfc),
+};
+
+void board_nand_init(void)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = uclass_get_device_by_driver(UCLASS_MTD,
+ DM_DRIVER_GET(meson_nand), &dev);
+
+ if (ret && ret != -ENODEV)
+ pr_err("Failed to initialize: %d\n", ret);
+}
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index c40a0f2..688d17b 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4118,7 +4118,7 @@
*/
void nand_decode_ext_id(struct nand_chip *chip)
{
- struct mtd_info *mtd = &chip->mtd;
+ struct mtd_info *mtd = nand_to_mtd(chip);
int extid;
/* The 3rd id byte holds MLC / multichip data */
chip->bits_per_cell = nand_get_bits_per_cell(chip->id.data[2]);
@@ -4185,7 +4185,7 @@
*/
static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type)
{
- struct mtd_info *mtd = &chip->mtd;
+ struct mtd_info *mtd = nand_to_mtd(chip);
mtd->erasesize = type->erasesize;
mtd->writesize = type->pagesize;
@@ -4265,7 +4265,7 @@
int nand_detect(struct nand_chip *chip, int *maf_id,
int *dev_id, struct nand_flash_dev *type)
{
- struct mtd_info *mtd = &chip->mtd;
+ struct mtd_info *mtd = nand_to_mtd(chip);
const struct nand_manufacturer *manufacturer_desc;
int busw, ret;
u8 *id_data = chip->id.data;
diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile
index f172f47..65b836b 100644
--- a/drivers/mtd/nand/spi/Makefile
+++ b/drivers/mtd/nand/spi/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
spinand-objs := core.o esmt.o gigadevice.o macronix.o micron.o paragon.o
-spinand-objs += toshiba.o winbond.o
+spinand-objs += toshiba.o winbond.o xtx.o
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 8ca3345..62c28aa 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -829,6 +829,7 @@
&toshiba_spinand_manufacturer,
&winbond_spinand_manufacturer,
&esmt_c8_spinand_manufacturer,
+ &xtx_spinand_manufacturer,
};
static int spinand_manufacturer_match(struct spinand_device *spinand,
diff --git a/drivers/mtd/nand/spi/xtx.c b/drivers/mtd/nand/spi/xtx.c
new file mode 100644
index 0000000..aee1849
--- /dev/null
+++ b/drivers/mtd/nand/spi/xtx.c
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Author:
+ * Felix Matouschek <felix@matouschek.org>
+ */
+
+#include <linux/bitfield.h>
+#ifndef __UBOOT__
+#include <linux/device.h>
+#include <linux/kernel.h>
+#endif
+#include <linux/mtd/spinand.h>
+
+#define SPINAND_MFR_XTX 0x0B
+
+#define XT26G0XA_STATUS_ECC_MASK GENMASK(5, 2)
+#define XT26G0XA_STATUS_ECC_NO_DETECTED (0 << 2)
+#define XT26G0XA_STATUS_ECC_8_CORRECTED (3 << 4)
+#define XT26G0XA_STATUS_ECC_UNCOR_ERROR (2 << 4)
+
+#define XT26XXXD_STATUS_ECC3_ECC2_MASK GENMASK(7, 6)
+#define XT26XXXD_STATUS_ECC_NO_DETECTED (0)
+#define XT26XXXD_STATUS_ECC_1_7_CORRECTED (1)
+#define XT26XXXD_STATUS_ECC_8_CORRECTED (3)
+#define XT26XXXD_STATUS_ECC_UNCOR_ERROR (2)
+
+static SPINAND_OP_VARIANTS(read_cache_variants,
+ SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+
+static SPINAND_OP_VARIANTS(write_cache_variants,
+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
+
+static SPINAND_OP_VARIANTS(update_cache_variants,
+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
+
+static int xt26g0xa_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section)
+ return -ERANGE;
+
+ region->offset = 48;
+ region->length = 16;
+
+ return 0;
+}
+
+static int xt26g0xa_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section)
+ return -ERANGE;
+
+ region->offset = 1;
+ region->length = 47;
+
+ return 0;
+}
+
+static const struct mtd_ooblayout_ops xt26g0xa_ooblayout = {
+ .ecc = xt26g0xa_ooblayout_ecc,
+ .rfree = xt26g0xa_ooblayout_free,
+};
+
+static int xt26g0xa_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
+{
+ status = status & XT26G0XA_STATUS_ECC_MASK;
+
+ switch (status) {
+ case XT26G0XA_STATUS_ECC_NO_DETECTED:
+ return 0;
+ case XT26G0XA_STATUS_ECC_8_CORRECTED:
+ return 8;
+ case XT26G0XA_STATUS_ECC_UNCOR_ERROR:
+ return -EBADMSG;
+ default:
+ break;
+ }
+
+ /* At this point values greater than (2 << 4) are invalid */
+ if (status > XT26G0XA_STATUS_ECC_UNCOR_ERROR)
+ return -EINVAL;
+
+ /* (1 << 2) through (7 << 2) are 1-7 corrected errors */
+ return status >> 2;
+}
+
+static int xt26xxxd_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section)
+ return -ERANGE;
+
+ region->offset = mtd->oobsize / 2;
+ region->length = mtd->oobsize / 2;
+
+ return 0;
+}
+
+static int xt26xxxd_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section)
+ return -ERANGE;
+
+ region->offset = 2;
+ region->length = mtd->oobsize / 2 - 2;
+
+ return 0;
+}
+
+static const struct mtd_ooblayout_ops xt26xxxd_ooblayout = {
+ .ecc = xt26xxxd_ooblayout_ecc,
+ .rfree = xt26xxxd_ooblayout_free,
+};
+
+static int xt26xxxd_ecc_get_status(struct spinand_device *spinand,
+ u8 status)
+{
+ switch (FIELD_GET(STATUS_ECC_MASK, status)) {
+ case XT26XXXD_STATUS_ECC_NO_DETECTED:
+ return 0;
+ case XT26XXXD_STATUS_ECC_UNCOR_ERROR:
+ return -EBADMSG;
+ case XT26XXXD_STATUS_ECC_1_7_CORRECTED:
+ return 4 + FIELD_GET(XT26XXXD_STATUS_ECC3_ECC2_MASK, status);
+ case XT26XXXD_STATUS_ECC_8_CORRECTED:
+ return 8;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static const struct spinand_info xtx_spinand_table[] = {
+ SPINAND_INFO("XT26G01A",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE1),
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&xt26g0xa_ooblayout,
+ xt26g0xa_ecc_get_status)),
+ SPINAND_INFO("XT26G02A",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE2),
+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&xt26g0xa_ooblayout,
+ xt26g0xa_ecc_get_status)),
+ SPINAND_INFO("XT26G04A",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE3),
+ NAND_MEMORG(1, 2048, 64, 128, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&xt26g0xa_ooblayout,
+ xt26g0xa_ecc_get_status)),
+ SPINAND_INFO("XT26G01D",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x31),
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&xt26xxxd_ooblayout,
+ xt26xxxd_ecc_get_status)),
+ SPINAND_INFO("XT26G11D",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x34),
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&xt26xxxd_ooblayout,
+ xt26xxxd_ecc_get_status)),
+ SPINAND_INFO("XT26Q01D",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x51),
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&xt26xxxd_ooblayout,
+ xt26xxxd_ecc_get_status)),
+ SPINAND_INFO("XT26G02D",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x32),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&xt26xxxd_ooblayout,
+ xt26xxxd_ecc_get_status)),
+ SPINAND_INFO("XT26G12D",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x35),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&xt26xxxd_ooblayout,
+ xt26xxxd_ecc_get_status)),
+ SPINAND_INFO("XT26Q02D",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x52),
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&xt26xxxd_ooblayout,
+ xt26xxxd_ecc_get_status)),
+ SPINAND_INFO("XT26G04D",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x33),
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&xt26xxxd_ooblayout,
+ xt26xxxd_ecc_get_status)),
+ SPINAND_INFO("XT26Q04D",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x53),
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
+ NAND_ECCREQ(8, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ 0,
+ SPINAND_ECCINFO(&xt26xxxd_ooblayout,
+ xt26xxxd_ecc_get_status)),
+};
+
+static const struct spinand_manufacturer_ops xtx_spinand_manuf_ops = {
+};
+
+const struct spinand_manufacturer xtx_spinand_manufacturer = {
+ .id = SPINAND_MFR_XTX,
+ .name = "XTX",
+ .chips = xtx_spinand_table,
+ .nchips = ARRAY_SIZE(xtx_spinand_table),
+ .ops = &xtx_spinand_manuf_ops,
+};
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index c222197..4c1642b 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -352,6 +352,11 @@
(phydev->duplex) ? "full" : "half",
(phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
+#ifdef CONFIG_ARCH_NPCM8XX
+ /* Pass all Multicast Frames */
+ setbits_le32(&mac_p->framefilt, BIT(4));
+
+#endif
return 0;
}
@@ -554,6 +559,11 @@
ulong desc_start = (ulong)desc_p;
ulong desc_end = desc_start +
roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
+ ulong data_start = desc_p->dmamac_addr;
+ ulong data_end = data_start + roundup(CFG_ETH_BUFSIZE, ARCH_DMA_MINALIGN);
+
+ /* Invalidate the descriptor buffer data */
+ invalidate_dcache_range(data_start, data_end);
/*
* Make the current descriptor valid again and go to
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 9b3bce1..67d80d9 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -159,7 +159,7 @@
ret = eqos_mdio_wait_idle(eqos);
if (ret) {
- pr_err("MDIO not idle at entry");
+ pr_err("MDIO not idle at entry\n");
return ret;
}
@@ -179,7 +179,7 @@
ret = eqos_mdio_wait_idle(eqos);
if (ret) {
- pr_err("MDIO read didn't complete");
+ pr_err("MDIO read didn't complete\n");
return ret;
}
@@ -203,7 +203,7 @@
ret = eqos_mdio_wait_idle(eqos);
if (ret) {
- pr_err("MDIO not idle at entry");
+ pr_err("MDIO not idle at entry\n");
return ret;
}
@@ -225,7 +225,7 @@
ret = eqos_mdio_wait_idle(eqos);
if (ret) {
- pr_err("MDIO read didn't complete");
+ pr_err("MDIO read didn't complete\n");
return ret;
}
@@ -242,37 +242,37 @@
ret = clk_enable(&eqos->clk_slave_bus);
if (ret < 0) {
- pr_err("clk_enable(clk_slave_bus) failed: %d", ret);
+ pr_err("clk_enable(clk_slave_bus) failed: %d\n", ret);
goto err;
}
ret = clk_enable(&eqos->clk_master_bus);
if (ret < 0) {
- pr_err("clk_enable(clk_master_bus) failed: %d", ret);
+ pr_err("clk_enable(clk_master_bus) failed: %d\n", ret);
goto err_disable_clk_slave_bus;
}
ret = clk_enable(&eqos->clk_rx);
if (ret < 0) {
- pr_err("clk_enable(clk_rx) failed: %d", ret);
+ pr_err("clk_enable(clk_rx) failed: %d\n", ret);
goto err_disable_clk_master_bus;
}
ret = clk_enable(&eqos->clk_ptp_ref);
if (ret < 0) {
- pr_err("clk_enable(clk_ptp_ref) failed: %d", ret);
+ pr_err("clk_enable(clk_ptp_ref) failed: %d\n", ret);
goto err_disable_clk_rx;
}
ret = clk_set_rate(&eqos->clk_ptp_ref, 125 * 1000 * 1000);
if (ret < 0) {
- pr_err("clk_set_rate(clk_ptp_ref) failed: %d", ret);
+ pr_err("clk_set_rate(clk_ptp_ref) failed: %d\n", ret);
goto err_disable_clk_ptp_ref;
}
ret = clk_enable(&eqos->clk_tx);
if (ret < 0) {
- pr_err("clk_enable(clk_tx) failed: %d", ret);
+ pr_err("clk_enable(clk_tx) failed: %d\n", ret);
goto err_disable_clk_ptp_ref;
}
#endif
@@ -305,26 +305,26 @@
ret = clk_enable(&eqos->clk_master_bus);
if (ret < 0) {
- pr_err("clk_enable(clk_master_bus) failed: %d", ret);
+ pr_err("clk_enable(clk_master_bus) failed: %d\n", ret);
goto err;
}
ret = clk_enable(&eqos->clk_rx);
if (ret < 0) {
- pr_err("clk_enable(clk_rx) failed: %d", ret);
+ pr_err("clk_enable(clk_rx) failed: %d\n", ret);
goto err_disable_clk_master_bus;
}
ret = clk_enable(&eqos->clk_tx);
if (ret < 0) {
- pr_err("clk_enable(clk_tx) failed: %d", ret);
+ pr_err("clk_enable(clk_tx) failed: %d\n", ret);
goto err_disable_clk_rx;
}
if (clk_valid(&eqos->clk_ck) && !eqos->clk_ck_enabled) {
ret = clk_enable(&eqos->clk_ck);
if (ret < 0) {
- pr_err("clk_enable(clk_ck) failed: %d", ret);
+ pr_err("clk_enable(clk_ck) failed: %d\n", ret);
goto err_disable_clk_tx;
}
eqos->clk_ck_enabled = true;
@@ -390,7 +390,7 @@
ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 1);
if (ret < 0) {
- pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d", ret);
+ pr_err("dm_gpio_set_value(phy_reset, assert) failed: %d\n", ret);
return ret;
}
@@ -398,13 +398,13 @@
ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
if (ret < 0) {
- pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d", ret);
+ pr_err("dm_gpio_set_value(phy_reset, deassert) failed: %d\n", ret);
return ret;
}
ret = reset_assert(&eqos->reset_ctl);
if (ret < 0) {
- pr_err("reset_assert() failed: %d", ret);
+ pr_err("reset_assert() failed: %d\n", ret);
return ret;
}
@@ -412,7 +412,7 @@
ret = reset_deassert(&eqos->reset_ctl);
if (ret < 0) {
- pr_err("reset_deassert() failed: %d", ret);
+ pr_err("reset_deassert() failed: %d\n", ret);
return ret;
}
@@ -448,14 +448,14 @@
ret = wait_for_bit_le32(&eqos->tegra186_regs->auto_cal_status,
EQOS_AUTO_CAL_STATUS_ACTIVE, true, 10, false);
if (ret) {
- pr_err("calibrate didn't start");
+ pr_err("calibrate didn't start\n");
goto failed;
}
ret = wait_for_bit_le32(&eqos->tegra186_regs->auto_cal_status,
EQOS_AUTO_CAL_STATUS_ACTIVE, false, 10, false);
if (ret) {
- pr_err("calibrate didn't finish");
+ pr_err("calibrate didn't finish\n");
goto failed;
}
@@ -586,13 +586,13 @@
rate = 2.5 * 1000 * 1000;
break;
default:
- pr_err("invalid speed %d", eqos->phy->speed);
+ pr_err("invalid speed %d\n", eqos->phy->speed);
return -EINVAL;
}
ret = clk_set_rate(&eqos->clk_tx, rate);
if (ret < 0) {
- pr_err("clk_set_rate(tx_clk, %lu) failed: %d", rate, ret);
+ pr_err("clk_set_rate(tx_clk, %lu) failed: %d\n", rate, ret);
return ret;
}
#endif
@@ -613,7 +613,7 @@
else
ret = eqos_set_half_duplex(dev);
if (ret < 0) {
- pr_err("eqos_set_*_duplex() failed: %d", ret);
+ pr_err("eqos_set_*_duplex() failed: %d\n", ret);
return ret;
}
@@ -631,32 +631,32 @@
ret = eqos_set_mii_speed_10(dev);
break;
default:
- pr_err("invalid speed %d", eqos->phy->speed);
+ pr_err("invalid speed %d\n", eqos->phy->speed);
return -EINVAL;
}
if (ret < 0) {
- pr_err("eqos_set_*mii_speed*() failed: %d", ret);
+ pr_err("eqos_set_*mii_speed*() failed: %d\n", ret);
return ret;
}
if (en_calibration) {
ret = eqos->config->ops->eqos_calibrate_pads(dev);
if (ret < 0) {
- pr_err("eqos_calibrate_pads() failed: %d",
+ pr_err("eqos_calibrate_pads() failed: %d\n",
ret);
return ret;
}
} else {
ret = eqos->config->ops->eqos_disable_calibration(dev);
if (ret < 0) {
- pr_err("eqos_disable_calibration() failed: %d",
+ pr_err("eqos_disable_calibration() failed: %d\n",
ret);
return ret;
}
}
ret = eqos->config->ops->eqos_set_tx_clk_speed(dev);
if (ret < 0) {
- pr_err("eqos_set_tx_clk_speed() failed: %d", ret);
+ pr_err("eqos_set_tx_clk_speed() failed: %d\n", ret);
return ret;
}
@@ -755,7 +755,7 @@
ret = eqos->config->ops->eqos_start_resets(dev);
if (ret < 0) {
- pr_err("eqos_start_resets() failed: %d", ret);
+ pr_err("eqos_start_resets() failed: %d\n", ret);
goto err;
}
@@ -773,13 +773,13 @@
EQOS_DMA_MODE_SWR, false,
eqos->config->swr_wait, false);
if (ret) {
- pr_err("EQOS_DMA_MODE_SWR stuck");
+ pr_err("EQOS_DMA_MODE_SWR stuck\n");
goto err_stop_resets;
}
ret = eqos->config->ops->eqos_calibrate_pads(dev);
if (ret < 0) {
- pr_err("eqos_calibrate_pads() failed: %d", ret);
+ pr_err("eqos_calibrate_pads() failed: %d\n", ret);
goto err_stop_resets;
}
@@ -812,7 +812,7 @@
}
if (!eqos->phy) {
- pr_err("phy_connect() failed");
+ pr_err("phy_connect() failed\n");
ret = -ENODEV;
goto err_stop_resets;
}
@@ -820,7 +820,7 @@
if (eqos->max_speed) {
ret = phy_set_supported(eqos->phy, eqos->max_speed);
if (ret) {
- pr_err("phy_set_supported() failed: %d", ret);
+ pr_err("phy_set_supported() failed: %d\n", ret);
goto err_shutdown_phy;
}
}
@@ -828,26 +828,26 @@
eqos->phy->node = eqos->phy_of_node;
ret = phy_config(eqos->phy);
if (ret < 0) {
- pr_err("phy_config() failed: %d", ret);
+ pr_err("phy_config() failed: %d\n", ret);
goto err_shutdown_phy;
}
}
ret = phy_startup(eqos->phy);
if (ret < 0) {
- pr_err("phy_startup() failed: %d", ret);
+ pr_err("phy_startup() failed: %d\n", ret);
goto err_shutdown_phy;
}
if (!eqos->phy->link) {
- pr_err("No link");
+ pr_err("No link\n");
ret = -EAGAIN;
goto err_shutdown_phy;
}
ret = eqos_adjust_link(dev);
if (ret < 0) {
- pr_err("eqos_adjust_link() failed: %d", ret);
+ pr_err("eqos_adjust_link() failed: %d\n", ret);
goto err_shutdown_phy;
}
@@ -1090,7 +1090,7 @@
err_stop_resets:
eqos->config->ops->eqos_stop_resets(dev);
err:
- pr_err("FAILED: %d", ret);
+ pr_err("FAILED: %d\n", ret);
return ret;
}
@@ -1217,7 +1217,7 @@
struct eqos_priv *eqos = dev_get_priv(dev);
u32 idx, idx_mask = eqos->desc_per_cacheline - 1;
uchar *packet_expected;
- struct eqos_desc *rx_desc;
+ struct eqos_desc *rx_desc = NULL;
debug("%s(packet=%p, length=%d)\n", __func__, packet, length);
@@ -1361,7 +1361,7 @@
ret = reset_get_by_name(dev, "eqos", &eqos->reset_ctl);
if (ret) {
- pr_err("reset_get_by_name(rst) failed: %d", ret);
+ pr_err("reset_get_by_name(rst) failed: %d\n", ret);
return ret;
}
@@ -1369,37 +1369,37 @@
&eqos->phy_reset_gpio,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
if (ret) {
- pr_err("gpio_request_by_name(phy reset) failed: %d", ret);
+ pr_err("gpio_request_by_name(phy reset) failed: %d\n", ret);
goto err_free_reset_eqos;
}
ret = clk_get_by_name(dev, "slave_bus", &eqos->clk_slave_bus);
if (ret) {
- pr_err("clk_get_by_name(slave_bus) failed: %d", ret);
+ pr_err("clk_get_by_name(slave_bus) failed: %d\n", ret);
goto err_free_gpio_phy_reset;
}
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);
+ pr_err("clk_get_by_name(master_bus) failed: %d\n", ret);
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);
+ pr_err("clk_get_by_name(rx) failed: %d\n", ret);
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);
+ pr_err("clk_get_by_name(ptp_ref) failed: %d\n", ret);
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);
+ pr_err("clk_get_by_name(tx) failed: %d\n", ret);
goto err_free_gpio_phy_reset;
}
@@ -1436,19 +1436,19 @@
ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus);
if (ret) {
- pr_err("clk_get_by_name(master_bus) failed: %d", ret);
+ pr_err("clk_get_by_name(master_bus) failed: %d\n", ret);
goto err_probe;
}
ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx);
if (ret) {
- pr_err("clk_get_by_name(rx) failed: %d", ret);
+ pr_err("clk_get_by_name(rx) failed: %d\n", ret);
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);
+ pr_err("clk_get_by_name(tx) failed: %d\n", ret);
goto err_probe;
}
@@ -1502,7 +1502,7 @@
eqos->regs = dev_read_addr(dev);
if (eqos->regs == FDT_ADDR_T_NONE) {
- pr_err("dev_read_addr() failed");
+ pr_err("dev_read_addr() failed\n");
return -ENODEV;
}
eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE);
@@ -1514,19 +1514,19 @@
ret = eqos_probe_resources_core(dev);
if (ret < 0) {
- pr_err("eqos_probe_resources_core() failed: %d", ret);
+ pr_err("eqos_probe_resources_core() failed: %d\n", ret);
return ret;
}
ret = eqos->config->ops->eqos_probe_resources(dev);
if (ret < 0) {
- pr_err("eqos_probe_resources() failed: %d", ret);
+ pr_err("eqos_probe_resources() failed: %d\n", ret);
goto err_remove_resources_core;
}
ret = eqos->config->ops->eqos_start_clks(dev);
if (ret < 0) {
- pr_err("eqos_start_clks() failed: %d", ret);
+ pr_err("eqos_start_clks() failed: %d\n", ret);
goto err_remove_resources_tegra;
}
@@ -1536,7 +1536,7 @@
if (!eqos->mii) {
eqos->mii = mdio_alloc();
if (!eqos->mii) {
- pr_err("mdio_alloc() failed");
+ pr_err("mdio_alloc() failed\n");
ret = -ENOMEM;
goto err_stop_clks;
}
@@ -1547,7 +1547,7 @@
ret = mdio_register(eqos->mii);
if (ret < 0) {
- pr_err("mdio_register() failed: %d", ret);
+ pr_err("mdio_register() failed: %d\n", ret);
goto err_free_mdio;
}
}
diff --git a/drivers/net/ti/Kconfig b/drivers/net/ti/Kconfig
index 72eccc9..ddfa95a 100644
--- a/drivers/net/ti/Kconfig
+++ b/drivers/net/ti/Kconfig
@@ -57,3 +57,16 @@
help
This driver supports the TI CPSW MDIO interface found in various
TI SoCs.
+
+config TI_ICSSG_PRUETH
+ bool "TI Gigabit PRU Ethernet driver"
+ depends on ARCH_K3
+ imply DM_MDIO
+ imply MISC_INIT_R
+ imply MISC
+ imply MDIO_TI_CPSW
+ select PHYLIB
+ select FS_LOADER
+ help
+ Support Gigabit Ethernet ports over the ICSSG PRU Subsystem
+ This subsystem is available starting with the AM65 platform.
diff --git a/drivers/net/ti/Makefile b/drivers/net/ti/Makefile
index 30c4c4b..b2b3aa3 100644
--- a/drivers/net/ti/Makefile
+++ b/drivers/net/ti/Makefile
@@ -7,3 +7,4 @@
obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o cpsw_mdio.o
obj-$(CONFIG_TI_AM65_CPSW_NUSS) += am65-cpsw-nuss.o
obj-$(CONFIG_MDIO_TI_CPSW) += cpsw_mdio.o
+obj-$(CONFIG_TI_ICSSG_PRUETH) += icssg_prueth.o icssg_classifier.o icssg_config.o icssg_queues.o
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
index d68ed67..b151e25 100644
--- a/drivers/net/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ti/am65-cpsw-nuss.c
@@ -664,7 +664,7 @@
struct am65_cpsw_priv *priv = dev_get_priv(dev);
struct eth_pdata *pdata = dev_get_plat(dev);
struct am65_cpsw_common *cpsw_common;
- char portname[15];
+ char portname[32];
int ret;
priv->dev = dev;
@@ -672,7 +672,7 @@
cpsw_common = dev_get_priv(dev->parent);
priv->cpsw_common = cpsw_common;
- sprintf(portname, "%s%s", dev->parent->name, dev->name);
+ snprintf(portname, sizeof(portname), "%s%s", dev->parent->name, dev->name);
device_set_name(dev, portname);
ret = am65_cpsw_ofdata_parse_phy(dev);
diff --git a/drivers/net/ti/icss_mii_rt.h b/drivers/net/ti/icss_mii_rt.h
new file mode 100644
index 0000000..fd95d4d
--- /dev/null
+++ b/drivers/net/ti/icss_mii_rt.h
@@ -0,0 +1,192 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* PRU-ICSS MII_RT register definitions
+ *
+ * Copyright (C) 2015-2024 Texas Instruments Incorporated - https://www.ti.com
+ */
+
+#ifndef __NET_PRUSS_MII_RT_H__
+#define __NET_PRUSS_MII_RT_H__
+
+#include <regmap.h>
+
+/* PRUSS_MII_RT Registers */
+#define PRUSS_MII_RT_RXCFG0 0x0
+#define PRUSS_MII_RT_RXCFG1 0x4
+#define PRUSS_MII_RT_TXCFG0 0x10
+#define PRUSS_MII_RT_TXCFG1 0x14
+#define PRUSS_MII_RT_TX_CRC0 0x20
+#define PRUSS_MII_RT_TX_CRC1 0x24
+#define PRUSS_MII_RT_TX_IPG0 0x30
+#define PRUSS_MII_RT_TX_IPG1 0x34
+#define PRUSS_MII_RT_PRS0 0x38
+#define PRUSS_MII_RT_PRS1 0x3c
+#define PRUSS_MII_RT_RX_FRMS0 0x40
+#define PRUSS_MII_RT_RX_FRMS1 0x44
+#define PRUSS_MII_RT_RX_PCNT0 0x48
+#define PRUSS_MII_RT_RX_PCNT1 0x4c
+#define PRUSS_MII_RT_RX_ERR0 0x50
+#define PRUSS_MII_RT_RX_ERR1 0x54
+
+/* PRUSS_MII_RT_RXCFG0/1 bits */
+#define PRUSS_MII_RT_RXCFG_RX_ENABLE BIT(0)
+#define PRUSS_MII_RT_RXCFG_RX_DATA_RDY_MODE_DIS BIT(1)
+#define PRUSS_MII_RT_RXCFG_RX_CUT_PREAMBLE BIT(2)
+#define PRUSS_MII_RT_RXCFG_RX_MUX_SEL BIT(3)
+#define PRUSS_MII_RT_RXCFG_RX_L2_EN BIT(4)
+#define PRUSS_MII_RT_RXCFG_RX_BYTE_SWAP BIT(5)
+#define PRUSS_MII_RT_RXCFG_RX_AUTO_FWD_PRE BIT(6)
+#define PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS BIT(9)
+
+/* PRUSS_MII_RT_TXCFG0/1 bits */
+#define PRUSS_MII_RT_TXCFG_TX_ENABLE BIT(0)
+#define PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE BIT(1)
+#define PRUSS_MII_RT_TXCFG_TX_EN_MODE BIT(2)
+#define PRUSS_MII_RT_TXCFG_TX_BYTE_SWAP BIT(3)
+#define PRUSS_MII_RT_TXCFG_TX_MUX_SEL BIT(8)
+#define PRUSS_MII_RT_TXCFG_PRE_TX_AUTO_SEQUENCE BIT(9)
+#define PRUSS_MII_RT_TXCFG_PRE_TX_AUTO_ESC_ERR BIT(10)
+#define PRUSS_MII_RT_TXCFG_TX_32_MODE_EN BIT(11)
+#define PRUSS_MII_RT_TXCFG_TX_IPG_WIRE_CLK_EN BIT(12) /* SR2.0 onwards */
+
+#define PRUSS_MII_RT_TXCFG_TX_START_DELAY_SHIFT 16
+#define PRUSS_MII_RT_TXCFG_TX_START_DELAY_MASK GENMASK(25, 16)
+
+#define PRUSS_MII_RT_TXCFG_TX_CLK_DELAY_SHIFT 28
+#define PRUSS_MII_RT_TXCFG_TX_CLK_DELAY_MASK GENMASK(30, 28)
+
+/* PRUSS_MII_RT_TX_IPG0/1 bits */
+#define PRUSS_MII_RT_TX_IPG_IPG_SHIFT 0
+#define PRUSS_MII_RT_TX_IPG_IPG_MASK GENMASK(9, 0)
+
+/* PRUSS_MII_RT_PRS0/1 bits */
+#define PRUSS_MII_RT_PRS_COL BIT(0)
+#define PRUSS_MII_RT_PRS_CRS BIT(1)
+
+/* PRUSS_MII_RT_RX_FRMS0/1 bits */
+#define PRUSS_MII_RT_RX_FRMS_MIN_FRM_SHIFT 0
+#define PRUSS_MII_RT_RX_FRMS_MIN_FRM_MASK GENMASK(15, 0)
+
+#define PRUSS_MII_RT_RX_FRMS_MAX_FRM_SHIFT 16
+#define PRUSS_MII_RT_RX_FRMS_MAX_FRM_MASK GENMASK(31, 16)
+
+/* Min/Max in MII_RT_RX_FRMS */
+/* For EMAC and Switch */
+#define PRUSS_MII_RT_RX_FRMS_MAX (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN)
+#define PRUSS_MII_RT_RX_FRMS_MIN_FRM (64)
+
+/* for HSR and PRP */
+#define PRUSS_MII_RT_RX_FRMS_MAX_FRM_LRE (PRUSS_MII_RT_RX_FRMS_MAX + \
+ ICSS_LRE_TAG_RCT_SIZE)
+/* PRUSS_MII_RT_RX_PCNT0/1 bits */
+#define PRUSS_MII_RT_RX_PCNT_MIN_PCNT_SHIFT 0
+#define PRUSS_MII_RT_RX_PCNT_MIN_PCNT_MASK GENMASK(3, 0)
+
+#define PRUSS_MII_RT_RX_PCNT_MAX_PCNT_SHIFT 4
+#define PRUSS_MII_RT_RX_PCNT_MAX_PCNT_MASK GENMASK(7, 4)
+
+/* PRUSS_MII_RT_RX_ERR0/1 bits */
+#define PRUSS_MII_RT_RX_ERR_MIN_PCNT_ERR BIT(0)
+#define PRUSS_MII_RT_RX_ERR_MAX_PCNT_ERR BIT(1)
+#define PRUSS_MII_RT_RX_ERR_MIN_FRM_ERR BIT(2)
+#define PRUSS_MII_RT_RX_ERR_MAX_FRM_ERR BIT(3)
+
+#define ICSSG_CFG_OFFSET 0
+#define RGMII_CFG_OFFSET 4
+
+/* Constant to choose between MII0 and MII1 */
+#define ICSS_MII0 0
+#define ICSS_MII1 1
+
+/* ICSSG_CFG Register bits */
+#define ICSSG_CFG_SGMII_MODE BIT(16)
+#define ICSSG_CFG_TX_PRU_EN BIT(11)
+#define ICSSG_CFG_RX_SFD_TX_SOF_EN BIT(10)
+#define ICSSG_CFG_RTU_PRU_PSI_SHARE_EN BIT(9)
+#define ICSSG_CFG_IEP1_TX_EN BIT(8)
+#define ICSSG_CFG_MII1_MODE GENMASK(6, 5)
+#define ICSSG_CFG_MII1_MODE_SHIFT 5
+#define ICSSG_CFG_MII0_MODE GENMASK(4, 3)
+#define ICSSG_CFG_MII0_MODE_SHIFT 3
+#define ICSSG_CFG_RX_L2_G_EN BIT(2)
+#define ICSSG_CFG_TX_L2_EN BIT(1)
+#define ICSSG_CFG_TX_L1_EN BIT(0)
+
+enum mii_mode { MII_MODE_MII = 0, MII_MODE_RGMII, MII_MODE_SGMII };
+
+/* RGMII CFG Register bits */
+#define RGMII_CFG_INBAND_EN_MII0 BIT(16)
+#define RGMII_CFG_GIG_EN_MII0 BIT(17)
+#define RGMII_CFG_INBAND_EN_MII1 BIT(20)
+#define RGMII_CFG_GIG_EN_MII1 BIT(21)
+#define RGMII_CFG_FULL_DUPLEX_MII0 BIT(18)
+#define RGMII_CFG_FULL_DUPLEX_MII1 BIT(22)
+#define RGMII_CFG_SPEED_MII0 GENMASK(2, 1)
+#define RGMII_CFG_SPEED_MII1 GENMASK(6, 5)
+#define RGMII_CFG_SPEED_MII0_SHIFT 1
+#define RGMII_CFG_SPEED_MII1_SHIFT 5
+#define RGMII_CFG_FULLDUPLEX_MII0 BIT(3)
+#define RGMII_CFG_FULLDUPLEX_MII1 BIT(7)
+#define RGMII_CFG_FULLDUPLEX_MII0_SHIFT 3
+#define RGMII_CFG_FULLDUPLEX_MII1_SHIFT 7
+#define RGMII_CFG_SPEED_10M 0
+#define RGMII_CFG_SPEED_100M 1
+#define RGMII_CFG_SPEED_1G 2
+
+static inline void icssg_mii_update_ipg(struct regmap *mii_rt, int mii, u32 ipg)
+{
+ u32 val;
+
+ if (mii == ICSS_MII0) {
+ regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG0, ipg);
+ } else {
+ /* Errata workaround: IEP1 is not read by h/w unless IEP0 is written */
+ regmap_read(mii_rt, PRUSS_MII_RT_TX_IPG0, &val);
+ regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG1, ipg);
+ regmap_write(mii_rt, PRUSS_MII_RT_TX_IPG0, val);
+ }
+}
+
+static inline void icssg_update_rgmii_cfg(struct regmap *miig_rt, int speed,
+ bool full_duplex, int slice, struct prueth_priv *priv)
+{
+ u32 gig_en_mask, gig_val = 0, full_duplex_mask, full_duplex_val = 0;
+ u32 inband_en_mask, inband_val = 0;
+
+ gig_en_mask = (slice == ICSS_MII0) ? RGMII_CFG_GIG_EN_MII0 :
+ RGMII_CFG_GIG_EN_MII1;
+ if (speed == SPEED_1000)
+ gig_val = gig_en_mask;
+ regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, gig_en_mask, gig_val);
+
+ inband_en_mask = (slice == ICSS_MII0) ? RGMII_CFG_INBAND_EN_MII0 :
+ RGMII_CFG_INBAND_EN_MII1;
+ if (speed == SPEED_10 && phy_interface_is_rgmii(priv->phydev))
+ inband_val = inband_en_mask;
+ regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, inband_en_mask, inband_val);
+
+ full_duplex_mask = (slice == ICSS_MII0) ? RGMII_CFG_FULL_DUPLEX_MII0 :
+ RGMII_CFG_FULL_DUPLEX_MII1;
+ if (full_duplex)
+ full_duplex_val = full_duplex_mask;
+ regmap_update_bits(miig_rt, RGMII_CFG_OFFSET, full_duplex_mask,
+ full_duplex_val);
+}
+
+static inline void icssg_miig_set_interface_mode(struct regmap *miig_rt, int mii, int phy_if)
+{
+ u32 val, mask, shift;
+
+ mask = mii == ICSS_MII0 ? ICSSG_CFG_MII0_MODE : ICSSG_CFG_MII1_MODE;
+ shift = mii == ICSS_MII0 ? ICSSG_CFG_MII0_MODE_SHIFT : ICSSG_CFG_MII1_MODE_SHIFT;
+
+ val = MII_MODE_RGMII;
+ if (phy_if == PHY_INTERFACE_MODE_MII)
+ val = MII_MODE_MII;
+
+ val <<= shift;
+ regmap_update_bits(miig_rt, ICSSG_CFG_OFFSET, mask, val);
+ regmap_read(miig_rt, ICSSG_CFG_OFFSET, &val);
+}
+
+#endif /* __NET_PRUSS_MII_RT_H__ */
diff --git a/drivers/net/ti/icssg_classifier.c b/drivers/net/ti/icssg_classifier.c
new file mode 100644
index 0000000..e510a1c
--- /dev/null
+++ b/drivers/net/ti/icssg_classifier.c
@@ -0,0 +1,376 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Texas Instruments ICSSG Ethernet Driver
+ *
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+#include <dm/ofnode.h>
+#include <regmap.h>
+
+#define ICSSG_NUM_CLASSIFIERS 16
+#define ICSSG_NUM_FT1_SLOTS 8
+#define ICSSG_NUM_FT3_SLOTS 16
+
+#define ICSSG_NUM_CLASSIFIERS_IN_USE 1
+
+/* Filter 1 - FT1 */
+#define FT1_NUM_SLOTS 8
+#define FT1_SLOT_SIZE 0x10 /* bytes */
+
+/* offsets from FT1 slot base i.e. slot 1 start */
+#define FT1_DA0 0x0
+#define FT1_DA1 0x4
+#define FT1_DA0_MASK 0x8
+#define FT1_DA1_MASK 0xc
+
+#define FT1_N_REG(slize, n, reg) (offs[slice].ft1_slot_base + FT1_SLOT_SIZE * (n) + (reg))
+
+#define FT1_LEN_MASK GENMASK(19, 16)
+#define FT1_LEN_SHIFT 16
+#define FT1_LEN(len) (((len) << FT1_LEN_SHIFT) & FT1_LEN_MASK)
+
+#define FT1_START_MASK GENMASK(14, 0)
+#define FT1_START(start) ((start) & FT1_START_MASK)
+
+#define FT1_MATCH_SLOT(n) (GENMASK(23, 16) & (BIT(n) << 16))
+
+enum ft1_cfg_type {
+ FT1_CFG_TYPE_DISABLED = 0,
+ FT1_CFG_TYPE_EQ,
+ FT1_CFG_TYPE_GT,
+ FT1_CFG_TYPE_LT,
+};
+
+#define FT1_CFG_SHIFT(n) (2 * (n))
+#define FT1_CFG_MASK(n) (0x3 << FT1_CFG_SHIFT((n)))
+
+/* Filter 3 - FT3 */
+#define FT3_NUM_SLOTS 16
+#define FT3_SLOT_SIZE 0x20 /* bytes */
+
+/* offsets from FT3 slot n's base */
+#define FT3_START 0
+#define FT3_START_AUTO 0x4
+#define FT3_START_OFFSET 0x8
+#define FT3_JUMP_OFFSET 0xc
+#define FT3_LEN 0x10
+#define FT3_CFG 0x14
+#define FT3_T 0x18
+#define FT3_T_MASK 0x1c
+
+#define FT3_N_REG(slize, n, reg) \
+ (offs[slice].ft3_slot_base + FT3_SLOT_SIZE * (n) + (reg))
+
+/* offsets from rx_class n's base */
+#define RX_CLASS_AND_EN 0
+#define RX_CLASS_OR_EN 0x4
+
+#define RX_CLASS_NUM_SLOTS 16
+#define RX_CLASS_EN_SIZE 0x8 /* bytes */
+
+#define RX_CLASS_N_REG(slice, n, reg) \
+ (offs[slice].rx_class_base + RX_CLASS_EN_SIZE * (n) + (reg))
+
+/* RX Class Gates */
+#define RX_CLASS_GATES_SIZE 0x4 /* bytes */
+
+#define RX_CLASS_GATES_N_REG(slice, n) \
+ (offs[slice].rx_class_gates_base + RX_CLASS_GATES_SIZE * (n))
+
+#define RX_CLASS_GATES_ALLOW_MASK BIT(6)
+#define RX_CLASS_GATES_RAW_MASK BIT(5)
+#define RX_CLASS_GATES_PHASE_MASK BIT(4)
+
+/* RX Class traffic data matching bits */
+#define RX_CLASS_FT_UC BIT(31)
+#define RX_CLASS_FT_MC BIT(30)
+#define RX_CLASS_FT_BC BIT(29)
+#define RX_CLASS_FT_FW BIT(28)
+#define RX_CLASS_FT_RCV BIT(27)
+#define RX_CLASS_FT_VLAN BIT(26)
+#define RX_CLASS_FT_DA_P BIT(25)
+#define RX_CLASS_FT_DA_I BIT(24)
+#define RX_CLASS_FT_FT1_MATCH_MASK GENMASK(23, 16)
+#define RX_CLASS_FT_FT1_MATCH_SHIFT 16
+#define RX_CLASS_FT_FT3_MATCH_MASK GENMASK(15, 0)
+#define RX_CLASS_FT_FT3_MATCH_SHIFT 0
+
+#define RX_CLASS_FT_FT1_MATCH(slot) \
+ ((BIT(slot) << RX_CLASS_FT_FT1_MATCH_SHIFT) & \
+ RX_CLASS_FT_FT1_MATCH_MASK)
+
+enum rx_class_sel_type {
+ RX_CLASS_SEL_TYPE_OR = 0,
+ RX_CLASS_SEL_TYPE_AND = 1,
+ RX_CLASS_SEL_TYPE_OR_AND_AND = 2,
+ RX_CLASS_SEL_TYPE_OR_OR_AND = 3,
+};
+
+#define FT1_CFG_SHIFT(n) (2 * (n))
+#define FT1_CFG_MASK(n) (0x3 << FT1_CFG_SHIFT((n)))
+
+#define RX_CLASS_SEL_SHIFT(n) (2 * (n))
+#define RX_CLASS_SEL_MASK(n) (0x3 << RX_CLASS_SEL_SHIFT((n)))
+
+#define ICSSG_CFG_OFFSET 0
+#define MAC_INTERFACE_0 0x18
+#define MAC_INTERFACE_1 0x1c
+
+#define ICSSG_CFG_RX_L2_G_EN BIT(2)
+
+/* these are register offsets per PRU */
+struct miig_rt_offsets {
+ u32 mac0;
+ u32 mac1;
+ u32 ft1_start_len;
+ u32 ft1_cfg;
+ u32 ft1_slot_base;
+ u32 ft3_slot_base;
+ u32 ft3_p_base;
+ u32 ft_rx_ptr;
+ u32 rx_class_base;
+ u32 rx_class_cfg1;
+ u32 rx_class_cfg2;
+ u32 rx_class_gates_base;
+ u32 rx_green;
+ u32 rx_rate_cfg_base;
+ u32 rx_rate_src_sel0;
+ u32 rx_rate_src_sel1;
+ u32 tx_rate_cfg_base;
+ u32 stat_base;
+ u32 tx_hsr_tag;
+ u32 tx_hsr_seq;
+ u32 tx_vlan_type;
+ u32 tx_vlan_ins;
+};
+
+static struct miig_rt_offsets offs[] = {
+ /* PRU0 */
+ {
+ 0x8,
+ 0xc,
+ 0x80,
+ 0x84,
+ 0x88,
+ 0x108,
+ 0x308,
+ 0x408,
+ 0x40c,
+ 0x48c,
+ 0x490,
+ 0x494,
+ 0x4d4,
+ 0x4e4,
+ 0x504,
+ 0x508,
+ 0x50c,
+ 0x54c,
+ 0x63c,
+ 0x640,
+ 0x644,
+ 0x648,
+ },
+ /* PRU1 */
+ {
+ 0x10,
+ 0x14,
+ 0x64c,
+ 0x650,
+ 0x654,
+ 0x6d4,
+ 0x8d4,
+ 0x9d4,
+ 0x9d8,
+ 0xa58,
+ 0xa5c,
+ 0xa60,
+ 0xaa0,
+ 0xab0,
+ 0xad0,
+ 0xad4,
+ 0xad8,
+ 0xb18,
+ 0xc08,
+ 0xc0c,
+ 0xc10,
+ 0xc14,
+ },
+};
+
+static inline u32 addr_to_da0(const u8 *addr)
+{
+ return (u32)(addr[0] | addr[1] << 8 |
+ addr[2] << 16 | addr[3] << 24);
+};
+
+static inline u32 addr_to_da1(const u8 *addr)
+{
+ return (u32)(addr[4] | addr[5] << 8);
+};
+
+static void rx_class_ft1_set_start_len(struct regmap *miig_rt, int slice,
+ u16 start, u8 len)
+{
+ u32 offset, val;
+
+ offset = offs[slice].ft1_start_len;
+ val = FT1_LEN(len) | FT1_START(start);
+ regmap_write(miig_rt, offset, val);
+}
+
+static void rx_class_ft1_set_da(struct regmap *miig_rt, int slice,
+ int n, const u8 *addr)
+{
+ u32 offset;
+
+ offset = FT1_N_REG(slice, n, FT1_DA0);
+ regmap_write(miig_rt, offset, addr_to_da0(addr));
+ offset = FT1_N_REG(slice, n, FT1_DA1);
+ regmap_write(miig_rt, offset, addr_to_da1(addr));
+}
+
+static void rx_class_ft1_set_da_mask(struct regmap *miig_rt, int slice,
+ int n, const u8 *addr)
+{
+ u32 offset;
+
+ offset = FT1_N_REG(slice, n, FT1_DA0_MASK);
+ regmap_write(miig_rt, offset, addr_to_da0(addr));
+ offset = FT1_N_REG(slice, n, FT1_DA1_MASK);
+ regmap_write(miig_rt, offset, addr_to_da1(addr));
+}
+
+static void rx_class_ft1_cfg_set_type(struct regmap *miig_rt, int slice, int n,
+ enum ft1_cfg_type type)
+{
+ u32 offset;
+
+ offset = offs[slice].ft1_cfg;
+ regmap_update_bits(miig_rt, offset, FT1_CFG_MASK(n),
+ type << FT1_CFG_SHIFT(n));
+}
+
+static void rx_class_sel_set_type(struct regmap *miig_rt, int slice, int n,
+ enum rx_class_sel_type type)
+{
+ u32 offset;
+
+ offset = offs[slice].rx_class_cfg1;
+ regmap_update_bits(miig_rt, offset, RX_CLASS_SEL_MASK(n),
+ type << RX_CLASS_SEL_SHIFT(n));
+}
+
+static void rx_class_set_and(struct regmap *miig_rt, int slice, int n,
+ u32 data)
+{
+ u32 offset;
+
+ offset = RX_CLASS_N_REG(slice, n, RX_CLASS_AND_EN);
+ regmap_write(miig_rt, offset, data);
+}
+
+static void rx_class_set_or(struct regmap *miig_rt, int slice, int n,
+ u32 data)
+{
+ u32 offset;
+
+ offset = RX_CLASS_N_REG(slice, n, RX_CLASS_OR_EN);
+ regmap_write(miig_rt, offset, data);
+}
+
+void icssg_class_set_host_mac_addr(struct regmap *miig_rt, u8 *mac)
+{
+ regmap_write(miig_rt, MAC_INTERFACE_0, addr_to_da0(mac));
+ regmap_write(miig_rt, MAC_INTERFACE_1, addr_to_da1(mac));
+}
+
+void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac)
+{
+ regmap_write(miig_rt, offs[slice].mac0, addr_to_da0(mac));
+ regmap_write(miig_rt, offs[slice].mac1, addr_to_da1(mac));
+}
+
+void icssg_class_disable_n(struct regmap *miig_rt, int slice, int n)
+{
+ u32 data, offset;
+
+ /* AND_EN = 0 */
+ rx_class_set_and(miig_rt, slice, n, 0);
+ /* OR_EN = 0 */
+ rx_class_set_or(miig_rt, slice, n, 0);
+
+ /* set CFG1 to OR */
+ rx_class_sel_set_type(miig_rt, slice, n, RX_CLASS_SEL_TYPE_OR);
+
+ /* configure gate */
+ offset = RX_CLASS_GATES_N_REG(slice, n);
+ regmap_read(miig_rt, offset, &data);
+ /* clear class_raw so we go through filters */
+ data &= ~RX_CLASS_GATES_RAW_MASK;
+ /* set allow and phase mask */
+ data |= RX_CLASS_GATES_ALLOW_MASK | RX_CLASS_GATES_PHASE_MASK;
+ regmap_write(miig_rt, offset, data);
+}
+
+/* disable all RX traffic */
+void icssg_class_disable(struct regmap *miig_rt, int slice)
+{
+ int n;
+
+ /* Enable RX_L2_G */
+ regmap_update_bits(miig_rt, ICSSG_CFG_OFFSET, ICSSG_CFG_RX_L2_G_EN,
+ ICSSG_CFG_RX_L2_G_EN);
+
+ for (n = 0; n < ICSSG_NUM_CLASSIFIERS; n++)
+ icssg_class_disable_n(miig_rt, slice, n);
+
+ /* FT1 Disabled */
+ for (n = 0; n < ICSSG_NUM_FT1_SLOTS; n++) {
+ u8 addr[] = { 0, 0, 0, 0, 0, 0, };
+
+ rx_class_ft1_cfg_set_type(miig_rt, slice, n,
+ FT1_CFG_TYPE_DISABLED);
+ rx_class_ft1_set_da(miig_rt, slice, n, addr);
+ rx_class_ft1_set_da_mask(miig_rt, slice, n, addr);
+ }
+
+ /* clear CFG2 */
+ regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
+}
+
+void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti)
+{
+ u32 data;
+
+ /* defaults */
+ icssg_class_disable(miig_rt, slice);
+
+ /* Setup Classifier */
+ /* match on Broadcast or MAC_PRU address */
+ data = RX_CLASS_FT_BC | RX_CLASS_FT_DA_P;
+
+ /* multicast? */
+ if (allmulti)
+ data |= RX_CLASS_FT_MC;
+
+ rx_class_set_or(miig_rt, slice, 0, data);
+
+ /* set CFG1 for OR_OR_AND for classifier */
+ rx_class_sel_set_type(miig_rt, slice, 0,
+ RX_CLASS_SEL_TYPE_OR_OR_AND);
+
+ /* clear CFG2 */
+ regmap_write(miig_rt, offs[slice].rx_class_cfg2, 0);
+}
+
+/* required for SR2 for SAV check */
+void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr)
+{
+ u8 mask_addr[] = { 0, 0, 0, 0, 0, 0, };
+
+ rx_class_ft1_set_start_len(miig_rt, slice, 6, 6);
+ rx_class_ft1_set_da(miig_rt, slice, 0, mac_addr);
+ rx_class_ft1_set_da_mask(miig_rt, slice, 0, mask_addr);
+ rx_class_ft1_cfg_set_type(miig_rt, slice, 0, FT1_CFG_TYPE_EQ);
+}
diff --git a/drivers/net/ti/icssg_config.c b/drivers/net/ti/icssg_config.c
new file mode 100644
index 0000000..5f132d0
--- /dev/null
+++ b/drivers/net/ti/icssg_config.c
@@ -0,0 +1,474 @@
+// SPDX-License-Identifier: GPL-2.0
+/* ICSSG Ethernet driver
+ *
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com
+ */
+
+#include <phy.h>
+#include "icssg_prueth.h"
+#include "icssg_switch_map.h"
+#include "icss_mii_rt.h"
+#include <dm/device_compat.h>
+#include <linux/iopoll.h>
+
+/* TX IPG Values to be set for 100M and 1G link speeds. These values are
+ * in ocp_clk cycles. So need change if ocp_clk is changed for a specific
+ * h/w design.
+ */
+
+/* SR2.0 IPG is in rgmii_clk (125MHz) clock cycles + 1 */
+#define MII_RT_TX_IPG_100M 0x17
+#define MII_RT_TX_IPG_1G 0xb
+
+#define ICSSG_QUEUES_MAX 64
+#define ICSSG_QUEUE_OFFSET 0xd00
+#define ICSSG_QUEUE_PEEK_OFFSET 0xe00
+#define ICSSG_QUEUE_CNT_OFFSET 0xe40
+#define ICSSG_QUEUE_RESET_OFFSET 0xf40
+
+#define ICSSG_NUM_TX_QUEUES 8
+
+#define RECYCLE_Q_SLICE0 16
+#define RECYCLE_Q_SLICE1 17
+
+#define ICSSG_NUM_OTHER_QUEUES 5 /* port, host and special queues */
+
+#define PORT_HI_Q_SLICE0 32
+#define PORT_LO_Q_SLICE0 33
+#define HOST_HI_Q_SLICE0 34
+#define HOST_LO_Q_SLICE0 35
+#define HOST_SPL_Q_SLICE0 40 /* Special Queue */
+
+#define PORT_HI_Q_SLICE1 36
+#define PORT_LO_Q_SLICE1 37
+#define HOST_HI_Q_SLICE1 38
+#define HOST_LO_Q_SLICE1 39
+#define HOST_SPL_Q_SLICE1 41 /* Special Queue */
+
+#define MII_RXCFG_DEFAULT (PRUSS_MII_RT_RXCFG_RX_ENABLE | \
+ PRUSS_MII_RT_RXCFG_RX_DATA_RDY_MODE_DIS | \
+ PRUSS_MII_RT_RXCFG_RX_L2_EN | \
+ PRUSS_MII_RT_RXCFG_RX_L2_EOF_SCLR_DIS)
+
+#define MII_TXCFG_DEFAULT (PRUSS_MII_RT_TXCFG_TX_ENABLE | \
+ PRUSS_MII_RT_TXCFG_TX_AUTO_PREAMBLE | \
+ PRUSS_MII_RT_TXCFG_TX_32_MODE_EN | \
+ PRUSS_MII_RT_TXCFG_TX_IPG_WIRE_CLK_EN)
+
+#define ICSSG_CFG_DEFAULT (ICSSG_CFG_TX_L1_EN | \
+ ICSSG_CFG_TX_L2_EN | ICSSG_CFG_RX_L2_G_EN | \
+ ICSSG_CFG_TX_PRU_EN | /* SR2.0 only */ \
+ ICSSG_CFG_SGMII_MODE)
+
+#define FDB_GEN_CFG1 0x60
+#define SMEM_VLAN_OFFSET 8
+#define SMEM_VLAN_OFFSET_MASK GENMASK(25, 8)
+
+#define FDB_GEN_CFG2 0x64
+#define FDB_VLAN_EN BIT(6)
+#define FDB_HOST_EN BIT(2)
+#define FDB_PRU1_EN BIT(1)
+#define FDB_PRU0_EN BIT(0)
+#define FDB_EN_ALL (FDB_PRU0_EN | FDB_PRU1_EN | \
+ FDB_HOST_EN | FDB_VLAN_EN)
+
+struct map {
+ int queue;
+ u32 pd_addr_start;
+ u32 flags;
+ bool special;
+};
+
+struct map hwq_map[2][ICSSG_NUM_OTHER_QUEUES] = {
+ {
+ { PORT_HI_Q_SLICE0, PORT_DESC0_HI, 0x200000, 0 },
+ { PORT_LO_Q_SLICE0, PORT_DESC0_LO, 0, 0 },
+ { HOST_HI_Q_SLICE0, HOST_DESC0_HI, 0x200000, 0 },
+ { HOST_LO_Q_SLICE0, HOST_DESC0_LO, 0, 0 },
+ { HOST_SPL_Q_SLICE0, HOST_SPPD0, 0x400000, 1 },
+ },
+ {
+ { PORT_HI_Q_SLICE1, PORT_DESC1_HI, 0xa00000, 0 },
+ { PORT_LO_Q_SLICE1, PORT_DESC1_LO, 0x800000, 0 },
+ { HOST_HI_Q_SLICE1, HOST_DESC1_HI, 0xa00000, 0 },
+ { HOST_LO_Q_SLICE1, HOST_DESC1_LO, 0x800000, 0 },
+ { HOST_SPL_Q_SLICE1, HOST_SPPD1, 0xc00000, 1 },
+ },
+};
+
+static void icssg_config_mii_init(struct prueth_priv *priv, int slice)
+{
+ struct prueth *prueth = priv->prueth;
+ struct regmap *mii_rt = prueth->mii_rt;
+ u32 txcfg_reg, pcnt_reg;
+ u32 txcfg;
+
+ txcfg_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_TXCFG0 :
+ PRUSS_MII_RT_TXCFG1;
+ pcnt_reg = (slice == ICSS_MII0) ? PRUSS_MII_RT_RX_PCNT0 :
+ PRUSS_MII_RT_RX_PCNT1;
+
+ txcfg = MII_TXCFG_DEFAULT;
+
+ if (prueth->phy_interface == PHY_INTERFACE_MODE_MII && slice == ICSS_MII0)
+ txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
+ else if (prueth->phy_interface != PHY_INTERFACE_MODE_MII && slice == ICSS_MII1)
+ txcfg |= PRUSS_MII_RT_TXCFG_TX_MUX_SEL;
+
+ regmap_write(mii_rt, txcfg_reg, txcfg);
+ regmap_write(mii_rt, pcnt_reg, 0x1);
+}
+
+static void icssg_miig_queues_init(struct prueth_priv *priv, int slice)
+{
+ struct prueth *prueth = priv->prueth;
+ void __iomem *smem = (void __iomem *)prueth->shram.pa;
+ struct regmap *miig_rt = prueth->miig_rt;
+ int queue = 0, i, j;
+ u8 pd[ICSSG_SPECIAL_PD_SIZE];
+ u32 *pdword;
+
+ /* reset hwqueues */
+ if (slice)
+ queue = ICSSG_NUM_TX_QUEUES;
+
+ for (i = 0; i < ICSSG_NUM_TX_QUEUES; i++) {
+ regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue);
+ queue++;
+ }
+
+ queue = slice ? RECYCLE_Q_SLICE1 : RECYCLE_Q_SLICE0;
+ regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET, queue);
+
+ for (i = 0; i < ICSSG_NUM_OTHER_QUEUES; i++) {
+ regmap_write(miig_rt, ICSSG_QUEUE_RESET_OFFSET,
+ hwq_map[slice][i].queue);
+ }
+
+ /* initialize packet descriptors in SMEM */
+ /* push pakcet descriptors to hwqueues */
+
+ pdword = (u32 *)pd;
+ for (j = 0; j < ICSSG_NUM_OTHER_QUEUES; j++) {
+ struct map *mp;
+ int pd_size, num_pds;
+ u32 pdaddr;
+
+ mp = &hwq_map[slice][j];
+ if (mp->special) {
+ pd_size = ICSSG_SPECIAL_PD_SIZE;
+ num_pds = ICSSG_NUM_SPECIAL_PDS;
+ } else {
+ pd_size = ICSSG_NORMAL_PD_SIZE;
+ num_pds = ICSSG_NUM_NORMAL_PDS;
+ }
+
+ for (i = 0; i < num_pds; i++) {
+ memset(pd, 0, pd_size);
+
+ pdword[0] &= cpu_to_le32(ICSSG_FLAG_MASK);
+ pdword[0] |= cpu_to_le32(mp->flags);
+ pdaddr = mp->pd_addr_start + i * pd_size;
+
+ memcpy_toio(smem + pdaddr, pd, pd_size);
+ queue = mp->queue;
+ regmap_write(miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue,
+ pdaddr);
+ }
+ }
+}
+
+void icssg_config_ipg(struct prueth_priv *priv, int speed, int mii)
+{
+ struct prueth *prueth = priv->prueth;
+
+ switch (speed) {
+ case SPEED_1000:
+ icssg_mii_update_ipg(prueth->mii_rt, mii, MII_RT_TX_IPG_1G);
+ break;
+ case SPEED_100:
+ icssg_mii_update_ipg(prueth->mii_rt, mii, MII_RT_TX_IPG_100M);
+ break;
+ default:
+ /* Other links speeds not supported */
+ pr_err("Unsupported link speed\n");
+ return;
+ }
+}
+
+static void emac_r30_cmd_init(struct prueth_priv *priv)
+{
+ struct prueth *prueth = priv->prueth;
+ struct icssg_r30_cmd *p;
+ int i;
+
+ p = (struct icssg_r30_cmd *)(prueth->dram[priv->port_id].pa + MGR_R30_CMD_OFFSET);
+
+ for (i = 0; i < 4; i++)
+ writel(EMAC_NONE, &p->cmd[i]);
+}
+
+static int emac_r30_is_done(struct prueth_priv *priv)
+{
+ struct prueth *prueth = priv->prueth;
+ const struct icssg_r30_cmd *p;
+ int i;
+ u32 cmd;
+
+ p = (const struct icssg_r30_cmd *)(prueth->dram[priv->port_id].pa + MGR_R30_CMD_OFFSET);
+
+ for (i = 0; i < 4; i++) {
+ cmd = readl(&p->cmd[i]);
+ if (cmd != EMAC_NONE)
+ return 0;
+ }
+
+ return 1;
+}
+
+static int prueth_emac_buffer_setup(struct prueth_priv *priv)
+{
+ struct prueth *prueth = priv->prueth;
+ struct icssg_buffer_pool_cfg *bpool_cfg;
+ struct icssg_rxq_ctx *rxq_ctx;
+ int slice = priv->port_id;
+ u32 addr;
+ int i;
+
+ /* Layout to have 64KB aligned buffer pool
+ * |BPOOL0|BPOOL1|RX_CTX0|RX_CTX1|
+ */
+
+ addr = lower_32_bits(prueth->sram_pa);
+ if (slice)
+ addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
+
+ if (addr % SZ_64K) {
+ dev_warn(prueth->dev, "buffer pool needs to be 64KB aligned\n");
+ return -EINVAL;
+ }
+
+ bpool_cfg = (struct icssg_buffer_pool_cfg *)(prueth->dram[priv->port_id].pa + BUFFER_POOL_0_ADDR_OFFSET);
+ /* workaround for f/w bug. bpool 0 needs to be initilalized */
+ bpool_cfg[0].addr = cpu_to_le32(addr);
+ bpool_cfg[0].len = 0;
+
+ for (i = PRUETH_EMAC_BUF_POOL_START;
+ i < (PRUETH_EMAC_BUF_POOL_START + PRUETH_NUM_BUF_POOLS);
+ i++) {
+ bpool_cfg[i].addr = cpu_to_le32(addr);
+ bpool_cfg[i].len = cpu_to_le32(PRUETH_EMAC_BUF_POOL_SIZE);
+ addr += PRUETH_EMAC_BUF_POOL_SIZE;
+ }
+
+ if (!slice)
+ addr += PRUETH_NUM_BUF_POOLS * PRUETH_EMAC_BUF_POOL_SIZE;
+ else
+ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE * 2;
+
+ rxq_ctx = (struct icssg_rxq_ctx *)(prueth->dram[priv->port_id].pa + HOST_RX_Q_PRE_CONTEXT_OFFSET);
+
+ for (i = 0; i < 3; i++)
+ rxq_ctx->start[i] = cpu_to_le32(addr);
+
+ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
+ rxq_ctx->end = cpu_to_le32(addr);
+
+ /* Express RX buffer queue */
+ rxq_ctx = (struct icssg_rxq_ctx *)(prueth->dram[priv->port_id].pa + HOST_RX_Q_EXP_CONTEXT_OFFSET);
+ for (i = 0; i < 3; i++)
+ rxq_ctx->start[i] = cpu_to_le32(addr);
+
+ addr += PRUETH_EMAC_RX_CTX_BUF_SIZE;
+ rxq_ctx->end = cpu_to_le32(addr);
+
+ return 0;
+}
+
+static void icssg_init_emac_mode(struct prueth *prueth)
+{
+ u8 mac[6] = { 0 };
+
+ regmap_update_bits(prueth->miig_rt, FDB_GEN_CFG1, SMEM_VLAN_OFFSET_MASK, 0);
+ regmap_write(prueth->miig_rt, FDB_GEN_CFG2, 0);
+ /* Clear host MAC address */
+ icssg_class_set_host_mac_addr(prueth->miig_rt, mac);
+}
+
+int icssg_config(struct prueth_priv *priv)
+{
+ struct prueth *prueth = priv->prueth;
+ void *config = (void *)(prueth->dram[priv->port_id].pa + ICSSG_CONFIG_OFFSET);
+ u8 *cfg_byte_ptr = config;
+ struct icssg_flow_cfg *flow_cfg;
+ u32 mask;
+ int ret;
+
+ int slice = priv->port_id;
+
+ icssg_init_emac_mode(prueth);
+
+ memset_io(config, 0, TAS_GATE_MASK_LIST0);
+ icssg_miig_queues_init(priv, slice);
+
+ prueth->speed = SPEED_1000;
+ prueth->duplex = DUPLEX_FULL;
+ if (!phy_interface_is_rgmii(priv->phydev)) {
+ prueth->speed = SPEED_100;
+ prueth->duplex = DUPLEX_FULL;
+ }
+
+ regmap_update_bits(prueth->miig_rt, ICSSG_CFG_OFFSET,
+ ICSSG_CFG_DEFAULT, ICSSG_CFG_DEFAULT);
+ icssg_miig_set_interface_mode(prueth->miig_rt, ICSS_MII0, prueth->phy_interface);
+ icssg_miig_set_interface_mode(prueth->miig_rt, ICSS_MII1, prueth->phy_interface);
+ icssg_config_mii_init(priv, slice);
+
+ icssg_config_ipg(priv, SPEED_1000, slice);
+ icssg_update_rgmii_cfg(prueth->miig_rt, SPEED_1000, true, slice, priv);
+
+ /* set GPI mode */
+ pruss_cfg_gpimode(prueth->pruss, slice, PRUSS_GPI_MODE_MII);
+
+ /* enable XFR shift for PRU and RTU */
+ mask = PRUSS_SPP_XFER_SHIFT_EN | PRUSS_SPP_RTU_XFR_SHIFT_EN;
+ pruss_cfg_update(prueth->pruss, PRUSS_CFG_SPP, mask, mask);
+
+ flow_cfg = config + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
+ flow_cfg->rx_base_flow = prueth->dma_rx.id;
+ flow_cfg->mgm_base_flow = 0;
+ *(cfg_byte_ptr + SPL_PKT_DEFAULT_PRIORITY) = 0;
+ *(cfg_byte_ptr + QUEUE_NUM_UNTAGGED) = 0x0;
+
+ ret = prueth_emac_buffer_setup(priv);
+
+ if (ret)
+ return ret;
+
+ emac_r30_cmd_init(priv);
+ return 0;
+}
+
+/* commands to program ICSSG R30 registers */
+static struct icssg_r30_cmd emac_r32_bitmask[] = {
+ {{0xffff0004, 0xffff0100, 0xffff0004, EMAC_NONE}}, /* EMAC_PORT_DISABLE */
+ {{0xfffb0040, 0xfeff0200, 0xfeff0200, EMAC_NONE}}, /* EMAC_PORT_BLOCK */
+ {{0xffbb0000, 0xfcff0000, 0xdcfb0000, EMAC_NONE}}, /* EMAC_PORT_FORWARD */
+ {{0xffbb0000, 0xfcff0000, 0xfcff2000, EMAC_NONE}}, /* EMAC_PORT_FORWARD_WO_LEARNING */
+ {{0xffff0001, EMAC_NONE, EMAC_NONE, EMAC_NONE}}, /* ACCEPT ALL */
+ {{0xfffe0002, EMAC_NONE, EMAC_NONE, EMAC_NONE}}, /* ACCEPT TAGGED */
+ {{0xfffc0000, EMAC_NONE, EMAC_NONE, EMAC_NONE}}, /* ACCEPT UNTAGGED and PRIO */
+ {{EMAC_NONE, 0xffff0020, EMAC_NONE, EMAC_NONE}}, /* TAS Trigger List change */
+ {{EMAC_NONE, 0xdfff1000, EMAC_NONE, EMAC_NONE}}, /* TAS set state ENABLE*/
+ {{EMAC_NONE, 0xefff2000, EMAC_NONE, EMAC_NONE}}, /* TAS set state RESET*/
+ {{EMAC_NONE, 0xcfff0000, EMAC_NONE, EMAC_NONE}}, /* TAS set state DISABLE*/
+ {{EMAC_NONE, EMAC_NONE, 0xffff0400, EMAC_NONE}}, /* UC flooding ENABLE*/
+ {{EMAC_NONE, EMAC_NONE, 0xfbff0000, EMAC_NONE}}, /* UC flooding DISABLE*/
+ {{EMAC_NONE, EMAC_NONE, 0xffff0800, EMAC_NONE}}, /* MC flooding ENABLE*/
+ {{EMAC_NONE, EMAC_NONE, 0xf7ff0000, EMAC_NONE}}, /* MC flooding DISABLE*/
+ {{EMAC_NONE, 0xffff4000, EMAC_NONE, EMAC_NONE}}, /* Preemption on Tx ENABLE*/
+ {{EMAC_NONE, 0xbfff0000, EMAC_NONE, EMAC_NONE}} /* Preemption on Tx DISABLE*/
+};
+
+int emac_set_port_state(struct prueth_priv *priv,
+ enum icssg_port_state_cmd cmd)
+{
+ struct prueth *prueth = priv->prueth;
+ struct icssg_r30_cmd *p;
+ int ret = -ETIMEDOUT;
+ int timeout = 10;
+ int i;
+
+ p = (struct icssg_r30_cmd *)(prueth->dram[priv->port_id].pa + MGR_R30_CMD_OFFSET);
+
+ if (cmd >= ICSSG_EMAC_PORT_MAX_COMMANDS) {
+ dev_err(prueth->dev, "invalid port command\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < 4; i++)
+ writel(emac_r32_bitmask[cmd].cmd[i], &p->cmd[i]);
+
+ /* wait for done */
+ while (timeout) {
+ if (emac_r30_is_done(priv)) {
+ ret = 0;
+ break;
+ }
+
+ udelay(2000);
+ timeout--;
+ }
+
+ if (ret == -ETIMEDOUT)
+ dev_err(prueth->dev, "timeout waiting for command done\n");
+
+ return ret;
+}
+
+int icssg_send_fdb_msg(struct prueth_priv *priv, struct mgmt_cmd *cmd,
+ struct mgmt_cmd_rsp *rsp)
+{
+ struct prueth *prueth = priv->prueth;
+ int slice = priv->port_id;
+ int ret, addr;
+
+ addr = icssg_queue_pop(prueth, slice == 0 ?
+ ICSSG_CMD_POP_SLICE0 : ICSSG_CMD_POP_SLICE1);
+ if (addr < 0)
+ return addr;
+
+ /* First 4 bytes have FW owned buffer linking info which should
+ * not be touched
+ */
+ memcpy_toio((void __iomem *)prueth->shram.pa + addr + 4, cmd, sizeof(*cmd));
+ icssg_queue_push(prueth, slice == 0 ?
+ ICSSG_CMD_PUSH_SLICE0 : ICSSG_CMD_PUSH_SLICE1, addr);
+ ret = read_poll_timeout(icssg_queue_pop, addr, addr >= 0,
+ 2000, 20000000, prueth, slice == 0 ?
+ ICSSG_RSP_POP_SLICE0 : ICSSG_RSP_POP_SLICE1);
+
+ if (ret) {
+ dev_err(prueth->dev, "Timedout sending HWQ message\n");
+ return ret;
+ }
+
+ memcpy_fromio(rsp, (void __iomem *)prueth->shram.pa + addr, sizeof(*rsp));
+ /* Return buffer back for to pool */
+ icssg_queue_push(prueth, slice == 0 ?
+ ICSSG_RSP_PUSH_SLICE0 : ICSSG_RSP_PUSH_SLICE1, addr);
+
+ return 0;
+}
+
+int emac_fdb_flow_id_updated(struct prueth_priv *priv)
+{
+ struct mgmt_cmd_rsp fdb_cmd_rsp = { 0 };
+ struct prueth *prueth = priv->prueth;
+ struct mgmt_cmd fdb_cmd = { 0 };
+ int slice = priv->port_id;
+ int ret = 0;
+
+ fdb_cmd.header = ICSSG_FW_MGMT_CMD_HEADER;
+ fdb_cmd.type = ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW;
+ fdb_cmd.seqnum = ++(prueth->icssg_hwcmdseq);
+ fdb_cmd.param = 0;
+
+ fdb_cmd.param |= (slice << 4);
+ fdb_cmd.cmd_args[0] = 0;
+
+ ret = icssg_send_fdb_msg(priv, &fdb_cmd, &fdb_cmd_rsp);
+ if (ret)
+ return ret;
+
+ if (fdb_cmd.seqnum != fdb_cmd_rsp.seqnum) {
+ dev_err(prueth->dev, "seqnum doesn't match, cmd.seqnum %d != rsp.seqnum %d\n",
+ fdb_cmd.seqnum, fdb_cmd_rsp.seqnum);
+ return -EINVAL;
+ }
+
+ if (fdb_cmd_rsp.status == 1)
+ return 0;
+
+ return -EINVAL;
+}
diff --git a/drivers/net/ti/icssg_config.h b/drivers/net/ti/icssg_config.h
new file mode 100644
index 0000000..d388484
--- /dev/null
+++ b/drivers/net/ti/icssg_config.h
@@ -0,0 +1,195 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Texas Instruments ICSSG Ethernet driver
+ *
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+#ifndef __NET_TI_ICSSG_CONFIG_H
+#define __NET_TI_ICSSG_CONFIG_H
+
+struct icssg_buffer_pool_cfg {
+ __le32 addr;
+ __le32 len;
+} __packed;
+
+struct icssg_flow_cfg {
+ __le16 rx_base_flow;
+ __le16 mgm_base_flow;
+} __packed;
+
+/* Config area lies in shared RAM */
+#define ICSSG_CONFIG_OFFSET_SLICE0 0
+#define ICSSG_CONFIG_OFFSET_SLICE1 0x8000
+
+/* pstate speed/duplex command to set speed and duplex settings
+ * in firmware.
+ * Command format : 0x8102ssPN. ss - sequence number: currently not
+ * used by driver, P - port number: For switch, N - Speed/Duplex state
+ * - Possible values of N:
+ * 0x0 - 10Mbps/Half duplex ;
+ * 0x8 - 10Mbps/Full duplex ;
+ * 0x2 - 100Mbps/Half duplex;
+ * 0xa - 100Mbps/Full duplex;
+ * 0xc - 1Gbps/Full duplex;
+ * NOTE: The above are same as bits [3..1](slice 0) or bits [8..6](slice 1) of
+ * RGMII CFG register. So suggested to read the register to populate the command
+ * bits.
+ */
+#define ICSSG_PSTATE_SPEED_DUPLEX_CMD 0x81020000
+#define ICSSG_PSTATE_FULL_DUPLEX BIT(3)
+#define ICSSG_PSTATE_SPEED_100 BIT(1)
+#define ICSSG_PSTATE_SPEED_1000 BIT(2)
+
+/* Flow IDs used in config structure to firmware. Should match with
+ * flow_id in struct dma for rx channels.
+ */
+#define ICSSG_RX_CHAN_FLOW_ID 0 /* flow id for host port */
+#define ICSSG_RX_MGM_CHAN_FLOW_ID 1 /* flow id for command response */
+
+/* Used to notify the FW of the current link speed */
+#define PORT_LINK_SPEED_OFFSET 0x00A8
+
+#define FW_LINK_SPEED_1G (0x00)
+#define FW_LINK_SPEED_100M (0x01)
+#define FW_LINK_SPEED_10M (0x02)
+#define FW_LINK_SPEED_HD (0x80)
+
+#define PRUETH_PKT_TYPE_CMD 0x10
+#define PRUETH_NAV_PS_DATA_SIZE 16 /* Protocol specific data size */
+#define PRUETH_NAV_SW_DATA_SIZE 16 /* SW related data size */
+#define PRUETH_MAX_RX_FLOWS 1 /* excluding default flow */
+#define PRUETH_RX_FLOW_DATA 0 /* FIXME: f/w bug to change to highest priority flow */
+
+#define PRUETH_EMAC_BUF_POOL_SIZE SZ_8K
+#define PRUETH_EMAC_POOLS_PER_SLICE 24
+#define PRUETH_EMAC_BUF_POOL_START 8
+#define PRUETH_NUM_BUF_POOLS 8
+#define PRUETH_EMAC_RX_CTX_BUF_SIZE SZ_16K /* per slice */
+#define MSMC_RAM_SIZE (2 * (PRUETH_EMAC_BUF_POOL_SIZE * PRUETH_NUM_BUF_POOLS + \
+ PRUETH_EMAC_RX_CTX_BUF_SIZE))
+
+struct icssg_rxq_ctx {
+ __le32 start[3];
+ __le32 end;
+} __packed;
+
+/* Load time Fiwmware Configuration */
+
+#define ICSSG_FW_MGMT_CMD_HEADER 0x81
+#define ICSSG_FW_MGMT_FDB_CMD_TYPE 0x03
+#define ICSSG_FW_MGMT_CMD_TYPE 0x04
+#define ICSSG_FW_MGMT_PKT 0x80000000
+#define ICSSG_FW_MGMT_FDB_CMD_TYPE_RX_FLOW 0x05
+
+struct icssg_r30_cmd {
+ u32 cmd[4];
+} __packed;
+
+enum icssg_port_state_cmd {
+ ICSSG_EMAC_PORT_DISABLE = 0,
+ ICSSG_EMAC_PORT_BLOCK,
+ ICSSG_EMAC_PORT_FORWARD,
+ ICSSG_EMAC_PORT_FORWARD_WO_LEARNING,
+ ICSSG_EMAC_PORT_ACCEPT_ALL,
+ ICSSG_EMAC_PORT_ACCEPT_TAGGED,
+ ICSSG_EMAC_PORT_ACCEPT_UNTAGGED_N_PRIO,
+ ICSSG_EMAC_PORT_TAS_TRIGGER,
+ ICSSG_EMAC_PORT_TAS_ENABLE,
+ ICSSG_EMAC_PORT_TAS_RESET,
+ ICSSG_EMAC_PORT_TAS_DISABLE,
+ ICSSG_EMAC_PORT_UC_FLOODING_ENABLE,
+ ICSSG_EMAC_PORT_UC_FLOODING_DISABLE,
+ ICSSG_EMAC_PORT_MC_FLOODING_ENABLE,
+ ICSSG_EMAC_PORT_MC_FLOODING_DISABLE,
+ ICSSG_EMAC_PORT_PREMPT_TX_ENABLE,
+ ICSSG_EMAC_PORT_PREMPT_TX_DISABLE,
+ ICSSG_EMAC_PORT_MAX_COMMANDS
+};
+
+#define EMAC_NONE 0xffff0000
+#define EMAC_PRU0_P_DI 0xffff0004
+#define EMAC_PRU1_P_DI 0xffff0040
+#define EMAC_TX_P_DI 0xffff0100
+
+#define EMAC_PRU0_P_EN 0xfffb0000
+#define EMAC_PRU1_P_EN 0xffbf0000
+#define EMAC_TX_P_EN 0xfeff0000
+
+#define EMAC_P_BLOCK 0xffff0040
+#define EMAC_TX_P_BLOCK 0xffff0200
+#define EMAC_P_UNBLOCK 0xffbf0000
+#define EMAC_TX_P_UNBLOCK 0xfdff0000
+#define EMAC_LEAN_EN 0xfff70000
+#define EMAC_LEAN_DI 0xffff0008
+
+#define EMAC_ACCEPT_ALL 0xffff0001
+#define EMAC_ACCEPT_TAG 0xfffe0002
+#define EMAC_ACCEPT_PRIOR 0xfffc0000
+
+/* Config area lies in DRAM */
+#define ICSSG_CONFIG_OFFSET 0x0
+
+#define ICSSG_NUM_NORMAL_PDS 64
+#define ICSSG_NUM_SPECIAL_PDS 16
+
+#define ICSSG_NORMAL_PD_SIZE 8
+#define ICSSG_SPECIAL_PD_SIZE 20
+
+#define ICSSG_FLAG_MASK 0xff00ffff
+
+struct icssg_setclock_desc {
+ u8 request;
+ u8 restore;
+ u8 acknowledgment;
+ u8 cmp_status;
+ u32 margin;
+ u32 cyclecounter0_set;
+ u32 cyclecounter1_set;
+ u32 iepcount_set;
+ u32 rsvd1;
+ u32 rsvd2;
+ u32 CMP0_current;
+ u32 iepcount_current;
+ u32 difference;
+ u32 cyclecounter0_new;
+ u32 cyclecounter1_new;
+ u32 CMP0_new;
+} __packed;
+
+struct mgmt_cmd {
+ u8 param;
+ u8 seqnum;
+ u8 type;
+ u8 header;
+ u32 cmd_args[3];
+} __packed;
+
+struct mgmt_cmd_rsp {
+ u32 reserved;
+ u8 status;
+ u8 seqnum;
+ u8 type;
+ u8 header;
+ u32 cmd_args[3];
+} __packed;
+
+#define ICSSG_CMD_POP_SLICE0 56
+#define ICSSG_CMD_POP_SLICE1 60
+
+#define ICSSG_CMD_PUSH_SLICE0 57
+#define ICSSG_CMD_PUSH_SLICE1 61
+
+#define ICSSG_RSP_POP_SLICE0 58
+#define ICSSG_RSP_POP_SLICE1 62
+
+#define ICSSG_RSP_PUSH_SLICE0 56
+#define ICSSG_RSP_PUSH_SLICE1 60
+
+#define ICSSG_TS_POP_SLICE0 59
+#define ICSSG_TS_POP_SLICE1 63
+
+#define ICSSG_TS_PUSH_SLICE0 40
+#define ICSSG_TS_PUSH_SLICE1 41
+
+#endif /* __NET_TI_ICSSG_CONFIG_H */
diff --git a/drivers/net/ti/icssg_prueth.c b/drivers/net/ti/icssg_prueth.c
new file mode 100644
index 0000000..2639f96
--- /dev/null
+++ b/drivers/net/ti/icssg_prueth.c
@@ -0,0 +1,691 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Texas Instruments K3 AM65 PRU Ethernet Driver
+ *
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <clk.h>
+#include <dm/lists.h>
+#include <dm/device.h>
+#include <dma-uclass.h>
+#include <dm/of_access.h>
+#include <dm/pinctrl.h>
+#include <fs_loader.h>
+#include <miiphy.h>
+#include <net.h>
+#include <phy.h>
+#include <power-domain.h>
+#include <linux/soc/ti/ti-udma.h>
+#include <regmap.h>
+#include <remoteproc.h>
+#include <syscon.h>
+#include <soc.h>
+#include <linux/pruss_driver.h>
+#include <dm/device_compat.h>
+
+#include "icssg_prueth.h"
+#include "icss_mii_rt.h"
+
+#define ICSS_SLICE0 0
+#define ICSS_SLICE1 1
+
+#ifdef PKTSIZE_ALIGN
+#define UDMA_RX_BUF_SIZE PKTSIZE_ALIGN
+#else
+#define UDMA_RX_BUF_SIZE ALIGN(PKTSIZE, ARCH_DMA_MINALIGN)
+#endif
+
+#ifdef PKTBUFSRX
+#define UDMA_RX_DESC_NUM PKTBUFSRX
+#else
+#define UDMA_RX_DESC_NUM 4
+#endif
+
+/* Config region lies in shared RAM */
+#define ICSS_CONFIG_OFFSET_SLICE0 0
+#define ICSS_CONFIG_OFFSET_SLICE1 0x8000
+
+/* Firmware flags */
+#define ICSS_SET_RUN_FLAG_VLAN_ENABLE BIT(0) /* switch only */
+#define ICSS_SET_RUN_FLAG_FLOOD_UNICAST BIT(1) /* switch only */
+#define ICSS_SET_RUN_FLAG_PROMISC BIT(2) /* MAC only */
+#define ICSS_SET_RUN_FLAG_MULTICAST_PROMISC BIT(3) /* MAC only */
+
+/* CTRLMMR_ICSSG_RGMII_CTRL register bits */
+#define ICSSG_CTRL_RGMII_ID_MODE BIT(24)
+
+/* Management packet type */
+#define PRUETH_PKT_TYPE_CMD 0x10
+
+/* Number of PRU Cores per Slice */
+#define ICSSG_NUM_PRU_CORES 3
+
+static int icssg_gmii_select(struct prueth_priv *priv)
+{
+ struct phy_device *phydev = priv->phydev;
+
+ if (phydev->interface != PHY_INTERFACE_MODE_MII &&
+ phydev->interface < PHY_INTERFACE_MODE_RGMII &&
+ phydev->interface > PHY_INTERFACE_MODE_RGMII_TXID) {
+ dev_err(priv->dev, "PHY mode unsupported %s\n",
+ phy_string_for_interface(phydev->interface));
+ return -EINVAL;
+ }
+
+ /* AM65 SR2.0 has TX Internal delay always enabled by hardware
+ * and it is not possible to disable TX Internal delay. The below
+ * switch case block describes how we handle different phy modes
+ * based on hardware restriction.
+ */
+ switch (phydev->interface) {
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ phydev->interface = PHY_INTERFACE_MODE_RGMII_RXID;
+ break;
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ phydev->interface = PHY_INTERFACE_MODE_RGMII;
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ dev_err(priv->dev, "RGMII mode without TX delay is not supported");
+ return -EINVAL;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int icssg_phy_init(struct udevice *dev)
+{
+ struct prueth_priv *priv = dev_get_priv(dev);
+ struct phy_device *phydev;
+ u32 supported = PHY_GBIT_FEATURES;
+ int ret;
+
+ phydev = dm_eth_phy_connect(dev);
+ if (!phydev) {
+ dev_err(dev, "phy_connect() failed\n");
+ return -ENODEV;
+ }
+
+ /* disable unsupported features */
+ supported &= ~(PHY_10BT_FEATURES |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_1000baseT_Half |
+ SUPPORTED_Pause |
+ SUPPORTED_Asym_Pause);
+
+ phydev->supported &= supported;
+ phydev->advertising = phydev->supported;
+ priv->phydev = phydev;
+
+ ret = icssg_gmii_select(priv);
+ if (ret)
+ goto out;
+
+ ret = phy_config(phydev);
+ if (ret < 0)
+ dev_err(dev, "phy_config() failed: %d", ret);
+out:
+ return ret;
+}
+
+static void icssg_config_set_speed(struct prueth_priv *priv, int speed)
+{
+ struct prueth *prueth = priv->prueth;
+ u8 fw_speed;
+
+ switch (speed) {
+ case SPEED_1000:
+ fw_speed = FW_LINK_SPEED_1G;
+ break;
+ case SPEED_100:
+ fw_speed = FW_LINK_SPEED_100M;
+ break;
+ case SPEED_10:
+ fw_speed = FW_LINK_SPEED_10M;
+ break;
+ default:
+ /* Other links speeds not supported */
+ dev_err(priv->dev, "Unsupported link speed\n");
+ return;
+ }
+
+ writeb(fw_speed, prueth->dram[priv->port_id].pa + PORT_LINK_SPEED_OFFSET);
+}
+
+static int icssg_update_link(struct prueth_priv *priv)
+{
+ struct phy_device *phy = priv->phydev;
+ struct prueth *prueth = priv->prueth;
+ bool gig_en = false, full_duplex = false;
+
+ if (phy->link) { /* link up */
+ if (phy->speed == SPEED_1000)
+ gig_en = true;
+ if (phy->duplex == DUPLEX_FULL)
+ full_duplex = true;
+ /* Set the RGMII cfg for gig en and full duplex */
+ icssg_update_rgmii_cfg(prueth->miig_rt, phy->speed, full_duplex,
+ priv->port_id, priv);
+ /* update the Tx IPG based on 100M/1G speed */
+ icssg_config_ipg(priv, phy->speed, priv->port_id);
+
+ /* Send command to firmware to update Speed setting */
+ icssg_config_set_speed(priv, phy->speed);
+
+ /* Enable PORT FORWARDING */
+ emac_set_port_state(priv, ICSSG_EMAC_PORT_FORWARD);
+
+ printf("link up on port %d, speed %d, %s duplex\n",
+ priv->port_id, phy->speed,
+ (phy->duplex == DUPLEX_FULL) ? "full" : "half");
+ } else {
+ emac_set_port_state(priv, ICSSG_EMAC_PORT_DISABLE);
+ printf("link down on port %d\n", priv->port_id);
+ }
+
+ return phy->link;
+}
+
+struct icssg_firmwares {
+ char *pru;
+ char *rtu;
+ char *txpru;
+};
+
+static struct icssg_firmwares icssg_emac_firmwares[] = {
+ {
+ .pru = "/lib/firmware/ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
+ .rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu0-prueth-fw.elf",
+ .txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru0-prueth-fw.elf",
+ },
+ {
+ .pru = "/lib/firmware/ti-pruss/am65x-sr2-pru1-prueth-fw.elf",
+ .rtu = "/lib/firmware/ti-pruss/am65x-sr2-rtu1-prueth-fw.elf",
+ .txpru = "/lib/firmware/ti-pruss/am65x-sr2-txpru1-prueth-fw.elf",
+ }
+};
+
+static int icssg_start_pru_cores(struct udevice *dev)
+{
+ struct prueth_priv *priv = dev_get_priv(dev);
+ struct prueth *prueth = priv->prueth;
+ struct icssg_firmwares *firmwares;
+ struct udevice *rproc_dev = NULL;
+ int ret, slice;
+ u32 phandle;
+ u8 index;
+
+ slice = priv->port_id;
+ index = slice * ICSSG_NUM_PRU_CORES;
+ firmwares = icssg_emac_firmwares;
+
+ ofnode_read_u32_index(dev_ofnode(prueth->dev), "ti,prus", index, &phandle);
+ ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle, &rproc_dev);
+ if (ret) {
+ dev_err(dev, "Unknown remote processor with phandle '0x%x' requested(%d)\n",
+ phandle, ret);
+ return ret;
+ }
+
+ prueth->pru_core_id = dev_seq(rproc_dev);
+ ret = rproc_set_firmware(rproc_dev, firmwares[slice].pru);
+ if (ret)
+ return ret;
+
+ ret = rproc_boot(rproc_dev);
+ if (ret) {
+ dev_err(dev, "failed to boot PRU%d: %d\n", slice, ret);
+ return -EINVAL;
+ }
+
+ ofnode_read_u32_index(dev_ofnode(prueth->dev), "ti,prus", index + 1, &phandle);
+ ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle, &rproc_dev);
+ if (ret) {
+ dev_err(dev, "Unknown remote processor with phandle '0x%x' requested(%d)\n",
+ phandle, ret);
+ goto halt_pru;
+ }
+
+ prueth->rtu_core_id = dev_seq(rproc_dev);
+ ret = rproc_set_firmware(rproc_dev, firmwares[slice].rtu);
+ if (ret)
+ goto halt_pru;
+
+ ret = rproc_boot(rproc_dev);
+ if (ret) {
+ dev_err(dev, "failed to boot RTU%d: %d\n", slice, ret);
+ goto halt_pru;
+ }
+
+ ofnode_read_u32_index(dev_ofnode(prueth->dev), "ti,prus", index + 2, &phandle);
+ ret = uclass_get_device_by_phandle_id(UCLASS_REMOTEPROC, phandle, &rproc_dev);
+ if (ret) {
+ dev_err(dev, "Unknown remote processor with phandle '0x%x' requested(%d)\n",
+ phandle, ret);
+ goto halt_rtu;
+ }
+
+ prueth->txpru_core_id = dev_seq(rproc_dev);
+ ret = rproc_set_firmware(rproc_dev, firmwares[slice].txpru);
+ if (ret)
+ goto halt_rtu;
+
+ ret = rproc_boot(rproc_dev);
+ if (ret) {
+ dev_err(dev, "failed to boot TXPRU%d: %d\n", slice, ret);
+ goto halt_rtu;
+ }
+
+ return 0;
+
+halt_rtu:
+ rproc_stop(prueth->rtu_core_id);
+
+halt_pru:
+ rproc_stop(prueth->pru_core_id);
+ return ret;
+}
+
+static int icssg_stop_pru_cores(struct udevice *dev)
+{
+ struct prueth_priv *priv = dev_get_priv(dev);
+ struct prueth *prueth = priv->prueth;
+
+ rproc_stop(prueth->pru_core_id);
+ rproc_stop(prueth->rtu_core_id);
+ rproc_stop(prueth->txpru_core_id);
+
+ return 0;
+}
+
+static int prueth_start(struct udevice *dev)
+{
+ struct ti_udma_drv_chan_cfg_data *dma_rx_cfg_data;
+ struct eth_pdata *pdata = dev_get_plat(dev);
+ struct prueth_priv *priv = dev_get_priv(dev);
+ struct prueth *prueth = priv->prueth;
+ struct icssg_flow_cfg *flow_cfg;
+ u8 *hwaddr = pdata->enetaddr;
+ char chn_name[16];
+ void *config;
+ int ret, i;
+
+ icssg_class_set_mac_addr(prueth->miig_rt, priv->port_id, hwaddr);
+ icssg_ft1_set_mac_addr(prueth->miig_rt, priv->port_id, hwaddr);
+ icssg_class_default(prueth->miig_rt, priv->port_id, 0);
+
+ /* Set Load time configuration */
+ icssg_config(priv);
+
+ ret = icssg_start_pru_cores(dev);
+ if (ret)
+ return ret;
+
+ /* To differentiate channels for SLICE0 vs SLICE1 */
+ snprintf(chn_name, sizeof(chn_name), "tx%d-0", priv->port_id);
+
+ ret = dma_get_by_name(prueth->dev, chn_name, &prueth->dma_tx);
+ if (ret)
+ dev_err(dev, "TX dma get failed %d\n", ret);
+
+ snprintf(chn_name, sizeof(chn_name), "rx%d", priv->port_id);
+ ret = dma_get_by_name(prueth->dev, chn_name, &prueth->dma_rx);
+ if (ret)
+ dev_err(dev, "RX dma get failed %d\n", ret);
+
+ for (i = 0; i < UDMA_RX_DESC_NUM; i++) {
+ ret = dma_prepare_rcv_buf(&prueth->dma_rx,
+ net_rx_packets[i],
+ UDMA_RX_BUF_SIZE);
+ if (ret)
+ dev_err(dev, "RX dma add buf failed %d\n", ret);
+ }
+
+ ret = dma_enable(&prueth->dma_tx);
+ if (ret) {
+ dev_err(dev, "TX dma_enable failed %d\n", ret);
+ goto tx_fail;
+ }
+
+ ret = dma_enable(&prueth->dma_rx);
+ if (ret) {
+ dev_err(dev, "RX dma_enable failed %d\n", ret);
+ goto rx_fail;
+ }
+
+ /* check if the rx_flow_id of dma_rx is as expected since
+ * driver hardcode that value in config struct to firmware
+ * in probe. Just add this sanity check to catch any change
+ * to rx channel assignment in the future.
+ */
+ dma_get_cfg(&prueth->dma_rx, 0, (void **)&dma_rx_cfg_data);
+ config = (void *)(prueth->dram[priv->port_id].pa + ICSSG_CONFIG_OFFSET);
+
+ flow_cfg = config + PSI_L_REGULAR_FLOW_ID_BASE_OFFSET;
+ writew(dma_rx_cfg_data->flow_id_base, &flow_cfg->rx_base_flow);
+ writew(0, &flow_cfg->mgm_base_flow);
+
+ dev_info(dev, "K3 ICSSG: rflow_id_base: %u, chn_name = %s\n",
+ dma_rx_cfg_data->flow_id_base, chn_name);
+
+ ret = emac_fdb_flow_id_updated(priv);
+ if (ret) {
+ dev_err(dev, "Failed to update Rx Flow ID %d", ret);
+ goto phy_fail;
+ }
+
+ ret = phy_startup(priv->phydev);
+ if (ret) {
+ dev_err(dev, "phy_startup failed\n");
+ goto phy_fail;
+ }
+
+ ret = icssg_update_link(priv);
+ if (!ret) {
+ ret = -ENODEV;
+ goto phy_shut;
+ }
+
+ return 0;
+
+phy_shut:
+ phy_shutdown(priv->phydev);
+phy_fail:
+ dma_disable(&prueth->dma_rx);
+ dma_free(&prueth->dma_rx);
+rx_fail:
+ dma_disable(&prueth->dma_tx);
+ dma_free(&prueth->dma_tx);
+
+tx_fail:
+ icssg_class_disable(prueth->miig_rt, priv->port_id);
+
+ return ret;
+}
+
+static int prueth_send(struct udevice *dev, void *packet, int length)
+{
+ struct prueth_priv *priv = dev_get_priv(dev);
+ struct prueth *prueth = priv->prueth;
+ int ret;
+
+ ret = dma_send(&prueth->dma_tx, packet, length, NULL);
+
+ return ret;
+}
+
+static int prueth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct prueth_priv *priv = dev_get_priv(dev);
+ struct prueth *prueth = priv->prueth;
+ int ret;
+
+ /* try to receive a new packet */
+ ret = dma_receive(&prueth->dma_rx, (void **)packetp, NULL);
+
+ return ret;
+}
+
+static int prueth_free_pkt(struct udevice *dev, uchar *packet, int length)
+{
+ struct prueth_priv *priv = dev_get_priv(dev);
+ struct prueth *prueth = priv->prueth;
+ int ret = 0;
+
+ if (length > 0) {
+ u32 pkt = prueth->rx_next % UDMA_RX_DESC_NUM;
+
+ dev_dbg(dev, "%s length:%d pkt:%u\n", __func__, length, pkt);
+
+ ret = dma_prepare_rcv_buf(&prueth->dma_rx,
+ net_rx_packets[pkt],
+ UDMA_RX_BUF_SIZE);
+ prueth->rx_next++;
+ }
+
+ return ret;
+}
+
+static void prueth_stop(struct udevice *dev)
+{
+ struct prueth_priv *priv = dev_get_priv(dev);
+ struct prueth *prueth = priv->prueth;
+
+ phy_shutdown(priv->phydev);
+
+ dma_disable(&prueth->dma_tx);
+ dma_disable(&prueth->dma_rx);
+
+ icssg_stop_pru_cores(dev);
+
+ dma_free(&prueth->dma_tx);
+ dma_free(&prueth->dma_rx);
+}
+
+static const struct eth_ops prueth_ops = {
+ .start = prueth_start,
+ .send = prueth_send,
+ .recv = prueth_recv,
+ .free_pkt = prueth_free_pkt,
+ .stop = prueth_stop,
+};
+
+static int icssg_ofdata_parse_phy(struct udevice *dev)
+{
+ struct prueth_priv *priv = dev_get_priv(dev);
+
+ dev_read_u32(dev, "reg", &priv->port_id);
+ priv->phy_interface = dev_read_phy_mode(dev);
+ if (priv->phy_interface == PHY_INTERFACE_MODE_NA) {
+ dev_err(dev, "Invalid PHY mode '%s', port %u\n",
+ phy_string_for_interface(priv->phy_interface),
+ priv->port_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int prueth_port_probe(struct udevice *dev)
+{
+ struct prueth_priv *priv = dev_get_priv(dev);
+ struct prueth *prueth;
+ char portname[15];
+ int ret;
+
+ priv->dev = dev;
+ prueth = dev_get_priv(dev->parent);
+ priv->prueth = prueth;
+
+ sprintf(portname, "%s-%s", dev->parent->name, dev->name);
+
+ device_set_name(dev, portname);
+
+ ret = icssg_ofdata_parse_phy(dev);
+ if (ret)
+ goto out;
+
+ ret = icssg_phy_init(dev);
+ if (ret)
+ goto out;
+
+ ret = pruss_request_mem_region(prueth->pruss,
+ priv->port_id ? PRUSS_MEM_DRAM1 : PRUSS_MEM_DRAM0,
+ &prueth->dram[priv->port_id]);
+ if (ret) {
+ dev_err(dev, "could not request DRAM%d region\n", priv->port_id);
+ return ret;
+ }
+out:
+ return ret;
+}
+
+static int prueth_probe(struct udevice *dev)
+{
+ ofnode node, pruss_node, mdio_node, sram_node, curr_sram_node;
+ struct prueth *prueth = dev_get_priv(dev);
+ u32 phandle, err, sp, prev_end_addr;
+ struct udevice **prussdev = NULL;
+ ofnode eth_ports_node, eth_node;
+ struct udevice *port_dev;
+ int ret = 0;
+
+ prueth->dev = dev;
+
+ err = ofnode_read_u32(dev_ofnode(dev), "ti,prus", &phandle);
+ if (err)
+ return err;
+
+ node = ofnode_get_by_phandle(phandle);
+ if (!ofnode_valid(node))
+ return -EINVAL;
+
+ pruss_node = ofnode_get_parent(node);
+ ret = device_get_global_by_ofnode(pruss_node, prussdev);
+ if (ret)
+ dev_err(dev, "error getting the pruss dev\n");
+ prueth->pruss = *prussdev;
+
+ ret = pruss_request_mem_region(*prussdev, PRUSS_MEM_SHRD_RAM2,
+ &prueth->shram);
+ if (ret)
+ return ret;
+
+ ret = pruss_request_tm_region(*prussdev, &prueth->tmaddr);
+ if (ret)
+ return ret;
+
+ prueth->miig_rt = syscon_regmap_lookup_by_phandle(dev, "ti,mii-g-rt");
+ if (!prueth->miig_rt) {
+ dev_err(dev, "couldn't get mii-g-rt syscon regmap\n");
+ return -ENODEV;
+ }
+
+ prueth->mii_rt = syscon_regmap_lookup_by_phandle(dev, "ti,mii-rt");
+ if (!prueth->mii_rt) {
+ dev_err(dev, "couldn't get mii-rt syscon regmap\n");
+ return -ENODEV;
+ }
+
+ ret = ofnode_read_u32(dev_ofnode(dev), "sram", &sp);
+ if (ret) {
+ dev_err(dev, "sram node fetch failed %d\n", ret);
+ return ret;
+ }
+
+ sram_node = ofnode_get_by_phandle(sp);
+ if (!ofnode_valid(sram_node))
+ return -EINVAL;
+
+ prev_end_addr = ofnode_get_addr(sram_node);
+
+ ofnode_for_each_subnode(curr_sram_node, sram_node) {
+ u32 start_addr, size, end_addr, avail;
+ const char *name;
+
+ name = ofnode_get_name(curr_sram_node);
+ start_addr = ofnode_get_addr(curr_sram_node);
+ size = ofnode_get_size(curr_sram_node);
+ end_addr = start_addr + size;
+ avail = start_addr - prev_end_addr;
+
+ if (avail > MSMC_RAM_SIZE)
+ break;
+
+ prev_end_addr = end_addr;
+ }
+
+ prueth->sram_pa = prev_end_addr;
+ if (prueth->sram_pa % SZ_64K != 0) {
+ /* This is constraint for SR2.0 firmware */
+ dev_err(dev, "sram address needs to be 64KB aligned\n");
+ return -EINVAL;
+ }
+ dev_dbg(dev, "sram: addr %x size %x\n", prueth->sram_pa, MSMC_RAM_SIZE);
+
+ mdio_node = ofnode_find_subnode(pruss_node, "mdio");
+ prueth->mdio_base = ofnode_get_addr(mdio_node);
+ ofnode_read_u32(mdio_node, "bus_freq", &prueth->mdio_freq);
+
+ ret = clk_get_by_name_nodev(mdio_node, "fck", &prueth->mdiofck);
+ if (ret) {
+ dev_err(dev, "failed to get clock %d\n", ret);
+ return ret;
+ }
+
+ ret = clk_enable(&prueth->mdiofck);
+ if (ret) {
+ dev_err(dev, "clk_enable failed %d\n", ret);
+ return ret;
+ }
+
+ eth_ports_node = dev_read_subnode(dev, "ethernet-ports");
+ if (!ofnode_valid(eth_ports_node))
+ return -ENOENT;
+
+ ofnode_for_each_subnode(eth_node, eth_ports_node) {
+ const char *node_name;
+ u32 port_id;
+ bool disabled;
+
+ node_name = ofnode_get_name(eth_node);
+ disabled = !ofnode_is_enabled(eth_node);
+ ret = ofnode_read_u32(eth_node, "reg", &port_id);
+ if (ret)
+ dev_err(dev, "%s: error reading port_id (%d)\n", node_name, ret);
+
+ if (port_id >= PRUETH_NUM_MACS) {
+ dev_err(dev, "%s: invalid port_id (%d)\n", node_name, port_id);
+ return -EINVAL;
+ }
+
+ if (port_id < 0)
+ continue;
+ if (disabled)
+ continue;
+
+ ret = device_bind_driver_to_node(dev, "prueth_port",
+ ofnode_get_name(eth_node),
+ eth_node, &port_dev);
+ if (ret) {
+ dev_err(dev, "Failed to bind to %s node\n", ofnode_get_name(eth_node));
+ goto out;
+ }
+ }
+
+ return 0;
+out:
+ clk_disable(&prueth->mdiofck);
+
+ return ret;
+}
+
+static const struct udevice_id prueth_ids[] = {
+ { .compatible = "ti,am654-icssg-prueth" },
+ { .compatible = "ti,am642-icssg-prueth" },
+ { }
+};
+
+U_BOOT_DRIVER(prueth) = {
+ .name = "prueth",
+ .id = UCLASS_MISC,
+ .of_match = prueth_ids,
+ .probe = prueth_probe,
+ .priv_auto = sizeof(struct prueth),
+};
+
+U_BOOT_DRIVER(prueth_port) = {
+ .name = "prueth_port",
+ .id = UCLASS_ETH,
+ .probe = prueth_port_probe,
+ .ops = &prueth_ops,
+ .priv_auto = sizeof(struct prueth_priv),
+ .plat_auto = sizeof(struct eth_pdata),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
diff --git a/drivers/net/ti/icssg_prueth.h b/drivers/net/ti/icssg_prueth.h
new file mode 100644
index 0000000..c69cfd4
--- /dev/null
+++ b/drivers/net/ti/icssg_prueth.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Texas Instruments K3 AM65 Ethernet Switch SubSystem Driver
+ *
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+#ifndef __NET_TI_ICSSG_PRUETH_H
+#define __NET_TI_ICSSG_PRUETH_H
+
+#include <asm/io.h>
+#include <clk.h>
+#include <dm/lists.h>
+#include <dm/ofnode.h>
+#include <dm/device.h>
+#include <dma-uclass.h>
+#include <regmap.h>
+#include <linux/sizes.h>
+#include <linux/pruss_driver.h>
+#include "icssg_config.h"
+#include "icssg_switch_map.h"
+
+void icssg_class_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac);
+void icssg_class_set_host_mac_addr(struct regmap *miig_rt, u8 *mac);
+void icssg_class_disable(struct regmap *miig_rt, int slice);
+void icssg_class_default(struct regmap *miig_rt, int slice, bool allmulti);
+void icssg_ft1_set_mac_addr(struct regmap *miig_rt, int slice, u8 *mac_addr);
+
+enum prueth_mac {
+ PRUETH_MAC0 = 0,
+ PRUETH_MAC1,
+ PRUETH_NUM_MACS,
+};
+
+enum prueth_port {
+ PRUETH_PORT_HOST = 0, /* host side port */
+ PRUETH_PORT_MII0, /* physical port MII 0 */
+ PRUETH_PORT_MII1, /* physical port MII 1 */
+};
+
+struct prueth {
+ struct udevice *dev;
+ struct udevice *pruss;
+ struct regmap *miig_rt;
+ struct regmap *mii_rt;
+ fdt_addr_t mdio_base;
+ struct pruss_mem_region shram;
+ struct pruss_mem_region dram[PRUETH_NUM_MACS];
+ phys_addr_t tmaddr;
+ struct mii_dev *bus;
+ u32 sram_pa;
+ ofnode eth_node[PRUETH_NUM_MACS];
+ u32 mdio_freq;
+ int phy_interface;
+ struct clk mdiofck;
+ struct dma dma_tx;
+ struct dma dma_rx;
+ struct dma dma_rx_mgm;
+ u32 rx_next;
+ u32 rx_pend;
+ int slice;
+ bool mdio_manual_mode;
+ int speed;
+ int duplex;
+ u8 pru_core_id;
+ u8 rtu_core_id;
+ u8 txpru_core_id;
+ u8 icssg_hwcmdseq;
+};
+
+struct prueth_priv {
+ struct udevice *dev;
+ struct prueth *prueth;
+ u32 port_id;
+ struct phy_device *phydev;
+ bool has_phy;
+ ofnode phy_node;
+ u32 phy_addr;
+ int phy_interface;
+};
+
+/* config helpers */
+void icssg_config_ipg(struct prueth_priv *priv, int speed, int mii);
+int icssg_config(struct prueth_priv *priv);
+int emac_set_port_state(struct prueth_priv *priv, enum icssg_port_state_cmd cmd);
+
+/* Buffer queue helpers */
+int icssg_queue_pop(struct prueth *prueth, u8 queue);
+void icssg_queue_push(struct prueth *prueth, int queue, u16 addr);
+u32 icssg_queue_level(struct prueth *prueth, int queue);
+
+/* FDB helpers */
+int icssg_send_fdb_msg(struct prueth_priv *priv, struct mgmt_cmd *cmd,
+ struct mgmt_cmd_rsp *rsp);
+int emac_fdb_flow_id_updated(struct prueth_priv *priv);
+
+#endif /* __NET_TI_ICSSG_PRUETH_H */
diff --git a/drivers/net/ti/icssg_queues.c b/drivers/net/ti/icssg_queues.c
new file mode 100644
index 0000000..fc4d33d
--- /dev/null
+++ b/drivers/net/ti/icssg_queues.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0
+/* ICSSG Buffer queue helpers
+ *
+ * Copyright (C) 2018-2024 Texas Instruments Incorporated - https://www.ti.com
+ */
+
+#include <dm/ofnode.h>
+#include <regmap.h>
+#include "icssg_prueth.h"
+
+#define ICSSG_QUEUES_MAX 64
+#define ICSSG_QUEUE_OFFSET 0xd00
+#define ICSSG_QUEUE_PEEK_OFFSET 0xe00
+#define ICSSG_QUEUE_CNT_OFFSET 0xe40
+#define ICSSG_QUEUE_RESET_OFFSET 0xf40
+
+int icssg_queue_pop(struct prueth *prueth, u8 queue)
+{
+ u32 val, cnt;
+
+ if (queue >= ICSSG_QUEUES_MAX)
+ return -EINVAL;
+
+ regmap_read(prueth->miig_rt, ICSSG_QUEUE_CNT_OFFSET + 4 * queue, &cnt);
+ if (!cnt)
+ return -EINVAL;
+
+ regmap_read(prueth->miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue, &val);
+
+ return val;
+}
+
+void icssg_queue_push(struct prueth *prueth, int queue, u16 addr)
+{
+ if (queue >= ICSSG_QUEUES_MAX)
+ return;
+
+ regmap_write(prueth->miig_rt, ICSSG_QUEUE_OFFSET + 4 * queue, addr);
+}
+
+u32 icssg_queue_level(struct prueth *prueth, int queue)
+{
+ u32 reg;
+
+ if (queue >= ICSSG_QUEUES_MAX)
+ return 0;
+
+ regmap_read(prueth->miig_rt, ICSSG_QUEUE_CNT_OFFSET + 4 * queue, ®);
+
+ return reg;
+}
diff --git a/drivers/net/ti/icssg_switch_map.h b/drivers/net/ti/icssg_switch_map.h
new file mode 100644
index 0000000..b62c514
--- /dev/null
+++ b/drivers/net/ti/icssg_switch_map.h
@@ -0,0 +1,209 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Texas Instruments ICSSG Ethernet driver
+ *
+ * Copyright (C) 2020-2024 Texas Instruments Incorporated - https://www.ti.com/
+ *
+ */
+
+#ifndef __NET_TI_ICSSG_SWITCH_MAP_H
+#define __NET_TI_ICSSG_SWITCH_MAP_H
+
+/*Time after which FDB entries are checked for aged out values. Value in nanoseconds*/
+#define FDB_AGEING_TIMEOUT_OFFSET 0x0014
+
+/*default VLAN tag for Host Port*/
+#define HOST_PORT_DF_VLAN_OFFSET 0x001C
+
+/*Same as HOST_PORT_DF_VLAN_OFFSET*/
+#define EMAC_ICSSG_SWITCH_PORT0_DEFAULT_VLAN_OFFSET HOST_PORT_DF_VLAN_OFFSET
+
+/*default VLAN tag for P1 Port*/
+#define P1_PORT_DF_VLAN_OFFSET 0x0020
+
+/*Same as P1_PORT_DF_VLAN_OFFSET*/
+#define EMAC_ICSSG_SWITCH_PORT1_DEFAULT_VLAN_OFFSET P1_PORT_DF_VLAN_OFFSET
+
+/*default VLAN tag for P2 Port*/
+#define P2_PORT_DF_VLAN_OFFSET 0x0024
+
+/*Same as P2_PORT_DF_VLAN_OFFSET*/
+#define EMAC_ICSSG_SWITCH_PORT2_DEFAULT_VLAN_OFFSET P2_PORT_DF_VLAN_OFFSET
+
+/*VLAN-FID Table offset. 4096 VIDs. 2B per VID = 8KB = 0x2000*/
+#define VLAN_STATIC_REG_TABLE_OFFSET 0x0100
+
+/*VLAN-FID Table offset for EMAC*/
+#define EMAC_ICSSG_SWITCH_DEFAULT_VLAN_TABLE_OFFSET VLAN_STATIC_REG_TABLE_OFFSET
+
+/*packet descriptor Q reserved memory*/
+#define PORT_DESC0_HI 0x2104
+
+/*packet descriptor Q reserved memory*/
+#define PORT_DESC0_LO 0x2F6C
+
+/*packet descriptor Q reserved memory*/
+#define PORT_DESC1_HI 0x3DD4
+
+/*packet descriptor Q reserved memory*/
+#define PORT_DESC1_LO 0x4C3C
+
+/*packet descriptor Q reserved memory*/
+#define HOST_DESC0_HI 0x5AA4
+
+/*packet descriptor Q reserved memory*/
+#define HOST_DESC0_LO 0x5F0C
+
+/*packet descriptor Q reserved memory*/
+#define HOST_DESC1_HI 0x6374
+
+/*packet descriptor Q reserved memory*/
+#define HOST_DESC1_LO 0x67DC
+
+/*special packet descriptor Q reserved memory*/
+#define HOST_SPPD0 0x7AAC
+
+/*special packet descriptor Q reserved memory*/
+#define HOST_SPPD1 0x7EAC
+
+/*_Small_Description_*/
+#define TIMESYNC_FW_WC_CYCLECOUNT_OFFSET 0x83EC
+
+/*IEP count hi roll over count*/
+#define TIMESYNC_FW_WC_HI_ROLLOVER_COUNT_OFFSET 0x83F4
+
+/*_Small_Description_*/
+#define TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET 0x83F8
+
+/*Set clock descriptor*/
+#define TIMESYNC_FW_WC_SETCLOCK_DESC_OFFSET 0x83FC
+
+/*_Small_Description_*/
+#define TIMESYNC_FW_WC_SYNCOUT_REDUCTION_FACTOR_OFFSET 0x843C
+
+/*_Small_Description_*/
+#define TIMESYNC_FW_WC_SYNCOUT_REDUCTION_COUNT_OFFSET 0x8440
+
+/*_Small_Description_*/
+#define TIMESYNC_FW_WC_SYNCOUT_START_TIME_CYCLECOUNT_OFFSET 0x8444
+
+/*Control variable to generate SYNC1*/
+#define TIMESYNC_FW_WC_ISOM_PIN_SIGNAL_EN_OFFSET 0x844C
+
+/*SystemTime Sync0 periodicity*/
+#define TIMESYNC_FW_ST_SYNCOUT_PERIOD_OFFSET 0x8450
+
+/*pktTxDelay for P1 = link speed dependent p1 mac delay + p1 phy delay*/
+#define TIMESYNC_FW_WC_PKTTXDELAY_P1_OFFSET 0x8454
+
+/*pktTxDelay for P2 = link speed dependent p2 mac delay + p2 phy delay*/
+#define TIMESYNC_FW_WC_PKTTXDELAY_P2_OFFSET 0x8458
+
+/*Set clock operation done signal for next task*/
+#define TIMESYNC_FW_SIG_PNFW_OFFSET 0x845C
+
+/*Set clock operation done signal for next task*/
+#define TIMESYNC_FW_SIG_TIMESYNCFW_OFFSET 0x8460
+
+/*New list is copied at this time*/
+#define TAS_CONFIG_CHANGE_TIME 0x000C
+
+/*config change error counter*/
+#define TAS_CONFIG_CHANGE_ERROR_COUNTER 0x0014
+
+/*TAS List update pending flag*/
+#define TAS_CONFIG_PENDING 0x0018
+
+/*TAS list update trigger flag*/
+#define TAS_CONFIG_CHANGE 0x0019
+
+/*List length for new TAS schedule*/
+#define TAS_ADMIN_LIST_LENGTH 0x001A
+
+/*Currently active TAS list index*/
+#define TAS_ACTIVE_LIST_INDEX 0x001B
+
+/*Cycle time for the new TAS schedule*/
+#define TAS_ADMIN_CYCLE_TIME 0x001C
+
+/*Cycle counts remaining till the TAS list update*/
+#define TAS_CONFIG_CHANGE_CYCLE_COUNT 0x0020
+
+/*Base Flow ID for sending packets to Host for Slice0*/
+#define PSI_L_REGULAR_FLOW_ID_BASE_OFFSET 0x0024
+
+/*Same as PSI_L_REGULAR_FLOW_ID_BASE_OFFSET*/
+#define EMAC_ICSSG_SWITCH_PSI_L_REGULAR_FLOW_ID_BASE_OFFSET PSI_L_REGULAR_FLOW_ID_BASE_OFFSET
+
+/*Base Flow ID for sending mgmt and Tx TS to Host for Slice0*/
+#define PSI_L_MGMT_FLOW_ID_OFFSET 0x0026
+
+/*Same as PSI_L_MGMT_FLOW_ID_OFFSET*/
+#define EMAC_ICSSG_SWITCH_PSI_L_MGMT_FLOW_ID_BASE_OFFSET PSI_L_MGMT_FLOW_ID_OFFSET
+
+/*Queue number for Special packets written here*/
+#define SPL_PKT_DEFAULT_PRIORITY 0x0028
+
+/*Express Preemptible Queue Mask*/
+#define EXPRESS_PRE_EMPTIVE_Q_MASK 0x0029
+
+/*Port1/Port2 Default Queue number for untagged packets, only 1B is used*/
+#define QUEUE_NUM_UNTAGGED 0x002A
+
+/*Stores the table used for priority regeneration. 1B per PCP/Queue*/
+#define PORT_Q_PRIORITY_REGEN_OFFSET 0x002C
+
+/* For marking Packet as priority/express (this feature is disabled) or
+ * cut-through/S&F.
+ */
+#define EXPRESS_PRE_EMPTIVE_Q_MAP 0x0034
+
+/*Stores the table used for priority mapping. 1B per PCP/Queue*/
+#define PORT_Q_PRIORITY_MAPPING_OFFSET 0x003C
+
+/*TAS gate mask for windows list0*/
+#define TAS_GATE_MASK_LIST0 0x0100
+
+/*TAS gate mask for windows list1*/
+#define TAS_GATE_MASK_LIST1 0x0350
+
+/*Memory to Enable/Disable Preemption on TX side*/
+#define PRE_EMPTION_ENABLE_TX 0x05A0
+
+/*Active State of Preemption on TX side*/
+#define PRE_EMPTION_ACTIVE_TX 0x05A1
+
+/*Memory to Enable/Disable Verify State Machine Preemption*/
+#define PRE_EMPTION_ENABLE_VERIFY 0x05A2
+
+/*Verify Status of State Machine*/
+#define PRE_EMPTION_VERIFY_STATUS 0x05A3
+
+/*Non Final Fragment Size supported by Link Partner*/
+#define PRE_EMPTION_ADD_FRAG_SIZE_REMOTE 0x05A4
+
+/*Non Final Fragment Size supported by Firmware*/
+#define PRE_EMPTION_ADD_FRAG_SIZE_LOCAL 0x05A6
+
+/*Time in ms the State machine waits for respond packet*/
+#define PRE_EMPTION_VERIFY_TIME 0x05A8
+
+/*Memory used for R30 related management commands*/
+#define MGR_R30_CMD_OFFSET 0x05AC
+
+/*HW Buffer Pool0 base address*/
+#define BUFFER_POOL_0_ADDR_OFFSET 0x05BC
+
+/*16B for Host Egress MSMC Q (Pre-emptible) context*/
+#define HOST_RX_Q_PRE_CONTEXT_OFFSET 0x0684
+
+/*Buffer for 8 FDB entries to be added by 'Add Multiple FDB entries IOCTL*/
+#define FDB_CMD_BUFFER 0x0894
+
+/*16B for Host Egress MSMC Q (Express) context*/
+#define HOST_RX_Q_EXP_CONTEXT_OFFSET 0x0940
+
+/*Start of 32 bits PA_STAT counters*/
+#define PA_STAT_32b_START_OFFSET 0x0080
+
+#endif
+/* __NET_TI_ICSSG_SWITCH_MAP_H */
diff --git a/drivers/rtc/goldfish_rtc.c b/drivers/rtc/goldfish_rtc.c
index 1ace990..3231eb0 100644
--- a/drivers/rtc/goldfish_rtc.c
+++ b/drivers/rtc/goldfish_rtc.c
@@ -72,7 +72,7 @@
return 0;
}
-int goldfish_rtc_probe(struct udevice *dev)
+static int goldfish_rtc_probe(struct udevice *dev)
{
struct goldfish_rtc *priv = dev_get_priv(dev);
fdt_addr_t addr;
diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c
index ce08a6b..3f2be72 100644
--- a/drivers/serial/serial_lpuart.c
+++ b/drivers/serial/serial_lpuart.c
@@ -109,28 +109,35 @@
}
#if CONFIG_IS_ENABLED(CLK)
-static int get_lpuart_clk_rate(struct udevice *dev, u32 *clk)
+static int get_lpuart_clk_rate(struct udevice *dev, u32 *clk_rate)
{
- struct clk per_clk;
+ struct lpuart_serial_plat *plat = dev_get_plat(dev);
+ struct clk clk;
ulong rate;
int ret;
+ char *name;
- ret = clk_get_by_name(dev, "per", &per_clk);
+ if (plat->devtype == DEV_MX7ULP)
+ name = "ipg";
+ else
+ name = "per";
+
+ ret = clk_get_by_name(dev, name, &clk);
if (ret) {
- dev_err(dev, "Failed to get per clk: %d\n", ret);
+ dev_err(dev, "Failed to get clk: %d\n", ret);
return ret;
}
- rate = clk_get_rate(&per_clk);
+ rate = clk_get_rate(&clk);
if ((long)rate <= 0) {
- dev_err(dev, "Failed to get per clk rate: %ld\n", (long)rate);
+ dev_err(dev, "Failed to get clk rate: %ld\n", (long)rate);
return ret;
}
- *clk = rate;
+ *clk_rate = rate;
return 0;
}
#else
-static inline int get_lpuart_clk_rate(struct udevice *dev, u32 *clk)
+static inline int get_lpuart_clk_rate(struct udevice *dev, u32 *clk_rate)
{ return -ENOSYS; }
#endif
@@ -479,19 +486,22 @@
static int lpuart_serial_probe(struct udevice *dev)
{
#if CONFIG_IS_ENABLED(CLK)
+ struct lpuart_serial_plat *plat = dev_get_plat(dev);
struct clk per_clk;
struct clk ipg_clk;
int ret;
- ret = clk_get_by_name(dev, "per", &per_clk);
- if (!ret) {
- ret = clk_enable(&per_clk);
- if (ret) {
- dev_err(dev, "Failed to enable per clk: %d\n", ret);
- return ret;
+ if (plat->devtype != DEV_MX7ULP) {
+ ret = clk_get_by_name(dev, "per", &per_clk);
+ if (!ret) {
+ ret = clk_enable(&per_clk);
+ if (ret) {
+ dev_err(dev, "Failed to enable per clk: %d\n", ret);
+ return ret;
+ }
+ } else {
+ debug("%s: Failed to get per clk: %d\n", __func__, ret);
}
- } else {
- debug("%s: Failed to get per clk: %d\n", __func__, ret);
}
ret = clk_get_by_name(dev, "ipg", &ipg_clk);
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c
index b6197da..35df413 100644
--- a/drivers/serial/serial_xuartlite.c
+++ b/drivers/serial/serial_xuartlite.c
@@ -23,7 +23,7 @@
#define ULITE_CONTROL_RST_TX 0x01
#define ULITE_CONTROL_RST_RX 0x02
-static bool little_endian;
+static bool little_endian __section(".data");
struct uartlite {
unsigned int rx_fifo;
diff --git a/drivers/soc/soc_xilinx_zynqmp.c b/drivers/soc/soc_xilinx_zynqmp.c
index 786825d..d8b4f17 100644
--- a/drivers/soc/soc_xilinx_zynqmp.c
+++ b/drivers/soc/soc_xilinx_zynqmp.c
@@ -44,6 +44,7 @@
ZYNQMP_VARIANT_DR = BIT(3),
ZYNQMP_VARIANT_DR_SE = BIT(4),
ZYNQMP_VARIANT_EG_SE = BIT(5),
+ ZYNQMP_VARIANT_TEG = BIT(6),
};
struct zynqmp_device {
@@ -75,6 +76,11 @@
.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
},
{
+ .id = 0x04718093,
+ .device = 3,
+ .variants = ZYNQMP_VARIANT_TEG,
+ },
+ {
.id = 0x04721093,
.device = 4,
.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
@@ -299,6 +305,8 @@
strlcat(priv->machine, "dr", sizeof(priv->machine));
} else if (device->variants & ZYNQMP_VARIANT_DR_SE) {
strlcat(priv->machine, "dr_SE", sizeof(priv->machine));
+ } else if (device->variants & ZYNQMP_VARIANT_TEG) {
+ strlcat(priv->machine, "teg", sizeof(priv->machine));
}
return 0;
diff --git a/drivers/sysreset/sysreset-ti-sci.c b/drivers/sysreset/sysreset-ti-sci.c
index 5fc05c4..0de1326 100644
--- a/drivers/sysreset/sysreset-ti-sci.c
+++ b/drivers/sysreset/sysreset-ti-sci.c
@@ -60,15 +60,9 @@
.request = ti_sci_sysreset_request,
};
-static const struct udevice_id ti_sci_sysreset_of_match[] = {
- { .compatible = "ti,sci-sysreset", },
- { /* sentinel */ },
-};
-
U_BOOT_DRIVER(ti_sci_sysreset) = {
.name = "ti-sci-sysreset",
.id = UCLASS_SYSRESET,
- .of_match = ti_sci_sysreset_of_match,
.probe = ti_sci_sysreset_probe,
.priv_auto = sizeof(struct ti_sci_sysreset_data),
.ops = &ti_sci_sysreset_ops,
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index b60661f..910c5f3 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -685,6 +685,9 @@
reset_ep(udev, ep_index);
ring = virt_dev->eps[ep_index].ring;
+ if (!ring)
+ return -EINVAL;
+
/*
* How much data is (potentially) left before the 64KB boundary?
* XHCI Spec puts restriction( TABLE 49 and 6.4.1 section of XHCI Spec)
@@ -871,6 +874,8 @@
ep_index = usb_pipe_ep_index(pipe);
ep_ring = virt_dev->eps[ep_index].ring;
+ if (!ep_ring)
+ return -EINVAL;
/*
* Check to see if the max packet size for the default control
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d13cbff..741e186 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -475,67 +475,34 @@
}
/**
- * Configure the endpoint, programming the device contexts.
+ * Fill endpoint contexts for interface descriptor ifdesc.
*
- * @param udev pointer to the USB device structure
- * Return: returns the status of the xhci_configure_endpoints
+ * @param udev pointer to the USB device structure
+ * @param ctrl pointer to the xhci pravte device structure
+ * @param virt_dev pointer to the xhci virtual device structure
+ * @param ifdesc pointer to the USB interface config descriptor
+ * Return: returns the status of xhci_init_ep_contexts_if
*/
-static int xhci_set_configuration(struct usb_device *udev)
+static int xhci_init_ep_contexts_if(struct usb_device *udev,
+ struct xhci_ctrl *ctrl,
+ struct xhci_virt_device *virt_dev,
+ struct usb_interface *ifdesc
+ )
{
- struct xhci_container_ctx *in_ctx;
- struct xhci_container_ctx *out_ctx;
- struct xhci_input_control_ctx *ctrl_ctx;
- struct xhci_slot_ctx *slot_ctx;
struct xhci_ep_ctx *ep_ctx[MAX_EP_CTX_NUM];
int cur_ep;
- int max_ep_flag = 0;
int ep_index;
unsigned int dir;
unsigned int ep_type;
- struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
- int num_of_ep;
- int ep_flag = 0;
u64 trb_64 = 0;
- int slot_id = udev->slot_id;
- struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
- struct usb_interface *ifdesc;
u32 max_esit_payload;
unsigned int interval;
unsigned int mult;
unsigned int max_burst;
unsigned int avg_trb_len;
unsigned int err_count = 0;
-
- out_ctx = virt_dev->out_ctx;
- in_ctx = virt_dev->in_ctx;
-
- num_of_ep = udev->config.if_desc[0].no_of_ep;
- ifdesc = &udev->config.if_desc[0];
-
- ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
- /* Initialize the input context control */
- ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
- ctrl_ctx->drop_flags = 0;
+ int num_of_ep = ifdesc->no_of_ep;
- /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
- for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
- ep_flag = xhci_get_ep_index(&ifdesc->ep_desc[cur_ep]);
- ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
- if (max_ep_flag < ep_flag)
- max_ep_flag = ep_flag;
- }
-
- xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
-
- /* slot context */
- xhci_slot_copy(ctrl, in_ctx, out_ctx);
- slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx);
- slot_ctx->dev_info &= ~(cpu_to_le32(LAST_CTX_MASK));
- slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(max_ep_flag + 1) | 0);
-
- xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
-
- /* filling up ep contexts */
for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
struct usb_endpoint_descriptor *endpt_desc = NULL;
struct usb_ss_ep_comp_descriptor *ss_ep_comp_desc = NULL;
@@ -561,7 +528,8 @@
avg_trb_len = max_esit_payload;
ep_index = xhci_get_ep_index(endpt_desc);
- ep_ctx[ep_index] = xhci_get_ep_ctx(ctrl, in_ctx, ep_index);
+ ep_ctx[ep_index] = xhci_get_ep_ctx(ctrl, virt_dev->in_ctx,
+ ep_index);
/* Allocate the ep rings */
virt_dev->eps[ep_index].ring = xhci_ring_alloc(ctrl, 1, true);
@@ -614,6 +582,72 @@
}
}
+ return 0;
+}
+
+/**
+ * Configure the endpoint, programming the device contexts.
+ *
+ * @param udev pointer to the USB device structure
+ * Return: returns the status of the xhci_configure_endpoints
+ */
+static int xhci_set_configuration(struct usb_device *udev)
+{
+ struct xhci_container_ctx *out_ctx;
+ struct xhci_container_ctx *in_ctx;
+ struct xhci_input_control_ctx *ctrl_ctx;
+ struct xhci_slot_ctx *slot_ctx;
+ int err;
+ int cur_ep;
+ int max_ep_flag = 0;
+ struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
+ int num_of_ep;
+ int ep_flag = 0;
+ int slot_id = udev->slot_id;
+ struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
+ struct usb_interface *ifdesc;
+ unsigned int ifnum;
+ unsigned int max_ifnum = min((unsigned int)USB_MAX_ACTIVE_INTERFACES,
+ (unsigned int)udev->config.no_of_if);
+
+ out_ctx = virt_dev->out_ctx;
+ in_ctx = virt_dev->in_ctx;
+
+ ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
+ /* Initialize the input context control */
+ ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
+ ctrl_ctx->drop_flags = 0;
+
+ for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
+ ifdesc = &udev->config.if_desc[ifnum];
+ num_of_ep = ifdesc->no_of_ep;
+ /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
+ for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
+ ep_flag = xhci_get_ep_index(&ifdesc->ep_desc[cur_ep]);
+ ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
+ if (max_ep_flag < ep_flag)
+ max_ep_flag = ep_flag;
+ }
+ }
+
+ xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
+
+ /* slot context */
+ xhci_slot_copy(ctrl, in_ctx, out_ctx);
+ slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx);
+ slot_ctx->dev_info &= ~(cpu_to_le32(LAST_CTX_MASK));
+ slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(max_ep_flag + 1) | 0);
+
+ xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
+
+ /* filling up ep contexts */
+ for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
+ ifdesc = &udev->config.if_desc[ifnum];
+ err = xhci_init_ep_contexts_if(udev, ctrl, virt_dev, ifdesc);
+ if (err < 0)
+ return err;
+ }
+
return xhci_configure_endpoints(udev, false);
}
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6f319ba..39c8252 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -180,6 +180,7 @@
config CONSOLE_TRUETYPE
bool "Support a console that uses TrueType fonts"
+ select X86_HARDFP if X86
help
TrueTrype fonts can provide outline-drawing capability rather than
needing to provide a bitmap for each font and size that is needed.
diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
index 362458a..28665a3 100644
--- a/drivers/video/console_truetype.c
+++ b/drivers/video/console_truetype.c
@@ -8,6 +8,7 @@
#include <dm.h>
#include <log.h>
#include <malloc.h>
+#include <spl.h>
#include <video.h>
#include <video_console.h>
@@ -802,6 +803,9 @@
struct console_tt_store store;
const uint size = sizeof(store);
+ if (spl_phase() <= PHASE_SPL)
+ return -ENOSYS;
+
/*
* store the whole priv structure as it is simpler that picking out
* what we need
@@ -823,6 +827,9 @@
struct console_tt_priv *priv = dev_get_priv(dev);
struct console_tt_store store;
+ if (spl_phase() <= PHASE_SPL)
+ return -ENOSYS;
+
memcpy(&store, abuf_data(buf), sizeof(store));
vc_priv->xcur_frac = store.cur.xpos_frac;
@@ -847,6 +854,9 @@
uint out, val;
int ret;
+ if (spl_phase() <= PHASE_SPL)
+ return -ENOSYS;
+
if (!visible)
return 0;
diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c
index 5f89f6a..5d06e51 100644
--- a/drivers/video/vidconsole-uclass.c
+++ b/drivers/video/vidconsole-uclass.c
@@ -126,6 +126,7 @@
priv->xcur_frac = VID_TO_POS(x);
priv->xstart_frac = priv->xcur_frac;
priv->ycur = y;
+ vidconsole_entry_start(dev);
}
/**
@@ -135,8 +136,10 @@
* @row: new row
* @col: new column
*/
-static void set_cursor_position(struct vidconsole_priv *priv, int row, int col)
+static void set_cursor_position(struct udevice *dev, int row, int col)
{
+ struct vidconsole_priv *priv = dev_get_uclass_priv(dev);
+
/*
* Ensure we stay in the bounds of the screen.
*/
@@ -145,9 +148,7 @@
if (col >= priv->cols)
col = priv->cols - 1;
- priv->ycur = row * priv->y_charsize;
- priv->xcur_frac = priv->xstart_frac +
- VID_TO_POS(col * priv->x_charsize);
+ vidconsole_position_cursor(dev, col, row);
}
/**
@@ -194,7 +195,7 @@
int row = priv->row_saved;
int col = priv->col_saved;
- set_cursor_position(priv, row, col);
+ set_cursor_position(dev, row, col);
priv->escape = 0;
return;
}
@@ -256,7 +257,7 @@
if (row < 0)
row = 0;
/* Right and bottom overflows are handled in the callee. */
- set_cursor_position(priv, row, col);
+ set_cursor_position(dev, row, col);
break;
}
case 'H':
@@ -280,7 +281,7 @@
if (col)
--col;
- set_cursor_position(priv, row, col);
+ set_cursor_position(dev, row, col);
break;
}
diff --git a/env/Kconfig b/env/Kconfig
index 7885c8b..1f8e90af 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -472,7 +472,7 @@
string "Device and partition for where to store the environemt in FAT"
depends on ENV_IS_IN_FAT
default "0:1" if TI_COMMON_CMD_OPTIONS
- default "0:auto" if ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL
+ default "0:auto" if ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET
default ":auto" if ARCH_SUNXI
default "0" if ARCH_AT91
help
diff --git a/fs/ext4/ext4_common.c b/fs/ext4/ext4_common.c
index 365c514..2ff0dca 100644
--- a/fs/ext4/ext4_common.c
+++ b/fs/ext4/ext4_common.c
@@ -765,11 +765,6 @@
struct ext2_inode *first_inode = NULL;
struct ext2_inode temp_inode;
- if (*dirname != '/') {
- printf("Please supply Absolute path\n");
- return -1;
- }
-
/* TODO: input validation make equivalent to linux */
depth_dirname = zalloc(strlen(dirname) + 1);
if (!depth_dirname)
diff --git a/fs/ext4/ext4_journal.c b/fs/ext4/ext4_journal.c
index 1a340b4..e80f797 100644
--- a/fs/ext4/ext4_journal.c
+++ b/fs/ext4/ext4_journal.c
@@ -430,7 +430,7 @@
printf("Recovery required\n");
} else {
if (recovery_flag == RECOVER)
- printf("File System is consistent\n");
+ log_debug("File System is consistent\n");
goto end;
}
diff --git a/fs/ext4/ext4_write.c b/fs/ext4/ext4_write.c
index ea4c5d4..d057f6b 100644
--- a/fs/ext4/ext4_write.c
+++ b/fs/ext4/ext4_write.c
@@ -847,6 +847,7 @@
{
int ret = 0;
struct ext2_inode *file_inode = NULL;
+ struct ext2_inode *existing_file_inode = NULL;
unsigned char *inode_buffer = NULL;
int parent_inodeno;
int inodeno;
@@ -900,6 +901,15 @@
/* check if the filename is already present in root */
existing_file_inodeno = ext4fs_filename_unlink(filename);
if (existing_file_inodeno != -1) {
+ existing_file_inode = (struct ext2_inode *)zalloc(fs->inodesz);
+ if (!existing_file_inode)
+ goto fail;
+ ret = ext4fs_iget(existing_file_inodeno, existing_file_inode);
+ if (ret) {
+ free(existing_file_inode);
+ goto fail;
+ }
+
ret = ext4fs_delete_file(existing_file_inodeno);
fs->first_pass_bbmap = 0;
fs->curr_blkno = 0;
@@ -948,9 +958,15 @@
sizebytes = 0;
}
} else {
- file_inode->mode = cpu_to_le16(S_IFREG | S_IRWXU | S_IRGRP |
- S_IROTH | S_IXGRP | S_IXOTH);
+ if (existing_file_inode) {
+ file_inode->mode = existing_file_inode->mode;
+ } else {
+ file_inode->mode = cpu_to_le16(S_IFREG | S_IRWXU | S_IRGRP |
+ S_IROTH | S_IXGRP | S_IXOTH);
+ }
}
+ if (existing_file_inode)
+ free(existing_file_inode);
/* ToDo: Update correct time */
file_inode->mtime = cpu_to_le32(timestamp);
file_inode->atime = cpu_to_le32(timestamp);
diff --git a/fs/zfs/dev.c b/fs/zfs/dev.c
index 251e7d1..fcd9893 100644
--- a/fs/zfs/dev.c
+++ b/fs/zfs/dev.c
@@ -26,5 +26,5 @@
int zfs_devread(int sector, int byte_offset, int byte_len, char *buf)
{
return fs_devread(zfs_blk_desc, part_info, sector, byte_offset,
- byte_len, buf);
+ byte_len, buf) ? 0 : 1;
}
diff --git a/fs/zfs/zfs.c b/fs/zfs/zfs.c
index 1fec96c..bfc11fa 100644
--- a/fs/zfs/zfs.c
+++ b/fs/zfs/zfs.c
@@ -655,7 +655,7 @@
dn->endian)
<< SPA_MINBLOCKSHIFT;
*buf = malloc(size);
- if (*buf) {
+ if (!*buf) {
err = ZFS_ERR_OUT_OF_MEMORY;
break;
}
@@ -1559,6 +1559,10 @@
return 0;
}
+int is_word_aligned_ptr(void *ptr) {
+ return ((uintptr_t)ptr & (sizeof(void *) - 1)) == 0;
+}
+
int
zfs_nvlist_lookup_uint64(char *nvlist, char *name, uint64_t *out)
{
@@ -1574,6 +1578,20 @@
return ZFS_ERR_BAD_FS;
}
+ /* On arm64, calling be64_to_cpu() on a value stored at a memory address
+ * that's not 8-byte aligned causes the CPU to reset. Avoid that by copying the
+ * value somewhere else if needed.
+ */
+ if (!is_word_aligned_ptr((void *)nvpair)) {
+ uint64_t *alignedptr = malloc(sizeof(uint64_t));
+ if (!alignedptr)
+ return 0;
+ memcpy(alignedptr, nvpair, sizeof(uint64_t));
+ *out = be64_to_cpu(*alignedptr);
+ free(alignedptr);
+ return 1;
+ }
+
*out = be64_to_cpu(*(uint64_t *) nvpair);
return 1;
}
@@ -1617,6 +1635,11 @@
&size, 0);
if (!found)
return 0;
+
+ /* Allocate 12 bytes in addition to the nvlist size: One uint32 before the
+ * nvlist to hold the encoding method, and two zero uint32's after the
+ * nvlist as the NULL terminator.
+ */
ret = calloc(1, size + 3 * sizeof(uint32_t));
if (!ret)
return 0;
@@ -2112,7 +2135,7 @@
* Find requested blkid and the offset within that block.
*/
uint64_t blkid = file->offset + red;
- blkid = do_div(blkid, blksz);
+ uint64_t blkoff = do_div(blkid, blksz);
free(data->file_buf);
data->file_buf = 0;
@@ -2127,8 +2150,7 @@
movesize = min(length, data->file_end - (int)file->offset - red);
- memmove(buf, data->file_buf + file->offset + red
- - data->file_start, movesize);
+ memmove(buf, data->file_buf + blkoff, movesize);
buf += movesize;
length -= movesize;
red += movesize;
diff --git a/include/bootm.h b/include/bootm.h
index 9e0f8d6..6983375 100644
--- a/include/bootm.h
+++ b/include/bootm.h
@@ -273,21 +273,24 @@
int bootm_process_cmdline_env(int flags);
/**
- * zboot_start() - Boot a zimage
+ * zboot_run() - Run through the various steps to boot a zimage
*
* Boot a zimage, given the component parts
*
* @addr: Address where the bzImage is moved before booting, either
* BZIMAGE_LOAD_ADDR or ZIMAGE_LOAD_ADDR
- * @base: Pointer to the boot parameters, typically at address
- * DEFAULT_SETUP_BASE
+ * @size: Size of bzImage, or 0 to detect this
* @initrd: Address of the initial ramdisk, or 0 if none
* @initrd_size: Size of the initial ramdisk, or 0 if none
- * @cmdline: Command line to use for booting
+ * @base_addr: If non-zero, this indicates that the boot parameters have already
+ * been loaded by the caller to this address, so the load_zimage() call
+ * in zboot_load() will be skipped when booting
+ * @cmdline: If non-NULL, the environment variable containing the command line
+ * to use for booting
* Return: -EFAULT on error (normally it does not return)
*/
-int zboot_start(ulong addr, ulong size, ulong initrd, ulong initrd_size,
- ulong base, char *cmdline);
+int zboot_run(ulong addr, ulong size, ulong initrd, ulong initrd_size,
+ ulong base, char *cmdline);
/*
* zimage_get_kernel_version() - Get the version string from a kernel
@@ -314,7 +317,7 @@
* bootm_boot_start() - Boot an image at the given address
*
* @addr: Image address
- * @cmdline: Command line to set
+ * @cmdline: Command line to set, NULL for default
*/
int bootm_boot_start(ulong addr, const char *cmdline);
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 7daca0a..bb51c02 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -345,9 +345,6 @@
extern const efi_guid_t efi_guid_text_input_protocol;
extern const efi_guid_t efi_guid_text_output_protocol;
-extern char __efi_runtime_start[], __efi_runtime_stop[];
-extern char __efi_runtime_rel_start[], __efi_runtime_rel_stop[];
-
/**
* struct efi_open_protocol_info_item - open protocol info item
*
diff --git a/include/efi_tcg2.h b/include/efi_tcg2.h
index b21c5cb..a75b5a3 100644
--- a/include/efi_tcg2.h
+++ b/include/efi_tcg2.h
@@ -150,16 +150,14 @@
* the variable.
* @variable_data_length: The size of the variable data.
* @unicode_name: The CHAR16 unicode name of the variable
- * without NULL-terminator.
- * @variable_data: The data parameter of the efi variable
- * in the GetVariable() API.
+ * without NULL-terminator followed by data.
*/
struct efi_tcg2_uefi_variable_data {
efi_guid_t variable_name;
u64 unicode_name_length;
u64 variable_data_length;
- u16 unicode_name[1];
- u8 variable_data[1];
+ u16 unicode_name[];
+ // u8 variable_data[];
};
/**
diff --git a/include/env_default.h b/include/env_default.h
index 2ca4a08..8ee500d 100644
--- a/include/env_default.h
+++ b/include/env_default.h
@@ -99,6 +99,17 @@
#ifdef CONFIG_SYS_SOC
"soc=" CONFIG_SYS_SOC "\0"
#endif
+#ifdef CONFIG_USB_HOST
+ "usb_ignorelist="
+#ifdef CONFIG_USB_KEYBOARD
+ /* Ignore Yubico devices. Currently only a single USB keyboard device is
+ * supported and the emulated HID keyboard Yubikeys present is useless
+ * as keyboard.
+ */
+ "0x1050:*,"
+#endif
+ "\0"
+#endif
#ifdef CONFIG_ENV_IMPORT_FDT
"env_fdt_path=" CONFIG_ENV_FDT_PATH "\0"
#endif
diff --git a/include/fastboot-internal.h b/include/fastboot-internal.h
index 610d4f9..e59c187 100644
--- a/include/fastboot-internal.h
+++ b/include/fastboot-internal.h
@@ -6,7 +6,7 @@
/**
* fastboot_buf_addr - base address of the fastboot download buffer
*/
-extern void *fastboot_buf_addr;
+extern ulong fastboot_buf_addr;
/**
* fastboot_buf_size - size of the fastboot download buffer
diff --git a/include/fastboot.h b/include/fastboot.h
index 1e7920e..c75184c 100644
--- a/include/fastboot.h
+++ b/include/fastboot.h
@@ -114,13 +114,13 @@
*/
void fastboot_set_progress_callback(void (*progress)(const char *msg));
-/*
+/**
* fastboot_init() - initialise new fastboot protocol session
*
- * @buf_addr: Pointer to download buffer, or NULL for default
+ * @buf_addr: Address of download buffer, or 0 for default
* @buf_size: Size of download buffer, or zero for default
*/
-void fastboot_init(void *buf_addr, u32 buf_size);
+void fastboot_init(ulong buf_addr, u32 buf_size);
/**
* fastboot_boot() - Execute fastboot boot command
diff --git a/include/image.h b/include/image.h
index 21de70f..acffd17 100644
--- a/include/image.h
+++ b/include/image.h
@@ -946,7 +946,7 @@
int image_check_hcrc(const struct legacy_img_hdr *hdr);
int image_check_dcrc(const struct legacy_img_hdr *hdr);
#ifndef USE_HOSTCC
-ulong env_get_bootm_low(void);
+phys_addr_t env_get_bootm_low(void);
phys_size_t env_get_bootm_size(void);
phys_size_t env_get_bootm_mapsize(void);
#endif
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index fb002ae..4abaf47 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -249,6 +249,13 @@
*/
#define NAND_USE_BOUNCE_BUFFER 0x00100000
+/*
+ * Do not try to tweak the timings at runtime. This is needed when the
+ * controller initializes the timings on itself or when it relies on
+ * configuration done by the bootloader.
+ */
+#define NAND_KEEP_TIMINGS 0x00800000
+
/* Options set by nand scan */
/* bbt has already been read */
#define NAND_BBT_SCANNED 0x40000000
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 6f479fa..13b5a52 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -251,6 +251,7 @@
extern const struct spinand_manufacturer toshiba_spinand_manufacturer;
extern const struct spinand_manufacturer winbond_spinand_manufacturer;
extern const struct spinand_manufacturer esmt_c8_spinand_manufacturer;
+extern const struct spinand_manufacturer xtx_spinand_manufacturer;
/**
* struct spinand_op_variants - SPI NAND operation variants
diff --git a/include/mcheck.h b/include/mcheck.h
new file mode 100644
index 0000000..bd506ae
--- /dev/null
+++ b/include/mcheck.h
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.1+ */
+/*
+ * Copyright (C) 1996-2024 Free Software Foundation, Inc.
+ * This file is part of the GNU C Library.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ * <https://www.gnu.org/licenses/>.
+ */
+#ifndef _MCHECK_H
+#define _MCHECK_H 1
+
+/*
+ * Return values for `mprobe': these are the kinds of inconsistencies that
+ * `mcheck' enables detection of.
+ */
+enum mcheck_status {
+ MCHECK_DISABLED = -1, /* Consistency checking is not turned on. */
+ MCHECK_OK, /* Block is fine. */
+ MCHECK_FREE, /* Block freed twice. */
+ MCHECK_HEAD, /* Memory before the block was clobbered. */
+ MCHECK_TAIL /* Memory after the block was clobbered. */
+};
+
+typedef void (*mcheck_abortfunc_t)(enum mcheck_status, const void *p);
+
+int mcheck(mcheck_abortfunc_t func);
+
+/*
+ * Similar to `mcheck' but performs checks for all block whenever one of
+ * the memory handling functions is called. This can be very slow.
+ */
+int mcheck_pedantic(mcheck_abortfunc_t f);
+
+/* Force check of all blocks now. */
+void mcheck_check_all(void);
+
+/*
+ * Check for aberrations in a particular malloc'd block. These are the
+ * same checks that `mcheck' does, when you free or reallocate a block.
+ */
+enum mcheck_status mprobe(void *__ptr);
+
+#endif
diff --git a/include/mmc.h b/include/mmc.h
index 1022db3..4b8327f 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -590,7 +590,7 @@
uint f_max;
uint b_max;
unsigned char part_type;
-#ifdef CONFIG_MMC_PWRSEQ
+#if CONFIG_IS_ENABLED(MMC_PWRSEQ)
struct udevice *pwr_dev;
#endif
};
@@ -736,7 +736,8 @@
* accessing the boot partitions
*/
u32 quirks;
- u8 hs400_tuning;
+ bool tuning:1;
+ bool hs400_tuning:1;
enum bus_mode user_speed_mode; /* input speed mode from user */
};
@@ -795,7 +796,7 @@
int mmc_initialize(struct bd_info *bis);
int mmc_init_device(int num);
int mmc_init(struct mmc *mmc);
-int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error);
+int mmc_send_tuning(struct mmc *mmc, u32 opcode);
int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data);
int mmc_deinit(struct mmc *mmc);
@@ -808,7 +809,7 @@
*/
int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg);
-#ifdef CONFIG_MMC_PWRSEQ
+#if CONFIG_IS_ENABLED(MMC_PWRSEQ)
/**
* mmc_pwrseq_get_power() - get a power device from device tree
*
diff --git a/include/u-boot/zlib.h b/include/u-boot/zlib.h
index a33cc87..ee19f46 100644
--- a/include/u-boot/zlib.h
+++ b/include/u-boot/zlib.h
@@ -49,9 +49,6 @@
extern "C" {
#endif
-#define ZLIB_VERSION "1.2.3"
-#define ZLIB_VERNUM 0x1230
-
/* #include "zconf.h" */ /* included directly here */
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2005 Jean-loup Gailly.
@@ -484,7 +481,6 @@
#define Z_DATA_ERROR (-3)
#define Z_MEM_ERROR (-4)
#define Z_BUF_ERROR (-5)
-#define Z_VERSION_ERROR (-6)
/* Return codes for the compression/decompression functions. Negative
* values are errors, positive values are used for special but normal events.
*/
@@ -523,11 +519,11 @@
ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
- const char *version, int stream_size));
+ int stream_size));
ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
int windowBits, int memLevel,
- int strategy, const char *version,
+ int strategy,
int stream_size));
ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
@@ -553,7 +549,7 @@
ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
- const char *version, int stream_size));
+ int stream_size));
ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
/*
inflate decompresses as much data as possible, and stops when the input
@@ -743,11 +739,11 @@
*/
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
- const char *version, int stream_size));
+ int stream_size));
#define inflateInit(strm) \
- inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
+ inflateInit_((strm), sizeof(z_stream))
#define inflateInit2(strm, windowBits) \
- inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+ inflateInit2_((strm), (windowBits), sizeof(z_stream))
#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
struct internal_state {int dummy;}; /* hack for buggy compilers */
diff --git a/include/usb.h b/include/usb.h
index 09e3f0c..3aafdc8 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -49,6 +49,12 @@
*/
#define USB_TIMEOUT_MS(pipe) (usb_pipebulk(pipe) ? 5000 : 1000)
+/*
+ * The xhcd hcd driver prepares only a limited number interfaces / endpoints.
+ * Define this limit so that drivers do not exceed it.
+ */
+#define USB_MAX_ACTIVE_INTERFACES 2
+
/* device request (setup) */
struct devrequest {
__u8 requesttype;
diff --git a/lib/Kconfig b/lib/Kconfig
index 37ac14f..efb7797 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -348,7 +348,7 @@
Enables function tracing within U-Boot. This allows recording of call
traces including timing information. The command can write data to
memory for exporting for analysis (e.g. using bootchart).
- See doc/README.trace for full details.
+ See doc/develop/trace.rst for full details.
config TRACE_BUFFER_SIZE
hex "Size of trace buffer in U-Boot"
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index 086521f..034e366 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -71,11 +71,11 @@
obj-$(CONFIG_EFI_UNICODE_COLLATION_PROTOCOL2) += efi_unicode_collation.o
obj-y += efi_var_common.o
obj-y += efi_var_mem.o
-obj-y += efi_var_file.o
ifeq ($(CONFIG_EFI_MM_COMM_TEE),y)
obj-y += efi_variable_tee.o
else
obj-y += efi_variable.o
+obj-y += efi_var_file.o
obj-$(CONFIG_EFI_VARIABLES_PRESEED) += efi_var_seed.o
endif
obj-y += efi_watchdog.o
diff --git a/lib/efi_loader/efi_acpi.c b/lib/efi_loader/efi_acpi.c
index 67bbd2a..67bd7f8 100644
--- a/lib/efi_loader/efi_acpi.c
+++ b/lib/efi_loader/efi_acpi.c
@@ -41,7 +41,7 @@
}
addr = gd_acpi_start();
- printf("EFI using ACPI tables at %lx\n", addr);
+ log_debug("EFI using ACPI tables at %lx\n", addr);
/* And expose them to our EFI payload */
return efi_install_configuration_table(&acpi_guid,
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index aba3100..12cf23f 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -15,6 +15,7 @@
#include <watchdog.h>
#include <asm/cache.h>
#include <asm/global_data.h>
+#include <asm/sections.h>
#include <linux/list_sort.h>
#include <linux/sizes.h>
diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c
index 16b2c3d..aa8feff 100644
--- a/lib/efi_loader/efi_var_common.c
+++ b/lib/efi_loader/efi_var_common.c
@@ -9,6 +9,7 @@
#include <efi_loader.h>
#include <efi_variable.h>
#include <stdlib.h>
+#include <u-boot/crc.h>
enum efi_secure_mode {
EFI_MODE_SETUP,
@@ -416,3 +417,76 @@
return buf;
}
+
+/**
+ * efi_var_collect() - Copy EFI variables mstching attributes mask
+ *
+ * @bufp: buffer containing variable collection
+ * @lenp: buffer length
+ * @attr_mask: mask of matched attributes
+ *
+ * Return: Status code
+ */
+efi_status_t __maybe_unused efi_var_collect(struct efi_var_file **bufp, loff_t *lenp,
+ u32 check_attr_mask)
+{
+ size_t len = EFI_VAR_BUF_SIZE;
+ struct efi_var_file *buf;
+ struct efi_var_entry *var, *old_var;
+ size_t old_var_name_length = 2;
+
+ *bufp = NULL; /* Avoid double free() */
+ buf = calloc(1, len);
+ if (!buf)
+ return EFI_OUT_OF_RESOURCES;
+ var = buf->var;
+ old_var = var;
+ for (;;) {
+ efi_uintn_t data_length, var_name_length;
+ u8 *data;
+ efi_status_t ret;
+
+ if ((uintptr_t)buf + len <=
+ (uintptr_t)var->name + old_var_name_length)
+ return EFI_BUFFER_TOO_SMALL;
+
+ var_name_length = (uintptr_t)buf + len - (uintptr_t)var->name;
+ memcpy(var->name, old_var->name, old_var_name_length);
+ guidcpy(&var->guid, &old_var->guid);
+ ret = efi_get_next_variable_name_int(
+ &var_name_length, var->name, &var->guid);
+ if (ret == EFI_NOT_FOUND)
+ break;
+ if (ret != EFI_SUCCESS) {
+ free(buf);
+ return ret;
+ }
+ old_var_name_length = var_name_length;
+ old_var = var;
+
+ data = (u8 *)var->name + old_var_name_length;
+ data_length = (uintptr_t)buf + len - (uintptr_t)data;
+ ret = efi_get_variable_int(var->name, &var->guid,
+ &var->attr, &data_length, data,
+ &var->time);
+ if (ret != EFI_SUCCESS) {
+ free(buf);
+ return ret;
+ }
+ if ((var->attr & check_attr_mask) == check_attr_mask) {
+ var->length = data_length;
+ var = (struct efi_var_entry *)ALIGN((uintptr_t)data + data_length, 8);
+ }
+ }
+
+ buf->reserved = 0;
+ buf->magic = EFI_VAR_FILE_MAGIC;
+ len = (uintptr_t)var - (uintptr_t)buf;
+ buf->crc32 = crc32(0, (u8 *)buf->var,
+ len - sizeof(struct efi_var_file));
+ buf->length = len;
+ *bufp = buf;
+ *lenp = len;
+
+ return EFI_SUCCESS;
+}
diff --git a/lib/efi_loader/efi_var_file.c b/lib/efi_loader/efi_var_file.c
index 532b6b4..413e179 100644
--- a/lib/efi_loader/efi_var_file.c
+++ b/lib/efi_loader/efi_var_file.c
@@ -52,70 +52,6 @@
return EFI_SUCCESS;
}
-efi_status_t __maybe_unused efi_var_collect(struct efi_var_file **bufp, loff_t *lenp,
- u32 check_attr_mask)
-{
- size_t len = EFI_VAR_BUF_SIZE;
- struct efi_var_file *buf;
- struct efi_var_entry *var, *old_var;
- size_t old_var_name_length = 2;
-
- *bufp = NULL; /* Avoid double free() */
- buf = calloc(1, len);
- if (!buf)
- return EFI_OUT_OF_RESOURCES;
- var = buf->var;
- old_var = var;
- for (;;) {
- efi_uintn_t data_length, var_name_length;
- u8 *data;
- efi_status_t ret;
-
- if ((uintptr_t)buf + len <=
- (uintptr_t)var->name + old_var_name_length)
- return EFI_BUFFER_TOO_SMALL;
-
- var_name_length = (uintptr_t)buf + len - (uintptr_t)var->name;
- memcpy(var->name, old_var->name, old_var_name_length);
- guidcpy(&var->guid, &old_var->guid);
- ret = efi_get_next_variable_name_int(
- &var_name_length, var->name, &var->guid);
- if (ret == EFI_NOT_FOUND)
- break;
- if (ret != EFI_SUCCESS) {
- free(buf);
- return ret;
- }
- old_var_name_length = var_name_length;
- old_var = var;
-
- data = (u8 *)var->name + old_var_name_length;
- data_length = (uintptr_t)buf + len - (uintptr_t)data;
- ret = efi_get_variable_int(var->name, &var->guid,
- &var->attr, &data_length, data,
- &var->time);
- if (ret != EFI_SUCCESS) {
- free(buf);
- return ret;
- }
- if ((var->attr & check_attr_mask) == check_attr_mask) {
- var->length = data_length;
- var = (struct efi_var_entry *)ALIGN((uintptr_t)data + data_length, 8);
- }
- }
-
- buf->reserved = 0;
- buf->magic = EFI_VAR_FILE_MAGIC;
- len = (uintptr_t)var - (uintptr_t)buf;
- buf->crc32 = crc32(0, (u8 *)buf->var,
- len - sizeof(struct efi_var_file));
- buf->length = len;
- *bufp = buf;
- *lenp = len;
-
- return EFI_SUCCESS;
-}
-
/**
* efi_var_to_file() - save non-volatile variables as file
*
diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index 2951dc7..e6c1219 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -163,6 +163,7 @@
break;
default:
/* TODO: support private authenticated variables */
+ ret = EFI_UNSUPPORTED;
goto err;
}
diff --git a/lib/gzip.c b/lib/gzip.c
index 5d9c195..a9a3df5 100644
--- a/lib/gzip.c
+++ b/lib/gzip.c
@@ -67,7 +67,7 @@
r = deflateInit2_(&s, Z_BEST_SPEED, Z_DEFLATED, window,
DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
- ZLIB_VERSION, sizeof(z_stream));
+ sizeof(z_stream));
if (r != Z_OK) {
printf ("Error: deflateInit2_() returned %d\n", r);
return -1;
diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c
index 1007b69..d3b4f71 100644
--- a/lib/rsa/rsa-verify.c
+++ b/lib/rsa/rsa-verify.c
@@ -342,7 +342,7 @@
return -EINVAL;
}
- debug("Checksum algorithm: %s", checksum->name);
+ debug("Checksum algorithm: %s\n", checksum->name);
/* Sanity check for stack size */
if (sig_len > RSA_MAX_SIG_BITS / 8) {
@@ -444,13 +444,13 @@
const char *algo;
if (node < 0) {
- debug("%s: Skipping invalid node", __func__);
+ debug("%s: Skipping invalid node\n", __func__);
return -EBADF;
}
algo = fdt_getprop(blob, node, "algo", NULL);
if (strcmp(info->name, algo)) {
- debug("%s: Wrong algo: have %s, expected %s", __func__,
+ debug("%s: Wrong algo: have %s, expected %s\n", __func__,
info->name, algo);
return -EFAULT;
}
@@ -470,7 +470,7 @@
prop.rr = fdt_getprop(blob, node, "rsa,r-squared", NULL);
if (!prop.num_bits || !prop.modulus || !prop.rr) {
- debug("%s: Missing RSA key info", __func__);
+ debug("%s: Missing RSA key info\n", __func__);
return -EFAULT;
}
diff --git a/lib/zlib/deflate.c b/lib/zlib/deflate.c
index 4549f4d..7e1ed4f 100644
--- a/lib/zlib/deflate.c
+++ b/lib/zlib/deflate.c
@@ -196,37 +196,30 @@
zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
/* ========================================================================= */
-int ZEXPORT deflateInit_(strm, level, version, stream_size)
+int ZEXPORT deflateInit_(strm, level, stream_size)
z_streamp strm;
int level;
- const char *version;
int stream_size;
{
return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
- Z_DEFAULT_STRATEGY, version, stream_size);
+ Z_DEFAULT_STRATEGY, stream_size);
/* To do: ignore strm->next_in if we use it as window */
}
/* ========================================================================= */
int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
- version, stream_size)
+ stream_size)
z_streamp strm;
int level;
int method;
int windowBits;
int memLevel;
int strategy;
- const char *version;
int stream_size;
{
deflate_state *s;
int wrap = 1;
- static const char my_version[] = ZLIB_VERSION;
- if (version == Z_NULL || version[0] != my_version[0] ||
- stream_size != sizeof(z_stream)) {
- return Z_VERSION_ERROR;
- }
if (strm == Z_NULL) return Z_STREAM_ERROR;
strm->msg = Z_NULL;
diff --git a/lib/zlib/inffast.c b/lib/zlib/inffast.c
index e3c7f3b..5e2a65a 100644
--- a/lib/zlib/inffast.c
+++ b/lib/zlib/inffast.c
@@ -1,5 +1,5 @@
/* inffast.c -- fast decoding
- * Copyright (C) 1995-2004 Mark Adler
+ * Copyright (C) 1995-2008, 2010, 2013 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@@ -12,25 +12,6 @@
#ifndef ASMINF
-/* Allow machine dependent optimization for post-increment or pre-increment.
- Based on testing to date,
- Pre-increment preferred for:
- - PowerPC G3 (Adler)
- - MIPS R5000 (Randers-Pehrson)
- Post-increment preferred for:
- - none
- No measurable difference:
- - Pentium III (Anderson)
- - M68060 (Nikl)
- */
-#ifdef POSTINC
-# define OFF 0
-# define PUP(a) *(a)++
-#else
-# define OFF 1
-# define PUP(a) *++(a)
-#endif
-
/*
Decode literal, length, and distance codes and write out the resulting
literal and match bytes until either not enough input or output is
@@ -66,12 +47,13 @@
requires strm->avail_out >= 258 for each loop to avoid checking for
output space.
*/
-void inflate_fast(z_streamp strm, unsigned start)
-/* start: inflate()'s starting value for strm->avail_out */
+void ZLIB_INTERNAL inflate_fast(strm, start)
+z_streamp strm;
+unsigned start; /* inflate()'s starting value for strm->avail_out */
{
struct inflate_state FAR *state;
- unsigned char FAR *in; /* local strm->next_in */
- unsigned char FAR *last; /* while in < last, enough input available */
+ z_const unsigned char FAR *in; /* local strm->next_in */
+ z_const unsigned char FAR *last; /* have enough input while in < last */
unsigned char FAR *out; /* local strm->next_out */
unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
unsigned char FAR *end; /* while out < end, enough space available */
@@ -80,7 +62,7 @@
#endif
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
+ unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
unsigned long hold; /* local strm->hold */
unsigned bits; /* local strm->bits */
@@ -88,7 +70,7 @@
code const FAR *dcode; /* local strm->distcode */
unsigned lmask; /* mask for first level of length codes */
unsigned dmask; /* mask for first level of distance codes */
- code this; /* retrieved table entry */
+ code here; /* retrieved table entry */
unsigned op; /* code bits, operation, extra bits, or */
/* window position, window bytes to copy */
unsigned len; /* match length, unused bytes */
@@ -97,7 +79,7 @@
/* copy state to local variables */
state = (struct inflate_state FAR *)strm->state;
- in = strm->next_in - OFF;
+ in = strm->next_in;
last = in + (strm->avail_in - 5);
if (in > last && strm->avail_in > 5) {
/*
@@ -107,7 +89,7 @@
strm->avail_in = 0xffffffff - (uintptr_t)in;
last = in + (strm->avail_in - 5);
}
- out = strm->next_out - OFF;
+ out = strm->next_out;
beg = out - (start - strm->avail_out);
end = out + (strm->avail_out - 257);
#ifdef INFLATE_STRICT
@@ -115,7 +97,7 @@
#endif
wsize = state->wsize;
whave = state->whave;
- write = state->write;
+ wnext = state->wnext;
window = state->window;
hold = state->hold;
bits = state->bits;
@@ -128,29 +110,29 @@
input data or output space */
do {
if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
}
- this = lcode[hold & lmask];
+ here = lcode[hold & lmask];
dolen:
- op = (unsigned)(this.bits);
+ op = (unsigned)(here.bits);
hold >>= op;
bits -= op;
- op = (unsigned)(this.op);
+ op = (unsigned)(here.op);
if (op == 0) { /* literal */
- Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
"inflate: literal '%c'\n" :
- "inflate: literal 0x%02x\n", this.val));
- PUP(out) = (unsigned char)(this.val);
+ "inflate: literal 0x%02x\n", here.val));
+ *out++ = (unsigned char)(here.val);
}
else if (op & 16) { /* length base */
- len = (unsigned)(this.val);
+ len = (unsigned)(here.val);
op &= 15; /* number of extra bits */
if (op) {
if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
}
len += (unsigned)hold & ((1U << op) - 1);
@@ -159,25 +141,25 @@
}
Tracevv((stderr, "inflate: length %u\n", len));
if (bits < 15) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
}
- this = dcode[hold & dmask];
+ here = dcode[hold & dmask];
dodist:
- op = (unsigned)(this.bits);
+ op = (unsigned)(here.bits);
hold >>= op;
bits -= op;
- op = (unsigned)(this.op);
+ op = (unsigned)(here.op);
if (op & 16) { /* distance base */
- dist = (unsigned)(this.val);
+ dist = (unsigned)(here.val);
op &= 15; /* number of extra bits */
if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
if (bits < op) {
- hold += (unsigned long)(PUP(in)) << bits;
+ hold += (unsigned long)(*in++) << bits;
bits += 8;
}
}
@@ -196,108 +178,80 @@
if (dist > op) { /* see if copy from window */
op = dist - op; /* distance back in window */
if (op > whave) {
- strm->msg = (char *)"invalid distance too far back";
+ strm->msg =
+ (char *)"invalid distance too far back";
state->mode = BAD;
break;
}
- from = window - OFF;
- if (write == 0) { /* very common case */
+ from = window;
+ if (wnext == 0) { /* very common case */
from += wsize - op;
if (op < len) { /* some from window */
len -= op;
do {
- PUP(out) = PUP(from);
+ *out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
- else if (write < op) { /* wrap around window */
- from += wsize + write - op;
- op -= write;
+ else if (wnext < op) { /* wrap around window */
+ from += wsize + wnext - op;
+ op -= wnext;
if (op < len) { /* some from end of window */
len -= op;
do {
- PUP(out) = PUP(from);
+ *out++ = *from++;
} while (--op);
- from = window - OFF;
- if (write < len) { /* some from start of window */
- op = write;
+ from = window;
+ if (wnext < len) { /* some from start of window */
+ op = wnext;
len -= op;
do {
- PUP(out) = PUP(from);
+ *out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
}
else { /* contiguous in window */
- from += write - op;
+ from += wnext - op;
if (op < len) { /* some from window */
len -= op;
do {
- PUP(out) = PUP(from);
+ *out++ = *from++;
} while (--op);
from = out - dist; /* rest from output */
}
}
while (len > 2) {
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
- PUP(out) = PUP(from);
+ *out++ = *from++;
+ *out++ = *from++;
+ *out++ = *from++;
len -= 3;
}
if (len) {
- PUP(out) = PUP(from);
+ *out++ = *from++;
if (len > 1)
- PUP(out) = PUP(from);
+ *out++ = *from++;
}
}
else {
- unsigned short *sout;
- unsigned long loops;
-
from = out - dist; /* copy direct from output */
- /* minimum length is three */
- /* Align out addr */
- if (!((long)(out - 1 + OFF) & 1)) {
- PUP(out) = PUP(from);
- len--;
- }
- sout = (unsigned short *)(out - OFF);
- if (dist > 2 ) {
- unsigned short *sfrom;
-
- sfrom = (unsigned short *)(from - OFF);
- loops = len >> 1;
- do
- PUP(sout) = get_unaligned(++sfrom);
- while (--loops);
- out = (unsigned char *)sout + OFF;
- from = (unsigned char *)sfrom + OFF;
- } else { /* dist == 1 or dist == 2 */
- unsigned short pat16;
-
- pat16 = *(sout-2+2*OFF);
- if (dist == 1)
-#if defined(__BIG_ENDIAN)
- pat16 = (pat16 & 0xff) | ((pat16 & 0xff ) << 8);
-#elif defined(__LITTLE_ENDIAN)
- pat16 = (pat16 & 0xff00) | ((pat16 & 0xff00 ) >> 8);
-#else
-#error __BIG_ENDIAN nor __LITTLE_ENDIAN is defined
-#endif
- loops = len >> 1;
- do
- PUP(sout) = pat16;
- while (--loops);
- out = (unsigned char *)sout + OFF;
- }
- if (len & 1)
- PUP(out) = PUP(from);
+ do { /* minimum length is three */
+ *out++ = *from++;
+ *out++ = *from++;
+ *out++ = *from++;
+ len -= 3;
+ } while (len > 2);
+ if (len) {
+ *out++ = *from++;
+ if (len > 1)
+ *out++ = *from++;
+ }
}
}
else if ((op & 64) == 0) { /* 2nd level distance code */
- this = dcode[this.val + (hold & ((1U << op) - 1))];
+ here = dcode[here.val + (hold & ((1U << op) - 1))];
goto dodist;
}
else {
@@ -307,7 +261,7 @@
}
}
else if ((op & 64) == 0) { /* 2nd level length code */
- this = lcode[this.val + (hold & ((1U << op) - 1))];
+ here = lcode[here.val + (hold & ((1U << op) - 1))];
goto dolen;
}
else if (op & 32) { /* end-of-block */
@@ -329,8 +283,8 @@
hold &= (1U << bits) - 1;
/* update state and return */
- strm->next_in = in + OFF;
- strm->next_out = out + OFF;
+ strm->next_in = in;
+ strm->next_out = out;
strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
strm->avail_out = (unsigned)(out < end ?
257 + (end - out) : 257 - (out - end));
@@ -343,7 +297,7 @@
inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
- Using bit fields for code structure
- Different op definition to avoid & for extra bits (do & for table bits)
- - Three separate decoding do-loops for direct, window, and write == 0
+ - Three separate decoding do-loops for direct, window, and wnext == 0
- Special case for distance > 1 copies to do overlapped load and store copy
- Explicit branch predictions (based on measured branch probabilities)
- Deferring match copy and interspersed it with decoding subsequent codes
diff --git a/lib/zlib/inflate.c b/lib/zlib/inflate.c
index 8f767b7..f7e81fc 100644
--- a/lib/zlib/inflate.c
+++ b/lib/zlib/inflate.c
@@ -21,7 +21,7 @@
state->head = Z_NULL;
state->wsize = 0;
state->whave = 0;
- state->write = 0;
+ state->wnext = 0;
state->hold = 0;
state->bits = 0;
state->lencode = state->distcode = state->next = state->codes;
@@ -30,14 +30,11 @@
return Z_OK;
}
-int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, const char *version,
+int ZEXPORT inflateInit2_(z_streamp strm, int windowBits,
int stream_size)
{
struct inflate_state FAR *state;
- if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
- stream_size != (int)(sizeof(z_stream)))
- return Z_VERSION_ERROR;
if (strm == Z_NULL) return Z_STREAM_ERROR;
strm->msg = Z_NULL; /* in case we return an error */
if (strm->zalloc == (alloc_func)0) {
@@ -70,9 +67,9 @@
return inflateReset(strm);
}
-int ZEXPORT inflateInit_(z_streamp strm, const char *version, int stream_size)
+int ZEXPORT inflateInit_(z_streamp strm, int stream_size)
{
- return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+ return inflateInit2_(strm, DEF_WBITS, stream_size);
}
local void fixedtables(struct inflate_state FAR *state)
@@ -115,7 +112,7 @@
/* if window not in use yet, initialize */
if (state->wsize == 0) {
state->wsize = 1U << state->wbits;
- state->write = 0;
+ state->wnext = 0;
state->whave = 0;
}
@@ -123,22 +120,22 @@
copy = out - strm->avail_out;
if (copy >= state->wsize) {
zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
- state->write = 0;
+ state->wnext = 0;
state->whave = state->wsize;
}
else {
- dist = state->wsize - state->write;
+ dist = state->wsize - state->wnext;
if (dist > copy) dist = copy;
- zmemcpy(state->window + state->write, strm->next_out - copy, dist);
+ zmemcpy(state->window + state->wnext, strm->next_out - copy, dist);
copy -= dist;
if (copy) {
zmemcpy(state->window, strm->next_out - copy, copy);
- state->write = copy;
+ state->wnext = copy;
state->whave = state->wsize;
}
else {
- state->write += dist;
- if (state->write == state->wsize) state->write = 0;
+ state->wnext += dist;
+ if (state->wnext == state->wsize) state->wnext = 0;
if (state->whave < state->wsize) state->whave += dist;
}
}
@@ -823,12 +820,12 @@
copy = out - left;
if (state->offset > copy) { /* copy from window */
copy = state->offset - copy;
- if (copy > state->write) {
- copy -= state->write;
+ if (copy > state->wnext) {
+ copy -= state->wnext;
from = state->window + (state->wsize - copy);
}
else
- from = state->window + (state->write - copy);
+ from = state->window + (state->wnext - copy);
if (copy > state->length) copy = state->length;
}
else { /* copy from output */
diff --git a/lib/zlib/inflate.h b/lib/zlib/inflate.h
index 07bd3e7..2657d61 100644
--- a/lib/zlib/inflate.h
+++ b/lib/zlib/inflate.h
@@ -88,7 +88,7 @@
unsigned wbits; /* log base 2 of requested window size */
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
- unsigned write; /* window write index */
+ unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* bit accumulator */
unsigned long hold; /* input bit accumulator */
diff --git a/lib/zlib/zutil.c b/lib/zlib/zutil.c
index 609aac5..ec21b45 100644
--- a/lib/zlib/zutil.c
+++ b/lib/zlib/zutil.c
@@ -21,7 +21,6 @@
"data error", /* Z_DATA_ERROR (-3) */
"insufficient memory", /* Z_MEM_ERROR (-4) */
"buffer error", /* Z_BUF_ERROR (-5) */
-"incompatible version",/* Z_VERSION_ERROR (-6) */
""};
#ifdef DEBUG
diff --git a/net/nfs.c b/net/nfs.c
index 7a8887e..c182824 100644
--- a/net/nfs.c
+++ b/net/nfs.c
@@ -57,7 +57,8 @@
static int nfs_len;
static const ulong nfs_timeout = CONFIG_NFS_TIMEOUT;
-static char dirfh[NFS_FHSIZE]; /* NFSv2 / NFSv3 file handle of directory */
+static char dirfh[NFS3_FHSIZE]; /* NFSv2 / NFSv3 file handle of directory */
+static unsigned int dirfh3_length; /* (variable) length of dirfh when NFSv3 */
static char filefh[NFS3_FHSIZE]; /* NFSv2 / NFSv3 file handle */
static unsigned int filefh3_length; /* (variable) length of filefh when NFSv3 */
@@ -377,9 +378,9 @@
rpc_req(PROG_NFS, NFS_LOOKUP, data, len);
} else { /* NFS_V3 */
- *p++ = htonl(NFS_FHSIZE); /* Dir handle length */
- memcpy(p, dirfh, NFS_FHSIZE);
- p += (NFS_FHSIZE / 4);
+ *p++ = htonl(dirfh3_length); /* Dir handle length */
+ memcpy(p, dirfh, dirfh3_length);
+ p += (dirfh3_length / 4);
*p++ = htonl(fnamelen);
if (fnamelen & 3)
*(p + fnamelen / 4) = 0;
@@ -565,7 +566,14 @@
fs_mounted = 1;
/* NFSv2 and NFSv3 use same structure */
- memcpy(dirfh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
+ if (choosen_nfs_version != NFS_V3) {
+ memcpy(dirfh, rpc_pkt.u.reply.data + 1, NFS_FHSIZE);
+ } else {
+ dirfh3_length = ntohl(rpc_pkt.u.reply.data[1]);
+ if (dirfh3_length > NFS3_FHSIZE)
+ dirfh3_length = NFS3_FHSIZE;
+ memcpy(dirfh, rpc_pkt.u.reply.data + 2, dirfh3_length);
+ }
return 0;
}
diff --git a/net/wget.c b/net/wget.c
index 817c5eb..abab371 100644
--- a/net/wget.c
+++ b/net/wget.c
@@ -50,6 +50,7 @@
static unsigned int packets;
static unsigned int initial_data_seq_num;
+static unsigned int next_data_seq_num;
static enum wget_state current_wget_state;
@@ -272,17 +273,18 @@
current_wget_state = WGET_TRANSFERRING;
+ initial_data_seq_num = tcp_seq_num + hlen;
+ next_data_seq_num = tcp_seq_num + len;
+
if (strstr((char *)pkt, http_ok) == 0) {
debug_cond(DEBUG_WGET,
"wget: Connected Bad Xfer\n");
- initial_data_seq_num = tcp_seq_num + hlen;
wget_loop_state = NETLOOP_FAIL;
wget_send(action, tcp_seq_num, tcp_ack_num, len);
} else {
debug_cond(DEBUG_WGET,
"wget: Connctd pkt %p hlen %x\n",
pkt, hlen);
- initial_data_seq_num = tcp_seq_num + hlen;
pos = strstr((char *)pkt, content_len);
if (!pos) {
@@ -396,9 +398,13 @@
"wget: Transferring, seq=%x, ack=%x,len=%x\n",
tcp_seq_num, tcp_ack_num, len);
+ if (next_data_seq_num != tcp_seq_num) {
+ debug_cond(DEBUG_WGET, "wget: seq=%x packet was lost\n", next_data_seq_num);
+ return;
+ }
+ next_data_seq_num = tcp_seq_num + len;
+
- if (tcp_seq_num >= initial_data_seq_num &&
- store_block(pkt, tcp_seq_num - initial_data_seq_num,
- len) != 0) {
+ if (store_block(pkt, tcp_seq_num - initial_data_seq_num, len) != 0) {
wget_fail("wget: store error\n",
tcp_seq_num, tcp_ack_num, action);
net_set_state(NETLOOP_FAIL);
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index d074ba2..1868f1b 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -381,6 +381,11 @@
$(objtree)/tools/mkexynosspl) $(VAR_SIZE_PARAM) $< $@
endif
+$(obj)/u-boot-spl.ldr: $(obj)/u-boot-spl
+ $(CREATE_LDR_ENV)
+ $(LDR) -T $(CONFIG_LDR_CPU) -c $@ $< $(LDR_FLAGS)
+ $(BOARD_SIZE_CHECK)
+
quiet_cmd_objcopy = OBJCOPY $@
cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
@@ -575,7 +580,7 @@
SPL_OF_LIST_TARGETS = $(patsubst %,dts/%.dtb,$(subst ",,$(CONFIG_SPL_OF_LIST)))
SHRUNK_ARCH_DTB = $(addprefix $(obj)/,$(SPL_OF_LIST_TARGETS))
-$(dir $(SHRUNK_ARCH_DTB)):
+$(sort $(dir $(SHRUNK_ARCH_DTB))):
$(shell [ -d $@ ] || mkdir -p $@)
.SECONDEXPANSION:
diff --git a/test/py/test.py b/test/py/test.py
index 95859a6..7c47790 100755
--- a/test/py/test.py
+++ b/test/py/test.py
@@ -11,7 +11,6 @@
import os.path
import sys
import pytest
-from pkg_resources import load_entry_point
if __name__ == '__main__':
# argv; py.test test_directory_name user-supplied-arguments
diff --git a/test/py/tests/test_scsi.py b/test/py/tests/test_scsi.py
index be2e283..445693c 100644
--- a/test/py/tests/test_scsi.py
+++ b/test/py/tests/test_scsi.py
@@ -87,6 +87,6 @@
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
+ assert 'Partition Map for scsi device' in output
output = u_boot_console.run_command('echo $?')
assert output.endswith('0')
diff --git a/tools/binman/btool/openssl.py b/tools/binman/btool/openssl.py
index fe81a1f..c6df64c 100644
--- a/tools/binman/btool/openssl.py
+++ b/tools/binman/btool/openssl.py
@@ -283,6 +283,7 @@
basicConstraints = CA:true
1.3.6.1.4.1.294.1.3=ASN1:SEQUENCE:swrv
1.3.6.1.4.1.294.1.9=ASN1:SEQUENCE:ext_boot_info
+1.3.6.1.4.1.294.1.8=ASN1:SEQUENCE:debug
[swrv]
swrv=INTEGER:{sw_rev}
@@ -323,6 +324,12 @@
shaType = OID:{sha_type}
shaValue = FORMAT:HEX,OCT:{hashval_sysfw_data}
+[ debug ]
+debugUID = FORMAT:HEX,OCT:0000000000000000000000000000000000000000000000000000000000000000
+debugType = INTEGER:4
+coreDbgEn = INTEGER:0
+coreDbgSecEn = INTEGER:0
+
{sysfw_inner_cert_ext_boot_block}
{dm_data_ext_boot_block}
diff --git a/tools/binman/etype/ti_board_config.py b/tools/binman/etype/ti_board_config.py
index 2c3bb8f..c10d66e 100644
--- a/tools/binman/etype/ti_board_config.py
+++ b/tools/binman/etype/ti_board_config.py
@@ -248,7 +248,7 @@
yaml_config = config.YamlLintConfig("extends: default")
for p in yamllint.linter.run(open(self._config_file, "r"), yaml_config):
- self.Raise(f"Yamllint error: {p.line}: {p.rule}")
+ self.Raise(f"Yamllint error: Line {p.line} in {self._config_file}: {p.rule}")
try:
validate(self.file_yaml, self.schema_yaml)
except Exception as e:
diff --git a/tools/fit_image.c b/tools/fit_image.c
index beef1fa..0fccfbb 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -137,7 +137,7 @@
int ret;
int fd;
- fd = open(fname, O_RDWR | O_BINARY);
+ fd = open(fname, O_RDONLY | O_BINARY);
if (fd < 0) {
fprintf(stderr, "%s: Can't open %s: %s\n",
params->cmdname, fname, strerror(errno));
diff --git a/tools/image-host.c b/tools/image-host.c
index b2a0f2e..7bfc0cb 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -346,17 +346,17 @@
unsigned char *key_iv_data, int expected_size)
{
char filename[PATH_MAX];
- int ret = -1;
+ int ret;
ret = snprintf(filename, sizeof(filename), "%s/%s%s",
keydir, key_iv_name, ".bin");
if (ret >= sizeof(filename)) {
- printf("Can't format the key or IV filename when setting up the cipher: insufficient buffer space\n");
- ret = -1;
+ fprintf(stderr, "Can't format the key or IV filename when setting up the cipher: insufficient buffer space\n");
+ return -1;
}
if (ret < 0) {
- printf("Can't format the key or IV filename when setting up the cipher: snprintf error\n");
- ret = -1;
+ fprintf(stderr, "Can't format the key or IV filename when setting up the cipher: snprintf error\n");
+ return -1;
}
ret = fit_image_read_data(filename, key_iv_data, expected_size);
diff --git a/tools/proftool.c b/tools/proftool.c
index fca45e4..c2e3809 100644
--- a/tools/proftool.c
+++ b/tools/proftool.c
@@ -290,7 +290,7 @@
"Options:\n"
" -c <cfg>\tSpecify config file\n"
" -f <subtype>\tSpecify output subtype\n"
- " -m <map>\tSpecify Systen.map file\n"
+ " -m <map>\tSpecify System.map file\n"
" -o <fname>\tSpecify output file\n"
" -t <fname>\tSpecify trace data file (from U-Boot 'trace calls')\n"
" -v <0-4>\tSpecify verbosity\n"
@@ -306,7 +306,7 @@
}
/**
- * h_cmp_offset - bsearch() function to compare two functions bny their offset
+ * h_cmp_offset - bsearch() function to compare two functions by their offset
*
* @v1: Pointer to first function (struct func_info)
* @v2: Pointer to second function (struct func_info)
@@ -431,7 +431,7 @@
static struct func_info *find_caller_by_offset(uint offset)
{
int low; /* least function that could be a match */
- int high; /* greated function that could be a match */
+ int high; /* greatest function that could be a match */
struct func_info key;
low = 0;
@@ -1352,7 +1352,7 @@
}
if (!(func->flags & FUNCF_TRACE)) {
- debug("Funcion '%s' is excluded from trace\n",
+ debug("Function '%s' is excluded from trace\n",
func->name);
skip_count++;
continue;
@@ -1781,7 +1781,8 @@
*
* This works by maintaining a string shared across all recursive calls. The
* function name for this node is added to the existing string, to make up the
- * full call-stack description. For example, on entry, @str might contain:
+ * full call-stack description. For example, on entry, @str_buf->data might
+ * contain:
*
* "initf_bootstage;bootstage_mark_name"
* ^ @base
@@ -1795,18 +1796,18 @@
* @fout: Output file
* @out_format: Output format to use
* @node: Node to output (pass the whole tree at first)
- * @str: String to use to build the output line (e.g. 500 charas long)
- * @maxlen: Maximum length of string
+ * @str_buf: String buffer to use to build the output line
* @base: Current base position in the string
* @treep: Returns the resulting flamegraph tree
* Returns 0 if OK, -1 on error
*/
static int output_tree(FILE *fout, enum out_format_t out_format,
- const struct flame_node *node, char *str, int maxlen,
+ const struct flame_node *node, struct abuf *str_buf,
int base)
{
const struct flame_node *child;
int pos;
+ char *str = abuf_data(str_buf);
if (node->count) {
if (out_format == OUT_FMT_FLAMEGRAPH_CALLS) {
@@ -1832,18 +1833,29 @@
if (pos)
str[pos++] = ';';
list_for_each_entry(child, &node->child_head, sibling_node) {
- int len;
+ int len, needed;
len = strlen(child->func->name);
- if (pos + len + 1 >= maxlen) {
- fprintf(stderr, "String too short (%d chars)\n",
- maxlen);
- return -1;
+ needed = pos + len + 1;
+ if (needed > abuf_size(str_buf)) {
+ /*
+ * We need to re-allocate the string buffer; increase
+ * its size by multiples of 500 characters.
+ */
+ needed = 500 * ((needed / 500) + 1);
+ if (!abuf_realloc(str_buf, needed))
+ return -1;
+ str = abuf_data(str_buf);
+ memset(str + pos, 0, abuf_size(str_buf) - pos);
}
strcpy(str + pos, child->func->name);
- if (output_tree(fout, out_format, child, str, maxlen,
- pos + len))
+ if (output_tree(fout, out_format, child, str_buf, pos + len))
return -1;
+ /*
+ * Update our pointer as the string buffer might have been
+ * re-allocated.
+ */
+ str = abuf_data(str_buf);
}
return 0;
@@ -1859,16 +1871,24 @@
static int make_flamegraph(FILE *fout, enum out_format_t out_format)
{
struct flame_node *tree;
- char str[500];
+ struct abuf str_buf;
+ char *str;
+ int ret = 0;
if (make_flame_tree(out_format, &tree))
return -1;
- *str = '\0';
- if (output_tree(fout, out_format, tree, str, sizeof(str), 0))
+ abuf_init(&str_buf);
+ if (!abuf_realloc(&str_buf, 500))
return -1;
- return 0;
+ str = abuf_data(&str_buf);
+ memset(str, 0, abuf_size(&str_buf));
+ if (output_tree(fout, out_format, tree, &str_buf, 0))
+ ret = -1;
+
+ abuf_uninit(&str_buf);
+ return ret;
}
/**