summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml13
-rw-r--r--MAINTAINERS2
-rw-r--r--Makefile7
-rw-r--r--arch/arm/dts/Makefile7
-rw-r--r--arch/arm/dts/am335x-base0033.dts95
-rw-r--r--arch/arm/dts/am335x-igep0033.dtsi323
-rw-r--r--arch/arm/dts/am335x-sl50.dts549
-rw-r--r--arch/arm/dts/hi6220-hikey-u-boot.dtsi14
-rw-r--r--arch/arm/dts/hi6220-hikey.dts11
-rw-r--r--arch/arm/dts/hi6220.dtsi18
-rw-r--r--arch/arm/dts/mt7623.dtsi21
-rw-r--r--arch/arm/dts/mt7623n-bananapi-bpi-r2.dts13
-rw-r--r--arch/arm/dts/mt7629-rfb.dts11
-rw-r--r--arch/arm/dts/mt7629.dtsi43
-rw-r--r--arch/arm/dts/omap3-igep.dtsi250
-rw-r--r--arch/arm/dts/omap3-igep0020-common.dtsi264
-rw-r--r--arch/arm/dts/omap3-igep0020-u-boot.dtsi24
-rw-r--r--arch/arm/dts/omap3-igep0020.dts50
-rw-r--r--arch/arm/include/asm/arch-hi3798cv200/hi3798cv200.h5
-rw-r--r--arch/arm/include/asm/arch-mediatek/reset.h13
-rw-r--r--arch/arm/lib/bootm.c10
-rw-r--r--arch/riscv/config.mk3
-rw-r--r--arch/riscv/cpu/ax25/cache.c22
-rw-r--r--arch/riscv/lib/cache.c14
-rw-r--r--arch/riscv/lib/interrupts.c3
-rw-r--r--arch/sandbox/config.mk2
-rw-r--r--arch/sandbox/cpu/sdl.c2
-rw-r--r--arch/sandbox/dts/sandbox.dts10
-rw-r--r--arch/sandbox/dts/sandbox64.dts6
-rw-r--r--arch/sandbox/dts/test.dts6
-rw-r--r--arch/sandbox/include/asm/io.h12
-rw-r--r--arch/x86/lib/acpi_table.c12
-rw-r--r--board/hisilicon/poplar/poplar.c28
-rw-r--r--board/isee/igep00x0/Kconfig2
-rw-r--r--board/isee/igep00x0/MAINTAINERS1
-rw-r--r--cmd/adc.c33
-rw-r--r--cmd/dtimg.c2
-rw-r--r--cmd/gpio.c2
-rw-r--r--cmd/help.c2
-rw-r--r--cmd/mmc.c13
-rw-r--r--cmd/mtd.c448
-rw-r--r--cmd/nvedit.c4
-rw-r--r--cmd/sf.c2
-rw-r--r--cmd/tpm-v2.c2
-rw-r--r--cmd/ubi.c6
-rw-r--r--cmd/unzip.c2
-rw-r--r--cmd/zip.c2
-rw-r--r--common/Kconfig10
-rw-r--r--common/bootm.c11
-rw-r--r--common/command.c100
-rw-r--r--common/fdt_support.c4
-rw-r--r--common/image-fdt.c56
-rw-r--r--common/spl/spl_ymodem.c29
-rw-r--r--common/xyzModem.c2
-rw-r--r--configs/am335x_igep003x_defconfig3
-rw-r--r--configs/am335x_sl50_defconfig3
-rw-r--r--configs/am57xx_evm_defconfig1
-rw-r--r--configs/hikey_defconfig1
-rw-r--r--configs/igep0032_defconfig53
-rw-r--r--configs/igep00x0_defconfig16
-rw-r--r--configs/mt7623n_bpir2_defconfig8
-rw-r--r--configs/mt7629_rfb_defconfig7
-rw-r--r--configs/poplar_defconfig12
-rw-r--r--configs/sandbox_defconfig5
-rw-r--r--configs/stm32f429-discovery_defconfig1
-rw-r--r--configs/stm32f429-evaluation_defconfig1
-rw-r--r--configs/stm32f469-discovery_defconfig1
-rw-r--r--configs/stm32h743-disco_defconfig1
-rw-r--r--configs/stm32h743-eval_defconfig1
-rw-r--r--doc/driver-model/fs_firmware_loader.txt35
-rw-r--r--drivers/block/blkcache.c2
-rw-r--r--drivers/clk/mediatek/clk-mt7623.c15
-rw-r--r--drivers/clk/mediatek/clk-mt7629.c15
-rw-r--r--drivers/clk/mediatek/clk-mtk.h2
-rw-r--r--drivers/core/dump.c4
-rw-r--r--drivers/i2c/Kconfig7
-rw-r--r--drivers/i2c/Makefile1
-rw-r--r--drivers/i2c/i2c-cdns.c9
-rw-r--r--drivers/i2c/muxes/i2c-mux-uclass.c4
-rw-r--r--drivers/i2c/muxes/pca954x.c2
-rw-r--r--drivers/i2c/xilinx_xiic.c340
-rw-r--r--drivers/misc/fs_loader.c108
-rw-r--r--drivers/mmc/hi6220_dw_mmc.c100
-rw-r--r--drivers/mmc/mmc.c39
-rw-r--r--drivers/mtd/nand/raw/Kconfig7
-rw-r--r--drivers/mtd/nand/raw/nand_base.c4
-rw-r--r--drivers/net/Kconfig10
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/mtk_eth.c1175
-rw-r--r--drivers/net/mtk_eth.h286
-rw-r--r--drivers/net/sandbox-raw.c9
-rw-r--r--drivers/reset/Kconfig7
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/reset-mediatek.c102
-rw-r--r--drivers/serial/Kconfig13
-rw-r--r--drivers/serial/ns16550.c20
-rw-r--r--drivers/serial/serial-uclass.c27
-rw-r--r--dts/Makefile3
-rw-r--r--env/common.c52
-rw-r--r--env/sf.c56
-rw-r--r--examples/standalone/Makefile1
-rw-r--r--examples/standalone/riscv.lds40
-rw-r--r--examples/standalone/stubs.c21
-rw-r--r--fs/fs.c56
-rw-r--r--include/command.h133
-rw-r--r--include/common.h8
-rw-r--r--include/configs/hikey.h2
-rw-r--r--include/configs/mt7623.h5
-rw-r--r--include/configs/mt7629.h5
-rw-r--r--include/configs/omap3_igep00x0.h10
-rw-r--r--include/configs/qemu-riscv.h2
-rw-r--r--include/dt-bindings/reset/mtk-reset.h18
-rw-r--r--include/fs_loader.h32
-rw-r--r--include/lmb.h7
-rw-r--r--include/log.h3
-rw-r--r--include/regmap.h14
-rw-r--r--include/serial.h38
-rw-r--r--lib/Makefile6
-rw-r--r--lib/efi_loader/efi_file.c4
-rw-r--r--lib/fdtdec.c10
-rw-r--r--lib/lmb.c106
-rw-r--r--lib/uuid.c2
-rw-r--r--net/tftp.c73
-rw-r--r--post/lib_powerpc/fpu/Makefile3
-rw-r--r--scripts/Kbuild.include6
-rw-r--r--scripts/Makefile.build2
-rw-r--r--scripts/Makefile.lib3
-rw-r--r--scripts/dtc/pylibfdt/Makefile2
-rw-r--r--test/dm/Makefile1
-rw-r--r--test/dm/bootcount.c30
-rw-r--r--test/dm/regmap.c7
-rw-r--r--test/dm/serial.c19
-rw-r--r--test/lib/Makefile1
-rw-r--r--test/lib/lmb.c601
-rw-r--r--test/py/tests/test_avb.py14
-rw-r--r--test/py/tests/test_bind.py143
-rw-r--r--test/py/tests/test_dfu.py38
-rw-r--r--test/py/tests/test_efi_loader.py12
-rw-r--r--test/py/tests/test_fpga.py54
-rw-r--r--test/py/tests/test_fs/conftest.py8
-rw-r--r--test/py/tests/test_mmc_rd.py66
-rw-r--r--test/py/tests/test_net.py22
-rw-r--r--test/py/tests/test_ums.py24
-rw-r--r--tools/buildman/README12
-rw-r--r--tools/buildman/builderthread.py8
-rw-r--r--tools/buildman/cmdline.py2
-rw-r--r--tools/buildman/control.py2
-rw-r--r--tools/buildman/toolchain.py42
-rw-r--r--tools/dtoc/dtb_platdata.py2
-rw-r--r--tools/imx8image.c2
150 files changed, 5947 insertions, 941 deletions
diff --git a/.travis.yml b/.travis.yml
index 321fd793a7..fc4d5a1d5c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -109,16 +109,9 @@ script:
#
# From buildman, exit code 129 means warnings only. If we've been asked to
# use clang only do one configuration.
- - if [[ "${TOOLCHAIN}" == "clang" ]]; then
+ - if [[ "${BUILDMAN}" != "" ]]; then
ret=0;
- make O=../.bm-work/${TEST_PY_BD} HOSTCC=clang-7 CC=clang-7 -j$(nproc)
- KCFLAGS=-Werror sandbox_config all || ret=$?;
- if [[ $ret -ne 0 ]]; then
- exit $ret;
- fi;
- elif [[ "${BUILDMAN}" != "" ]]; then
- ret=0;
- tools/buildman/buildman -P -E ${BUILDMAN} || ret=$?;
+ tools/buildman/buildman -P -E ${BUILDMAN} ${OVERRIDE}|| ret=$?;
if [[ $ret -ne 0 && $ret -ne 129 ]]; then
tools/buildman/buildman -sdeP ${BUILDMAN};
exit $ret;
@@ -351,7 +344,7 @@ matrix:
env:
- TEST_PY_BD="sandbox"
BUILDMAN="^sandbox$"
- TOOLCHAIN="clang"
+ OVERRIDE="clang-7"
- name: "test/py sandbox_spl"
env:
- TEST_PY_BD="sandbox_spl"
diff --git a/MAINTAINERS b/MAINTAINERS
index 3fa5d3e96f..399a839e07 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -176,6 +176,8 @@ F: drivers/ram/mediatek/
F: drivers/spi/mtk_qspi.c
F: drivers/timer/mtk_timer.c
F: drivers/watchdog/mtk_wdt.c
+F: drivers/net/mtk_eth.c
+F: drivers/reset/reset-mediatek.c
F: tools/mtk_image.c
F: tools/mtk_image.h
N: mediatek
diff --git a/Makefile b/Makefile
index 6aa08964ff..3be9fc5c34 100644
--- a/Makefile
+++ b/Makefile
@@ -534,7 +534,7 @@ include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
@# Otherwise, 'make silentoldconfig' would be invoked twice.
$(Q)touch include/config/auto.conf
-u-boot.cfg spl/u-boot.cfg tpl/u-boot.cfg: include/config.h FORCE
+u-boot.cfg spl/u-boot.cfg tpl/u-boot.cfg:
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.autoconf $(@)
-include include/autoconf.mk
@@ -910,7 +910,7 @@ quiet_cmd_cfgcheck = CFGCHK $2
cmd_cfgcheck = $(srctree)/scripts/check-config.sh $2 \
$(srctree)/scripts/config_whitelist.txt $(srctree)
-all: $(ALL-y) cfg
+all: $(ALL-y)
ifeq ($(CONFIG_DM_I2C_COMPAT)$(CONFIG_SANDBOX),y)
@echo >&2 "===================== WARNING ======================"
@echo >&2 "This board uses CONFIG_DM_I2C_COMPAT. Please remove"
@@ -1198,6 +1198,7 @@ MKIMAGEFLAGS_u-boot.pbl = -n $(srctree)/$(CONFIG_SYS_FSL_PBL_RCW:"%"=%) \
u-boot-dtb.img u-boot.img u-boot.kwb u-boot.pbl u-boot-ivt.img: \
$(if $(CONFIG_SPL_LOAD_FIT),u-boot-nodtb.bin dts/dt.dtb,u-boot.bin) FORCE
$(call if_changed,mkimage)
+ $(BOARD_SIZE_CHECK)
u-boot.itb: u-boot-nodtb.bin dts/dt.dtb $(U_BOOT_ITS) FORCE
$(call if_changed,mkfitimage)
@@ -1555,7 +1556,7 @@ ifneq ($(KBUILD_SRC),)
endif
# prepare2 creates a makefile if using a separate output directory
-prepare2: prepare3 outputmakefile
+prepare2: prepare3 outputmakefile cfg
prepare1: prepare2 $(version_h) $(timestamp_h) \
include/config/auto.conf
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index dda4e59491..b2ca87deef 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -193,7 +193,9 @@ dtb-$(CONFIG_AM33XX) += am335x-boneblack.dtb am335x-bone.dtb \
am335x-pxm50.dtb \
am335x-rut.dtb \
am335x-pdu001.dtb \
- am335x-chiliboard.dtb
+ am335x-chiliboard.dtb \
+ am335x-sl50.dtb \
+ am335x-base0033.dtb
dtb-$(CONFIG_AM43XX) += am437x-gp-evm.dtb am437x-sk-evm.dtb \
am43x-epos-evm.dtb \
am437x-idk-evm.dtb \
@@ -522,6 +524,9 @@ dtb-$(CONFIG_TARGET_OMAP3_BEAGLE) += \
omap3-beagle-xm.dtb \
omap3-beagle.dtb
+dtb-$(CONFIG_TARGET_OMAP3_IGEP00X0) += \
+ omap3-igep0020.dtb
+
dtb-$(CONFIG_TARGET_SAMA5D2_PTC_EK) += \
at91-sama5d2_ptc_ek.dtb
diff --git a/arch/arm/dts/am335x-base0033.dts b/arch/arm/dts/am335x-base0033.dts
new file mode 100644
index 0000000000..29782be076
--- /dev/null
+++ b/arch/arm/dts/am335x-base0033.dts
@@ -0,0 +1,95 @@
+/*
+ * am335x-base0033.dts - Device Tree file for IGEP AQUILA EXPANSION
+ *
+ * Copyright (C) 2013 ISEE 2007 SL - http://www.isee.biz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "am335x-igep0033.dtsi"
+
+/ {
+ model = "IGEP COM AM335x on AQUILA Expansion";
+ compatible = "isee,am335x-base0033", "isee,am335x-igep0033", "ti,am33xx";
+
+ hdmi {
+ compatible = "ti,tilcdc,slave";
+ i2c = <&i2c0>;
+ pinctrl-names = "default", "off";
+ pinctrl-0 = <&nxp_hdmi_pins>;
+ pinctrl-1 = <&nxp_hdmi_off_pins>;
+ status = "okay";
+ };
+
+ leds_base {
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_base_pins>;
+
+ compatible = "gpio-leds";
+
+ led0 {
+ label = "base:red:user";
+ gpios = <&gpio1 21 GPIO_ACTIVE_HIGH>; /* gpio1_21 */
+ default-state = "off";
+ };
+
+ led1 {
+ label = "base:green:user";
+ gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>; /* gpio2_0 */
+ default-state = "off";
+ };
+ };
+};
+
+&am33xx_pinmux {
+ nxp_hdmi_pins: pinmux_nxp_hdmi_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT | MUX_MODE3) /* xdma_event_intr0.clkout1 */
+ AM33XX_IOPAD(0x8a0, PIN_OUTPUT | MUX_MODE0) /* lcd_data0 */
+ AM33XX_IOPAD(0x8a4, PIN_OUTPUT | MUX_MODE0) /* lcd_data1 */
+ AM33XX_IOPAD(0x8a8, PIN_OUTPUT | MUX_MODE0) /* lcd_data2 */
+ AM33XX_IOPAD(0x8ac, PIN_OUTPUT | MUX_MODE0) /* lcd_data3 */
+ AM33XX_IOPAD(0x8b0, PIN_OUTPUT | MUX_MODE0) /* lcd_data4 */
+ AM33XX_IOPAD(0x8b4, PIN_OUTPUT | MUX_MODE0) /* lcd_data5 */
+ AM33XX_IOPAD(0x8b8, PIN_OUTPUT | MUX_MODE0) /* lcd_data6 */
+ AM33XX_IOPAD(0x8bc, PIN_OUTPUT | MUX_MODE0) /* lcd_data7 */
+ AM33XX_IOPAD(0x8c0, PIN_OUTPUT | MUX_MODE0) /* lcd_data8 */
+ AM33XX_IOPAD(0x8c4, PIN_OUTPUT | MUX_MODE0) /* lcd_data9 */
+ AM33XX_IOPAD(0x8c8, PIN_OUTPUT | MUX_MODE0) /* lcd_data10 */
+ AM33XX_IOPAD(0x8cc, PIN_OUTPUT | MUX_MODE0) /* lcd_data11 */
+ AM33XX_IOPAD(0x8d0, PIN_OUTPUT | MUX_MODE0) /* lcd_data12 */
+ AM33XX_IOPAD(0x8d4, PIN_OUTPUT | MUX_MODE0) /* lcd_data13 */
+ AM33XX_IOPAD(0x8d8, PIN_OUTPUT | MUX_MODE0) /* lcd_data14 */
+ AM33XX_IOPAD(0x8dc, PIN_OUTPUT | MUX_MODE0) /* lcd_data15 */
+ AM33XX_IOPAD(0x8e0, PIN_OUTPUT | MUX_MODE0) /* lcd_vsync */
+ AM33XX_IOPAD(0x8e4, PIN_OUTPUT | MUX_MODE0) /* lcd_hsync */
+ AM33XX_IOPAD(0x8e8, PIN_OUTPUT | MUX_MODE0) /* lcd_pclk */
+ AM33XX_IOPAD(0x8ec, PIN_OUTPUT | MUX_MODE0) /* lcd_ac_bias_en */
+ >;
+ };
+ nxp_hdmi_off_pins: pinmux_nxp_hdmi_off_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x9b0, PIN_OUTPUT | MUX_MODE3) /* xdma_event_intr0.clkout1 */
+ >;
+ };
+
+ leds_base_pins: pinmux_leds_base_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a5.gpio1_21 */
+ AM33XX_IOPAD(0x888, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_csn3.gpio2_0 */
+ >;
+ };
+};
+
+&lcdc {
+ status = "okay";
+};
+
+&i2c0 {
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c256";
+ reg = <0x50>;
+ };
+};
diff --git a/arch/arm/dts/am335x-igep0033.dtsi b/arch/arm/dts/am335x-igep0033.dtsi
new file mode 100644
index 0000000000..a5769a8f5f
--- /dev/null
+++ b/arch/arm/dts/am335x-igep0033.dtsi
@@ -0,0 +1,323 @@
+/*
+ * am335x-igep0033.dtsi - Device Tree file for IGEP COM AQUILA AM335x
+ *
+ * Copyright (C) 2013 ISEE 2007 SL - http://www.isee.biz
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+
+#include "am33xx.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&vdd1_reg>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x10000000>; /* 256 MB */
+ };
+
+ leds {
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_pins>;
+
+ compatible = "gpio-leds";
+
+ led0 {
+ label = "com:green:user";
+ gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+ };
+
+ vbat: fixedregulator0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vbat";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-boot-on;
+ };
+
+ vmmc: fixedregulator1 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmc";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&am33xx_pinmux {
+ i2c0_pins: pinmux_i2c0_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ nandflash_pins: pinmux_nandflash_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad0.gpmc_ad0 */
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad1.gpmc_ad1 */
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad2.gpmc_ad2 */
+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad3.gpmc_ad3 */
+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad4.gpmc_ad4 */
+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad5.gpmc_ad5 */
+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad6.gpmc_ad6 */
+ AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_ad7.gpmc_ad7 */
+ AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE0) /* gpmc_wait0.gpmc_wait0 */
+ AM33XX_IOPAD(0x874, PIN_INPUT_PULLUP | MUX_MODE7) /* gpmc_wpn.gpio0_30 */
+ AM33XX_IOPAD(0x87c, PIN_OUTPUT | MUX_MODE0) /* gpmc_csn0.gpmc_csn0 */
+ AM33XX_IOPAD(0x890, PIN_OUTPUT | MUX_MODE0) /* gpmc_advn_ale.gpmc_advn_ale */
+ AM33XX_IOPAD(0x894, PIN_OUTPUT | MUX_MODE0) /* gpmc_oen_ren.gpmc_oen_ren */
+ AM33XX_IOPAD(0x898, PIN_OUTPUT | MUX_MODE0) /* gpmc_wen.gpmc_wen */
+ AM33XX_IOPAD(0x89c, PIN_OUTPUT | MUX_MODE0) /* gpmc_be0n_cle.gpmc_be0n_cle */
+ >;
+ };
+
+ uart0_pins: pinmux_uart0_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+ >;
+ };
+
+ leds_pins: pinmux_leds_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x85c, PIN_OUTPUT_PULLDOWN | MUX_MODE7) /* gpmc_a7.gpio1_23 */
+ >;
+ };
+};
+
+&mac {
+ status = "okay";
+};
+
+&davinci_mdio {
+ status = "okay";
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "rmii";
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <1>;
+ phy-mode = "rmii";
+};
+
+&phy_sel {
+ rmii-clock-ext;
+};
+
+&elm {
+ status = "okay";
+};
+
+&gpmc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&nandflash_pins>;
+
+ ranges = <0 0 0x08000000 0x1000000>; /* CS0: 16MB for NAND */
+
+ nand@0,0 {
+ compatible = "ti,omap2-nand";
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ interrupt-parent = <&gpmc>;
+ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+ <1 IRQ_TYPE_NONE>; /* termcount */
+ rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
+ nand-bus-width = <8>;
+ ti,nand-ecc-opt = "bch8";
+ gpmc,device-width = <1>;
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-on-ns = <0>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,clk-activation-ns = <0>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ti,elm-id = <&elm>;
+
+ /* MTD partition table */
+ partition@0 {
+ label = "SPL";
+ reg = <0x00000000 0x000080000>;
+ };
+
+ partition@1 {
+ label = "U-boot";
+ reg = <0x00080000 0x001e0000>;
+ };
+
+ partition@2 {
+ label = "U-Boot Env";
+ reg = <0x00260000 0x00020000>;
+ };
+
+ partition@3 {
+ label = "Kernel";
+ reg = <0x00280000 0x00500000>;
+ };
+
+ partition@4 {
+ label = "File System";
+ reg = <0x00780000 0x007880000>;
+ };
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ clock-frequency = <400000>;
+
+ tps: tps@2d {
+ reg = <0x2d>;
+ };
+};
+
+&mmc1 {
+ status = "okay";
+ vmmc-supply = <&vmmc>;
+ bus-width = <4>;
+};
+
+&uart0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+};
+
+&usb {
+ status = "okay";
+};
+
+&usb_ctrl_mod {
+ status = "okay";
+};
+
+&usb0_phy {
+ status = "okay";
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+ dr_mode = "host";
+};
+
+&cppi41dma {
+ status = "okay";
+};
+
+#include "tps65910.dtsi"
+
+&tps {
+ vcc1-supply = <&vbat>;
+ vcc2-supply = <&vbat>;
+ vcc3-supply = <&vbat>;
+ vcc4-supply = <&vbat>;
+ vcc5-supply = <&vbat>;
+ vcc6-supply = <&vbat>;
+ vcc7-supply = <&vbat>;
+ vccio-supply = <&vbat>;
+
+ regulators {
+ vrtc_reg: regulator@0 {
+ regulator-always-on;
+ };
+
+ vio_reg: regulator@1 {
+ regulator-always-on;
+ };
+
+ vdd1_reg: regulator@2 {
+ /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
+ regulator-name = "vdd_mpu";
+ regulator-min-microvolt = <912500>;
+ regulator-max-microvolt = <1312500>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd2_reg: regulator@3 {
+ /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <912500>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdd3_reg: regulator@4 {
+ regulator-always-on;
+ };
+
+ vdig1_reg: regulator@5 {
+ regulator-always-on;
+ };
+
+ vdig2_reg: regulator@6 {
+ regulator-always-on;
+ };
+
+ vpll_reg: regulator@7 {
+ regulator-always-on;
+ };
+
+ vdac_reg: regulator@8 {
+ regulator-always-on;
+ };
+
+ vaux1_reg: regulator@9 {
+ regulator-always-on;
+ };
+
+ vaux2_reg: regulator@10 {
+ regulator-always-on;
+ };
+
+ vaux33_reg: regulator@11 {
+ regulator-always-on;
+ };
+
+ vmmc_reg: regulator@12 {
+ regulator-always-on;
+ };
+ };
+};
+
diff --git a/arch/arm/dts/am335x-sl50.dts b/arch/arm/dts/am335x-sl50.dts
new file mode 100644
index 0000000000..1bcc60424e
--- /dev/null
+++ b/arch/arm/dts/am335x-sl50.dts
@@ -0,0 +1,549 @@
+/*
+ * Copyright (C) 2015 Toby Churchill - http://www.toby-churchill.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "am33xx.dtsi"
+
+/ {
+ model = "Toby Churchill SL50 Series";
+ compatible = "tcl,am335x-sl50", "ti,am33xx";
+
+ cpus {
+ cpu@0 {
+ cpu0-supply = <&dcdc2_reg>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB */
+ };
+
+ chosen {
+ stdout-path = &uart0;
+ };
+
+ leds {
+ compatible = "gpio-leds";
+ pinctrl-names = "default";
+ pinctrl-0 = <&led_pins>;
+
+ led0 {
+ label = "sl50:green:usr0";
+ gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led1 {
+ label = "sl50:red:usr1";
+ gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led2 {
+ label = "sl50:green:usr2";
+ gpios = <&gpio1 23 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+
+ led3 {
+ label = "sl50:red:usr3";
+ gpios = <&gpio1 24 GPIO_ACTIVE_LOW>;
+ default-state = "off";
+ };
+ };
+
+ backlight0: disp0 {
+ compatible = "pwm-backlight";
+ pwms = <&ehrpwm1 0 500000 0>;
+ brightness-levels = <0 10 20 30 40 50 60 70 80 90 99>;
+ default-brightness-level = <6>;
+ };
+
+ backlight1: disp1 {
+ compatible = "pwm-backlight";
+ pwms = <&ehrpwm1 1 500000 0>;
+ brightness-levels = <0 10 20 30 40 50 60 70 80 90 99>;
+ default-brightness-level = <6>;
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ /* audio external oscillator */
+ tlv320aic3x_mclk: oscillator@0 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24576000>; /* 24.576MHz */
+ };
+ };
+
+ sound {
+ compatible = "ti,da830-evm-audio";
+ ti,model = "AM335x-SL50";
+ ti,audio-codec = <&audio_codec>;
+ ti,mcasp-controller = <&mcasp0>;
+
+ clocks = <&tlv320aic3x_mclk>;
+ clock-names = "mclk";
+
+ ti,audio-routing =
+ "Headphone Jack", "HPLOUT",
+ "Headphone Jack", "HPROUT",
+ "LINE1R", "Line In",
+ "LINE1L", "Line In";
+ };
+
+ emmc_pwrseq: pwrseq@0 {
+ compatible = "mmc-pwrseq-emmc";
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_pwrseq_pins>;
+ reset-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+ };
+
+ vmmcsd_fixed: fixedregulator0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsd_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+};
+
+&am33xx_pinmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&lwb_pins>;
+
+ led_pins: pinmux_led_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x854, PIN_OUTPUT | MUX_MODE7) /* gpmc_a5.gpio1_21 */
+ AM33XX_IOPAD(0x858, PIN_OUTPUT | MUX_MODE7) /* gpmc_a6.gpio1_22 */
+ AM33XX_IOPAD(0x85c, PIN_OUTPUT | MUX_MODE7) /* gpmc_a7.gpio1_23 */
+ AM33XX_IOPAD(0x860, PIN_OUTPUT | MUX_MODE7) /* gpmc_a8.gpio1_24 */
+ >;
+ };
+
+ uart0_pins: pinmux_uart0_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */
+ AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart0_txd.uart0_txd */
+ >;
+ };
+
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */
+ AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_txd.uart1_txd */
+ >;
+ };
+
+ uart4_pins: pinmux_uart4_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x870, PIN_INPUT_PULLUP | MUX_MODE6) /* gpmc_wait0.uart4_rxd */
+ AM33XX_IOPAD(0x874, PIN_OUTPUT_PULLDOWN | MUX_MODE6) /* gpmc_wpn.uart4_txd */
+ >;
+ };
+
+ i2c0_pins: pinmux_i2c0_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_sda.i2c0_sda */
+ AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c0_scl.i2c0_scl */
+ >;
+ };
+
+ i2c2_pins: pinmux_i2c2_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x978, PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_ctsn.i2c2_sda */
+ AM33XX_IOPAD(0x97c, PIN_INPUT_PULLUP | MUX_MODE3) /* uart1_rtsn.i2c2_scl */
+ >;
+ };
+
+ cpsw_default: cpsw_default {
+ pinctrl-single,pins = <
+ /* Slave 1 */
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxerr.mii1_rxerr */
+ AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txen.mii1_txen */
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxdv.mii1_rxdv */
+ AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd3.mii1_txd3 */
+ AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd2.mii1_txd2 */
+ AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd1.mii1_txd1 */
+ AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mii1_txd0.mii1_txd0 */
+ AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_txclk.mii1_txclk */
+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxclk.mii1_rxclk */
+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd3.mii1_rxd3 */
+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd2.mii1_rxd2 */
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd1.mii1_rxd1 */
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE0) /* mii1_rxd0.mii1_rxd0 */
+ >;
+ };
+
+ cpsw_sleep: cpsw_sleep {
+ pinctrl-single,pins = <
+ /* Slave 1 reset value */
+ AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ davinci_mdio_default: davinci_mdio_default {
+ pinctrl-single,pins = <
+ /* MDIO */
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0) /* mdio_data.mdio_data */
+ AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0) /* mdio_clk.mdio_clk */
+ >;
+ };
+
+ davinci_mdio_sleep: davinci_mdio_sleep {
+ pinctrl-single,pins = <
+ /* MDIO reset value */
+ AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x96c, PIN_INPUT | MUX_MODE7) /* uart0_rtsn.gpio1_9 */
+ >;
+ };
+
+ emmc_pwrseq_pins: pinmux_emmc_pwrseq_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x850, PIN_OUTPUT_PULLUP | MUX_MODE7) /* gpmc_a4.gpio1_20 */
+ >;
+ };
+
+ emmc_pins: pinmux_emmc_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
+ AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
+ AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
+ AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
+ AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
+ AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
+ AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
+ AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
+ AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
+ AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
+ >;
+ };
+
+ audio_pins: pinmux_audio_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x9ac, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_ahcklx.mcasp0_ahclkx */
+ AM33XX_IOPAD(0x994, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */
+ AM33XX_IOPAD(0x990, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */
+ AM33XX_IOPAD(0x998, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_axr0.mcasp0_axr0 */
+ AM33XX_IOPAD(0x99c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2 */
+ >;
+ };
+
+ ehrpwm1_pins: pinmux_ehrpwm1a_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x848, PIN_OUTPUT | MUX_MODE6) /* gpmc_a2.ehrpwm1a */
+ AM33XX_IOPAD(0x84c, PIN_OUTPUT | MUX_MODE6) /* gpmc_a3.ehrpwm1b */
+ >;
+ };
+
+ spi0_pins: pinmux_spi0_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x954, PIN_INPUT_PULLUP | MUX_MODE0) /* SPI0_MOSI - spi0_d0.spi0_d0 */
+ AM33XX_IOPAD(0x958, PIN_INPUT_PULLUP | MUX_MODE0) /* SPI0_MISO - spi0_d1.spi0_d1 */
+ AM33XX_IOPAD(0x950, PIN_INPUT_PULLUP | MUX_MODE0) /* SPI0_CLK - spi0_clk.spi0_clk */
+ AM33XX_IOPAD(0x95c, PIN_INPUT_PULLUP | MUX_MODE0) /* SPI0_CS0 (NBATTSS) - spi0_cs0.spi0_cs0 */
+ AM33XX_IOPAD(0x960, PIN_INPUT_PULLUP | MUX_MODE0) /* SPI0_CS1 (FPGA_FLASH_NCS) - spi0_cs1.spi0_cs1 */
+ >;
+ };
+
+ lwb_pins: pinmux_lwb_pins {
+ pinctrl-single,pins = <
+ AM33XX_IOPAD(0x9a4, PIN_OUTPUT | MUX_MODE7) /* SoundPA_en - mcasp0_fsr.gpio3_19 */
+ AM33XX_IOPAD(0x828, PIN_OUTPUT | MUX_MODE7) /* nKbdOnC - gpmc_ad10.gpio0_26 */
+ AM33XX_IOPAD(0x830, PIN_INPUT_PULLUP | MUX_MODE7) /* nKbdInt - gpmc_ad12.gpio1_12 */
+ AM33XX_IOPAD(0x834, PIN_INPUT_PULLUP | MUX_MODE7) /* nKbdReset - gpmc_ad13.gpio1_13 */
+ AM33XX_IOPAD(0x838, PIN_INPUT_PULLUP | MUX_MODE7) /* nDispReset - gpmc_ad14.gpio1_14 */
+ AM33XX_IOPAD(0x844, PIN_INPUT_PULLUP | MUX_MODE7) /* USB1_enPower - gpmc_a1.gpio1_17 */
+ /* PDI Bus - Battery system */
+ AM33XX_IOPAD(0x840, PIN_INPUT_PULLUP | MUX_MODE7) /* nBattReset gpmc_a0.gpio1_16 */
+ AM33XX_IOPAD(0x83c, PIN_INPUT_PULLUP | MUX_MODE7) /* BattPDIData gpmc_ad15.gpio1_15 */
+ >;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+
+ clock-frequency = <400000>;
+
+ tps: tps@24 {
+ reg = <0x24>;
+ };
+
+ bq32000: rtc@68 {
+ compatible = "ti,bq32000";
+ trickle-resistor-ohms = <1120>;
+ reg = <0x68>;
+ };
+
+ eeprom: eeprom@50 {
+ compatible = "atmel,24c256";
+ reg = <0x50>;
+ };
+
+ gpio_exp: mcp23017@20 {
+ compatible = "microchip,mcp23017";
+ reg = <0x20>;
+ };
+
+};
+
+&i2c2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c2_pins>;
+
+ clock-frequency = <400000>;
+
+ audio_codec: tlv320aic3106@1b {
+ status = "okay";
+ compatible = "ti,tlv320aic3106";
+ reg = <0x1b>;
+
+ AVDD-supply = <&ldo4_reg>;
+ IOVDD-supply = <&ldo4_reg>;
+ DRVDD-supply = <&ldo4_reg>;
+ DVDD-supply = <&ldo3_reg>;
+ };
+
+ /* Ambient Light Sensor */
+ als: isl29023@44 {
+ compatible = "isil,isl29023";
+ reg = <0x44>;
+ };
+};
+
+&rtc {
+ status = "disabled";
+};
+
+&usb {
+ status = "okay";
+};
+
+&usb_ctrl_mod {
+ status = "okay";
+};
+
+&usb0_phy {
+ status = "okay";
+};
+
+&usb1_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "peripheral";
+};
+
+&usb1 {
+ status = "okay";
+ dr_mode = "host";
+};
+
+&cppi41dma {
+ status = "okay";
+};
+
+&mmc1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ bus-width = <4>;
+ cd-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&vmmcsd_fixed>;
+};
+
+&mmc2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&emmc_pins>;
+ bus-width = <8>;
+ vmmc-supply = <&vmmcsd_fixed>;
+ mmc-pwrseq = <&emmc_pwrseq>;
+};
+
+&mcasp0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&audio_pins>;
+
+ op-mode = <0>; /* MCASP_ISS_MODE */
+ tdm-slots = <2>;
+ serial-dir = <
+ 2 0 1 0
+ 0 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ >;
+ tx-num-evt = <1>;
+ rx-num-evt = <1>;
+};
+
+&uart0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_pins>;
+};
+
+&uart1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+};
+
+&uart4 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart4_pins>;
+};
+
+&spi0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&spi0_pins>;
+
+ flash: n25q032@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "micron,n25q032";
+ reg = <1>;
+ spi-max-frequency = <5000000>;
+ };
+};
+
+#include "tps65217.dtsi"
+
+&tps {
+ ti,pmic-shutdown-controller;
+
+ interrupt-parent = <&intc>;
+ interrupts = <7>; /* NNMI */
+
+ regulators {
+ dcdc1_reg: regulator@0 {
+ /* VDDS_DDR */
+ regulator-min-microvolt = <1500000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ };
+
+ dcdc2_reg: regulator@1 {
+ /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
+ regulator-name = "vdd_mpu";
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <1325000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ dcdc3_reg: regulator@2 {
+ /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
+ regulator-name = "vdd_core";
+ regulator-min-microvolt = <925000>;
+ regulator-max-microvolt = <1150000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ ldo1_reg: regulator@3 {
+ /* VRTC / VIO / VDDS*/
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo2_reg: regulator@4 {
+ /* VDD_3V3AUX */
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo3_reg: regulator@5 {
+ /* VDD_1V8 */
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: regulator@6 {
+ /* VDD_3V3A */
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+ };
+};
+
+&cpsw_emac0 {
+ phy_id = <&davinci_mdio>, <0>;
+ phy-mode = "mii";
+};
+
+&cpsw_emac1 {
+ phy_id = <&davinci_mdio>, <1>;
+ phy-mode = "mii";
+};
+
+&mac {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&cpsw_default>;
+ pinctrl-1 = <&cpsw_sleep>;
+};
+
+&davinci_mdio {
+ status = "okay";
+ pinctrl-names = "default", "sleep";
+ pinctrl-0 = <&davinci_mdio_default>;
+ pinctrl-1 = <&davinci_mdio_sleep>;
+};
+
+&sham {
+ status = "okay";
+};
+
+&aes {
+ status = "okay";
+};
+
+&epwmss1 {
+ status = "okay";
+};
+
+&ehrpwm1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&ehrpwm1_pins>;
+};
diff --git a/arch/arm/dts/hi6220-hikey-u-boot.dtsi b/arch/arm/dts/hi6220-hikey-u-boot.dtsi
new file mode 100644
index 0000000000..3113983240
--- /dev/null
+++ b/arch/arm/dts/hi6220-hikey-u-boot.dtsi
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * U-Boot additions
+ *
+ * Copyright (c) 2018 Linaro Ltd.
+ */
+
+&mmc0 {
+ u-boot,dm-pre-reloc;
+};
+
+&mmc1 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/arm/dts/hi6220-hikey.dts b/arch/arm/dts/hi6220-hikey.dts
index 24f09257af..d63929348b 100644
--- a/arch/arm/dts/hi6220-hikey.dts
+++ b/arch/arm/dts/hi6220-hikey.dts
@@ -40,6 +40,17 @@
};
};
+&mmc0 {
+ status = "okay";
+ non-removable;
+ bus-width = <8>;
+};
+
+&mmc1 {
+ status = "okay";
+ bus-width = <4>;
+};
+
&uart2 {
label = "LS-UART0";
};
diff --git a/arch/arm/dts/hi6220.dtsi b/arch/arm/dts/hi6220.dtsi
index a610ccb634..501c8906fd 100644
--- a/arch/arm/dts/hi6220.dtsi
+++ b/arch/arm/dts/hi6220.dtsi
@@ -162,6 +162,24 @@
#clock-cells = <1>;
};
+ mmc0: dwmmc@f723d000 {
+ compatible = "hisilicon,hi6220-dw-mshc";
+ reg = <0x0 0xf723d000 0x0 0x1000>;
+ interrupts = <0x0 0x48 0x4>;
+ clocks = <&sys_ctrl 2>, <&sys_ctrl 1>;
+ clock-names = "ciu", "biu";
+ status = "disabled";
+ };
+
+ mmc1: dwmmc@f723e000 {
+ compatible = "hisilicon,hi6220-dw-mshc";
+ reg = <0x0 0xf723e000 0x0 0x1000>;
+ interrupts = <0x0 0x49 0x4>;
+ clocks = <&sys_ctrl 4>, <&sys_ctrl 3>;
+ clock-names = "ciu", "biu";
+ status = "disabled";
+ };
+
uart0: uart@f8015000 { /* console */
compatible = "arm,pl011", "arm,primecell";
reg = <0x0 0xf8015000 0x0 0x1000>;
diff --git a/arch/arm/dts/mt7623.dtsi b/arch/arm/dts/mt7623.dtsi
index f50f4ef1b9..448d1d7381 100644
--- a/arch/arm/dts/mt7623.dtsi
+++ b/arch/arm/dts/mt7623.dtsi
@@ -10,6 +10,7 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/mt7623-power.h>
+#include <dt-bindings/reset/mtk-reset.h>
#include "skeleton.dtsi"
/ {
@@ -248,8 +249,26 @@
};
ethsys: syscon@1b000000 {
- compatible = "mediatek,mt7623-ethsys";
+ compatible = "mediatek,mt7623-ethsys", "syscon";
reg = <0x1b000000 0x1000>;
#clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ eth: ethernet@1b100000 {
+ compatible = "mediatek,mt7623-eth", "syscon";
+ reg = <0x1b100000 0x20000>;
+ clocks = <&topckgen CLK_TOP_ETHIF_SEL>,
+ <&ethsys CLK_ETHSYS_ESW>,
+ <&ethsys CLK_ETHSYS_GP1>,
+ <&ethsys CLK_ETHSYS_GP2>,
+ <&apmixedsys CLK_APMIXED_TRGPLL>;
+ clock-names = "ethif", "esw", "gp1", "gp2", "trgpll";
+ power-domains = <&scpsys MT7623_POWER_DOMAIN_ETH>;
+ resets = <&ethsys ETHSYS_FE_RST>,
+ <&ethsys ETHSYS_MCM_RST>;
+ reset-names = "fe", "mcm";
+ mediatek,ethsys = <&ethsys>;
+ status = "disabled";
};
};
diff --git a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
index 84a77fde44..51628bb639 100644
--- a/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
+++ b/arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
@@ -67,6 +67,19 @@
};
};
+&eth {
+ status = "okay";
+ mediatek,gmac-id = <0>;
+ phy-mode = "rgmii";
+ mediatek,switch = "mt7530";
+ reset-gpios = <&gpio 33 GPIO_ACTIVE_HIGH>;
+
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
+};
+
&mmc0 {
pinctrl-names = "default";
pinctrl-0 = <&mmc0_pins_default>;
diff --git a/arch/arm/dts/mt7629-rfb.dts b/arch/arm/dts/mt7629-rfb.dts
index a6d28a060f..95d10aa6d3 100644
--- a/arch/arm/dts/mt7629-rfb.dts
+++ b/arch/arm/dts/mt7629-rfb.dts
@@ -22,6 +22,17 @@
};
};
+&eth {
+ status = "okay";
+ mediatek,gmac-id = <1>;
+ phy-mode = "gmii";
+ phy-handle = <&phy0>;
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
&pinctrl {
qspi_pins: qspi-pins {
mux {
diff --git a/arch/arm/dts/mt7629.dtsi b/arch/arm/dts/mt7629.dtsi
index e6052bbdcf..c87115e0fe 100644
--- a/arch/arm/dts/mt7629.dtsi
+++ b/arch/arm/dts/mt7629.dtsi
@@ -10,6 +10,7 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/power/mt7629-power.h>
+#include <dt-bindings/reset/mtk-reset.h>
#include "skeleton.dtsi"
/ {
@@ -228,6 +229,48 @@
compatible = "mediatek,mt7629-ethsys", "syscon";
reg = <0x1b000000 0x1000>;
#clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ eth: ethernet@1b100000 {
+ compatible = "mediatek,mt7629-eth", "syscon";
+ reg = <0x1b100000 0x20000>;
+ clocks = <&topckgen CLK_TOP_ETH_SEL>,
+ <&topckgen CLK_TOP_F10M_REF_SEL>,
+ <&ethsys CLK_ETH_ESW_EN>,
+ <&ethsys CLK_ETH_GP0_EN>,
+ <&ethsys CLK_ETH_GP1_EN>,
+ <&ethsys CLK_ETH_GP2_EN>,
+ <&ethsys CLK_ETH_FE_EN>,
+ <&sgmiisys0 CLK_SGMII_TX_EN>,
+ <&sgmiisys0 CLK_SGMII_RX_EN>,
+ <&sgmiisys0 CLK_SGMII_CDR_REF>,
+ <&sgmiisys0 CLK_SGMII_CDR_FB>,
+ <&sgmiisys1 CLK_SGMII_TX_EN>,
+ <&sgmiisys1 CLK_SGMII_RX_EN>,
+ <&sgmiisys1 CLK_SGMII_CDR_REF>,
+ <&sgmiisys1 CLK_SGMII_CDR_FB>,
+ <&apmixedsys CLK_APMIXED_SGMIPLL>,
+ <&apmixedsys CLK_APMIXED_ETH2PLL>;
+ clock-names = "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2",
+ "fe", "sgmii_tx250m", "sgmii_rx250m",
+ "sgmii_cdr_ref", "sgmii_cdr_fb",
+ "sgmii2_tx250m", "sgmii2_rx250m",
+ "sgmii2_cdr_ref", "sgmii2_cdr_fb",
+ "sgmii_ck", "eth2pll";
+ assigned-clocks = <&topckgen CLK_TOP_ETH_SEL>,
+ <&topckgen CLK_TOP_F10M_REF_SEL>;
+ assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>,
+ <&topckgen CLK_TOP_SGMIIPLL_D2>;
+ power-domains = <&scpsys MT7629_POWER_DOMAIN_ETHSYS>;
+ resets = <&ethsys ETHSYS_FE_RST>;
+ reset-names = "fe";
+ mediatek,ethsys = <&ethsys>;
+ mediatek,sgmiisys = <&sgmiisys0>;
+ mediatek,infracfg = <&infracfg>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
};
sgmiisys0: syscon@1b128000 {
diff --git a/arch/arm/dts/omap3-igep.dtsi b/arch/arm/dts/omap3-igep.dtsi
new file mode 100644
index 0000000000..f33cc80c9d
--- /dev/null
+++ b/arch/arm/dts/omap3-igep.dtsi
@@ -0,0 +1,250 @@
+/*
+ * Common device tree for IGEP boards based on AM/DM37x
+ *
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@osg.samsung.com>
+ * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+/dts-v1/;
+
+#include "omap36xx.dtsi"
+
+/ {
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x80000000 0x20000000>; /* 512 MB */
+ };
+
+ chosen {
+ stdout-path = &uart3;
+ };
+
+ sound {
+ compatible = "ti,omap-twl4030";
+ ti,model = "igep2";
+ ti,mcbsp = <&mcbsp2>;
+ };
+
+ vdd33: regulator-vdd33 {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd33";
+ regulator-always-on;
+ };
+
+};
+
+&omap3_pmx_core {
+ gpmc_pins: pinmux_gpmc_pins {
+ pinctrl-single,pins = <
+ /* OneNAND seems to require PIN_INPUT on clock. */
+ OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0) /* gpmc_clk.gpmc_clk */
+ >;
+ };
+
+ uart1_pins: pinmux_uart1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2182, PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */
+ OMAP3_CORE1_IOPAD(0x217c, PIN_OUTPUT | MUX_MODE0) /* uart1_tx.uart1_tx */
+ >;
+ };
+
+ uart3_pins: pinmux_uart3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x219e, PIN_INPUT | MUX_MODE0) /* uart3_rx.uart3_rx */
+ OMAP3_CORE1_IOPAD(0x21a0, PIN_OUTPUT | MUX_MODE0) /* uart3_tx.uart3_tx */
+ >;
+ };
+
+ mcbsp2_pins: pinmux_mcbsp2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x213c, PIN_INPUT | MUX_MODE0) /* mcbsp2_fsx.mcbsp2_fsx */
+ OMAP3_CORE1_IOPAD(0x213e, PIN_INPUT | MUX_MODE0) /* mcbsp2_clkx.mcbsp2_clkx */
+ OMAP3_CORE1_IOPAD(0x2140, PIN_INPUT | MUX_MODE0) /* mcbsp2_dr.mcbsp2.dr */
+ OMAP3_CORE1_IOPAD(0x2142, PIN_OUTPUT | MUX_MODE0) /* mcbsp2_dx.mcbsp2_dx */
+ >;
+ };
+
+ mmc1_pins: pinmux_mmc1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */
+ OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */
+ OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat0.sdmmc1_dat0 */
+ OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat1.sdmmc1_dat1 */
+ OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat2.sdmmc1_dat2 */
+ OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_dat3.sdmmc1_dat3 */
+ >;
+ };
+
+ mmc2_pins: pinmux_mmc2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_clk.sdmmc2_clk */
+ OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_cmd.sdmmc2_cmd */
+ OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat0.sdmmc2_dat0 */
+ OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat1.sdmmc2_dat1 */
+ OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat2.sdmmc2_dat2 */
+ OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc2_dat3.sdmmc2_dat3 */
+ >;
+ };
+
+ i2c1_pins: pinmux_i2c1_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21ba, PIN_INPUT | MUX_MODE0) /* i2c1_scl.i2c1_scl */
+ OMAP3_CORE1_IOPAD(0x21bc, PIN_INPUT | MUX_MODE0) /* i2c1_sda.i2c1_sda */
+ >;
+ };
+
+ i2c3_pins: pinmux_i2c3_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c2, PIN_INPUT | MUX_MODE0) /* i2c3_scl.i2c3_scl */
+ OMAP3_CORE1_IOPAD(0x21c4, PIN_INPUT | MUX_MODE0) /* i2c3_sda.i2c3_sda */
+ >;
+ };
+};
+
+&gpmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&gpmc_pins>;
+
+ nand@0,0 {
+ compatible = "ti,omap2-nand";
+ reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+ interrupt-parent = <&gpmc>;
+ interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+ <1 IRQ_TYPE_NONE>; /* termcount */
+ linux,mtd-name= "micron,mt29c4g96maz";
+ nand-bus-width = <16>;
+ gpmc,device-width = <2>;
+ ti,nand-ecc-opt = "bch8";
+
+ gpmc,sync-clk-ps = <0>;
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <44>;
+ gpmc,cs-wr-off-ns = <44>;
+ gpmc,adv-on-ns = <6>;
+ gpmc,adv-rd-off-ns = <34>;
+ gpmc,adv-wr-off-ns = <44>;
+ gpmc,we-off-ns = <40>;
+ gpmc,oe-off-ns = <54>;
+ gpmc,access-ns = <64>;
+ gpmc,rd-cycle-ns = <82>;
+ gpmc,wr-cycle-ns = <82>;
+ gpmc,wr-access-ns = <40>;
+ gpmc,wr-data-mux-bus-ns = <0>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ status = "okay";
+ };
+
+ onenand@0,0 {
+ compatible = "ti,omap2-onenand";
+ reg = <0 0 0x20000>; /* CS0, offset 0, IO size 128K */
+
+ gpmc,sync-read;
+ gpmc,sync-write;
+ gpmc,burst-length = <16>;
+ gpmc,burst-wrap;
+ gpmc,burst-read;
+ gpmc,burst-write;
+ gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */
+ gpmc,mux-add-data = <2>; /* GPMC_MUX_AD */
+ gpmc,cs-on-ns = <0>;
+ gpmc,cs-rd-off-ns = <96>;
+ gpmc,cs-wr-off-ns = <96>;
+ gpmc,adv-on-ns = <0>;
+ gpmc,adv-rd-off-ns = <12>;
+ gpmc,adv-wr-off-ns = <12>;
+ gpmc,oe-on-ns = <18>;
+ gpmc,oe-off-ns = <96>;
+ gpmc,we-on-ns = <0>;
+ gpmc,we-off-ns = <96>;
+ gpmc,rd-cycle-ns = <114>;
+ gpmc,wr-cycle-ns = <114>;
+ gpmc,access-ns = <90>;
+ gpmc,page-burst-access-ns = <12>;
+ gpmc,bus-turnaround-ns = <0>;
+ gpmc,cycle2cycle-delay-ns = <0>;
+ gpmc,wait-monitoring-ns = <0>;
+ gpmc,clk-activation-ns = <6>;
+ gpmc,wr-data-mux-bus-ns = <30>;
+ gpmc,wr-access-ns = <90>;
+ gpmc,sync-clk-ps = <12000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ status = "disabled";
+ };
+};
+
+&i2c1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c1_pins>;
+ clock-frequency = <2600000>;
+
+ twl: twl@48 {
+ reg = <0x48>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+ interrupt-parent = <&intc>;
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ codec {
+ };
+ };
+ };
+};
+
+#include "twl4030.dtsi"
+#include "twl4030_omap3.dtsi"
+
+&i2c3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c3_pins>;
+};
+
+&mcbsp2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcbsp2_pins>;
+ status = "okay";
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&vmmc1>;
+ vmmc_aux-supply = <&vsim>;
+ bus-width = <4>;
+ cd-gpios = <&twl_gpio 0 GPIO_ACTIVE_LOW>;
+};
+
+&mmc3 {
+ status = "disabled";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart1_pins>;
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart3_pins>;
+};
+
+&twl_gpio {
+ ti,use-leds;
+};
+
+&usb_otg_hs {
+ interface-type = <0>;
+ usb-phy = <&usb2_phy>;
+ phys = <&usb2_phy>;
+ phy-names = "usb2-phy";
+ mode = <3>;
+ power = <50>;
+};
diff --git a/arch/arm/dts/omap3-igep0020-common.dtsi b/arch/arm/dts/omap3-igep0020-common.dtsi
new file mode 100644
index 0000000000..ecbec23af4
--- /dev/null
+++ b/arch/arm/dts/omap3-igep0020-common.dtsi
@@ -0,0 +1,264 @@
+/*
+ * Common Device Tree Source for IGEPv2
+ *
+ * Copyright (C) 2014 Javier Martinez Canillas <javier@osg.samsung.com>
+ * Copyright (C) 2014 Enric Balletbo i Serra <eballetbo@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "omap3-igep.dtsi"
+#include "omap-gpmc-smsc9221.dtsi"
+
+/ {
+
+ leds {
+ pinctrl-names = "default";
+ pinctrl-0 = <&leds_pins>;
+ compatible = "gpio-leds";
+
+ boot {
+ label = "omap3:green:boot";
+ gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+
+ user0 {
+ label = "omap3:red:user0";
+ gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ user1 {
+ label = "omap3:red:user1";
+ gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+
+ user2 {
+ label = "omap3:green:user1";
+ gpios = <&twl_gpio 19 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ /* HS USB Port 1 Power */
+ hsusb1_power: hsusb1_power_reg {
+ compatible = "regulator-fixed";
+ regulator-name = "hsusb1_vbus";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&twl_gpio 18 GPIO_ACTIVE_LOW>; /* GPIO LEDA */
+ startup-delay-us = <70000>;
+ };
+
+ /* HS USB Host PHY on PORT 1 */
+ hsusb1_phy: hsusb1_phy {
+ compatible = "usb-nop-xceiv";
+ reset-gpios = <&gpio1 24 GPIO_ACTIVE_LOW>; /* gpio_24 */
+ vcc-supply = <&hsusb1_power>;
+ #phy-cells = <0>;
+ };
+
+ tfp410: encoder {
+ compatible = "ti,tfp410";
+ powerdown-gpios = <&gpio6 10 GPIO_ACTIVE_LOW>; /* gpio_170 */
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ tfp410_in: endpoint {
+ remote-endpoint = <&dpi_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ tfp410_out: endpoint {
+ remote-endpoint = <&dvi_connector_in>;
+ };
+ };
+ };
+ };
+
+ dvi0: connector {
+ compatible = "dvi-connector";
+ label = "dvi";
+
+ digital;
+
+ ddc-i2c-bus = <&i2c3>;
+
+ port {
+ dvi_connector_in: endpoint {
+ remote-endpoint = <&tfp410_out>;
+ };
+ };
+ };
+};
+
+&omap3_pmx_core {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &tfp410_pins
+ &dss_dpi_pins
+ >;
+
+ tfp410_pins: pinmux_tfp410_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21c6, PIN_OUTPUT | MUX_MODE4) /* hdq_sio.gpio_170 */
+ >;
+ };
+
+ dss_dpi_pins: pinmux_dss_dpi_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x20d4, PIN_OUTPUT | MUX_MODE0) /* dss_pclk.dss_pclk */
+ OMAP3_CORE1_IOPAD(0x20d6, PIN_OUTPUT | MUX_MODE0) /* dss_hsync.dss_hsync */
+ OMAP3_CORE1_IOPAD(0x20d8, PIN_OUTPUT | MUX_MODE0) /* dss_vsync.dss_vsync */
+ OMAP3_CORE1_IOPAD(0x20da, PIN_OUTPUT | MUX_MODE0) /* dss_acbias.dss_acbias */
+ OMAP3_CORE1_IOPAD(0x20dc, PIN_OUTPUT | MUX_MODE0) /* dss_data0.dss_data0 */
+ OMAP3_CORE1_IOPAD(0x20de, PIN_OUTPUT | MUX_MODE0) /* dss_data1.dss_data1 */
+ OMAP3_CORE1_IOPAD(0x20e0, PIN_OUTPUT | MUX_MODE0) /* dss_data2.dss_data2 */
+ OMAP3_CORE1_IOPAD(0x20e2, PIN_OUTPUT | MUX_MODE0) /* dss_data3.dss_data3 */
+ OMAP3_CORE1_IOPAD(0x20e4, PIN_OUTPUT | MUX_MODE0) /* dss_data4.dss_data4 */
+ OMAP3_CORE1_IOPAD(0x20e6, PIN_OUTPUT | MUX_MODE0) /* dss_data5.dss_data5 */
+ OMAP3_CORE1_IOPAD(0x20e8, PIN_OUTPUT | MUX_MODE0) /* dss_data6.dss_data6 */
+ OMAP3_CORE1_IOPAD(0x20ea, PIN_OUTPUT | MUX_MODE0) /* dss_data7.dss_data7 */
+ OMAP3_CORE1_IOPAD(0x20ec, PIN_OUTPUT | MUX_MODE0) /* dss_data8.dss_data8 */
+ OMAP3_CORE1_IOPAD(0x20ee, PIN_OUTPUT | MUX_MODE0) /* dss_data9.dss_data9 */
+ OMAP3_CORE1_IOPAD(0x20f0, PIN_OUTPUT | MUX_MODE0) /* dss_data10.dss_data10 */
+ OMAP3_CORE1_IOPAD(0x20f2, PIN_OUTPUT | MUX_MODE0) /* dss_data11.dss_data11 */
+ OMAP3_CORE1_IOPAD(0x20f4, PIN_OUTPUT | MUX_MODE0) /* dss_data12.dss_data12 */
+ OMAP3_CORE1_IOPAD(0x20f6, PIN_OUTPUT | MUX_MODE0) /* dss_data13.dss_data13 */
+ OMAP3_CORE1_IOPAD(0x20f8, PIN_OUTPUT | MUX_MODE0) /* dss_data14.dss_data14 */
+ OMAP3_CORE1_IOPAD(0x20fa, PIN_OUTPUT | MUX_MODE0) /* dss_data15.dss_data15 */
+ OMAP3_CORE1_IOPAD(0x20fc, PIN_OUTPUT | MUX_MODE0) /* dss_data16.dss_data16 */
+ OMAP3_CORE1_IOPAD(0x20fe, PIN_OUTPUT | MUX_MODE0) /* dss_data17.dss_data17 */
+ OMAP3_CORE1_IOPAD(0x2100, PIN_OUTPUT | MUX_MODE0) /* dss_data18.dss_data18 */
+ OMAP3_CORE1_IOPAD(0x2102, PIN_OUTPUT | MUX_MODE0) /* dss_data19.dss_data19 */
+ OMAP3_CORE1_IOPAD(0x2104, PIN_OUTPUT | MUX_MODE0) /* dss_data20.dss_data20 */
+ OMAP3_CORE1_IOPAD(0x2106, PIN_OUTPUT | MUX_MODE0) /* dss_data21.dss_data21 */
+ OMAP3_CORE1_IOPAD(0x2108, PIN_OUTPUT | MUX_MODE0) /* dss_data22.dss_data22 */
+ OMAP3_CORE1_IOPAD(0x210a, PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */
+ >;
+ };
+
+ uart2_pins: pinmux_uart2_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2174, PIN_INPUT | MUX_MODE0) /* uart2_cts.uart2_cts */
+ OMAP3_CORE1_IOPAD(0x2176, PIN_OUTPUT | MUX_MODE0) /* uart2_rts .uart2_rts*/
+ OMAP3_CORE1_IOPAD(0x2178, PIN_OUTPUT | MUX_MODE0) /* uart2_tx.uart2_tx */
+ OMAP3_CORE1_IOPAD(0x217a, PIN_INPUT | MUX_MODE0) /* uart2_rx.uart2_rx */
+ >;
+ };
+
+ smsc9221_pins: pinmux_smsc9221_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x21d2, PIN_INPUT | MUX_MODE4) /* mcspi1_cs2.gpio_176 */
+ >;
+ };
+};
+
+&omap3_pmx_core2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <
+ &hsusbb1_pins
+ >;
+
+ hsusbb1_pins: pinmux_hsusbb1_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25da, PIN_OUTPUT | MUX_MODE3) /* etk_ctl.hsusb1_clk */
+ OMAP3630_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE3) /* etk_clk.hsusb1_stp */
+ OMAP3630_CORE2_IOPAD(0x25ec, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d8.hsusb1_dir */
+ OMAP3630_CORE2_IOPAD(0x25ee, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d9.hsusb1_nxt */
+ OMAP3630_CORE2_IOPAD(0x25dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d0.hsusb1_data0 */
+ OMAP3630_CORE2_IOPAD(0x25de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d1.hsusb1_data1 */
+ OMAP3630_CORE2_IOPAD(0x25e0, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d2.hsusb1_data2 */
+ OMAP3630_CORE2_IOPAD(0x25e2, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d3.hsusb1_data7 */
+ OMAP3630_CORE2_IOPAD(0x25e4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d4.hsusb1_data4 */
+ OMAP3630_CORE2_IOPAD(0x25e6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d5.hsusb1_data5 */
+ OMAP3630_CORE2_IOPAD(0x25e8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d6.hsusb1_data6 */
+ OMAP3630_CORE2_IOPAD(0x25ea, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d7.hsusb1_data3 */
+ >;
+ };
+
+ leds_pins: pinmux_leds_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25f4, PIN_OUTPUT | MUX_MODE4) /* etk_d12.gpio_26 */
+ OMAP3630_CORE2_IOPAD(0x25f6, PIN_OUTPUT | MUX_MODE4) /* etk_d13.gpio_27 */
+ OMAP3630_CORE2_IOPAD(0x25f8, PIN_OUTPUT | MUX_MODE4) /* etk_d14.gpio_28 */
+ >;
+ };
+
+ mmc1_wp_pins: pinmux_mmc1_cd_pins {
+ pinctrl-single,pins = <
+ OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT | MUX_MODE4) /* etk_d15.gpio_29 */
+ >;
+ };
+};
+
+&i2c3 {
+ clock-frequency = <100000>;
+
+ /*
+ * Display monitor features are burnt in the EEPROM
+ * as EDID data.
+ */
+ eeprom@50 {
+ compatible = "ti,eeprom";
+ reg = <0x50>;
+ };
+};
+
+&gpmc {
+ ranges = <0 0 0x30000000 0x01000000>, /* CS0: 16MB for NAND */
+ <5 0 0x2c000000 0x01000000>; /* CS5: 16MB for ethernet */
+
+ ethernet@gpmc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&smsc9221_pins>;
+ reg = <5 0 0xff>;
+ interrupt-parent = <&gpio6>;
+ interrupts = <16 IRQ_TYPE_LEVEL_LOW>;
+ };
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pins>;
+};
+
+&usbhshost {
+ port1-mode = "ehci-phy";
+};
+
+&usbhsehci {
+ phys = <&hsusb1_phy>;
+};
+
+&vpll2 {
+ /* Needed for DSS */
+ regulator-name = "vdds_dsi";
+};
+
+&dss {
+ status = "ok";
+
+ port {
+ dpi_out: endpoint {
+ remote-endpoint = <&tfp410_in>;
+ data-lines = <24>;
+ };
+ };
+};
+
+&mmc1 {
+ pinctrl-0 = <&mmc1_pins &mmc1_wp_pins>;
+ wp-gpios = <&gpio1 29 GPIO_ACTIVE_LOW>; /* gpio_29 */
+};
diff --git a/arch/arm/dts/omap3-igep0020-u-boot.dtsi b/arch/arm/dts/omap3-igep0020-u-boot.dtsi
new file mode 100644
index 0000000000..41beaf0900
--- /dev/null
+++ b/arch/arm/dts/omap3-igep0020-u-boot.dtsi
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * U-Boot additions
+ *
+ * (C) Copyright 2017 Derald D. Woods <woods.technical@gmail.com>
+ */
+
+/ {
+ chosen {
+ stdout-path = &uart3;
+ };
+};
+
+&uart1 {
+ reg-shift = <2>;
+};
+
+&uart2 {
+ reg-shift = <2>;
+};
+
+&uart3 {
+ reg-shift = <2>;
+};
diff --git a/arch/arm/dts/omap3-igep0020.dts b/arch/arm/dts/omap3-igep0020.dts
new file mode 100644
index 0000000000..33d6b4ead0
--- /dev/null
+++ b/arch/arm/dts/omap3-igep0020.dts
@@ -0,0 +1,50 @@
+/*
+ * Device Tree Source for IGEPv2 Rev. C (TI OMAP AM/DM37x)
+ *
+ * Copyright (C) 2012 Javier Martinez Canillas <javier@osg.samsung.com>
+ * Copyright (C) 2012 Enric Balletbo i Serra <eballetbo@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "omap3-igep0020-common.dtsi"
+
+/ {
+ model = "IGEPv2 Rev. C (TI OMAP AM/DM37x)";
+ compatible = "isee,omap3-igep0020", "ti,omap36xx", "ti,omap3";
+
+ vmmcsdio_fixed: fixedregulator-mmcsdio {
+ compatible = "regulator-fixed";
+ regulator-name = "vmmcsdio_fixed";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ mmc2_pwrseq: mmc2_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>, /* gpio_139 - RESET_N_W */
+ <&gpio5 10 GPIO_ACTIVE_LOW>; /* gpio_138 - WIFI_PDN */
+ };
+};
+
+&omap3_pmx_core {
+ lbee1usjyc_pins: pinmux_lbee1usjyc_pins {
+ pinctrl-single,pins = <
+ OMAP3_CORE1_IOPAD(0x2166, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat5.gpio_137 - RESET_N_W */
+ OMAP3_CORE1_IOPAD(0x2168, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat6.gpio_138 - WIFI_PDN */
+ OMAP3_CORE1_IOPAD(0x216a, PIN_OUTPUT | MUX_MODE4) /* sdmmc2_dat7.gpio_139 - RST_N_B */
+ >;
+ };
+};
+
+/* On board Wifi module */
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins &lbee1usjyc_pins>;
+ vmmc-supply = <&vmmcsdio_fixed>;
+ mmc-pwrseq = <&mmc2_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+};
diff --git a/arch/arm/include/asm/arch-hi3798cv200/hi3798cv200.h b/arch/arm/include/asm/arch-hi3798cv200/hi3798cv200.h
index f97b1eb29f..bb221e17e0 100644
--- a/arch/arm/include/asm/arch-hi3798cv200/hi3798cv200.h
+++ b/arch/arm/include/asm/arch-hi3798cv200/hi3798cv200.h
@@ -13,11 +13,16 @@
/* DEVICES */
#define REG_BASE_MCI 0xF9830000
#define REG_BASE_UART0 0xF8B00000
+#define HIOTG_BASE_ADDR 0xF98C0000
/* PERI control registers (4KB) */
/* USB2 PHY01 configuration register */
#define PERI_CTRL_USB0 (REG_BASE_PERI_CTRL + 0x120)
+ /* USB2 controller configuration register */
+#define PERI_CTRL_USB3 (REG_BASE_PERI_CTRL + 0x12c)
+#define USB2_2P_CHIPID (1 << 28)
+
/* PERI CRG registers (4KB) */
/* USB2 CTRL0 clock and soft reset */
#define PERI_CRG46 (REG_BASE_CRG + 0xb8)
diff --git a/arch/arm/include/asm/arch-mediatek/reset.h b/arch/arm/include/asm/arch-mediatek/reset.h
new file mode 100644
index 0000000000..9704666d24
--- /dev/null
+++ b/arch/arm/include/asm/arch-mediatek/reset.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef __MEDIATEK_RESET_H
+#define __MEDIATEK_RESET_H
+
+#include <dm.h>
+
+int mediatek_reset_bind(struct udevice *pdev, u32 regofs, u32 num_regs);
+
+#endif /* __MEDIATEK_RESET_H */
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index c3c1d2fdfa..329f20c2bf 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -64,13 +64,15 @@ void arch_lmb_reserve(struct lmb *lmb)
/* adjust sp by 4K to be safe */
sp -= 4096;
for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
- if (sp < gd->bd->bi_dram[bank].start)
+ if (!gd->bd->bi_dram[bank].size ||
+ sp < gd->bd->bi_dram[bank].start)
continue;
+ /* Watch out for RAM at end of address space! */
bank_end = gd->bd->bi_dram[bank].start +
- gd->bd->bi_dram[bank].size;
- if (sp >= bank_end)
+ gd->bd->bi_dram[bank].size - 1;
+ if (sp > bank_end)
continue;
- lmb_reserve(lmb, sp, bank_end - sp);
+ lmb_reserve(lmb, sp, bank_end - sp + 1);
break;
}
}
diff --git a/arch/riscv/config.mk b/arch/riscv/config.mk
index ff4fe64001..84654eb3ed 100644
--- a/arch/riscv/config.mk
+++ b/arch/riscv/config.mk
@@ -23,8 +23,7 @@ PLATFORM_LDFLAGS += -m $(64bit-emul)
EFI_LDS := elf_riscv64_efi.lds
endif
-CONFIG_STANDALONE_LOAD_ADDR = 0x00000000
-LDFLAGS_STANDALONE += -T $(srctree)/examples/standalone/riscv.lds
+CONFIG_STANDALONE_LOAD_ADDR ?= 0x00000000
PLATFORM_CPPFLAGS += -ffixed-gp -fpic
PLATFORM_RELFLAGS += -fno-common -gdwarf-2 -ffunction-sections \
diff --git a/arch/riscv/cpu/ax25/cache.c b/arch/riscv/cpu/ax25/cache.c
index 8d6ae170b8..228fc55f56 100644
--- a/arch/riscv/cpu/ax25/cache.c
+++ b/arch/riscv/cpu/ax25/cache.c
@@ -6,6 +6,28 @@
#include <common.h>
+void flush_dcache_all(void)
+{
+ /*
+ * Andes' AX25 does not have a coherence agent. U-Boot must use data
+ * cache flush and invalidate functions to keep data in the system
+ * coherent.
+ * The implementation of the fence instruction in the AX25 flushes the
+ * data cache and is used for this purpose.
+ */
+ asm volatile ("fence" ::: "memory");
+}
+
+void flush_dcache_range(unsigned long start, unsigned long end)
+{
+ flush_dcache_all();
+}
+
+void invalidate_dcache_range(unsigned long start, unsigned long end)
+{
+ flush_dcache_all();
+}
+
void icache_enable(void)
{
#ifndef CONFIG_SYS_ICACHE_OFF
diff --git a/arch/riscv/lib/cache.c b/arch/riscv/lib/cache.c
index ae5c60716f..5437a122a1 100644
--- a/arch/riscv/lib/cache.c
+++ b/arch/riscv/lib/cache.c
@@ -11,13 +11,12 @@ void invalidate_icache_all(void)
asm volatile ("fence.i" ::: "memory");
}
-void flush_dcache_all(void)
+__weak void flush_dcache_all(void)
{
- asm volatile ("fence" :::"memory");
}
-void flush_dcache_range(unsigned long start, unsigned long end)
+
+__weak void flush_dcache_range(unsigned long start, unsigned long end)
{
- flush_dcache_all();
}
void invalidate_icache_range(unsigned long start, unsigned long end)
@@ -29,9 +28,8 @@ void invalidate_icache_range(unsigned long start, unsigned long end)
invalidate_icache_all();
}
-void invalidate_dcache_range(unsigned long start, unsigned long end)
+__weak void invalidate_dcache_range(unsigned long start, unsigned long end)
{
- flush_dcache_all();
}
void cache_flush(void)
@@ -42,8 +40,8 @@ void cache_flush(void)
void flush_cache(unsigned long addr, unsigned long size)
{
- invalidate_icache_all();
- flush_dcache_all();
+ invalidate_icache_range(addr, addr + size);
+ flush_dcache_range(addr, addr + size);
}
__weak void icache_enable(void)
diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index e185933b01..74c1e561c7 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -37,7 +37,8 @@ static void _exit_trap(ulong code, ulong epc, struct pt_regs *regs)
printf("exception code: %ld , %s , epc %lx , ra %lx\n",
code, exception_code[code], epc, regs->ra);
} else {
- printf("Reserved\n");
+ printf("reserved exception code: %ld , epc %lx , ra %lx\n",
+ code, epc, regs->ra);
}
hang();
diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk
index 7226b7be42..31a12db103 100644
--- a/arch/sandbox/config.mk
+++ b/arch/sandbox/config.mk
@@ -11,11 +11,9 @@ PLATFORM_LIBS += -lrt
ifneq ($(NO_SDL),)
PLATFORM_CPPFLAGS += -DSANDBOX_NO_SDL
else
-ifdef CONFIG_SANDBOX_SDL
PLATFORM_LIBS += $(shell sdl-config --libs)
PLATFORM_CPPFLAGS += $(shell sdl-config --cflags)
endif
-endif
cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds $(u-boot-init) \
-Wl,--start-group $(u-boot-main) -Wl,--end-group \
diff --git a/arch/sandbox/cpu/sdl.c b/arch/sandbox/cpu/sdl.c
index f668f5379a..080c7c8d74 100644
--- a/arch/sandbox/cpu/sdl.c
+++ b/arch/sandbox/cpu/sdl.c
@@ -6,7 +6,7 @@
#include <errno.h>
#include <unistd.h>
#include <linux/input.h>
-#include <SDL/SDL.h>
+#include <SDL.h>
#include <asm/state.h>
/**
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index ae3189ec8c..a41b5f052d 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -100,11 +100,13 @@
eeprom@2c {
reg = <0x2c>;
compatible = "i2c-eeprom";
+ sandbox,emul = <&emul_eeprom>;
};
rtc_0: rtc@43 {
reg = <0x43>;
compatible = "sandbox-rtc";
+ sandbox,emul = <&emul0>;
};
sandbox_pmic: sandbox_pmic {
reg = <0x40>;
@@ -115,18 +117,14 @@
};
i2c_emul: emul {
- #address-cells = <1>;
- #size-cells = <0>;
reg = <0xff>;
compatible = "sandbox,i2c-emul-parent";
- emul-eeprom {
- reg = <0x2c>;
+ emul_eeprom: emul-eeprom {
compatible = "sandbox,i2c-eeprom";
sandbox,filename = "i2c.bin";
sandbox,size = <256>;
};
- emul0 {
- reg = <0x43>;
+ emul0: emul0 {
compatible = "sandbox,i2c-rtc";
};
};
diff --git a/arch/sandbox/dts/sandbox64.dts b/arch/sandbox/dts/sandbox64.dts
index d30fd62a2a..a3c95f2cdb 100644
--- a/arch/sandbox/dts/sandbox64.dts
+++ b/arch/sandbox/dts/sandbox64.dts
@@ -90,11 +90,13 @@
eeprom@2c {
reg = <0x2c>;
compatible = "i2c-eeprom";
+ sandbox,emul = <&emul_eeprom>;
};
rtc_0: rtc@43 {
reg = <0x43>;
compatible = "sandbox-rtc";
+ sandbox,emul = <&emul0>;
};
sandbox_pmic: sandbox_pmic {
reg = <0x40>;
@@ -107,12 +109,12 @@
i2c_emul: emul {
reg = <0xff>;
compatible = "sandbox,i2c-emul-parent";
- emul-eeprom {
+ emul_eeprom: emul-eeprom {
compatible = "sandbox,i2c-eeprom";
sandbox,filename = "i2c.bin";
sandbox,size = <256>;
};
- emul0 {
+ emul0: emul0 {
compatible = "sandbox,i2c-rtc";
};
};
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 3790b4c520..1d011ded7c 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -315,6 +315,12 @@
};
};
+ bootcount@0 {
+ compatible = "u-boot,bootcount-rtc";
+ rtc = <&rtc_1>;
+ offset = <0x13>;
+ };
+
adc@0 {
compatible = "sandbox,adc";
vdd-supply = <&buck2>;
diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h
index 81b7750628..2a350a826c 100644
--- a/arch/sandbox/include/asm/io.h
+++ b/arch/sandbox/include/asm/io.h
@@ -173,6 +173,18 @@ static inline void _outsw(volatile u16 *port, const void *buf, int ns)
{
}
+static inline void memset_io(volatile void *addr, unsigned char val, int count)
+{
+}
+
+static inline void memcpy_fromio(void *dst, const volatile void *src, int count)
+{
+}
+
+static inline void memcpy_toio(volatile void *dst, const void *src, int count)
+{
+}
+
#define insw(port, buf, ns) _insw((u16 *)port, buf, ns)
#define outsw(port, buf, ns) _outsw((u16 *)port, buf, ns)
diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c
index 79bc2000bd..04058a60d7 100644
--- a/arch/x86/lib/acpi_table.c
+++ b/arch/x86/lib/acpi_table.c
@@ -342,6 +342,7 @@ static void acpi_create_spcr(struct acpi_spcr *spcr)
struct acpi_table_header *header = &(spcr->header);
struct serial_device_info serial_info = {0};
ulong serial_address, serial_offset;
+ struct udevice *dev;
uint serial_config;
uint serial_width;
int access_size;
@@ -353,7 +354,10 @@ static void acpi_create_spcr(struct acpi_spcr *spcr)
header->length = sizeof(struct acpi_spcr);
header->revision = 2;
- ret = serial_getinfo(&serial_info);
+ /* Read the device once, here. It is reused below */
+ ret = uclass_first_device_err(UCLASS_SERIAL, &dev);
+ if (!ret)
+ ret = serial_getinfo(dev, &serial_info);
if (ret)
serial_info.type = SERIAL_CHIP_UNKNOWN;
@@ -431,9 +435,9 @@ static void acpi_create_spcr(struct acpi_spcr *spcr)
break;
}
- ret = serial_getconfig(&serial_config);
- if (ret)
- serial_config = SERIAL_DEFAULT_CONFIG;
+ serial_config = SERIAL_DEFAULT_CONFIG;
+ if (dev)
+ ret = serial_getconfig(dev, &serial_config);
spcr->parity = SERIAL_GET_PARITY(serial_config);
spcr->stop_bits = SERIAL_GET_STOP(serial_config);
diff --git a/board/hisilicon/poplar/poplar.c b/board/hisilicon/poplar/poplar.c
index 8adc750962..155dfbb401 100644
--- a/board/hisilicon/poplar/poplar.c
+++ b/board/hisilicon/poplar/poplar.c
@@ -166,6 +166,34 @@ int board_mmc_init(bd_t *bis)
return ret;
}
+#if defined(CONFIG_USB_GADGET) && defined(CONFIG_USB_GADGET_DWC2_OTG)
+#include <usb.h>
+#include <usb/dwc2_udc.h>
+#include <g_dnl.h>
+
+static struct dwc2_plat_otg_data poplar_otg_data = {
+ .regs_otg = HIOTG_BASE_ADDR
+};
+
+static void set_usb_to_device(void)
+{
+ setbits_le32(PERI_CTRL_USB3, USB2_2P_CHIPID);
+}
+
+int board_usb_init(int index, enum usb_init_type init)
+{
+ set_usb_to_device();
+ return dwc2_udc_probe(&poplar_otg_data);
+}
+
+int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
+{
+ if (!env_get("serial#"))
+ g_dnl_set_serialnumber("0123456789POPLAR");
+ return 0;
+}
+#endif
+
int board_init(void)
{
usb2_phy_init();
diff --git a/board/isee/igep00x0/Kconfig b/board/isee/igep00x0/Kconfig
index aa46882b05..597d6d92cf 100644
--- a/board/isee/igep00x0/Kconfig
+++ b/board/isee/igep00x0/Kconfig
@@ -9,4 +9,6 @@ config SYS_VENDOR
config SYS_CONFIG_NAME
default "omap3_igep00x0"
+source "board/ti/common/Kconfig"
+
endif
diff --git a/board/isee/igep00x0/MAINTAINERS b/board/isee/igep00x0/MAINTAINERS
index d75d400eed..a07c9f49a8 100644
--- a/board/isee/igep00x0/MAINTAINERS
+++ b/board/isee/igep00x0/MAINTAINERS
@@ -4,4 +4,3 @@ S: Maintained
F: board/isee/igep00x0/
F: include/configs/omap3_igep00x0.h
F: configs/igep00x0_defconfig
-F: configs/igep0032_defconfig
diff --git a/cmd/adc.c b/cmd/adc.c
index 2d635acbd9..381961cf51 100644
--- a/cmd/adc.c
+++ b/cmd/adc.c
@@ -146,37 +146,14 @@ static int do_adc_scan(cmd_tbl_t *cmdtp, int flag, int argc,
return CMD_RET_SUCCESS;
}
-static cmd_tbl_t cmd_adc_sub[] = {
- U_BOOT_CMD_MKENT(list, 1, 1, do_adc_list, "", ""),
- U_BOOT_CMD_MKENT(info, 2, 1, do_adc_info, "", ""),
- U_BOOT_CMD_MKENT(single, 3, 1, do_adc_single, "", ""),
- U_BOOT_CMD_MKENT(scan, 3, 1, do_adc_scan, "", ""),
-};
-
-static int do_adc(cmd_tbl_t *cmdtp, int flag, int argc,
- char *const argv[])
-{
- cmd_tbl_t *c;
-
- if (argc < 2)
- return CMD_RET_USAGE;
-
- /* Strip off leading 'adc' command argument */
- argc--;
- argv++;
-
- c = find_cmd_tbl(argv[0], &cmd_adc_sub[0], ARRAY_SIZE(cmd_adc_sub));
-
- if (c)
- return c->cmd(cmdtp, flag, argc, argv);
- else
- return CMD_RET_USAGE;
-}
-
static char adc_help_text[] =
"list - list ADC devices\n"
"adc info <name> - Get ADC device info\n"
"adc single <name> <channel> - Get Single data of ADC device channel\n"
"adc scan <name> [channel mask] - Scan all [or masked] ADC channels";
-U_BOOT_CMD(adc, 4, 1, do_adc, "ADC sub-system", adc_help_text);
+U_BOOT_CMD_WITH_SUBCMDS(adc, "ADC sub-system", adc_help_text,
+ U_BOOT_SUBCMD_MKENT(list, 1, 1, do_adc_list),
+ U_BOOT_SUBCMD_MKENT(info, 2, 1, do_adc_info),
+ U_BOOT_SUBCMD_MKENT(single, 3, 1, do_adc_single),
+ U_BOOT_SUBCMD_MKENT(scan, 3, 1, do_adc_scan));
diff --git a/cmd/dtimg.c b/cmd/dtimg.c
index 65c8d101b9..ae7d82f26d 100644
--- a/cmd/dtimg.c
+++ b/cmd/dtimg.c
@@ -116,7 +116,7 @@ static int do_dtimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (!cp || argc > cp->maxargs)
return CMD_RET_USAGE;
- if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
+ if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
return CMD_RET_SUCCESS;
return cp->cmd(cmdtp, flag, argc, argv);
diff --git a/cmd/gpio.c b/cmd/gpio.c
index ecdc453918..c60946bc06 100644
--- a/cmd/gpio.c
+++ b/cmd/gpio.c
@@ -213,7 +213,7 @@ static int do_gpio(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
gpio_direction_output(gpio, value);
}
- printf("gpio: pin %s (gpio %i) value is ", str_gpio, gpio);
+ printf("gpio: pin %s (gpio %u) value is ", str_gpio, gpio);
if (IS_ERR_VALUE(value))
printf("unknown (ret=%d)\n", value);
else
diff --git a/cmd/help.c b/cmd/help.c
index 503fa632e7..fa2010c67e 100644
--- a/cmd/help.c
+++ b/cmd/help.c
@@ -29,7 +29,7 @@ U_BOOT_CMD(
/* This does not use the U_BOOT_CMD macro as ? can't be used in symbol names */
ll_entry_declare(cmd_tbl_t, question_mark, cmd) = {
- "?", CONFIG_SYS_MAXARGS, 1, do_help,
+ "?", CONFIG_SYS_MAXARGS, cmd_always_repeatable, do_help,
"alias for 'help'",
#ifdef CONFIG_SYS_LONGHELP
""
diff --git a/cmd/mmc.c b/cmd/mmc.c
index 3920a1836a..8bc3648193 100644
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -101,10 +101,19 @@ static struct mmc *init_mmc_device(int dev, bool force_init)
return NULL;
}
+ if (!mmc_getcd(mmc))
+ force_init = true;
+
if (force_init)
mmc->has_init = 0;
if (mmc_init(mmc))
return NULL;
+
+#ifdef CONFIG_BLOCK_CACHE
+ struct blk_desc *bd = mmc_get_blk_desc(mmc);
+ blkcache_invalidate(bd->if_type, bd->devnum);
+#endif
+
return mmc;
}
static int do_mmcinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
@@ -247,7 +256,7 @@ static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag,
if (cp == NULL || argc > cp->maxargs)
return CMD_RET_USAGE;
- if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
+ if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
return CMD_RET_SUCCESS;
mmc = init_mmc_device(curr_device, false);
@@ -907,7 +916,7 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (cp == NULL || argc > cp->maxargs)
return CMD_RET_USAGE;
- if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
+ if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
return CMD_RET_SUCCESS;
if (curr_device < 0) {
diff --git a/cmd/mtd.c b/cmd/mtd.c
index 6142223984..cda702d18b 100644
--- a/cmd/mtd.c
+++ b/cmd/mtd.c
@@ -15,6 +15,22 @@
#include <mapmem.h>
#include <mtd.h>
+#include <linux/ctype.h>
+
+static struct mtd_info *get_mtd_by_name(const char *name)
+{
+ struct mtd_info *mtd;
+
+ mtd_probe_devices();
+
+ mtd = get_mtd_device_nm(name);
+ if (IS_ERR_OR_NULL(mtd))
+ printf("MTD device %s not found, ret %ld\n", name,
+ PTR_ERR(mtd));
+
+ return mtd;
+}
+
static uint mtd_len_to_pages(struct mtd_info *mtd, u64 len)
{
do_div(len, mtd->writesize);
@@ -177,7 +193,8 @@ static bool mtd_oob_write_is_empty(struct mtd_oob_ops *op)
return true;
}
-static int do_mtd_list(void)
+static int do_mtd_list(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
{
struct mtd_info *mtd;
int dev_nb = 0;
@@ -221,229 +238,287 @@ static int mtd_special_write_oob(struct mtd_info *mtd, u64 off,
return ret;
}
-static int do_mtd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int do_mtd_io(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
+ bool dump, read, raw, woob, write_empty_pages, has_pages = false;
+ u64 start_off, off, len, remaining, default_len;
+ struct mtd_oob_ops io_op = {};
+ uint user_addr = 0, npages;
+ const char *cmd = argv[0];
struct mtd_info *mtd;
- const char *cmd;
- char *mtd_name;
+ u32 oob_len;
+ u8 *buf;
+ int ret;
- /* All MTD commands need at least two arguments */
if (argc < 2)
return CMD_RET_USAGE;
- /* Parse the command name and its optional suffixes */
- cmd = argv[1];
+ mtd = get_mtd_by_name(argv[1]);
+ if (IS_ERR_OR_NULL(mtd))
+ return CMD_RET_FAILURE;
- /* List the MTD devices if that is what the user wants */
- if (strcmp(cmd, "list") == 0)
- return do_mtd_list();
+ if (mtd->type == MTD_NANDFLASH || mtd->type == MTD_MLCNANDFLASH)
+ has_pages = true;
- /*
- * The remaining commands require also at least a device ID.
- * Check the selected device is valid. Ensure it is probed.
- */
- if (argc < 3)
- return CMD_RET_USAGE;
+ dump = !strncmp(cmd, "dump", 4);
+ read = dump || !strncmp(cmd, "read", 4);
+ raw = strstr(cmd, ".raw");
+ woob = strstr(cmd, ".oob");
+ write_empty_pages = !has_pages || strstr(cmd, ".dontskipff");
- mtd_name = argv[2];
- mtd_probe_devices();
- mtd = get_mtd_device_nm(mtd_name);
- if (IS_ERR_OR_NULL(mtd)) {
- printf("MTD device %s not found, ret %ld\n",
- mtd_name, PTR_ERR(mtd));
- return CMD_RET_FAILURE;
- }
- put_mtd_device(mtd);
+ argc -= 2;
+ argv += 2;
- argc -= 3;
- argv += 3;
-
- /* Do the parsing */
- if (!strncmp(cmd, "read", 4) || !strncmp(cmd, "dump", 4) ||
- !strncmp(cmd, "write", 5)) {
- bool has_pages = mtd->type == MTD_NANDFLASH ||
- mtd->type == MTD_MLCNANDFLASH;
- bool dump, read, raw, woob, write_empty_pages;
- struct mtd_oob_ops io_op = {};
- uint user_addr = 0, npages;
- u64 start_off, off, len, remaining, default_len;
- u32 oob_len;
- u8 *buf;
- int ret;
-
- dump = !strncmp(cmd, "dump", 4);
- read = dump || !strncmp(cmd, "read", 4);
- raw = strstr(cmd, ".raw");
- woob = strstr(cmd, ".oob");
- write_empty_pages = !has_pages || strstr(cmd, ".dontskipff");
-
- if (!dump) {
- if (!argc)
- return CMD_RET_USAGE;
-
- user_addr = simple_strtoul(argv[0], NULL, 16);
- argc--;
- argv++;
+ if (!dump) {
+ if (!argc) {
+ ret = CMD_RET_USAGE;
+ goto out_put_mtd;
}
- start_off = argc > 0 ? simple_strtoul(argv[0], NULL, 16) : 0;
- if (!mtd_is_aligned_with_min_io_size(mtd, start_off)) {
- printf("Offset not aligned with a page (0x%x)\n",
- mtd->writesize);
- return CMD_RET_FAILURE;
- }
+ user_addr = simple_strtoul(argv[0], NULL, 16);
+ argc--;
+ argv++;
+ }
- default_len = dump ? mtd->writesize : mtd->size;
- len = argc > 1 ? simple_strtoul(argv[1], NULL, 16) :
- default_len;
- if (!mtd_is_aligned_with_min_io_size(mtd, len)) {
- len = round_up(len, mtd->writesize);
- printf("Size not on a page boundary (0x%x), rounding to 0x%llx\n",
- mtd->writesize, len);
- }
+ start_off = argc > 0 ? simple_strtoul(argv[0], NULL, 16) : 0;
+ if (!mtd_is_aligned_with_min_io_size(mtd, start_off)) {
+ printf("Offset not aligned with a page (0x%x)\n",
+ mtd->writesize);
+ ret = CMD_RET_FAILURE;
+ goto out_put_mtd;
+ }
- remaining = len;
- npages = mtd_len_to_pages(mtd, len);
- oob_len = woob ? npages * mtd->oobsize : 0;
+ default_len = dump ? mtd->writesize : mtd->size;
+ len = argc > 1 ? simple_strtoul(argv[1], NULL, 16) : default_len;
+ if (!mtd_is_aligned_with_min_io_size(mtd, len)) {
+ len = round_up(len, mtd->writesize);
+ printf("Size not on a page boundary (0x%x), rounding to 0x%llx\n",
+ mtd->writesize, len);
+ }
- if (dump)
- buf = kmalloc(len + oob_len, GFP_KERNEL);
- else
- buf = map_sysmem(user_addr, 0);
+ remaining = len;
+ npages = mtd_len_to_pages(mtd, len);
+ oob_len = woob ? npages * mtd->oobsize : 0;
- if (!buf) {
- printf("Could not map/allocate the user buffer\n");
- return CMD_RET_FAILURE;
+ if (dump)
+ buf = kmalloc(len + oob_len, GFP_KERNEL);
+ else
+ buf = map_sysmem(user_addr, 0);
+
+ if (!buf) {
+ printf("Could not map/allocate the user buffer\n");
+ ret = CMD_RET_FAILURE;
+ goto out_put_mtd;
+ }
+
+ if (has_pages)
+ printf("%s %lld byte(s) (%d page(s)) at offset 0x%08llx%s%s%s\n",
+ read ? "Reading" : "Writing", len, npages, start_off,
+ raw ? " [raw]" : "", woob ? " [oob]" : "",
+ !read && write_empty_pages ? " [dontskipff]" : "");
+ else
+ printf("%s %lld byte(s) at offset 0x%08llx\n",
+ read ? "Reading" : "Writing", len, start_off);
+
+ io_op.mode = raw ? MTD_OPS_RAW : MTD_OPS_AUTO_OOB;
+ io_op.len = has_pages ? mtd->writesize : len;
+ io_op.ooblen = woob ? mtd->oobsize : 0;
+ io_op.datbuf = buf;
+ io_op.oobbuf = woob ? &buf[len] : NULL;
+
+ /* Search for the first good block after the given offset */
+ off = start_off;
+ while (mtd_block_isbad(mtd, off))
+ off += mtd->erasesize;
+
+ /* Loop over the pages to do the actual read/write */
+ while (remaining) {
+ /* Skip the block if it is bad */
+ if (mtd_is_aligned_with_block_size(mtd, off) &&
+ mtd_block_isbad(mtd, off)) {
+ off += mtd->erasesize;
+ continue;
}
- if (has_pages)
- printf("%s %lld byte(s) (%d page(s)) at offset 0x%08llx%s%s%s\n",
- read ? "Reading" : "Writing", len, npages, start_off,
- raw ? " [raw]" : "", woob ? " [oob]" : "",
- !read && write_empty_pages ? " [dontskipff]" : "");
+ if (read)
+ ret = mtd_read_oob(mtd, off, &io_op);
else
- printf("%s %lld byte(s) at offset 0x%08llx\n",
- read ? "Reading" : "Writing", len, start_off);
-
- io_op.mode = raw ? MTD_OPS_RAW : MTD_OPS_AUTO_OOB;
- io_op.len = has_pages ? mtd->writesize : len;
- io_op.ooblen = woob ? mtd->oobsize : 0;
- io_op.datbuf = buf;
- io_op.oobbuf = woob ? &buf[len] : NULL;
-
- /* Search for the first good block after the given offset */
- off = start_off;
- while (mtd_block_isbad(mtd, off))
- off += mtd->erasesize;
+ ret = mtd_special_write_oob(mtd, off, &io_op,
+ write_empty_pages, woob);
- /* Loop over the pages to do the actual read/write */
- while (remaining) {
- /* Skip the block if it is bad */
- if (mtd_is_aligned_with_block_size(mtd, off) &&
- mtd_block_isbad(mtd, off)) {
- off += mtd->erasesize;
- continue;
- }
+ if (ret) {
+ printf("Failure while %s at offset 0x%llx\n",
+ read ? "reading" : "writing", off);
+ break;
+ }
- if (read)
- ret = mtd_read_oob(mtd, off, &io_op);
- else
- ret = mtd_special_write_oob(mtd, off, &io_op,
- write_empty_pages,
- woob);
-
- if (ret) {
- printf("Failure while %s at offset 0x%llx\n",
- read ? "reading" : "writing", off);
- return CMD_RET_FAILURE;
- }
+ off += io_op.retlen;
+ remaining -= io_op.retlen;
+ io_op.datbuf += io_op.retlen;
+ io_op.oobbuf += io_op.oobretlen;
+ }
- off += io_op.retlen;
- remaining -= io_op.retlen;
- io_op.datbuf += io_op.retlen;
- io_op.oobbuf += io_op.oobretlen;
- }
+ if (!ret && dump)
+ mtd_dump_device_buf(mtd, start_off, buf, len, woob);
- if (!ret && dump)
- mtd_dump_device_buf(mtd, start_off, buf, len, woob);
+ if (dump)
+ kfree(buf);
+ else
+ unmap_sysmem(buf);
- if (dump)
- kfree(buf);
- else
- unmap_sysmem(buf);
+ if (ret) {
+ printf("%s on %s failed with error %d\n",
+ read ? "Read" : "Write", mtd->name, ret);
+ ret = CMD_RET_FAILURE;
+ } else {
+ ret = CMD_RET_SUCCESS;
+ }
- if (ret) {
- printf("%s on %s failed with error %d\n",
- read ? "Read" : "Write", mtd->name, ret);
- return CMD_RET_FAILURE;
- }
+out_put_mtd:
+ put_mtd_device(mtd);
- } else if (!strcmp(cmd, "erase")) {
- bool scrub = strstr(cmd, ".dontskipbad");
- struct erase_info erase_op = {};
- u64 off, len;
- int ret;
+ return ret;
+}
- off = argc > 0 ? simple_strtoul(argv[0], NULL, 16) : 0;
- len = argc > 1 ? simple_strtoul(argv[1], NULL, 16) : mtd->size;
+static int do_mtd_erase(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ struct erase_info erase_op = {};
+ struct mtd_info *mtd;
+ u64 off, len;
+ bool scrub;
+ int ret;
- if (!mtd_is_aligned_with_block_size(mtd, off)) {
- printf("Offset not aligned with a block (0x%x)\n",
- mtd->erasesize);
- return CMD_RET_FAILURE;
- }
+ if (argc < 2)
+ return CMD_RET_USAGE;
- if (!mtd_is_aligned_with_block_size(mtd, len)) {
- printf("Size not a multiple of a block (0x%x)\n",
- mtd->erasesize);
- return CMD_RET_FAILURE;
- }
+ mtd = get_mtd_by_name(argv[1]);
+ if (IS_ERR_OR_NULL(mtd))
+ return CMD_RET_FAILURE;
- printf("Erasing 0x%08llx ... 0x%08llx (%d eraseblock(s))\n",
- off, off + len - 1, mtd_div_by_eb(len, mtd));
+ scrub = strstr(argv[0], ".dontskipbad");
- erase_op.mtd = mtd;
- erase_op.addr = off;
- erase_op.len = len;
- erase_op.scrub = scrub;
+ argc -= 2;
+ argv += 2;
- while (erase_op.len) {
- ret = mtd_erase(mtd, &erase_op);
+ off = argc > 0 ? simple_strtoul(argv[0], NULL, 16) : 0;
+ len = argc > 1 ? simple_strtoul(argv[1], NULL, 16) : mtd->size;
- /* Abort if its not a bad block error */
- if (ret != -EIO)
- break;
+ if (!mtd_is_aligned_with_block_size(mtd, off)) {
+ printf("Offset not aligned with a block (0x%x)\n",
+ mtd->erasesize);
+ ret = CMD_RET_FAILURE;
+ goto out_put_mtd;
+ }
- printf("Skipping bad block at 0x%08llx\n",
- erase_op.fail_addr);
+ if (!mtd_is_aligned_with_block_size(mtd, len)) {
+ printf("Size not a multiple of a block (0x%x)\n",
+ mtd->erasesize);
+ ret = CMD_RET_FAILURE;
+ goto out_put_mtd;
+ }
- /* Skip bad block and continue behind it */
- erase_op.len -= erase_op.fail_addr - erase_op.addr;
- erase_op.len -= mtd->erasesize;
- erase_op.addr = erase_op.fail_addr + mtd->erasesize;
- }
+ printf("Erasing 0x%08llx ... 0x%08llx (%d eraseblock(s))\n",
+ off, off + len - 1, mtd_div_by_eb(len, mtd));
- if (ret && ret != -EIO)
- return CMD_RET_FAILURE;
- } else if (!strcmp(cmd, "bad")) {
- loff_t off;
+ erase_op.mtd = mtd;
+ erase_op.addr = off;
+ erase_op.len = len;
+ erase_op.scrub = scrub;
- if (!mtd_can_have_bb(mtd)) {
- printf("Only NAND-based devices can have bad blocks\n");
- return CMD_RET_SUCCESS;
- }
+ while (erase_op.len) {
+ ret = mtd_erase(mtd, &erase_op);
- printf("MTD device %s bad blocks list:\n", mtd->name);
- for (off = 0; off < mtd->size; off += mtd->erasesize)
- if (mtd_block_isbad(mtd, off))
- printf("\t0x%08llx\n", off);
- } else {
+ /* Abort if its not a bad block error */
+ if (ret != -EIO)
+ break;
+
+ printf("Skipping bad block at 0x%08llx\n", erase_op.fail_addr);
+
+ /* Skip bad block and continue behind it */
+ erase_op.len -= erase_op.fail_addr - erase_op.addr;
+ erase_op.len -= mtd->erasesize;
+ erase_op.addr = erase_op.fail_addr + mtd->erasesize;
+ }
+
+ if (ret && ret != -EIO)
+ ret = CMD_RET_FAILURE;
+ else
+ ret = CMD_RET_SUCCESS;
+
+out_put_mtd:
+ put_mtd_device(mtd);
+
+ return ret;
+}
+
+static int do_mtd_bad(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ struct mtd_info *mtd;
+ loff_t off;
+
+ if (argc < 2)
return CMD_RET_USAGE;
+
+ mtd = get_mtd_by_name(argv[1]);
+ if (IS_ERR_OR_NULL(mtd))
+ return CMD_RET_FAILURE;
+
+ if (!mtd_can_have_bb(mtd)) {
+ printf("Only NAND-based devices can have bad blocks\n");
+ goto out_put_mtd;
+ }
+
+ printf("MTD device %s bad blocks list:\n", mtd->name);
+ for (off = 0; off < mtd->size; off += mtd->erasesize) {
+ if (mtd_block_isbad(mtd, off))
+ printf("\t0x%08llx\n", off);
}
+out_put_mtd:
+ put_mtd_device(mtd);
+
return CMD_RET_SUCCESS;
}
+#ifdef CONFIG_AUTO_COMPLETE
+static int mtd_name_complete(int argc, char * const argv[], char last_char,
+ int maxv, char *cmdv[])
+{
+ int len = 0, n_found = 0;
+ struct mtd_info *mtd;
+
+ argc--;
+ argv++;
+
+ if (argc > 1 ||
+ (argc == 1 && (last_char == '\0' || isblank(last_char))))
+ return 0;
+
+ if (argc)
+ len = strlen(argv[0]);
+
+ mtd_for_each_device(mtd) {
+ if (argc &&
+ (len > strlen(mtd->name) ||
+ strncmp(argv[0], mtd->name, len)))
+ continue;
+
+ if (n_found >= maxv - 2) {
+ cmdv[n_found++] = "...";
+ break;
+ }
+
+ cmdv[n_found++] = mtd->name;
+ }
+
+ cmdv[n_found] = NULL;
+
+ return n_found;
+}
+#endif /* CONFIG_AUTO_COMPLETE */
+
static char mtd_help_text[] =
#ifdef CONFIG_SYS_LONGHELP
"- generic operations on memory technology devices\n\n"
@@ -470,4 +545,15 @@ static char mtd_help_text[] =
#endif
"";
-U_BOOT_CMD(mtd, 10, 1, do_mtd, "MTD utils", mtd_help_text);
+U_BOOT_CMD_WITH_SUBCMDS(mtd, "MTD utils", mtd_help_text,
+ U_BOOT_SUBCMD_MKENT(list, 1, 1, do_mtd_list),
+ U_BOOT_SUBCMD_MKENT_COMPLETE(read, 5, 0, do_mtd_io,
+ mtd_name_complete),
+ U_BOOT_SUBCMD_MKENT_COMPLETE(write, 5, 0, do_mtd_io,
+ mtd_name_complete),
+ U_BOOT_SUBCMD_MKENT_COMPLETE(dump, 4, 0, do_mtd_io,
+ mtd_name_complete),
+ U_BOOT_SUBCMD_MKENT_COMPLETE(erase, 4, 0, do_mtd_erase,
+ mtd_name_complete),
+ U_BOOT_SUBCMD_MKENT_COMPLETE(bad, 2, 1, do_mtd_bad,
+ mtd_name_complete));
diff --git a/cmd/nvedit.c b/cmd/nvedit.c
index de16c72c23..ebaa16b754 100644
--- a/cmd/nvedit.c
+++ b/cmd/nvedit.c
@@ -708,8 +708,8 @@ int env_get_f(const char *name, char *buf, unsigned len)
if (n)
*--buf = '\0';
- printf("env_buf [%d bytes] too small for value of \"%s\"\n",
- len, name);
+ printf("env_buf [%u bytes] too small for value of \"%s\"\n",
+ len, name);
return n;
}
diff --git a/cmd/sf.c b/cmd/sf.c
index 84bb0575f2..738ef0e46d 100644
--- a/cmd/sf.c
+++ b/cmd/sf.c
@@ -413,7 +413,7 @@ static void show_time(struct test_info *test, int stage)
do_div(speed, test->time_ms[stage] * 1024);
bps = speed * 8;
- printf("%d %s: %d ticks, %d KiB/s %d.%03d Mbps\n", stage,
+ printf("%d %s: %u ticks, %d KiB/s %d.%03d Mbps\n", stage,
stage_name[stage], test->time_ms[stage],
(int)speed, bps / 1000, bps % 1000);
}
diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c
index bb51834c47..459a955d29 100644
--- a/cmd/tpm-v2.c
+++ b/cmd/tpm-v2.c
@@ -151,7 +151,7 @@ static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag, int argc,
rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, data, &updates);
if (!rc) {
- printf("PCR #%u content (%d known updates):\n", index, updates);
+ printf("PCR #%u content (%u known updates):\n", index, updates);
print_byte_string(data, TPM2_DIGEST_LEN);
}
diff --git a/cmd/ubi.c b/cmd/ubi.c
index a12ac703eb..c511a2fb76 100644
--- a/cmd/ubi.c
+++ b/cmd/ubi.c
@@ -472,12 +472,8 @@ static int do_ubi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (argc < 2)
return CMD_RET_USAGE;
- if (strcmp(argv[1], "detach") == 0) {
- if (argc < 2)
- return CMD_RET_USAGE;
-
+ if (strcmp(argv[1], "detach") == 0)
return ubi_detach();
- }
if (strcmp(argv[1], "part") == 0) {
const char *vid_header_offset = NULL;
diff --git a/cmd/unzip.c b/cmd/unzip.c
index f7aabf72d1..6c0f97cb4b 100644
--- a/cmd/unzip.c
+++ b/cmd/unzip.c
@@ -27,7 +27,7 @@ static int do_unzip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (gunzip((void *) dst, dst_len, (void *) src, &src_len) != 0)
return 1;
- printf("Uncompressed size: %ld = 0x%lX\n", src_len, src_len);
+ printf("Uncompressed size: %lu = 0x%lX\n", src_len, src_len);
env_set_hex("filesize", src_len);
return 0;
diff --git a/cmd/zip.c b/cmd/zip.c
index d105d84e38..9cd400a7e8 100644
--- a/cmd/zip.c
+++ b/cmd/zip.c
@@ -28,7 +28,7 @@ static int do_zip(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (gzip((void *) dst, &dst_len, (void *) src, src_len) != 0)
return 1;
- printf("Compressed size: %ld = 0x%lX\n", dst_len, dst_len);
+ printf("Compressed size: %lu = 0x%lX\n", dst_len, dst_len);
env_set_hex("filesize", dst_len);
return 0;
diff --git a/common/Kconfig b/common/Kconfig
index 57bd16d962..2c017df408 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -308,7 +308,7 @@ config SILENT_CONSOLE
help
This option allows the console to be silenced, meaning that no
output will appear on the console devices. This is controlled by
- setting the environment vaariable 'silent' to a non-empty value.
+ setting the environment variable 'silent' to a non-empty value.
Note this also silences the console when booting Linux.
When the console is set up, the variable is checked, and the
@@ -430,7 +430,7 @@ config SYS_CONSOLE_INFO_QUIET
help
Normally U-Boot displays the current settings for stdout, stdin
and stderr on boot when the post-relocation console is set up.
- Enable this option to supress this output. It can be obtained by
+ Enable this option to suppress this output. It can be obtained by
calling stdio_print_current_devices() from board code.
config SYS_STDIO_DEREGISTER
@@ -565,14 +565,14 @@ config LOG_TEST
This enables a 'log test' command to test logging. It is normally
executed from a pytest and simply outputs logging information
in various different ways to test that the logging system works
- correctly with varoius settings.
+ correctly with various settings.
config LOG_ERROR_RETURN
bool "Log all functions which return an error"
depends on LOG
help
When an error is returned in U-Boot it is sometimes difficult to
- figure out the root cause. For eaxmple, reading from SPI flash may
+ figure out the root cause. For example, reading from SPI flash may
fail due to a problem in the SPI controller or due to the flash part
not returning the expected information. This option changes
log_ret() to log any errors it sees. With this option disabled,
@@ -661,7 +661,7 @@ config ARCH_MISC_INIT
With this option U-Boot will call arch_misc_init() after
relocation to allow miscellaneous arch-dependent initialisation
to be performed. This function should be defined by the board
- and will be called after the console is set up, after relocaiton.
+ and will be called after the console is set up, after relocation.
config BOARD_EARLY_INIT_F
bool "Call board-specific init before relocation"
diff --git a/common/bootm.c b/common/bootm.c
index 8bf84ebcb7..a4618b6d2e 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -56,15 +56,11 @@ static void boot_start_lmb(bootm_headers_t *images)
ulong mem_start;
phys_size_t mem_size;
- lmb_init(&images->lmb);
-
mem_start = env_get_bootm_low();
mem_size = env_get_bootm_size();
- lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size);
-
- arch_lmb_reserve(&images->lmb);
- board_lmb_reserve(&images->lmb);
+ lmb_init_and_reserve(&images->lmb, (phys_addr_t)mem_start, mem_size,
+ NULL);
}
#else
#define lmb_reserve(lmb, base, size)
@@ -262,7 +258,8 @@ int bootm_find_images(int flag, int argc, char * const argv[])
puts("Could not find a valid device tree\n");
return 1;
}
- set_working_fdt_addr(map_to_sysmem(images.ft_addr));
+ if (CONFIG_IS_ENABLED(CMD_FDT))
+ set_working_fdt_addr(map_to_sysmem(images.ft_addr));
#endif
#if IMAGE_ENABLE_FIT
diff --git a/common/command.c b/common/command.c
index 2433a89e0a..e14d1fa1d6 100644
--- a/common/command.c
+++ b/common/command.c
@@ -142,30 +142,45 @@ int cmd_usage(const cmd_tbl_t *cmdtp)
}
#ifdef CONFIG_AUTO_COMPLETE
+static char env_complete_buf[512];
int var_complete(int argc, char * const argv[], char last_char, int maxv, char *cmdv[])
{
- static char tmp_buf[512];
int space;
space = last_char == '\0' || isblank(last_char);
if (space && argc == 1)
- return env_complete("", maxv, cmdv, sizeof(tmp_buf), tmp_buf);
+ return env_complete("", maxv, cmdv, sizeof(env_complete_buf),
+ env_complete_buf, false);
if (!space && argc == 2)
- return env_complete(argv[1], maxv, cmdv, sizeof(tmp_buf), tmp_buf);
+ return env_complete(argv[1], maxv, cmdv,
+ sizeof(env_complete_buf),
+ env_complete_buf, false);
return 0;
}
+static int dollar_complete(int argc, char * const argv[], char last_char,
+ int maxv, char *cmdv[])
+{
+ /* Make sure the last argument starts with a $. */
+ if (argc < 1 || argv[argc - 1][0] != '$' ||
+ last_char == '\0' || isblank(last_char))
+ return 0;
+
+ return env_complete(argv[argc - 1], maxv, cmdv, sizeof(env_complete_buf),
+ env_complete_buf, true);
+}
+
/*************************************************************************************/
-static int complete_cmdv(int argc, char * const argv[], char last_char, int maxv, char *cmdv[])
+int complete_subcmdv(cmd_tbl_t *cmdtp, int count, int argc,
+ char * const argv[], char last_char,
+ int maxv, char *cmdv[])
{
#ifdef CONFIG_CMDLINE
- cmd_tbl_t *cmdtp = ll_entry_start(cmd_tbl_t, cmd);
- const int count = ll_entry_count(cmd_tbl_t, cmd);
const cmd_tbl_t *cmdend = cmdtp + count;
const char *p;
int len, clen;
@@ -193,7 +208,7 @@ static int complete_cmdv(int argc, char * const argv[], char last_char, int maxv
/* more than one arg or one but the start of the next */
if (argc > 1 || last_char == '\0' || isblank(last_char)) {
- cmdtp = find_cmd(argv[0]);
+ cmdtp = find_cmd_tbl(argv[0], cmdtp, count);
if (cmdtp == NULL || cmdtp->complete == NULL) {
cmdv[0] = NULL;
return 0;
@@ -238,6 +253,18 @@ static int complete_cmdv(int argc, char * const argv[], char last_char, int maxv
#endif
}
+static int complete_cmdv(int argc, char * const argv[], char last_char,
+ int maxv, char *cmdv[])
+{
+#ifdef CONFIG_CMDLINE
+ return complete_subcmdv(ll_entry_start(cmd_tbl_t, cmd),
+ ll_entry_count(cmd_tbl_t, cmd), argc, argv,
+ last_char, maxv, cmdv);
+#else
+ return 0;
+#endif
+}
+
static int make_argv(char *s, int argvsz, char *argv[])
{
int argc = 0;
@@ -345,9 +372,14 @@ int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *colp)
/* separate into argv */
argc = make_argv(tmp_buf, sizeof(argv)/sizeof(argv[0]), argv);
- /* do the completion and return the possible completions */
- i = complete_cmdv(argc, argv, last_char,
- sizeof(cmdv) / sizeof(cmdv[0]), cmdv);
+ /* first try a $ completion */
+ i = dollar_complete(argc, argv, last_char,
+ sizeof(cmdv) / sizeof(cmdv[0]), cmdv);
+ if (!i) {
+ /* do the completion and return the possible completions */
+ i = complete_cmdv(argc, argv, last_char,
+ sizeof(cmdv) / sizeof(cmdv[0]), cmdv);
+ }
/* no match; bell and out */
if (i == 0) {
@@ -362,13 +394,21 @@ int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *colp)
sep = NULL;
seplen = 0;
if (i == 1) { /* one match; perfect */
- k = strlen(argv[argc - 1]);
+ if (last_char != '\0' && !isblank(last_char))
+ k = strlen(argv[argc - 1]);
+ else
+ k = 0;
+
s = cmdv[0] + k;
len = strlen(s);
sep = " ";
seplen = 1;
} else if (i > 1 && (j = find_common_prefix(cmdv)) != 0) { /* more */
- k = strlen(argv[argc - 1]);
+ if (last_char != '\0' && !isblank(last_char))
+ k = strlen(argv[argc - 1]);
+ else
+ k = 0;
+
j -= k;
if (j > 0) {
s = cmdv[0] + k;
@@ -481,6 +521,30 @@ void fixup_cmdtable(cmd_tbl_t *cmdtp, int size)
}
#endif
+int cmd_always_repeatable(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[], int *repeatable)
+{
+ *repeatable = 1;
+
+ return cmdtp->cmd(cmdtp, flag, argc, argv);
+}
+
+int cmd_never_repeatable(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[], int *repeatable)
+{
+ *repeatable = 0;
+
+ return cmdtp->cmd(cmdtp, flag, argc, argv);
+}
+
+int cmd_discard_repeatable(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ int repeatable;
+
+ return cmdtp->cmd_rep(cmdtp, flag, argc, argv, &repeatable);
+}
+
/**
* Call a command function. This should be the only route in U-Boot to call
* a command, so that we can track whether we are waiting for input or
@@ -490,13 +554,15 @@ void fixup_cmdtable(cmd_tbl_t *cmdtp, int size)
* @param flag Some flags normally 0 (see CMD_FLAG_.. above)
* @param argc Number of arguments (arg 0 must be the command text)
* @param argv Arguments
+ * @param repeatable Can the command be repeated
* @return 0 if command succeeded, else non-zero (CMD_RET_...)
*/
-static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
+ int *repeatable)
{
int result;
- result = (cmdtp->cmd)(cmdtp, flag, argc, argv);
+ result = cmdtp->cmd_rep(cmdtp, flag, argc, argv, repeatable);
if (result)
debug("Command failed, result=%d\n", result);
return result;
@@ -533,12 +599,14 @@ enum command_ret_t cmd_process(int flag, int argc, char * const argv[],
/* If OK so far, then do the command */
if (!rc) {
+ int newrep;
+
if (ticks)
*ticks = get_timer(0);
- rc = cmd_call(cmdtp, flag, argc, argv);
+ rc = cmd_call(cmdtp, flag, argc, argv, &newrep);
if (ticks)
*ticks = get_timer(*ticks);
- *repeatable &= cmdtp->repeatable;
+ *repeatable &= newrep;
}
if (rc == CMD_RET_USAGE)
rc = cmd_usage(cmdtp);
diff --git a/common/fdt_support.c b/common/fdt_support.c
index 3440e42a25..42583e3ed8 100644
--- a/common/fdt_support.c
+++ b/common/fdt_support.c
@@ -1025,7 +1025,7 @@ static u64 of_bus_default_map(fdt32_t *addr, const fdt32_t *range,
s = fdt_read_number(range + na + pna, ns);
da = fdt_read_number(addr, na);
- debug("OF: default map, cp=%llu, s=%llu, da=%llu\n", cp, s, da);
+ debug("OF: default map, cp=%llx, s=%llx, da=%llx\n", cp, s, da);
if (da < cp || da >= (cp + s))
return OF_BAD_ADDR;
@@ -1080,7 +1080,7 @@ static u64 of_bus_isa_map(fdt32_t *addr, const fdt32_t *range,
s = fdt_read_number(range + na + pna, ns);
da = fdt_read_number(addr + 1, na - 1);
- debug("OF: ISA map, cp=%llu, s=%llu, da=%llu\n", cp, s, da);
+ debug("OF: ISA map, cp=%llx, s=%llx, da=%llx\n", cp, s, da);
if (da < cp || da >= (cp + s))
return OF_BAD_ADDR;
diff --git a/common/image-fdt.c b/common/image-fdt.c
index 95748f0ae1..5988808f18 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <fdt_support.h>
+#include <fdtdec.h>
#include <errno.h>
#include <image.h>
#include <linux/libfdt.h>
@@ -67,30 +68,66 @@ static const image_header_t *image_get_fdt(ulong fdt_addr)
}
#endif
+static void boot_fdt_reserve_region(struct lmb *lmb, uint64_t addr,
+ uint64_t size)
+{
+ int ret;
+
+ ret = lmb_reserve(lmb, addr, size);
+ if (!ret) {
+ debug(" reserving fdt memory region: addr=%llx size=%llx\n",
+ (unsigned long long)addr, (unsigned long long)size);
+ } else {
+ puts("ERROR: reserving fdt memory region failed ");
+ printf("(addr=%llx size=%llx)\n",
+ (unsigned long long)addr, (unsigned long long)size);
+ }
+}
+
/**
- * boot_fdt_add_mem_rsv_regions - Mark the memreserve sections as unusable
+ * boot_fdt_add_mem_rsv_regions - Mark the memreserve and reserved-memory
+ * sections as unusable
* @lmb: pointer to lmb handle, will be used for memory mgmt
* @fdt_blob: pointer to fdt blob base address
*
- * Adds the memreserve regions in the dtb to the lmb block. Adding the
- * memreserve regions prevents u-boot from using them to store the initrd
- * or the fdt blob.
+ * Adds the and reserved-memorymemreserve regions in the dtb to the lmb block.
+ * Adding the memreserve regions prevents u-boot from using them to store the
+ * initrd or the fdt blob.
*/
void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob)
{
uint64_t addr, size;
- int i, total;
+ int i, total, ret;
+ int nodeoffset, subnode;
+ struct fdt_resource res;
if (fdt_check_header(fdt_blob) != 0)
return;
+ /* process memreserve sections */
total = fdt_num_mem_rsv(fdt_blob);
for (i = 0; i < total; i++) {
if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0)
continue;
- printf(" reserving fdt memory region: addr=%llx size=%llx\n",
- (unsigned long long)addr, (unsigned long long)size);
- lmb_reserve(lmb, addr, size);
+ boot_fdt_reserve_region(lmb, addr, size);
+ }
+
+ /* process reserved-memory */
+ nodeoffset = fdt_subnode_offset(fdt_blob, 0, "reserved-memory");
+ if (nodeoffset >= 0) {
+ subnode = fdt_first_subnode(fdt_blob, nodeoffset);
+ while (subnode >= 0) {
+ /* check if this subnode has a reg property */
+ ret = fdt_get_resource(fdt_blob, subnode, "reg", 0,
+ &res);
+ if (!ret) {
+ addr = res.start;
+ size = res.end - res.start + 1;
+ boot_fdt_reserve_region(lmb, addr, size);
+ }
+
+ subnode = fdt_next_subnode(fdt_blob, subnode);
+ }
}
}
@@ -193,7 +230,8 @@ int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size)
*of_flat_tree = of_start;
*of_size = of_len;
- set_working_fdt_addr(map_to_sysmem(*of_flat_tree));
+ if (CONFIG_IS_ENABLED(CMD_FDT))
+ set_working_fdt_addr(map_to_sysmem(*of_flat_tree));
return 0;
error:
diff --git a/common/spl/spl_ymodem.c b/common/spl/spl_ymodem.c
index 3b1bd71bda..577fdc69af 100644
--- a/common/spl/spl_ymodem.c
+++ b/common/spl/spl_ymodem.c
@@ -69,12 +69,13 @@ static ulong ymodem_read_fit(struct spl_load_info *load, ulong offset,
static int spl_ymodem_load_image(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev)
{
- int size = 0;
+ ulong size = 0;
int err;
int res;
int ret;
connection_info_t info;
char buf[BUF_SIZE];
+ struct image_header *ih;
ulong addr = 0;
info.mode = xyzModem_ymodem;
@@ -107,12 +108,18 @@ static int spl_ymodem_load_image(struct spl_image_info *spl_image,
while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0)
size += res;
} else {
- ret = spl_parse_image_header(spl_image,
- (struct image_header *)buf);
+ ih = (struct image_header *)buf;
+ ret = spl_parse_image_header(spl_image, ih);
if (ret)
return ret;
- addr = spl_image->load_addr;
+#ifdef CONFIG_SPL_GZIP
+ if (ih->ih_comp == IH_COMP_GZIP)
+ addr = CONFIG_SYS_LOAD_ADDR;
+ else
+#endif
+ addr = spl_image->load_addr;
memcpy((void *)addr, buf, res);
+ ih = (struct image_header *)addr;
size += res;
addr += res;
@@ -121,13 +128,25 @@ static int spl_ymodem_load_image(struct spl_image_info *spl_image,
size += res;
addr += res;
}
+
+#ifdef CONFIG_SPL_GZIP
+ if (ih->ih_comp == IH_COMP_GZIP) {
+ if (gunzip((void *)(spl_image->load_addr + sizeof(*ih)),
+ CONFIG_SYS_BOOTM_LEN,
+ (void *)(CONFIG_SYS_LOAD_ADDR + sizeof(*ih)),
+ &size)) {
+ puts("Uncompressing error\n");
+ return -EIO;
+ }
+ }
+#endif
}
end_stream:
xyzModem_stream_close(&err);
xyzModem_stream_terminate(false, &getcymodem);
- printf("Loaded %d bytes\n", size);
+ printf("Loaded %lu bytes\n", size);
return 0;
}
SPL_LOAD_IMAGE_METHOD("UART", 0, BOOT_DEVICE_UART, spl_ymodem_load_image);
diff --git a/common/xyzModem.c b/common/xyzModem.c
index e5c65b480a..e85da74a69 100644
--- a/common/xyzModem.c
+++ b/common/xyzModem.c
@@ -25,6 +25,7 @@
#include <xyzModem.h>
#include <stdarg.h>
#include <u-boot/crc.h>
+#include <watchdog.h>
/* Assumption - run xyzModem protocol over the console port */
@@ -63,6 +64,7 @@ CYGACC_COMM_IF_GETC_TIMEOUT (char chan, char *c)
{
ulong now = get_timer(0);
+ WATCHDOG_RESET();
while (!tstc ())
{
if (get_timer(now) > xyzModem_CHAR_TIMEOUT)
diff --git a/configs/am335x_igep003x_defconfig b/configs/am335x_igep003x_defconfig
index 186c65f0bf..0a8feadc75 100644
--- a/configs/am335x_igep003x_defconfig
+++ b/configs/am335x_igep003x_defconfig
@@ -41,6 +41,9 @@ CONFIG_CMD_UBI=y
# CONFIG_CMD_UBIFS is not set
CONFIG_ENV_IS_IN_UBI=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_DEFAULT_DEVICE_TREE="am335x-base0033"
+CONFIG_OF_CONTROL=y
+CONFIG_DM_MMC=y
CONFIG_MMC_OMAP_HS=y
CONFIG_NAND=y
CONFIG_MTD_UBI_FASTMAP=y
diff --git a/configs/am335x_sl50_defconfig b/configs/am335x_sl50_defconfig
index 822f73d114..8c622471da 100644
--- a/configs/am335x_sl50_defconfig
+++ b/configs/am335x_sl50_defconfig
@@ -40,6 +40,9 @@ CONFIG_CMD_EXT4_WRITE=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_BOOTCOUNT_LIMIT=y
+CONFIG_DEFAULT_DEVICE_TREE="am335x-sl50"
+CONFIG_OF_CONTROL=y
+CONFIG_DM_MMC=y
CONFIG_MMC_OMAP_HS=y
CONFIG_MII=y
CONFIG_DRIVER_TI_CPSW=y
diff --git a/configs/am57xx_evm_defconfig b/configs/am57xx_evm_defconfig
index 91293daee7..51dedc6111 100644
--- a/configs/am57xx_evm_defconfig
+++ b/configs/am57xx_evm_defconfig
@@ -25,6 +25,7 @@ CONFIG_SPL_DMA_SUPPORT=y
# CONFIG_SPL_NAND_SUPPORT is not set
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
+CONFIG_SPL_YMODEM_SUPPORT=y
CONFIG_CMD_SPL=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_SETEXPR is not set
diff --git a/configs/hikey_defconfig b/configs/hikey_defconfig
index 3bc5ceb5d8..e9a9857322 100644
--- a/configs/hikey_defconfig
+++ b/configs/hikey_defconfig
@@ -18,6 +18,7 @@ CONFIG_DEFAULT_DEVICE_TREE="hi6220-hikey"
CONFIG_ENV_IS_IN_FAT=y
CONFIG_ENV_FAT_INTERFACE="mmc"
CONFIG_ENV_FAT_DEVICE_AND_PART="1:1"
+CONFIG_DM_MMC=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_K3=y
CONFIG_CONS_INDEX=4
diff --git a/configs/igep0032_defconfig b/configs/igep0032_defconfig
deleted file mode 100644
index 20d2cf5820..0000000000
--- a/configs/igep0032_defconfig
+++ /dev/null
@@ -1,53 +0,0 @@
-CONFIG_ARM=y
-CONFIG_ARCH_OMAP2PLUS=y
-CONFIG_TARGET_OMAP3_IGEP00X0=y
-CONFIG_SPL=y
-CONFIG_DISTRO_DEFAULTS=y
-CONFIG_NR_DRAM_BANKS=2
-CONFIG_OF_BOARD_SETUP=y
-CONFIG_BOOTDELAY=3
-CONFIG_BOOTCOMMAND="run findfdt; run distro_bootcmd"
-CONFIG_SYS_CONSOLE_IS_IN_ENV=y
-CONFIG_SYS_CONSOLE_INFO_QUIET=y
-CONFIG_VERSION_VARIABLE=y
-# CONFIG_DISPLAY_BOARDINFO is not set
-# CONFIG_SPL_EXT_SUPPORT is not set
-CONFIG_SPL_MTD_SUPPORT=y
-CONFIG_SPL_ONENAND_SUPPORT=y
-CONFIG_SPL_OS_BOOT=y
-CONFIG_CMD_SPL=y
-CONFIG_CMD_ASKENV=y
-# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPIO=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_MMC=y
-CONFIG_CMD_NAND=y
-CONFIG_CMD_ONENAND=y
-CONFIG_CMD_SPI=y
-# CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_CACHE=y
-CONFIG_CMD_EXT4_WRITE=y
-CONFIG_CMD_MTDPARTS=y
-CONFIG_CMD_UBI=y
-# CONFIG_CMD_UBIFS is not set
-CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_MMC_OMAP_HS=y
-CONFIG_NAND=y
-CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
-CONFIG_SPL_NAND_SIMPLE=y
-CONFIG_SMC911X=y
-CONFIG_SMC911X_BASE=0x2C000000
-CONFIG_SMC911X_32_BIT=y
-CONFIG_CONS_INDEX=3
-CONFIG_SPI=y
-CONFIG_OMAP3_SPI=y
-CONFIG_USB=y
-CONFIG_USB_MUSB_UDC=y
-CONFIG_USB_OMAP3=y
-CONFIG_TWL4030_USB=y
-CONFIG_USB_GADGET=y
-CONFIG_FAT_WRITE=y
-CONFIG_UBIFS_SILENCE_MSG=y
-CONFIG_BCH=y
-CONFIG_OF_LIBFDT=y
-CONFIG_FDT_FIXUP_PARTITIONS=y
diff --git a/configs/igep00x0_defconfig b/configs/igep00x0_defconfig
index 330350c32a..efd8519d14 100644
--- a/configs/igep00x0_defconfig
+++ b/configs/igep00x0_defconfig
@@ -1,7 +1,9 @@
CONFIG_ARM=y
CONFIG_ARCH_OMAP2PLUS=y
+CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_TARGET_OMAP3_IGEP00X0=y
CONFIG_SPL=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_NR_DRAM_BANKS=2
CONFIG_OF_BOARD_SETUP=y
@@ -16,21 +18,18 @@ CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_ONENAND_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_CMD_SPL=y
-CONFIG_CMD_ASKENV=y
# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPIO=y
-CONFIG_CMD_I2C=y
-CONFIG_CMD_MMC=y
CONFIG_CMD_NAND=y
CONFIG_CMD_ONENAND=y
-CONFIG_CMD_SPI=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_CACHE=y
-CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_UBI=y
# CONFIG_CMD_UBIFS is not set
CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_DEFAULT_DEVICE_TREE="omap3-igep0020"
+CONFIG_OF_CONTROL=y
+CONFIG_DM_MMC=y
CONFIG_MMC_OMAP_HS=y
CONFIG_NAND=y
CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
@@ -42,11 +41,6 @@ CONFIG_SMC911X_32_BIT=y
CONFIG_CONS_INDEX=3
CONFIG_SPI=y
CONFIG_OMAP3_SPI=y
-CONFIG_USB=y
-CONFIG_USB_MUSB_UDC=y
-CONFIG_USB_OMAP3=y
-CONFIG_TWL4030_USB=y
-CONFIG_USB_GADGET=y
CONFIG_FAT_WRITE=y
CONFIG_UBIFS_SILENCE_MSG=y
CONFIG_BCH=y
diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig
index ae4fb280dc..8cb4907326 100644
--- a/configs/mt7623n_bpir2_defconfig
+++ b/configs/mt7623n_bpir2_defconfig
@@ -26,8 +26,9 @@ CONFIG_CMD_READ=y
CONFIG_CMD_PING=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
-CONFIG_OF_EMBED=y
+CONFIG_OF_SEPARATE=y
CONFIG_DEFAULT_DEVICE_TREE="mt7623n-bananapi-bpi-r2"
+CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
# CONFIG_BLOCK_CACHE is not set
@@ -37,6 +38,11 @@ CONFIG_DM_MMC=y
# CONFIG_MMC_QUIRKS is not set
CONFIG_MMC_HS400_SUPPORT=y
CONFIG_MMC_MTK=y
+CONFIG_DM_RESET=y
+CONFIG_RESET_MEDIATEK=y
+CONFIG_PHY_FIXED=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
CONFIG_PINCTRL=y
CONFIG_PINCONF=y
CONFIG_PINCTRL_MT7623=y
diff --git a/configs/mt7629_rfb_defconfig b/configs/mt7629_rfb_defconfig
index 1729d13c3d..1da9932dcd 100644
--- a/configs/mt7629_rfb_defconfig
+++ b/configs/mt7629_rfb_defconfig
@@ -29,9 +29,10 @@ CONFIG_CMD_SF_TEST=y
# CONFIG_CMD_NFS is not set
CONFIG_CMD_PING=y
# CONFIG_PARTITIONS is not set
-CONFIG_OF_EMBED=y
+CONFIG_OF_SEPARATE=y
CONFIG_DEFAULT_DEVICE_TREE="mt7629-rfb"
CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-parents"
+CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_REGMAP=y
CONFIG_SPL_REGMAP=y
@@ -51,6 +52,10 @@ CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_RESET=y
+CONFIG_RESET_MEDIATEK=y
+CONFIG_DM_ETH=y
+CONFIG_MEDIATEK_ETH=y
CONFIG_PINCTRL=y
CONFIG_PINCONF=y
CONFIG_PINCTRL_MT7629=y
diff --git a/configs/poplar_defconfig b/configs/poplar_defconfig
index 239783a592..81bd3702e4 100644
--- a/configs/poplar_defconfig
+++ b/configs/poplar_defconfig
@@ -11,11 +11,23 @@ CONFIG_CMD_USB=y
# CONFIG_ISO_PARTITION is not set
CONFIG_DEFAULT_DEVICE_TREE="hi3798cv200-poplar"
CONFIG_ENV_IS_IN_MMC=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x20000000
+CONFIG_FASTBOOT_BUF_SIZE=0x10000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_DM_MMC=y
CONFIG_MMC_DW=y
CONFIG_MMC_DW_K3=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="HiSilicon"
+CONFIG_USB_GADGET_VENDOR_NUM=0x18d1
+CONFIG_USB_GADGET_PRODUCT_NUM=0xd00d
+CONFIG_USB_GADGET_DWC2_OTG=y
+CONFIG_USB_GADGET_DWC2_OTG_PHY_BUS_WIDTH_8=y
CONFIG_USB_HOST_ETHER=y
CONFIG_USB_ETHER_ASIX=y
CONFIG_FAT_WRITE=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 90146f64cd..78a684b5ec 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -57,6 +57,7 @@ CONFIG_CMD_DNS=y
CONFIG_CMD_LINK_LOCAL=y
CONFIG_CMD_ETHSW=y
CONFIG_CMD_BMP=y
+CONFIG_CMD_BOOTCOUNT=y
CONFIG_CMD_TIME=y
CONFIG_CMD_TIMER=y
CONFIG_CMD_SOUND=y
@@ -86,6 +87,9 @@ CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
+CONFIG_BOOTCOUNT_LIMIT=y
+CONFIG_DM_BOOTCOUNT=y
+CONFIG_DM_BOOTCOUNT_RTC=y
CONFIG_CLK=y
CONFIG_CPU=y
CONFIG_DM_DEMO=y
@@ -217,3 +221,4 @@ CONFIG_UNIT_TEST=y
CONFIG_UT_TIME=y
CONFIG_UT_DM=y
CONFIG_UT_ENV=y
+CONFIG_UT_OVERLAY=y
diff --git a/configs/stm32f429-discovery_defconfig b/configs/stm32f429-discovery_defconfig
index ef0f6f7373..265b1ec068 100644
--- a/configs/stm32f429-discovery_defconfig
+++ b/configs/stm32f429-discovery_defconfig
@@ -20,7 +20,6 @@ CONFIG_CMD_IMLS=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIMER=y
CONFIG_OF_CONTROL=y
-CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="stm32f429-disco"
CONFIG_ENV_IS_IN_FLASH=y
# CONFIG_MMC is not set
diff --git a/configs/stm32f429-evaluation_defconfig b/configs/stm32f429-evaluation_defconfig
index 6a2ed2a9b0..9f1a7680ad 100644
--- a/configs/stm32f429-evaluation_defconfig
+++ b/configs/stm32f429-evaluation_defconfig
@@ -23,7 +23,6 @@ CONFIG_CMD_CACHE=y
CONFIG_CMD_TIMER=y
# CONFIG_ISO_PARTITION is not set
CONFIG_OF_CONTROL=y
-CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="stm32429i-eval"
CONFIG_DM_MMC=y
CONFIG_ARM_PL180_MMCI=y
diff --git a/configs/stm32f469-discovery_defconfig b/configs/stm32f469-discovery_defconfig
index 0b36c0fc58..801af6bb61 100644
--- a/configs/stm32f469-discovery_defconfig
+++ b/configs/stm32f469-discovery_defconfig
@@ -23,7 +23,6 @@ CONFIG_CMD_CACHE=y
CONFIG_CMD_TIMER=y
# CONFIG_ISO_PARTITION is not set
CONFIG_OF_CONTROL=y
-CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="stm32f469-disco"
CONFIG_DM_MMC=y
CONFIG_ARM_PL180_MMCI=y
diff --git a/configs/stm32h743-disco_defconfig b/configs/stm32h743-disco_defconfig
index 92d21d180b..5460ad029a 100644
--- a/configs/stm32h743-disco_defconfig
+++ b/configs/stm32h743-disco_defconfig
@@ -23,7 +23,6 @@ CONFIG_CMD_TIMER=y
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_ISO_PARTITION is not set
CONFIG_OF_CONTROL=y
-CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="stm32h743i-disco"
CONFIG_DM_MMC=y
CONFIG_STM32_SDMMC2=y
diff --git a/configs/stm32h743-eval_defconfig b/configs/stm32h743-eval_defconfig
index c08363d136..2884c96648 100644
--- a/configs/stm32h743-eval_defconfig
+++ b/configs/stm32h743-eval_defconfig
@@ -23,7 +23,6 @@ CONFIG_CMD_TIMER=y
CONFIG_CMD_EXT4_WRITE=y
# CONFIG_ISO_PARTITION is not set
CONFIG_OF_CONTROL=y
-CONFIG_OF_EMBED=y
CONFIG_DEFAULT_DEVICE_TREE="stm32h743i-eval"
CONFIG_DM_MMC=y
CONFIG_STM32_SDMMC2=y
diff --git a/doc/driver-model/fs_firmware_loader.txt b/doc/driver-model/fs_firmware_loader.txt
index 290915a959..b9aee848cc 100644
--- a/doc/driver-model/fs_firmware_loader.txt
+++ b/doc/driver-model/fs_firmware_loader.txt
@@ -74,17 +74,16 @@ Firmware storage device described in device tree source
File system firmware Loader API
-------------------------------
-int request_firmware_into_buf(struct device_platdata *plat,
+int request_firmware_into_buf(struct udevice *dev,
const char *name,
- void *buf, size_t size, u32 offset,
- struct firmware **firmwarep)
+ void *buf, size_t size, u32 offset)
--------------------------------------------------------------------
Load firmware into a previously allocated buffer
Parameters:
-1. struct device_platdata *plat
- Platform data such as storage and partition firmware loading from
+1. struct udevice *dev
+ An instance of a driver
2. const char *name
name of firmware file
@@ -98,36 +97,16 @@ Parameters:
5. u32 offset
offset of a file for start reading into buffer
-6. struct firmware **firmwarep
- pointer to firmware image
-
return:
size of total read
-ve when error
Description:
- The firmware is loaded directly into the buffer pointed to by buf and
- the @firmwarep data member is pointed at buf
-
-Note: Memory would be allocated for firmware image, hence user should
- free() *firmwarep and *firmwarep->priv structs after usage of
- request_firmware_into_buf(), otherwise it will always leak memory
- while subsequent calls of request_firmware_into_buf() with the same
- *firmwarep argument. Those arguments can be free through calling API
- below release_firmware();
+ The firmware is loaded directly into the buffer pointed to by buf
Example of creating firmware loader instance and calling
request_firmware_into_buf API:
if (uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0, &dev)) {
- request_firmware_into_buf(dev->plat, filename, buffer_location,
- buffer_size, offset_ofreading, &fw);
+ request_firmware_into_buf(dev, filename, buffer_location,
+ buffer_size, offset_ofreading);
}
-
-void release_firmware(struct firmware *firmware)
-------------------------------------------------
-Release the resource associated with a firmware image
-
-Parameters:
-
-1. struct firmware *firmware
- Firmware resource to release
diff --git a/drivers/block/blkcache.c b/drivers/block/blkcache.c
index 294511fcdb..1fa64989d3 100644
--- a/drivers/block/blkcache.c
+++ b/drivers/block/blkcache.c
@@ -24,7 +24,7 @@ struct block_cache_node {
static LIST_HEAD(block_cache);
static struct block_cache_stats _stats = {
- .max_blocks_per_entry = 2,
+ .max_blocks_per_entry = 8,
.max_entries = 32
};
diff --git a/drivers/clk/mediatek/clk-mt7623.c b/drivers/clk/mediatek/clk-mt7623.c
index c6b09d8e18..87ad4f79ce 100644
--- a/drivers/clk/mediatek/clk-mt7623.c
+++ b/drivers/clk/mediatek/clk-mt7623.c
@@ -8,6 +8,7 @@
#include <common.h>
#include <dm.h>
+#include <asm/arch-mediatek/reset.h>
#include <asm/io.h>
#include <dt-bindings/clock/mt7623-clk.h>
@@ -782,6 +783,19 @@ static int mt7623_ethsys_probe(struct udevice *dev)
return mtk_common_clk_gate_init(dev, &mt7623_clk_tree, eth_cgs);
}
+static int mt7623_ethsys_bind(struct udevice *dev)
+{
+ int ret = 0;
+
+#if CONFIG_IS_ENABLED(RESET_MEDIATEK)
+ ret = mediatek_reset_bind(dev, ETHSYS_RST_CTRL_OFS, 1);
+ if (ret)
+ debug("Warning: failed to bind ethsys reset controller\n");
+#endif
+
+ return ret;
+}
+
static const struct udevice_id mt7623_apmixed_compat[] = {
{ .compatible = "mediatek,mt7623-apmixedsys" },
{ }
@@ -865,6 +879,7 @@ U_BOOT_DRIVER(mtk_clk_ethsys) = {
.id = UCLASS_CLK,
.of_match = mt7623_ethsys_compat,
.probe = mt7623_ethsys_probe,
+ .bind = mt7623_ethsys_bind,
.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
.ops = &mtk_clk_gate_ops,
};
diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c
index 2601b6cf30..6a9f60139c 100644
--- a/drivers/clk/mediatek/clk-mt7629.c
+++ b/drivers/clk/mediatek/clk-mt7629.c
@@ -8,6 +8,7 @@
#include <common.h>
#include <dm.h>
+#include <asm/arch-mediatek/reset.h>
#include <asm/io.h>
#include <dt-bindings/clock/mt7629-clk.h>
@@ -602,6 +603,19 @@ static int mt7629_ethsys_probe(struct udevice *dev)
return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, eth_cgs);
}
+static int mt7629_ethsys_bind(struct udevice *dev)
+{
+ int ret = 0;
+
+#if CONFIG_IS_ENABLED(RESET_MEDIATEK)
+ ret = mediatek_reset_bind(dev, ETHSYS_RST_CTRL_OFS, 1);
+ if (ret)
+ debug("Warning: failed to bind ethsys reset controller\n");
+#endif
+
+ return ret;
+}
+
static int mt7629_sgmiisys_probe(struct udevice *dev)
{
return mtk_common_clk_gate_init(dev, &mt7629_clk_tree, sgmii_cgs);
@@ -695,6 +709,7 @@ U_BOOT_DRIVER(mtk_clk_ethsys) = {
.id = UCLASS_CLK,
.of_match = mt7629_ethsys_compat,
.probe = mt7629_ethsys_probe,
+ .bind = mt7629_ethsys_bind,
.priv_auto_alloc_size = sizeof(struct mtk_cg_priv),
.ops = &mtk_clk_gate_ops,
};
diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h
index 74152ed9c6..7847388b2a 100644
--- a/drivers/clk/mediatek/clk-mtk.h
+++ b/drivers/clk/mediatek/clk-mtk.h
@@ -23,6 +23,8 @@
#define CLK_PARENT_TOPCKGEN BIT(5)
#define CLK_PARENT_MASK GENMASK(5, 4)
+#define ETHSYS_RST_CTRL_OFS 0x34
+
/* struct mtk_pll_data - hardware-specific PLLs data */
struct mtk_pll_data {
const int id;
diff --git a/drivers/core/dump.c b/drivers/core/dump.c
index 04217cbde8..8fbfd93fb5 100644
--- a/drivers/core/dump.c
+++ b/drivers/core/dump.c
@@ -16,7 +16,7 @@ static void show_devices(struct udevice *dev, int depth, int last_flag)
struct udevice *child;
/* print the first 20 characters to not break the tree-format. */
- printf(" %-10.10s %d [ %c ] %-20.20s ", dev->uclass->uc_drv->name,
+ printf(" %-10.10s %2d [ %c ] %-20.20s ", dev->uclass->uc_drv->name,
dev_get_uclass_index(dev, NULL),
dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ', dev->driver->name);
@@ -49,7 +49,7 @@ void dm_dump_all(void)
root = dm_root();
if (root) {
- printf(" Class index Probed Driver Name\n");
+ printf(" Class Index Probed Driver Name\n");
printf("-----------------------------------------------------------\n");
show_devices(root, -1, 0);
}
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 1ef22e6bcd..7579eb8755 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -450,9 +450,16 @@ config SYS_I2C_BUS_MAX
help
Define the maximum number of available I2C buses.
+config SYS_I2C_XILINX_XIIC
+ bool "Xilinx AXI I2C driver"
+ depends on DM_I2C
+ help
+ Support for Xilinx AXI I2C controller.
+
config SYS_I2C_ZYNQ
bool "Xilinx I2C driver"
depends on ARCH_ZYNQMP || ARCH_ZYNQ
+ depends on !DM_I2C
help
Support for Xilinx I2C controller.
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index d3637bcd8d..ec2d1964c3 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o
obj-$(CONFIG_SYS_I2C_UNIPHIER_F) += i2c-uniphier-f.o
obj-$(CONFIG_SYS_I2C_VERSATILE) += i2c-versatile.o
+obj-$(CONFIG_SYS_I2C_XILINX_XIIC) += xilinx_xiic.o
obj-$(CONFIG_SYS_I2C_ZYNQ) += zynq_i2c.o
obj-$(CONFIG_TEGRA186_BPMP_I2C) += tegra186_bpmp_i2c.o
diff --git a/drivers/i2c/i2c-cdns.c b/drivers/i2c/i2c-cdns.c
index 30be173343..f2c4b2073c 100644
--- a/drivers/i2c/i2c-cdns.c
+++ b/drivers/i2c/i2c-cdns.c
@@ -17,6 +17,7 @@
#include <fdtdec.h>
#include <mapmem.h>
#include <wait_bit.h>
+#include <clk.h>
/* i2c register set */
struct cdns_i2c_regs {
@@ -415,6 +416,8 @@ static int cdns_i2c_ofdata_to_platdata(struct udevice *dev)
struct i2c_cdns_bus *i2c_bus = dev_get_priv(dev);
struct cdns_i2c_platform_data *pdata =
(struct cdns_i2c_platform_data *)dev_get_driver_data(dev);
+ struct clk clk;
+ int ret;
i2c_bus->regs = (struct cdns_i2c_regs *)devfdt_get_addr(dev);
if (!i2c_bus->regs)
@@ -423,7 +426,11 @@ static int cdns_i2c_ofdata_to_platdata(struct udevice *dev)
if (pdata)
i2c_bus->quirks = pdata->quirks;
- i2c_bus->input_freq = 100000000; /* TODO hardcode input freq for now */
+ ret = clk_get_by_index(dev, 0, &clk);
+ if (ret)
+ return ret;
+
+ i2c_bus->input_freq = clk_get_rate(&clk);
return 0;
}
diff --git a/drivers/i2c/muxes/i2c-mux-uclass.c b/drivers/i2c/muxes/i2c-mux-uclass.c
index 10336919ad..a680ee1762 100644
--- a/drivers/i2c/muxes/i2c-mux-uclass.c
+++ b/drivers/i2c/muxes/i2c-mux-uclass.c
@@ -11,8 +11,6 @@
#include <dm/lists.h>
#include <dm/root.h>
-DECLARE_GLOBAL_DATA_PTR;
-
/**
* struct i2c_mux: Information the uclass stores about an I2C mux
*
@@ -39,7 +37,7 @@ static int i2c_mux_child_post_bind(struct udevice *dev)
struct i2c_mux_bus *plat = dev_get_parent_platdata(dev);
int channel;
- channel = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", -1);
+ channel = dev_read_u32_default(dev, "reg", -1);
if (channel < 0)
return -EINVAL;
plat->channel = channel;
diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c
index ab8b4000af..bd4e9abe5f 100644
--- a/drivers/i2c/muxes/pca954x.c
+++ b/drivers/i2c/muxes/pca954x.c
@@ -101,7 +101,7 @@ static int pca954x_ofdata_to_platdata(struct udevice *dev)
struct pca954x_priv *priv = dev_get_priv(dev);
const struct chip_desc *chip = &chips[dev_get_driver_data(dev)];
- priv->addr = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "reg", 0);
+ priv->addr = dev_read_u32_default(dev, "reg", 0);
if (!priv->addr) {
debug("MUX not found\n");
return -ENODEV;
diff --git a/drivers/i2c/xilinx_xiic.c b/drivers/i2c/xilinx_xiic.c
new file mode 100644
index 0000000000..83114ed510
--- /dev/null
+++ b/drivers/i2c/xilinx_xiic.c
@@ -0,0 +1,340 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Xilinx AXI I2C driver
+ *
+ * Copyright (C) 2018 Marek Vasut <marex@denx.de>
+ *
+ * Based on Linux 4.14.y i2c-xiic.c
+ * Copyright (c) 2002-2007 Xilinx Inc.
+ * Copyright (c) 2009-2010 Intel Corporation
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <i2c.h>
+#include <wait_bit.h>
+#include <asm/io.h>
+
+struct xilinx_xiic_priv {
+ void __iomem *base;
+ struct clk clk;
+};
+
+#define XIIC_MSB_OFFSET 0
+#define XIIC_REG_OFFSET (0x100+XIIC_MSB_OFFSET)
+
+/*
+ * Register offsets in bytes from RegisterBase. Three is added to the
+ * base offset to access LSB (IBM style) of the word
+ */
+#define XIIC_CR_REG_OFFSET (0x00+XIIC_REG_OFFSET) /* Control Register */
+#define XIIC_SR_REG_OFFSET (0x04+XIIC_REG_OFFSET) /* Status Register */
+#define XIIC_DTR_REG_OFFSET (0x08+XIIC_REG_OFFSET) /* Data Tx Register */
+#define XIIC_DRR_REG_OFFSET (0x0C+XIIC_REG_OFFSET) /* Data Rx Register */
+#define XIIC_ADR_REG_OFFSET (0x10+XIIC_REG_OFFSET) /* Address Register */
+#define XIIC_TFO_REG_OFFSET (0x14+XIIC_REG_OFFSET) /* Tx FIFO Occupancy */
+#define XIIC_RFO_REG_OFFSET (0x18+XIIC_REG_OFFSET) /* Rx FIFO Occupancy */
+#define XIIC_TBA_REG_OFFSET (0x1C+XIIC_REG_OFFSET) /* 10 Bit Address reg */
+#define XIIC_RFD_REG_OFFSET (0x20+XIIC_REG_OFFSET) /* Rx FIFO Depth reg */
+#define XIIC_GPO_REG_OFFSET (0x24+XIIC_REG_OFFSET) /* Output Register */
+
+/* Control Register masks */
+#define XIIC_CR_ENABLE_DEVICE_MASK 0x01 /* Device enable = 1 */
+#define XIIC_CR_TX_FIFO_RESET_MASK 0x02 /* Transmit FIFO reset=1 */
+#define XIIC_CR_MSMS_MASK 0x04 /* Master starts Txing=1 */
+#define XIIC_CR_DIR_IS_TX_MASK 0x08 /* Dir of tx. Txing=1 */
+#define XIIC_CR_NO_ACK_MASK 0x10 /* Tx Ack. NO ack = 1 */
+#define XIIC_CR_REPEATED_START_MASK 0x20 /* Repeated start = 1 */
+#define XIIC_CR_GENERAL_CALL_MASK 0x40 /* Gen Call enabled = 1 */
+
+/* Status Register masks */
+#define XIIC_SR_GEN_CALL_MASK 0x01 /* 1=a mstr issued a GC */
+#define XIIC_SR_ADDR_AS_SLAVE_MASK 0x02 /* 1=when addr as slave */
+#define XIIC_SR_BUS_BUSY_MASK 0x04 /* 1 = bus is busy */
+#define XIIC_SR_MSTR_RDING_SLAVE_MASK 0x08 /* 1=Dir: mstr <-- slave */
+#define XIIC_SR_TX_FIFO_FULL_MASK 0x10 /* 1 = Tx FIFO full */
+#define XIIC_SR_RX_FIFO_FULL_MASK 0x20 /* 1 = Rx FIFO full */
+#define XIIC_SR_RX_FIFO_EMPTY_MASK 0x40 /* 1 = Rx FIFO empty */
+#define XIIC_SR_TX_FIFO_EMPTY_MASK 0x80 /* 1 = Tx FIFO empty */
+
+/* Interrupt Status Register masks Interrupt occurs when... */
+#define XIIC_INTR_ARB_LOST_MASK 0x01 /* 1 = arbitration lost */
+#define XIIC_INTR_TX_ERROR_MASK 0x02 /* 1=Tx error/msg complete */
+#define XIIC_INTR_TX_EMPTY_MASK 0x04 /* 1 = Tx FIFO/reg empty */
+#define XIIC_INTR_RX_FULL_MASK 0x08 /* 1=Rx FIFO/reg=OCY level */
+#define XIIC_INTR_BNB_MASK 0x10 /* 1 = Bus not busy */
+#define XIIC_INTR_AAS_MASK 0x20 /* 1 = when addr as slave */
+#define XIIC_INTR_NAAS_MASK 0x40 /* 1 = not addr as slave */
+#define XIIC_INTR_TX_HALF_MASK 0x80 /* 1 = TX FIFO half empty */
+
+/* The following constants specify the depth of the FIFOs */
+#define IIC_RX_FIFO_DEPTH 16 /* Rx fifo capacity */
+#define IIC_TX_FIFO_DEPTH 16 /* Tx fifo capacity */
+
+/*
+ * Tx Fifo upper bit masks.
+ */
+#define XIIC_TX_DYN_START_MASK 0x0100 /* 1 = Set dynamic start */
+#define XIIC_TX_DYN_STOP_MASK 0x0200 /* 1 = Set dynamic stop */
+
+/*
+ * The following constants define the register offsets for the Interrupt
+ * registers. There are some holes in the memory map for reserved addresses
+ * to allow other registers to be added and still match the memory map of the
+ * interrupt controller registers
+ */
+#define XIIC_DGIER_OFFSET 0x1C /* Device Global Interrupt Enable Register */
+#define XIIC_IISR_OFFSET 0x20 /* Interrupt Status Register */
+#define XIIC_IIER_OFFSET 0x28 /* Interrupt Enable Register */
+#define XIIC_RESETR_OFFSET 0x40 /* Reset Register */
+
+#define XIIC_RESET_MASK 0xAUL
+
+static u8 i2c_8bit_addr_from_flags(uint addr, u16 flags)
+{
+ return (addr << 1) | (flags & I2C_M_RD ? 1 : 0);
+}
+
+static void xiic_irq_clr(struct xilinx_xiic_priv *priv, u32 mask)
+{
+ u32 isr = readl(priv->base + XIIC_IISR_OFFSET);
+
+ writel(isr & mask, priv->base + XIIC_IISR_OFFSET);
+}
+
+static int xiic_read_rx(struct xilinx_xiic_priv *priv,
+ struct i2c_msg *msg, int nmsgs)
+{
+ u8 bytes_in_fifo;
+ u32 pos = 0;
+ int i, ret;
+
+ while (pos < msg->len) {
+ ret = wait_for_bit_8(priv->base + XIIC_SR_REG_OFFSET,
+ XIIC_SR_RX_FIFO_EMPTY_MASK, false,
+ 1000, true);
+ if (ret)
+ return ret;
+
+ bytes_in_fifo = readb(priv->base + XIIC_RFO_REG_OFFSET) + 1;
+
+ if (bytes_in_fifo > msg->len)
+ bytes_in_fifo = msg->len;
+
+ for (i = 0; i < bytes_in_fifo; i++) {
+ msg->buf[pos++] = readb(priv->base +
+ XIIC_DRR_REG_OFFSET);
+ }
+ }
+
+ return 0;
+}
+
+static int xiic_tx_fifo_space(struct xilinx_xiic_priv *priv)
+{
+ /* return the actual space left in the FIFO */
+ return IIC_TX_FIFO_DEPTH - readb(priv->base + XIIC_TFO_REG_OFFSET) - 1;
+}
+
+static void xiic_fill_tx_fifo(struct xilinx_xiic_priv *priv,
+ struct i2c_msg *msg, int nmsgs)
+{
+ u8 fifo_space = xiic_tx_fifo_space(priv);
+ int len = msg->len;
+ u32 pos = 0;
+
+ len = (len > fifo_space) ? fifo_space : len;
+
+ while (len--) {
+ u16 data = msg->buf[pos++];
+
+ if (pos == len && nmsgs == 1) {
+ /* last message in transfer -> STOP */
+ data |= XIIC_TX_DYN_STOP_MASK;
+ }
+ writew(data, priv->base + XIIC_DTR_REG_OFFSET);
+ }
+}
+
+static void xilinx_xiic_set_addr(struct udevice *dev, u8 addr,
+ u16 flags, u32 len, u32 nmsgs)
+{
+ struct xilinx_xiic_priv *priv = dev_get_priv(dev);
+
+ xiic_irq_clr(priv, XIIC_INTR_TX_ERROR_MASK);
+
+ if (!(flags & I2C_M_NOSTART)) {
+ /* write the address */
+ u16 data = i2c_8bit_addr_from_flags(addr, flags) |
+ XIIC_TX_DYN_START_MASK;
+ if (nmsgs == 1 && len == 0)
+ /* no data and last message -> add STOP */
+ data |= XIIC_TX_DYN_STOP_MASK;
+
+ writew(data, priv->base + XIIC_DTR_REG_OFFSET);
+ }
+}
+
+static int xilinx_xiic_read_common(struct udevice *dev, struct i2c_msg *msg,
+ u32 nmsgs)
+{
+ struct xilinx_xiic_priv *priv = dev_get_priv(dev);
+ u8 rx_watermark;
+
+ /* Clear and enable Rx full interrupt. */
+ xiic_irq_clr(priv, XIIC_INTR_RX_FULL_MASK | XIIC_INTR_TX_ERROR_MASK);
+
+ /* we want to get all but last byte, because the TX_ERROR IRQ is used
+ * to inidicate error ACK on the address, and negative ack on the last
+ * received byte, so to not mix them receive all but last.
+ * In the case where there is only one byte to receive
+ * we can check if ERROR and RX full is set at the same time
+ */
+ rx_watermark = msg->len;
+ if (rx_watermark > IIC_RX_FIFO_DEPTH)
+ rx_watermark = IIC_RX_FIFO_DEPTH;
+
+ writeb(rx_watermark - 1, priv->base + XIIC_RFD_REG_OFFSET);
+
+ xilinx_xiic_set_addr(dev, msg->addr, msg->flags, msg->len, nmsgs);
+
+ xiic_irq_clr(priv, XIIC_INTR_BNB_MASK);
+
+ writew((msg->len & 0xff) | ((nmsgs == 1) ? XIIC_TX_DYN_STOP_MASK : 0),
+ priv->base + XIIC_DTR_REG_OFFSET);
+
+ if (nmsgs == 1)
+ /* very last, enable bus not busy as well */
+ xiic_irq_clr(priv, XIIC_INTR_BNB_MASK);
+
+ return xiic_read_rx(priv, msg, nmsgs);
+}
+
+static int xilinx_xiic_write_common(struct udevice *dev, struct i2c_msg *msg,
+ int nmsgs)
+{
+ struct xilinx_xiic_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ xilinx_xiic_set_addr(dev, msg->addr, msg->flags, msg->len, nmsgs);
+ xiic_fill_tx_fifo(priv, msg, nmsgs);
+
+ ret = wait_for_bit_8(priv->base + XIIC_SR_REG_OFFSET,
+ XIIC_SR_TX_FIFO_EMPTY_MASK, false, 1000, true);
+ if (ret)
+ return ret;
+
+ /* Clear any pending Tx empty, Tx Error and then enable them. */
+ xiic_irq_clr(priv, XIIC_INTR_TX_EMPTY_MASK | XIIC_INTR_TX_ERROR_MASK |
+ XIIC_INTR_BNB_MASK);
+
+ return 0;
+}
+
+static void xiic_clear_rx_fifo(struct xilinx_xiic_priv *priv)
+{
+ u8 sr;
+
+ for (sr = readb(priv->base + XIIC_SR_REG_OFFSET);
+ !(sr & XIIC_SR_RX_FIFO_EMPTY_MASK);
+ sr = readb(priv->base + XIIC_SR_REG_OFFSET))
+ readb(priv->base + XIIC_DRR_REG_OFFSET);
+}
+
+static void xiic_reinit(struct xilinx_xiic_priv *priv)
+{
+ writel(XIIC_RESET_MASK, priv->base + XIIC_RESETR_OFFSET);
+
+ /* Set receive Fifo depth to maximum (zero based). */
+ writeb(IIC_RX_FIFO_DEPTH - 1, priv->base + XIIC_RFD_REG_OFFSET);
+
+ /* Reset Tx Fifo. */
+ writeb(XIIC_CR_TX_FIFO_RESET_MASK, priv->base + XIIC_CR_REG_OFFSET);
+
+ /* Enable IIC Device, remove Tx Fifo reset & disable general call. */
+ writeb(XIIC_CR_ENABLE_DEVICE_MASK, priv->base + XIIC_CR_REG_OFFSET);
+
+ /* make sure RX fifo is empty */
+ xiic_clear_rx_fifo(priv);
+
+ /* Disable interrupts */
+ writel(0, priv->base + XIIC_DGIER_OFFSET);
+
+ xiic_irq_clr(priv, XIIC_INTR_ARB_LOST_MASK);
+}
+
+static int xilinx_xiic_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
+{
+ int ret = 0;
+
+ for (; nmsgs > 0; nmsgs--, msg++) {
+ if (msg->flags & I2C_M_RD)
+ ret = xilinx_xiic_read_common(dev, msg, nmsgs);
+ else
+ ret = xilinx_xiic_write_common(dev, msg, nmsgs);
+
+ if (ret)
+ return -EREMOTEIO;
+ }
+
+ return ret;
+}
+
+static int xilinx_xiic_probe_chip(struct udevice *dev, uint addr, uint flags)
+{
+ struct xilinx_xiic_priv *priv = dev_get_priv(dev);
+ u32 reg;
+ int ret;
+
+ xiic_reinit(priv);
+
+ xilinx_xiic_set_addr(dev, addr, 0, 0, 1);
+ ret = wait_for_bit_8(priv->base + XIIC_SR_REG_OFFSET,
+ XIIC_SR_BUS_BUSY_MASK, false, 1000, true);
+ if (ret)
+ return ret;
+
+ reg = readl(priv->base + XIIC_IISR_OFFSET);
+ if (reg & XIIC_INTR_TX_ERROR_MASK)
+ return -ENODEV;
+
+ return 0;
+}
+
+static int xilinx_xiic_set_speed(struct udevice *dev, uint speed)
+{
+ return 0;
+}
+
+static int xilinx_xiic_probe(struct udevice *dev)
+{
+ struct xilinx_xiic_priv *priv = dev_get_priv(dev);
+
+ priv->base = dev_read_addr_ptr(dev);
+
+ writel(XIIC_CR_TX_FIFO_RESET_MASK, priv->base + XIIC_CR_REG_OFFSET);
+ xiic_reinit(priv);
+
+ return 0;
+}
+
+static const struct dm_i2c_ops xilinx_xiic_ops = {
+ .xfer = xilinx_xiic_xfer,
+ .probe_chip = xilinx_xiic_probe_chip,
+ .set_bus_speed = xilinx_xiic_set_speed,
+};
+
+static const struct udevice_id xilinx_xiic_ids[] = {
+ { .compatible = "xlnx,xps-iic-2.00.a" },
+ { }
+};
+
+U_BOOT_DRIVER(xilinx_xiic) = {
+ .name = "xilinx_axi_i2c",
+ .id = UCLASS_I2C,
+ .of_match = xilinx_xiic_ids,
+ .probe = xilinx_xiic_probe,
+ .priv_auto_alloc_size = sizeof(struct xilinx_xiic_priv),
+ .ops = &xilinx_xiic_ops,
+};
diff --git a/drivers/misc/fs_loader.c b/drivers/misc/fs_loader.c
index baa5f8302a..57a14a3479 100644
--- a/drivers/misc/fs_loader.c
+++ b/drivers/misc/fs_loader.c
@@ -16,9 +16,22 @@
DECLARE_GLOBAL_DATA_PTR;
-struct firmware_priv {
- const char *name; /* Filename */
- u32 offset; /* Offset of reading a file */
+/**
+ * struct firmware - A place for storing firmware and its attribute data.
+ *
+ * This holds information about a firmware and its content.
+ *
+ * @size: Size of a file
+ * @data: Buffer for file
+ * @priv: Firmware loader private fields
+ * @name: Filename
+ * @offset: Offset of reading a file
+ */
+struct firmware {
+ size_t size;
+ const u8 *data;
+ const char *name;
+ u32 offset;
};
#ifdef CONFIG_CMD_UBIFS
@@ -88,74 +101,42 @@ static int select_fs_dev(struct device_platdata *plat)
/**
* _request_firmware_prepare - Prepare firmware struct.
*
+ * @dev: An instance of a driver.
* @name: Name of firmware file.
* @dbuf: Address of buffer to load firmware into.
* @size: Size of buffer.
* @offset: Offset of a file for start reading into buffer.
- * @firmwarep: Pointer to pointer to firmware image.
*
* Return: Negative value if fail, 0 for successful.
*/
-static int _request_firmware_prepare(const char *name, void *dbuf,
- size_t size, u32 offset,
- struct firmware **firmwarep)
+static int _request_firmware_prepare(struct udevice *dev,
+ const char *name, void *dbuf,
+ size_t size, u32 offset)
{
if (!name || name[0] == '\0')
return -EINVAL;
- /* No memory allocation is required if *firmwarep is allocated */
- if (!(*firmwarep)) {
- (*firmwarep) = calloc(1, sizeof(struct firmware));
- if (!(*firmwarep))
- return -ENOMEM;
+ struct firmware *firmwarep = dev_get_priv(dev);
- (*firmwarep)->priv = calloc(1, sizeof(struct firmware_priv));
- if (!(*firmwarep)->priv) {
- free(*firmwarep);
- return -ENOMEM;
- }
- } else if (!(*firmwarep)->priv) {
- (*firmwarep)->priv = calloc(1, sizeof(struct firmware_priv));
- if (!(*firmwarep)->priv) {
- free(*firmwarep);
- return -ENOMEM;
- }
- }
+ if (!firmwarep)
+ return -ENOMEM;
- ((struct firmware_priv *)((*firmwarep)->priv))->name = name;
- ((struct firmware_priv *)((*firmwarep)->priv))->offset = offset;
- (*firmwarep)->data = dbuf;
- (*firmwarep)->size = size;
+ firmwarep->name = name;
+ firmwarep->offset = offset;
+ firmwarep->data = dbuf;
+ firmwarep->size = size;
return 0;
}
/**
- * release_firmware - Release the resource associated with a firmware image
- * @firmware: Firmware resource to release
- */
-void release_firmware(struct firmware *firmware)
-{
- if (firmware) {
- if (firmware->priv) {
- free(firmware->priv);
- firmware->priv = NULL;
- }
- free(firmware);
- }
-}
-
-/**
* fw_get_filesystem_firmware - load firmware into an allocated buffer.
- * @plat: Platform data such as storage and partition firmware loading from.
- * @firmware: pointer to firmware image.
+ * @dev: An instance of a driver.
*
* Return: Size of total read, negative value when error.
*/
-static int fw_get_filesystem_firmware(struct device_platdata *plat,
- struct firmware *firmware)
+static int fw_get_filesystem_firmware(struct udevice *dev)
{
- struct firmware_priv *fw_priv = NULL;
loff_t actread;
char *storage_interface, *dev_part, *ubi_mtdpart, *ubi_volume;
int ret;
@@ -178,20 +159,23 @@ static int fw_get_filesystem_firmware(struct device_platdata *plat,
else
ret = -ENODEV;
} else {
- ret = select_fs_dev(plat);
+ ret = select_fs_dev(dev->platdata);
}
if (ret)
goto out;
- fw_priv = firmware->priv;
+ struct firmware *firmwarep = dev_get_priv(dev);
+
+ if (!firmwarep)
+ return -ENOMEM;
- ret = fs_read(fw_priv->name, (ulong)map_to_sysmem(firmware->data),
- fw_priv->offset, firmware->size, &actread);
+ ret = fs_read(firmwarep->name, (ulong)map_to_sysmem(firmwarep->data),
+ firmwarep->offset, firmwarep->size, &actread);
if (ret) {
debug("Error: %d Failed to read %s from flash %lld != %zu.\n",
- ret, fw_priv->name, actread, firmware->size);
+ ret, firmwarep->name, actread, firmwarep->size);
} else {
ret = actread;
}
@@ -205,33 +189,30 @@ out:
/**
* request_firmware_into_buf - Load firmware into a previously allocated buffer.
- * @plat: Platform data such as storage and partition firmware loading from.
+ * @dev: An instance of a driver.
* @name: Name of firmware file.
* @buf: Address of buffer to load firmware into.
* @size: Size of buffer.
* @offset: Offset of a file for start reading into buffer.
- * @firmwarep: Pointer to firmware image.
*
- * The firmware is loaded directly into the buffer pointed to by @buf and
- * the @firmwarep data member is pointed at @buf.
+ * The firmware is loaded directly into the buffer pointed to by @buf.
*
* Return: Size of total read, negative value when error.
*/
-int request_firmware_into_buf(struct device_platdata *plat,
+int request_firmware_into_buf(struct udevice *dev,
const char *name,
- void *buf, size_t size, u32 offset,
- struct firmware **firmwarep)
+ void *buf, size_t size, u32 offset)
{
int ret;
- if (!plat)
+ if (!dev)
return -EINVAL;
- ret = _request_firmware_prepare(name, buf, size, offset, firmwarep);
+ ret = _request_firmware_prepare(dev, name, buf, size, offset);
if (ret < 0) /* error */
return ret;
- ret = fw_get_filesystem_firmware(plat, *firmwarep);
+ ret = fw_get_filesystem_firmware(dev);
return ret;
}
@@ -286,6 +267,7 @@ U_BOOT_DRIVER(fs_loader) = {
.probe = fs_loader_probe,
.ofdata_to_platdata = fs_loader_ofdata_to_platdata,
.platdata_auto_alloc_size = sizeof(struct device_platdata),
+ .priv_auto_alloc_size = sizeof(struct firmware),
};
UCLASS_DRIVER(fs_loader) = {
diff --git a/drivers/mmc/hi6220_dw_mmc.c b/drivers/mmc/hi6220_dw_mmc.c
index ce395d53c9..cc58aff38c 100644
--- a/drivers/mmc/hi6220_dw_mmc.c
+++ b/drivers/mmc/hi6220_dw_mmc.c
@@ -5,51 +5,89 @@
*/
#include <common.h>
+#include <dm.h>
#include <dwmmc.h>
+#include <errno.h>
+#include <fdtdec.h>
#include <malloc.h>
-#include <linux/errno.h>
-#define DWMMC_MAX_CH_NUM 4
+DECLARE_GLOBAL_DATA_PTR;
-#define DWMMC_MAX_FREQ 50000000
-#define DWMMC_MIN_FREQ 400000
+struct hi6220_dwmmc_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
-/* Source clock is configured to 100MHz by ATF bl1*/
-#define MMC0_DEFAULT_FREQ 100000000
+struct hi6220_dwmmc_priv_data {
+ struct dwmci_host host;
+};
-static int hi6220_dwmci_core_init(struct dwmci_host *host, int index)
+static int hi6220_dwmmc_ofdata_to_platdata(struct udevice *dev)
{
- host->name = "Hisilicon DWMMC";
+ struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev);
+ struct dwmci_host *host = &priv->host;
- host->dev_index = index;
+ host->name = dev->name;
+ host->ioaddr = (void *)devfdt_get_addr(dev);
+ host->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
+ "bus-width", 4);
+
+ /* use non-removable property for differentiating SD card and eMMC */
+ if (dev_read_bool(dev, "non-removable"))
+ host->dev_index = 0;
+ else
+ host->dev_index = 1;
+
+ host->priv = priv;
- /* Add the mmc channel to be registered with mmc core */
- if (add_dwmci(host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ)) {
- printf("DWMMC%d registration failed\n", index);
- return -1;
- }
return 0;
}
-/*
- * This function adds the mmc channel to be registered with mmc core.
- * index - mmc channel number.
- * regbase - register base address of mmc channel specified in 'index'.
- * bus_width - operating bus width of mmc channel specified in 'index'.
- */
-int hi6220_dwmci_add_port(int index, u32 regbase, int bus_width)
+static int hi6220_dwmmc_probe(struct udevice *dev)
{
- struct dwmci_host *host = NULL;
+ struct hi6220_dwmmc_plat *plat = dev_get_platdata(dev);
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct hi6220_dwmmc_priv_data *priv = dev_get_priv(dev);
+ struct dwmci_host *host = &priv->host;
- host = calloc(1, sizeof(struct dwmci_host));
- if (!host) {
- pr_err("dwmci_host calloc failed!\n");
- return -ENOMEM;
- }
+ /* Use default bus speed due to absence of clk driver */
+ host->bus_hz = 50000000;
- host->ioaddr = (void *)(ulong)regbase;
- host->buswidth = bus_width;
- host->bus_hz = MMC0_DEFAULT_FREQ;
+ dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, 400000);
+ host->mmc = &plat->mmc;
- return hi6220_dwmci_core_init(host, index);
+ host->mmc->priv = &priv->host;
+ upriv->mmc = host->mmc;
+ host->mmc->dev = dev;
+
+ return dwmci_probe(dev);
}
+
+static int hi6220_dwmmc_bind(struct udevice *dev)
+{
+ struct hi6220_dwmmc_plat *plat = dev_get_platdata(dev);
+ int ret;
+
+ ret = dwmci_bind(dev, &plat->mmc, &plat->cfg);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static const struct udevice_id hi6220_dwmmc_ids[] = {
+ { .compatible = "hisilicon,hi6220-dw-mshc" },
+ { }
+};
+
+U_BOOT_DRIVER(hi6220_dwmmc_drv) = {
+ .name = "hi6220_dwmmc",
+ .id = UCLASS_MMC,
+ .of_match = hi6220_dwmmc_ids,
+ .ofdata_to_platdata = hi6220_dwmmc_ofdata_to_platdata,
+ .ops = &dm_dwmci_ops,
+ .bind = hi6220_dwmmc_bind,
+ .probe = hi6220_dwmmc_probe,
+ .priv_auto_alloc_size = sizeof(struct hi6220_dwmmc_priv_data),
+ .platdata_auto_alloc_size = sizeof(struct hi6220_dwmmc_plat),
+};
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index d858127132..84d157ff40 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -754,7 +754,8 @@ int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
}
#if !CONFIG_IS_ENABLED(MMC_TINY)
-static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode)
+static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode,
+ bool hsdowngrade)
{
int err;
int speed_bits;
@@ -788,6 +789,20 @@ static int mmc_set_card_speed(struct mmc *mmc, enum bus_mode mode)
if (err)
return err;
+#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
+ CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+ /*
+ * In case the eMMC is in HS200/HS400 mode and we are downgrading
+ * to HS mode, the card clock are still running much faster than
+ * the supported HS mode clock, so we can not reliably read out
+ * Extended CSD. Reconfigure the controller to run at HS mode.
+ */
+ if (hsdowngrade) {
+ mmc_select_mode(mmc, MMC_HS);
+ mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
+ }
+#endif
+
if ((mode == MMC_HS) || (mode == MMC_HS_52)) {
/* Now check to see that it worked */
err = mmc_send_ext_csd(mmc, test_csd);
@@ -1849,7 +1864,7 @@ static int mmc_select_hs400(struct mmc *mmc)
int err;
/* Set timing to HS200 for tuning */
- err = mmc_set_card_speed(mmc, MMC_HS_200);
+ err = mmc_set_card_speed(mmc, MMC_HS_200, false);
if (err)
return err;
@@ -1865,7 +1880,7 @@ static int mmc_select_hs400(struct mmc *mmc)
}
/* Set back to HS */
- mmc_set_card_speed(mmc, MMC_HS);
+ mmc_set_card_speed(mmc, MMC_HS, false);
mmc_set_clock(mmc, mmc_mode2freq(mmc, MMC_HS), false);
err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
@@ -1873,7 +1888,7 @@ static int mmc_select_hs400(struct mmc *mmc)
if (err)
return err;
- err = mmc_set_card_speed(mmc, MMC_HS_400);
+ err = mmc_set_card_speed(mmc, MMC_HS_400, false);
if (err)
return err;
@@ -1920,7 +1935,19 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
return -ENOTSUPP;
}
- mmc_set_clock(mmc, mmc->legacy_speed, MMC_CLK_ENABLE);
+#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT) || \
+ CONFIG_IS_ENABLED(MMC_HS400_SUPPORT)
+ /*
+ * In case the eMMC is in HS200/HS400 mode, downgrade to HS mode
+ * before doing anything else, since a transition from either of
+ * the HS200/HS400 mode directly to legacy mode is not supported.
+ */
+ if (mmc->selected_mode == MMC_HS_200 ||
+ mmc->selected_mode == MMC_HS_400)
+ mmc_set_card_speed(mmc, MMC_HS, true);
+ else
+#endif
+ mmc_set_clock(mmc, mmc->legacy_speed, MMC_CLK_ENABLE);
for_each_mmc_mode_by_pref(card_caps, mwt) {
for_each_supported_width(card_caps & mwt->widths,
@@ -1952,7 +1979,7 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps)
}
} else {
/* configure the bus speed (card) */
- err = mmc_set_card_speed(mmc, mwt->mode);
+ err = mmc_set_card_speed(mmc, mwt->mode, false);
if (err)
goto error;
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index fd1723feda..ffc6cc98aa 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -9,6 +9,12 @@ config SYS_NAND_SELF_INIT
This option, if enabled, provides more flexible and linux-like
NAND initialization process.
+config SYS_NAND_DRIVER_ECC_LAYOUT
+ bool
+ help
+ Omit standard ECC layouts to safe space. Select this if your driver
+ is known to provide its own ECC layout.
+
config NAND_ATMEL
bool "Support Atmel NAND controller"
imply SYS_NAND_USE_FLASH_BBT
@@ -81,6 +87,7 @@ config NAND_OMAP_ELM
config NAND_VF610_NFC
bool "Support for Freescale NFC for VF610"
select SYS_NAND_SELF_INIT
+ select SYS_NAND_DRIVER_ECC_LAYOUT
imply CMD_NAND
help
Enables support for NAND Flash Controller on some Freescale
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 92daebe120..6d2ff58d86 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -47,6 +47,7 @@
#include <linux/errno.h>
/* Define default oob placement schemes for large and small page devices */
+#ifdef CONFIG_SYS_NAND_DRIVER_ECC_LAYOUT
static struct nand_ecclayout nand_oob_8 = {
.eccbytes = 3,
.eccpos = {0, 1, 2},
@@ -89,6 +90,7 @@ static struct nand_ecclayout nand_oob_128 = {
{.offset = 2,
.length = 78} }
};
+#endif
static int nand_get_device(struct mtd_info *mtd, int new_state);
@@ -4339,6 +4341,7 @@ int nand_scan_tail(struct mtd_info *mtd)
*/
if (!ecc->layout && (ecc->mode != NAND_ECC_SOFT_BCH)) {
switch (mtd->oobsize) {
+#ifdef CONFIG_SYS_NAND_DRIVER_ECC_LAYOUT
case 8:
ecc->layout = &nand_oob_8;
break;
@@ -4351,6 +4354,7 @@ int nand_scan_tail(struct mtd_info *mtd)
case 128:
ecc->layout = &nand_oob_128;
break;
+#endif
default:
pr_warn("No oob scheme defined for oobsize %d\n",
mtd->oobsize);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 7044c6adf3..ff55e03d3f 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -513,4 +513,14 @@ config TSEC_ENET
This driver implements support for the (Enhanced) Three-Speed
Ethernet Controller found on Freescale SoCs.
+config MEDIATEK_ETH
+ bool "MediaTek Ethernet GMAC Driver"
+ depends on DM_ETH
+ select PHYLIB
+ select DM_GPIO
+ select DM_RESET
+ help
+ This Driver support MediaTek Ethernet GMAC
+ Say Y to enable support for the MediaTek Ethernet GMAC.
+
endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 0dbfa03306..ee7f3e71a8 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -74,3 +74,4 @@ obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o
obj-$(CONFIG_FSL_PFE) += pfe_eth/
obj-$(CONFIG_SNI_AVE) += sni_ave.o
obj-y += ti/
+obj-$(CONFIG_MEDIATEK_ETH) += mtk_eth.o
diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c
new file mode 100644
index 0000000000..cc09404830
--- /dev/null
+++ b/drivers/net/mtk_eth.c
@@ -0,0 +1,1175 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ * Author: Mark Lee <mark-mc.lee@mediatek.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <regmap.h>
+#include <reset.h>
+#include <syscon.h>
+#include <wait_bit.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <linux/err.h>
+#include <linux/ioport.h>
+#include <linux/mdio.h>
+#include <linux/mii.h>
+
+#include "mtk_eth.h"
+
+#define NUM_TX_DESC 24
+#define NUM_RX_DESC 24
+#define TX_TOTAL_BUF_SIZE (NUM_TX_DESC * PKTSIZE_ALIGN)
+#define RX_TOTAL_BUF_SIZE (NUM_RX_DESC * PKTSIZE_ALIGN)
+#define TOTAL_PKT_BUF_SIZE (TX_TOTAL_BUF_SIZE + RX_TOTAL_BUF_SIZE)
+
+#define MT7530_NUM_PHYS 5
+#define MT7530_DFL_SMI_ADDR 31
+
+#define MT7530_PHY_ADDR(base, addr) \
+ (((base) + (addr)) & 0x1f)
+
+#define GDMA_FWD_TO_CPU \
+ (0x20000000 | \
+ GDM_ICS_EN | \
+ GDM_TCS_EN | \
+ GDM_UCS_EN | \
+ STRP_CRC | \
+ (DP_PDMA << MYMAC_DP_S) | \
+ (DP_PDMA << BC_DP_S) | \
+ (DP_PDMA << MC_DP_S) | \
+ (DP_PDMA << UN_DP_S))
+
+#define GDMA_FWD_DISCARD \
+ (0x20000000 | \
+ GDM_ICS_EN | \
+ GDM_TCS_EN | \
+ GDM_UCS_EN | \
+ STRP_CRC | \
+ (DP_DISCARD << MYMAC_DP_S) | \
+ (DP_DISCARD << BC_DP_S) | \
+ (DP_DISCARD << MC_DP_S) | \
+ (DP_DISCARD << UN_DP_S))
+
+struct pdma_rxd_info1 {
+ u32 PDP0;
+};
+
+struct pdma_rxd_info2 {
+ u32 PLEN1 : 14;
+ u32 LS1 : 1;
+ u32 UN_USED : 1;
+ u32 PLEN0 : 14;
+ u32 LS0 : 1;
+ u32 DDONE : 1;
+};
+
+struct pdma_rxd_info3 {
+ u32 PDP1;
+};
+
+struct pdma_rxd_info4 {
+ u32 FOE_ENTRY : 14;
+ u32 CRSN : 5;
+ u32 SP : 3;
+ u32 L4F : 1;
+ u32 L4VLD : 1;
+ u32 TACK : 1;
+ u32 IP4F : 1;
+ u32 IP4 : 1;
+ u32 IP6 : 1;
+ u32 UN_USED : 4;
+};
+
+struct pdma_rxdesc {
+ struct pdma_rxd_info1 rxd_info1;
+ struct pdma_rxd_info2 rxd_info2;
+ struct pdma_rxd_info3 rxd_info3;
+ struct pdma_rxd_info4 rxd_info4;
+};
+
+struct pdma_txd_info1 {
+ u32 SDP0;
+};
+
+struct pdma_txd_info2 {
+ u32 SDL1 : 14;
+ u32 LS1 : 1;
+ u32 BURST : 1;
+ u32 SDL0 : 14;
+ u32 LS0 : 1;
+ u32 DDONE : 1;
+};
+
+struct pdma_txd_info3 {
+ u32 SDP1;
+};
+
+struct pdma_txd_info4 {
+ u32 VLAN_TAG : 16;
+ u32 INS : 1;
+ u32 RESV : 2;
+ u32 UDF : 6;
+ u32 FPORT : 3;
+ u32 TSO : 1;
+ u32 TUI_CO : 3;
+};
+
+struct pdma_txdesc {
+ struct pdma_txd_info1 txd_info1;
+ struct pdma_txd_info2 txd_info2;
+ struct pdma_txd_info3 txd_info3;
+ struct pdma_txd_info4 txd_info4;
+};
+
+enum mtk_switch {
+ SW_NONE,
+ SW_MT7530
+};
+
+enum mtk_soc {
+ SOC_MT7623,
+ SOC_MT7629
+};
+
+struct mtk_eth_priv {
+ char pkt_pool[TOTAL_PKT_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN);
+
+ struct pdma_txdesc *tx_ring_noc;
+ struct pdma_rxdesc *rx_ring_noc;
+
+ int rx_dma_owner_idx0;
+ int tx_cpu_owner_idx0;
+
+ void __iomem *fe_base;
+ void __iomem *gmac_base;
+ void __iomem *ethsys_base;
+
+ struct mii_dev *mdio_bus;
+ int (*mii_read)(struct mtk_eth_priv *priv, u8 phy, u8 reg);
+ int (*mii_write)(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 val);
+ int (*mmd_read)(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg);
+ int (*mmd_write)(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg,
+ u16 val);
+
+ enum mtk_soc soc;
+ int gmac_id;
+ int force_mode;
+ int speed;
+ int duplex;
+
+ struct phy_device *phydev;
+ int phy_interface;
+ int phy_addr;
+
+ enum mtk_switch sw;
+ int (*switch_init)(struct mtk_eth_priv *priv);
+ u32 mt7530_smi_addr;
+ u32 mt7530_phy_base;
+
+ struct gpio_desc rst_gpio;
+ int mcm;
+
+ struct reset_ctl rst_fe;
+ struct reset_ctl rst_mcm;
+};
+
+static void mtk_pdma_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
+{
+ writel(val, priv->fe_base + PDMA_BASE + reg);
+}
+
+static void mtk_pdma_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
+ u32 set)
+{
+ clrsetbits_le32(priv->fe_base + PDMA_BASE + reg, clr, set);
+}
+
+static void mtk_gdma_write(struct mtk_eth_priv *priv, int no, u32 reg,
+ u32 val)
+{
+ u32 gdma_base;
+
+ if (no == 1)
+ gdma_base = GDMA2_BASE;
+ else
+ gdma_base = GDMA1_BASE;
+
+ writel(val, priv->fe_base + gdma_base + reg);
+}
+
+static u32 mtk_gmac_read(struct mtk_eth_priv *priv, u32 reg)
+{
+ return readl(priv->gmac_base + reg);
+}
+
+static void mtk_gmac_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
+{
+ writel(val, priv->gmac_base + reg);
+}
+
+static void mtk_gmac_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set)
+{
+ clrsetbits_le32(priv->gmac_base + reg, clr, set);
+}
+
+static void mtk_ethsys_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
+ u32 set)
+{
+ clrsetbits_le32(priv->ethsys_base + reg, clr, set);
+}
+
+/* Direct MDIO clause 22/45 access via SoC */
+static int mtk_mii_rw(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 data,
+ u32 cmd, u32 st)
+{
+ int ret;
+ u32 val;
+
+ val = (st << MDIO_ST_S) |
+ ((cmd << MDIO_CMD_S) & MDIO_CMD_M) |
+ (((u32)phy << MDIO_PHY_ADDR_S) & MDIO_PHY_ADDR_M) |
+ (((u32)reg << MDIO_REG_ADDR_S) & MDIO_REG_ADDR_M);
+
+ if (cmd == MDIO_CMD_WRITE)
+ val |= data & MDIO_RW_DATA_M;
+
+ mtk_gmac_write(priv, GMAC_PIAC_REG, val | PHY_ACS_ST);
+
+ ret = wait_for_bit_le32(priv->gmac_base + GMAC_PIAC_REG,
+ PHY_ACS_ST, 0, 5000, 0);
+ if (ret) {
+ pr_warn("MDIO access timeout\n");
+ return ret;
+ }
+
+ if (cmd == MDIO_CMD_READ) {
+ val = mtk_gmac_read(priv, GMAC_PIAC_REG);
+ return val & MDIO_RW_DATA_M;
+ }
+
+ return 0;
+}
+
+/* Direct MDIO clause 22 read via SoC */
+static int mtk_mii_read(struct mtk_eth_priv *priv, u8 phy, u8 reg)
+{
+ return mtk_mii_rw(priv, phy, reg, 0, MDIO_CMD_READ, MDIO_ST_C22);
+}
+
+/* Direct MDIO clause 22 write via SoC */
+static int mtk_mii_write(struct mtk_eth_priv *priv, u8 phy, u8 reg, u16 data)
+{
+ return mtk_mii_rw(priv, phy, reg, data, MDIO_CMD_WRITE, MDIO_ST_C22);
+}
+
+/* Direct MDIO clause 45 read via SoC */
+static int mtk_mmd_read(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg)
+{
+ int ret;
+
+ ret = mtk_mii_rw(priv, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
+ if (ret)
+ return ret;
+
+ return mtk_mii_rw(priv, addr, devad, 0, MDIO_CMD_READ_C45,
+ MDIO_ST_C45);
+}
+
+/* Direct MDIO clause 45 write via SoC */
+static int mtk_mmd_write(struct mtk_eth_priv *priv, u8 addr, u8 devad,
+ u16 reg, u16 val)
+{
+ int ret;
+
+ ret = mtk_mii_rw(priv, addr, devad, reg, MDIO_CMD_ADDR, MDIO_ST_C45);
+ if (ret)
+ return ret;
+
+ return mtk_mii_rw(priv, addr, devad, val, MDIO_CMD_WRITE,
+ MDIO_ST_C45);
+}
+
+/* Indirect MDIO clause 45 read via MII registers */
+static int mtk_mmd_ind_read(struct mtk_eth_priv *priv, u8 addr, u8 devad,
+ u16 reg)
+{
+ int ret;
+
+ ret = priv->mii_write(priv, addr, MII_MMD_ACC_CTL_REG,
+ (MMD_ADDR << MMD_CMD_S) |
+ ((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
+ if (ret)
+ return ret;
+
+ ret = priv->mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, reg);
+ if (ret)
+ return ret;
+
+ ret = priv->mii_write(priv, addr, MII_MMD_ACC_CTL_REG,
+ (MMD_DATA << MMD_CMD_S) |
+ ((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
+ if (ret)
+ return ret;
+
+ return priv->mii_read(priv, addr, MII_MMD_ADDR_DATA_REG);
+}
+
+/* Indirect MDIO clause 45 write via MII registers */
+static int mtk_mmd_ind_write(struct mtk_eth_priv *priv, u8 addr, u8 devad,
+ u16 reg, u16 val)
+{
+ int ret;
+
+ ret = priv->mii_write(priv, addr, MII_MMD_ACC_CTL_REG,
+ (MMD_ADDR << MMD_CMD_S) |
+ ((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
+ if (ret)
+ return ret;
+
+ ret = priv->mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, reg);
+ if (ret)
+ return ret;
+
+ ret = priv->mii_write(priv, addr, MII_MMD_ACC_CTL_REG,
+ (MMD_DATA << MMD_CMD_S) |
+ ((devad << MMD_DEVAD_S) & MMD_DEVAD_M));
+ if (ret)
+ return ret;
+
+ return priv->mii_write(priv, addr, MII_MMD_ADDR_DATA_REG, val);
+}
+
+static int mtk_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+ struct mtk_eth_priv *priv = bus->priv;
+
+ if (devad < 0)
+ return priv->mii_read(priv, addr, reg);
+ else
+ return priv->mmd_read(priv, addr, devad, reg);
+}
+
+static int mtk_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
+ u16 val)
+{
+ struct mtk_eth_priv *priv = bus->priv;
+
+ if (devad < 0)
+ return priv->mii_write(priv, addr, reg, val);
+ else
+ return priv->mmd_write(priv, addr, devad, reg, val);
+}
+
+static int mtk_mdio_register(struct udevice *dev)
+{
+ struct mtk_eth_priv *priv = dev_get_priv(dev);
+ struct mii_dev *mdio_bus = mdio_alloc();
+ int ret;
+
+ if (!mdio_bus)
+ return -ENOMEM;
+
+ /* Assign MDIO access APIs according to the switch/phy */
+ switch (priv->sw) {
+ case SW_MT7530:
+ priv->mii_read = mtk_mii_read;
+ priv->mii_write = mtk_mii_write;
+ priv->mmd_read = mtk_mmd_ind_read;
+ priv->mmd_write = mtk_mmd_ind_write;
+ break;
+ default:
+ priv->mii_read = mtk_mii_read;
+ priv->mii_write = mtk_mii_write;
+ priv->mmd_read = mtk_mmd_read;
+ priv->mmd_write = mtk_mmd_write;
+ }
+
+ mdio_bus->read = mtk_mdio_read;
+ mdio_bus->write = mtk_mdio_write;
+ snprintf(mdio_bus->name, sizeof(mdio_bus->name), dev->name);
+
+ mdio_bus->priv = (void *)priv;
+
+ ret = mdio_register(mdio_bus);
+
+ if (ret)
+ return ret;
+
+ priv->mdio_bus = mdio_bus;
+
+ return 0;
+}
+
+/*
+ * MT7530 Internal Register Address Bits
+ * -------------------------------------------------------------------
+ * | 15 14 13 12 11 10 9 8 7 6 | 5 4 3 2 | 1 0 |
+ * |----------------------------------------|---------------|--------|
+ * | Page Address | Reg Address | Unused |
+ * -------------------------------------------------------------------
+ */
+
+static int mt7530_reg_read(struct mtk_eth_priv *priv, u32 reg, u32 *data)
+{
+ int ret, low_word, high_word;
+
+ /* Write page address */
+ ret = mtk_mii_write(priv, priv->mt7530_smi_addr, 0x1f, reg >> 6);
+ if (ret)
+ return ret;
+
+ /* Read low word */
+ low_word = mtk_mii_read(priv, priv->mt7530_smi_addr, (reg >> 2) & 0xf);
+ if (low_word < 0)
+ return low_word;
+
+ /* Read high word */
+ high_word = mtk_mii_read(priv, priv->mt7530_smi_addr, 0x10);
+ if (high_word < 0)
+ return high_word;
+
+ if (data)
+ *data = ((u32)high_word << 16) | (low_word & 0xffff);
+
+ return 0;
+}
+
+static int mt7530_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 data)
+{
+ int ret;
+
+ /* Write page address */
+ ret = mtk_mii_write(priv, priv->mt7530_smi_addr, 0x1f, reg >> 6);
+ if (ret)
+ return ret;
+
+ /* Write low word */
+ ret = mtk_mii_write(priv, priv->mt7530_smi_addr, (reg >> 2) & 0xf,
+ data & 0xffff);
+ if (ret)
+ return ret;
+
+ /* Write high word */
+ return mtk_mii_write(priv, priv->mt7530_smi_addr, 0x10, data >> 16);
+}
+
+static void mt7530_reg_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr,
+ u32 set)
+{
+ u32 val;
+
+ mt7530_reg_read(priv, reg, &val);
+ val &= ~clr;
+ val |= set;
+ mt7530_reg_write(priv, reg, val);
+}
+
+static void mt7530_core_reg_write(struct mtk_eth_priv *priv, u32 reg, u32 val)
+{
+ u8 phy_addr = MT7530_PHY_ADDR(priv->mt7530_phy_base, 0);
+
+ mtk_mmd_ind_write(priv, phy_addr, 0x1f, reg, val);
+}
+
+static int mt7530_pad_clk_setup(struct mtk_eth_priv *priv, int mode)
+{
+ u32 ncpo1, ssc_delta;
+
+ switch (mode) {
+ case PHY_INTERFACE_MODE_RGMII:
+ ncpo1 = 0x0c80;
+ ssc_delta = 0x87;
+ break;
+ default:
+ printf("error: xMII mode %d not supported\n", mode);
+ return -EINVAL;
+ }
+
+ /* Disable MT7530 core clock */
+ mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, 0);
+
+ /* Disable MT7530 PLL */
+ mt7530_core_reg_write(priv, CORE_GSWPLL_GRP1,
+ (2 << RG_GSWPLL_POSDIV_200M_S) |
+ (32 << RG_GSWPLL_FBKDIV_200M_S));
+
+ /* For MT7530 core clock = 500Mhz */
+ mt7530_core_reg_write(priv, CORE_GSWPLL_GRP2,
+ (1 << RG_GSWPLL_POSDIV_500M_S) |
+ (25 << RG_GSWPLL_FBKDIV_500M_S));
+
+ /* Enable MT7530 PLL */
+ mt7530_core_reg_write(priv, CORE_GSWPLL_GRP1,
+ (2 << RG_GSWPLL_POSDIV_200M_S) |
+ (32 << RG_GSWPLL_FBKDIV_200M_S) |
+ RG_GSWPLL_EN_PRE);
+
+ udelay(20);
+
+ mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG, REG_GSWCK_EN);
+
+ /* Setup the MT7530 TRGMII Tx Clock */
+ mt7530_core_reg_write(priv, CORE_PLL_GROUP5, ncpo1);
+ mt7530_core_reg_write(priv, CORE_PLL_GROUP6, 0);
+ mt7530_core_reg_write(priv, CORE_PLL_GROUP10, ssc_delta);
+ mt7530_core_reg_write(priv, CORE_PLL_GROUP11, ssc_delta);
+ mt7530_core_reg_write(priv, CORE_PLL_GROUP4, RG_SYSPLL_DDSFBK_EN |
+ RG_SYSPLL_BIAS_EN | RG_SYSPLL_BIAS_LPF_EN);
+
+ mt7530_core_reg_write(priv, CORE_PLL_GROUP2,
+ RG_SYSPLL_EN_NORMAL | RG_SYSPLL_VODEN |
+ (1 << RG_SYSPLL_POSDIV_S));
+
+ mt7530_core_reg_write(priv, CORE_PLL_GROUP7,
+ RG_LCDDS_PCW_NCPO_CHG | (3 << RG_LCCDS_C_S) |
+ RG_LCDDS_PWDB | RG_LCDDS_ISO_EN);
+
+ /* Enable MT7530 core clock */
+ mt7530_core_reg_write(priv, CORE_TRGMII_GSW_CLK_CG,
+ REG_GSWCK_EN | REG_TRGMIICK_EN);
+
+ return 0;
+}
+
+static int mt7530_setup(struct mtk_eth_priv *priv)
+{
+ u16 phy_addr, phy_val;
+ u32 val;
+ int i;
+
+ /* Select 250MHz clk for RGMII mode */
+ mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG,
+ ETHSYS_TRGMII_CLK_SEL362_5, 0);
+
+ /* Global reset switch */
+ if (priv->mcm) {
+ reset_assert(&priv->rst_mcm);
+ udelay(1000);
+ reset_deassert(&priv->rst_mcm);
+ mdelay(1000);
+ } else if (dm_gpio_is_valid(&priv->rst_gpio)) {
+ dm_gpio_set_value(&priv->rst_gpio, 0);
+ udelay(1000);
+ dm_gpio_set_value(&priv->rst_gpio, 1);
+ mdelay(1000);
+ }
+
+ /* Modify HWTRAP first to allow direct access to internal PHYs */
+ mt7530_reg_read(priv, HWTRAP_REG, &val);
+ val |= CHG_TRAP;
+ val &= ~C_MDIO_BPS;
+ mt7530_reg_write(priv, MHWTRAP_REG, val);
+
+ /* Calculate the phy base address */
+ val = ((val & SMI_ADDR_M) >> SMI_ADDR_S) << 3;
+ priv->mt7530_phy_base = (val | 0x7) + 1;
+
+ /* Turn off PHYs */
+ for (i = 0; i < MT7530_NUM_PHYS; i++) {
+ phy_addr = MT7530_PHY_ADDR(priv->mt7530_phy_base, i);
+ phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
+ phy_val |= BMCR_PDOWN;
+ priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
+ }
+
+ /* Force MAC link down before reset */
+ mt7530_reg_write(priv, PCMR_REG(5), FORCE_MODE);
+ mt7530_reg_write(priv, PCMR_REG(6), FORCE_MODE);
+
+ /* MT7530 reset */
+ mt7530_reg_write(priv, SYS_CTRL_REG, SW_SYS_RST | SW_REG_RST);
+ udelay(100);
+
+ val = (1 << IPG_CFG_S) |
+ MAC_MODE | FORCE_MODE |
+ MAC_TX_EN | MAC_RX_EN |
+ BKOFF_EN | BACKPR_EN |
+ (SPEED_1000M << FORCE_SPD_S) |
+ FORCE_DPX | FORCE_LINK;
+
+ /* MT7530 Port6: Forced 1000M/FD, FC disabled */
+ mt7530_reg_write(priv, PCMR_REG(6), val);
+
+ /* MT7530 Port5: Forced link down */
+ mt7530_reg_write(priv, PCMR_REG(5), FORCE_MODE);
+
+ /* MT7530 Port6: Set to RGMII */
+ mt7530_reg_rmw(priv, MT7530_P6ECR, P6_INTF_MODE_M, P6_INTF_MODE_RGMII);
+
+ /* Hardware Trap: Enable Port6, Disable Port5 */
+ mt7530_reg_read(priv, HWTRAP_REG, &val);
+ val |= CHG_TRAP | LOOPDET_DIS | P5_INTF_DIS |
+ (P5_INTF_SEL_GMAC5 << P5_INTF_SEL_S) |
+ (P5_INTF_MODE_RGMII << P5_INTF_MODE_S);
+ val &= ~(C_MDIO_BPS | P6_INTF_DIS);
+ mt7530_reg_write(priv, MHWTRAP_REG, val);
+
+ /* Setup switch core pll */
+ mt7530_pad_clk_setup(priv, priv->phy_interface);
+
+ /* Lower Tx Driving for TRGMII path */
+ for (i = 0 ; i < NUM_TRGMII_CTRL ; i++)
+ mt7530_reg_write(priv, MT7530_TRGMII_TD_ODT(i),
+ (8 << TD_DM_DRVP_S) | (8 << TD_DM_DRVN_S));
+
+ for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
+ mt7530_reg_rmw(priv, MT7530_TRGMII_RD(i), RD_TAP_M, 16);
+
+ /* Turn on PHYs */
+ for (i = 0; i < MT7530_NUM_PHYS; i++) {
+ phy_addr = MT7530_PHY_ADDR(priv->mt7530_phy_base, i);
+ phy_val = priv->mii_read(priv, phy_addr, MII_BMCR);
+ phy_val &= ~BMCR_PDOWN;
+ priv->mii_write(priv, phy_addr, MII_BMCR, phy_val);
+ }
+
+ /* Set port isolation */
+ for (i = 0; i < 8; i++) {
+ /* Set port matrix mode */
+ if (i != 6)
+ mt7530_reg_write(priv, PCR_REG(i),
+ (0x40 << PORT_MATRIX_S));
+ else
+ mt7530_reg_write(priv, PCR_REG(i),
+ (0x3f << PORT_MATRIX_S));
+
+ /* Set port mode to user port */
+ mt7530_reg_write(priv, PVC_REG(i),
+ (0x8100 << STAG_VPID_S) |
+ (VLAN_ATTR_USER << VLAN_ATTR_S));
+ }
+
+ return 0;
+}
+
+static void mtk_phy_link_adjust(struct mtk_eth_priv *priv)
+{
+ u16 lcl_adv = 0, rmt_adv = 0;
+ u8 flowctrl;
+ u32 mcr;
+
+ mcr = (1 << IPG_CFG_S) |
+ (MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) |
+ MAC_MODE | FORCE_MODE |
+ MAC_TX_EN | MAC_RX_EN |
+ BKOFF_EN | BACKPR_EN;
+
+ switch (priv->phydev->speed) {
+ case SPEED_10:
+ mcr |= (SPEED_10M << FORCE_SPD_S);
+ break;
+ case SPEED_100:
+ mcr |= (SPEED_100M << FORCE_SPD_S);
+ break;
+ case SPEED_1000:
+ mcr |= (SPEED_1000M << FORCE_SPD_S);
+ break;
+ };
+
+ if (priv->phydev->link)
+ mcr |= FORCE_LINK;
+
+ if (priv->phydev->duplex) {
+ mcr |= FORCE_DPX;
+
+ if (priv->phydev->pause)
+ rmt_adv = LPA_PAUSE_CAP;
+ if (priv->phydev->asym_pause)
+ rmt_adv |= LPA_PAUSE_ASYM;
+
+ if (priv->phydev->advertising & ADVERTISED_Pause)
+ lcl_adv |= ADVERTISE_PAUSE_CAP;
+ if (priv->phydev->advertising & ADVERTISED_Asym_Pause)
+ lcl_adv |= ADVERTISE_PAUSE_ASYM;
+
+ flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
+
+ if (flowctrl & FLOW_CTRL_TX)
+ mcr |= FORCE_TX_FC;
+ if (flowctrl & FLOW_CTRL_RX)
+ mcr |= FORCE_RX_FC;
+
+ debug("rx pause %s, tx pause %s\n",
+ flowctrl & FLOW_CTRL_RX ? "enabled" : "disabled",
+ flowctrl & FLOW_CTRL_TX ? "enabled" : "disabled");
+ }
+
+ mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), mcr);
+}
+
+static int mtk_phy_start(struct mtk_eth_priv *priv)
+{
+ struct phy_device *phydev = priv->phydev;
+ int ret;
+
+ ret = phy_startup(phydev);
+
+ if (ret) {
+ debug("Could not initialize PHY %s\n", phydev->dev->name);
+ return ret;
+ }
+
+ if (!phydev->link) {
+ debug("%s: link down.\n", phydev->dev->name);
+ return 0;
+ }
+
+ mtk_phy_link_adjust(priv);
+
+ debug("Speed: %d, %s duplex%s\n", phydev->speed,
+ (phydev->duplex) ? "full" : "half",
+ (phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
+
+ return 0;
+}
+
+static int mtk_phy_probe(struct udevice *dev)
+{
+ struct mtk_eth_priv *priv = dev_get_priv(dev);
+ struct phy_device *phydev;
+
+ phydev = phy_connect(priv->mdio_bus, priv->phy_addr, dev,
+ priv->phy_interface);
+ if (!phydev)
+ return -ENODEV;
+
+ phydev->supported &= PHY_GBIT_FEATURES;
+ phydev->advertising = phydev->supported;
+
+ priv->phydev = phydev;
+ phy_config(phydev);
+
+ return 0;
+}
+
+static void mtk_mac_init(struct mtk_eth_priv *priv)
+{
+ int i, ge_mode = 0;
+ u32 mcr;
+
+ switch (priv->phy_interface) {
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_SGMII:
+ ge_mode = GE_MODE_RGMII;
+ break;
+ case PHY_INTERFACE_MODE_MII:
+ case PHY_INTERFACE_MODE_GMII:
+ ge_mode = GE_MODE_MII;
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ ge_mode = GE_MODE_RMII;
+ break;
+ default:
+ break;
+ }
+
+ /* set the gmac to the right mode */
+ mtk_ethsys_rmw(priv, ETHSYS_SYSCFG0_REG,
+ SYSCFG0_GE_MODE_M << SYSCFG0_GE_MODE_S(priv->gmac_id),
+ ge_mode << SYSCFG0_GE_MODE_S(priv->gmac_id));
+
+ if (priv->force_mode) {
+ mcr = (1 << IPG_CFG_S) |
+ (MAC_RX_PKT_LEN_1536 << MAC_RX_PKT_LEN_S) |
+ MAC_MODE | FORCE_MODE |
+ MAC_TX_EN | MAC_RX_EN |
+ BKOFF_EN | BACKPR_EN |
+ FORCE_LINK;
+
+ switch (priv->speed) {
+ case SPEED_10:
+ mcr |= SPEED_10M << FORCE_SPD_S;
+ break;
+ case SPEED_100:
+ mcr |= SPEED_100M << FORCE_SPD_S;
+ break;
+ case SPEED_1000:
+ mcr |= SPEED_1000M << FORCE_SPD_S;
+ break;
+ }
+
+ if (priv->duplex)
+ mcr |= FORCE_DPX;
+
+ mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), mcr);
+ }
+
+ if (priv->soc == SOC_MT7623) {
+ /* Lower Tx Driving for TRGMII path */
+ for (i = 0 ; i < NUM_TRGMII_CTRL; i++)
+ mtk_gmac_write(priv, GMAC_TRGMII_TD_ODT(i),
+ (8 << TD_DM_DRVP_S) |
+ (8 << TD_DM_DRVN_S));
+
+ mtk_gmac_rmw(priv, GMAC_TRGMII_RCK_CTRL, 0,
+ RX_RST | RXC_DQSISEL);
+ mtk_gmac_rmw(priv, GMAC_TRGMII_RCK_CTRL, RX_RST, 0);
+ }
+}
+
+static void mtk_eth_fifo_init(struct mtk_eth_priv *priv)
+{
+ char *pkt_base = priv->pkt_pool;
+ int i;
+
+ mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0);
+ udelay(500);
+
+ memset(priv->tx_ring_noc, 0, NUM_TX_DESC * sizeof(struct pdma_txdesc));
+ memset(priv->rx_ring_noc, 0, NUM_RX_DESC * sizeof(struct pdma_rxdesc));
+ memset(priv->pkt_pool, 0, TOTAL_PKT_BUF_SIZE);
+
+ flush_dcache_range((u32)pkt_base, (u32)(pkt_base + TOTAL_PKT_BUF_SIZE));
+
+ priv->rx_dma_owner_idx0 = 0;
+ priv->tx_cpu_owner_idx0 = 0;
+
+ for (i = 0; i < NUM_TX_DESC; i++) {
+ priv->tx_ring_noc[i].txd_info2.LS0 = 1;
+ priv->tx_ring_noc[i].txd_info2.DDONE = 1;
+ priv->tx_ring_noc[i].txd_info4.FPORT = priv->gmac_id + 1;
+
+ priv->tx_ring_noc[i].txd_info1.SDP0 = virt_to_phys(pkt_base);
+ pkt_base += PKTSIZE_ALIGN;
+ }
+
+ for (i = 0; i < NUM_RX_DESC; i++) {
+ priv->rx_ring_noc[i].rxd_info2.PLEN0 = PKTSIZE_ALIGN;
+ priv->rx_ring_noc[i].rxd_info1.PDP0 = virt_to_phys(pkt_base);
+ pkt_base += PKTSIZE_ALIGN;
+ }
+
+ mtk_pdma_write(priv, TX_BASE_PTR_REG(0),
+ virt_to_phys(priv->tx_ring_noc));
+ mtk_pdma_write(priv, TX_MAX_CNT_REG(0), NUM_TX_DESC);
+ mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0);
+
+ mtk_pdma_write(priv, RX_BASE_PTR_REG(0),
+ virt_to_phys(priv->rx_ring_noc));
+ mtk_pdma_write(priv, RX_MAX_CNT_REG(0), NUM_RX_DESC);
+ mtk_pdma_write(priv, RX_CRX_IDX_REG(0), NUM_RX_DESC - 1);
+
+ mtk_pdma_write(priv, PDMA_RST_IDX_REG, RST_DTX_IDX0 | RST_DRX_IDX0);
+}
+
+static int mtk_eth_start(struct udevice *dev)
+{
+ struct mtk_eth_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ /* Reset FE */
+ reset_assert(&priv->rst_fe);
+ udelay(1000);
+ reset_deassert(&priv->rst_fe);
+ mdelay(10);
+
+ /* Packets forward to PDMA */
+ mtk_gdma_write(priv, priv->gmac_id, GDMA_IG_CTRL_REG, GDMA_FWD_TO_CPU);
+
+ if (priv->gmac_id == 0)
+ mtk_gdma_write(priv, 1, GDMA_IG_CTRL_REG, GDMA_FWD_DISCARD);
+ else
+ mtk_gdma_write(priv, 0, GDMA_IG_CTRL_REG, GDMA_FWD_DISCARD);
+
+ udelay(500);
+
+ mtk_eth_fifo_init(priv);
+
+ /* Start PHY */
+ if (priv->sw == SW_NONE) {
+ ret = mtk_phy_start(priv);
+ if (ret)
+ return ret;
+ }
+
+ mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0,
+ TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN);
+ udelay(500);
+
+ return 0;
+}
+
+static void mtk_eth_stop(struct udevice *dev)
+{
+ struct mtk_eth_priv *priv = dev_get_priv(dev);
+
+ mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG,
+ TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN, 0);
+ udelay(500);
+
+ wait_for_bit_le32(priv->fe_base + PDMA_BASE + PDMA_GLO_CFG_REG,
+ RX_DMA_BUSY | TX_DMA_BUSY, 0, 5000, 0);
+}
+
+static int mtk_eth_write_hwaddr(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct mtk_eth_priv *priv = dev_get_priv(dev);
+ unsigned char *mac = pdata->enetaddr;
+ u32 macaddr_lsb, macaddr_msb;
+
+ macaddr_msb = ((u32)mac[0] << 8) | (u32)mac[1];
+ macaddr_lsb = ((u32)mac[2] << 24) | ((u32)mac[3] << 16) |
+ ((u32)mac[4] << 8) | (u32)mac[5];
+
+ mtk_gdma_write(priv, priv->gmac_id, GDMA_MAC_MSB_REG, macaddr_msb);
+ mtk_gdma_write(priv, priv->gmac_id, GDMA_MAC_LSB_REG, macaddr_lsb);
+
+ return 0;
+}
+
+static int mtk_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct mtk_eth_priv *priv = dev_get_priv(dev);
+ u32 idx = priv->tx_cpu_owner_idx0;
+ void *pkt_base;
+
+ if (!priv->tx_ring_noc[idx].txd_info2.DDONE) {
+ debug("mtk-eth: TX DMA descriptor ring is full\n");
+ return -EPERM;
+ }
+
+ pkt_base = (void *)phys_to_virt(priv->tx_ring_noc[idx].txd_info1.SDP0);
+ memcpy(pkt_base, packet, length);
+ flush_dcache_range((u32)pkt_base, (u32)pkt_base +
+ roundup(length, ARCH_DMA_MINALIGN));
+
+ priv->tx_ring_noc[idx].txd_info2.SDL0 = length;
+ priv->tx_ring_noc[idx].txd_info2.DDONE = 0;
+
+ priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC;
+ mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0);
+
+ return 0;
+}
+
+static int mtk_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct mtk_eth_priv *priv = dev_get_priv(dev);
+ u32 idx = priv->rx_dma_owner_idx0;
+ uchar *pkt_base;
+ u32 length;
+
+ if (!priv->rx_ring_noc[idx].rxd_info2.DDONE) {
+ debug("mtk-eth: RX DMA descriptor ring is empty\n");
+ return -EAGAIN;
+ }
+
+ length = priv->rx_ring_noc[idx].rxd_info2.PLEN0;
+ pkt_base = (void *)phys_to_virt(priv->rx_ring_noc[idx].rxd_info1.PDP0);
+ invalidate_dcache_range((u32)pkt_base, (u32)pkt_base +
+ roundup(length, ARCH_DMA_MINALIGN));
+
+ if (packetp)
+ *packetp = pkt_base;
+
+ return length;
+}
+
+static int mtk_eth_free_pkt(struct udevice *dev, uchar *packet, int length)
+{
+ struct mtk_eth_priv *priv = dev_get_priv(dev);
+ u32 idx = priv->rx_dma_owner_idx0;
+
+ priv->rx_ring_noc[idx].rxd_info2.DDONE = 0;
+ priv->rx_ring_noc[idx].rxd_info2.LS0 = 0;
+ priv->rx_ring_noc[idx].rxd_info2.PLEN0 = PKTSIZE_ALIGN;
+
+ mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx);
+ priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC;
+
+ return 0;
+}
+
+static int mtk_eth_probe(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct mtk_eth_priv *priv = dev_get_priv(dev);
+ u32 iobase = pdata->iobase;
+ int ret;
+
+ /* Frame Engine Register Base */
+ priv->fe_base = (void *)iobase;
+
+ /* GMAC Register Base */
+ priv->gmac_base = (void *)(iobase + GMAC_BASE);
+
+ /* MDIO register */
+ ret = mtk_mdio_register(dev);
+ if (ret)
+ return ret;
+
+ /* Prepare for tx/rx rings */
+ priv->tx_ring_noc = (struct pdma_txdesc *)
+ noncached_alloc(sizeof(struct pdma_txdesc) * NUM_TX_DESC,
+ ARCH_DMA_MINALIGN);
+ priv->rx_ring_noc = (struct pdma_rxdesc *)
+ noncached_alloc(sizeof(struct pdma_rxdesc) * NUM_RX_DESC,
+ ARCH_DMA_MINALIGN);
+
+ /* Set MAC mode */
+ mtk_mac_init(priv);
+
+ /* Probe phy if switch is not specified */
+ if (priv->sw == SW_NONE)
+ return mtk_phy_probe(dev);
+
+ /* Initialize switch */
+ return priv->switch_init(priv);
+}
+
+static int mtk_eth_remove(struct udevice *dev)
+{
+ struct mtk_eth_priv *priv = dev_get_priv(dev);
+
+ /* MDIO unregister */
+ mdio_unregister(priv->mdio_bus);
+ mdio_free(priv->mdio_bus);
+
+ /* Stop possibly started DMA */
+ mtk_eth_stop(dev);
+
+ return 0;
+}
+
+static int mtk_eth_ofdata_to_platdata(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct mtk_eth_priv *priv = dev_get_priv(dev);
+ struct ofnode_phandle_args args;
+ struct regmap *regmap;
+ const char *str;
+ ofnode subnode;
+ int ret;
+
+ priv->soc = dev_get_driver_data(dev);
+
+ pdata->iobase = devfdt_get_addr(dev);
+
+ /* get corresponding ethsys phandle */
+ ret = dev_read_phandle_with_args(dev, "mediatek,ethsys", NULL, 0, 0,
+ &args);
+ if (ret)
+ return ret;
+
+ regmap = syscon_node_to_regmap(args.node);
+ if (IS_ERR(regmap))
+ return PTR_ERR(regmap);
+
+ priv->ethsys_base = regmap_get_range(regmap, 0);
+ if (!priv->ethsys_base) {
+ dev_err(dev, "Unable to find ethsys\n");
+ return -ENODEV;
+ }
+
+ /* Reset controllers */
+ ret = reset_get_by_name(dev, "fe", &priv->rst_fe);
+ if (ret) {
+ printf("error: Unable to get reset ctrl for frame engine\n");
+ return ret;
+ }
+
+ priv->gmac_id = dev_read_u32_default(dev, "mediatek,gmac-id", 0);
+
+ /* Interface mode is required */
+ str = dev_read_string(dev, "phy-mode");
+ if (str) {
+ pdata->phy_interface = phy_get_interface_by_name(str);
+ priv->phy_interface = pdata->phy_interface;
+ } else {
+ printf("error: phy-mode is not set\n");
+ return -EINVAL;
+ }
+
+ /* Force mode or autoneg */
+ subnode = ofnode_find_subnode(dev_ofnode(dev), "fixed-link");
+ if (ofnode_valid(subnode)) {
+ priv->force_mode = 1;
+ priv->speed = ofnode_read_u32_default(subnode, "speed", 0);
+ priv->duplex = ofnode_read_bool(subnode, "full-duplex");
+
+ if (priv->speed != SPEED_10 && priv->speed != SPEED_100 &&
+ priv->speed != SPEED_1000) {
+ printf("error: no valid speed set in fixed-link\n");
+ return -EINVAL;
+ }
+ }
+
+ /* check for switch first, otherwise phy will be used */
+ priv->sw = SW_NONE;
+ priv->switch_init = NULL;
+ str = dev_read_string(dev, "mediatek,switch");
+
+ if (str) {
+ if (!strcmp(str, "mt7530")) {
+ priv->sw = SW_MT7530;
+ priv->switch_init = mt7530_setup;
+ priv->mt7530_smi_addr = MT7530_DFL_SMI_ADDR;
+ } else {
+ printf("error: unsupported switch\n");
+ return -EINVAL;
+ }
+
+ priv->mcm = dev_read_bool(dev, "mediatek,mcm");
+ if (priv->mcm) {
+ ret = reset_get_by_name(dev, "mcm", &priv->rst_mcm);
+ if (ret) {
+ printf("error: no reset ctrl for mcm\n");
+ return ret;
+ }
+ } else {
+ gpio_request_by_name(dev, "reset-gpios", 0,
+ &priv->rst_gpio, GPIOD_IS_OUT);
+ }
+ } else {
+ subnode = ofnode_find_subnode(dev_ofnode(dev), "phy-handle");
+ if (!ofnode_valid(subnode)) {
+ printf("error: phy-handle is not specified\n");
+ return ret;
+ }
+
+ priv->phy_addr = ofnode_read_s32_default(subnode, "reg", -1);
+ if (priv->phy_addr < 0) {
+ printf("error: phy address is not specified\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const struct udevice_id mtk_eth_ids[] = {
+ { .compatible = "mediatek,mt7629-eth", .data = SOC_MT7629 },
+ { .compatible = "mediatek,mt7623-eth", .data = SOC_MT7623 },
+ {}
+};
+
+static const struct eth_ops mtk_eth_ops = {
+ .start = mtk_eth_start,
+ .stop = mtk_eth_stop,
+ .send = mtk_eth_send,
+ .recv = mtk_eth_recv,
+ .free_pkt = mtk_eth_free_pkt,
+ .write_hwaddr = mtk_eth_write_hwaddr,
+};
+
+U_BOOT_DRIVER(mtk_eth) = {
+ .name = "mtk-eth",
+ .id = UCLASS_ETH,
+ .of_match = mtk_eth_ids,
+ .ofdata_to_platdata = mtk_eth_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+ .probe = mtk_eth_probe,
+ .remove = mtk_eth_remove,
+ .ops = &mtk_eth_ops,
+ .priv_auto_alloc_size = sizeof(struct mtk_eth_priv),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h
new file mode 100644
index 0000000000..fe89a03739
--- /dev/null
+++ b/drivers/net/mtk_eth.h
@@ -0,0 +1,286 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ * Author: Mark Lee <mark-mc.lee@mediatek.com>
+ */
+
+#ifndef _MTK_ETH_H_
+#define _MTK_ETH_H_
+
+/* Frame Engine Register Bases */
+#define PDMA_BASE 0x0800
+#define GDMA1_BASE 0x0500
+#define GDMA2_BASE 0x1500
+#define GMAC_BASE 0x10000
+
+/* Ethernet subsystem registers */
+
+#define ETHSYS_SYSCFG0_REG 0x14
+#define SYSCFG0_GE_MODE_S(n) (12 + ((n) * 2))
+#define SYSCFG0_GE_MODE_M 0x3
+
+#define ETHSYS_CLKCFG0_REG 0x2c
+#define ETHSYS_TRGMII_CLK_SEL362_5 BIT(11)
+
+/* SYSCFG0_GE_MODE: GE Modes */
+#define GE_MODE_RGMII 0
+#define GE_MODE_MII 1
+#define GE_MODE_MII_PHY 2
+#define GE_MODE_RMII 3
+
+/* Frame Engine Registers */
+
+/* PDMA */
+#define TX_BASE_PTR_REG(n) (0x000 + (n) * 0x10)
+#define TX_MAX_CNT_REG(n) (0x004 + (n) * 0x10)
+#define TX_CTX_IDX_REG(n) (0x008 + (n) * 0x10)
+#define TX_DTX_IDX_REG(n) (0x00c + (n) * 0x10)
+
+#define RX_BASE_PTR_REG(n) (0x100 + (n) * 0x10)
+#define RX_MAX_CNT_REG(n) (0x104 + (n) * 0x10)
+#define RX_CRX_IDX_REG(n) (0x108 + (n) * 0x10)
+#define RX_DRX_IDX_REG(n) (0x10c + (n) * 0x10)
+
+#define PDMA_GLO_CFG_REG 0x204
+#define TX_WB_DDONE BIT(6)
+#define RX_DMA_BUSY BIT(3)
+#define RX_DMA_EN BIT(2)
+#define TX_DMA_BUSY BIT(1)
+#define TX_DMA_EN BIT(0)
+
+#define PDMA_RST_IDX_REG 0x208
+#define RST_DRX_IDX0 BIT(16)
+#define RST_DTX_IDX0 BIT(0)
+
+/* GDMA */
+#define GDMA_IG_CTRL_REG 0x000
+#define GDM_ICS_EN BIT(22)
+#define GDM_TCS_EN BIT(21)
+#define GDM_UCS_EN BIT(20)
+#define STRP_CRC BIT(16)
+#define MYMAC_DP_S 12
+#define MYMAC_DP_M 0xf000
+#define BC_DP_S 8
+#define BC_DP_M 0xf00
+#define MC_DP_S 4
+#define MC_DP_M 0xf0
+#define UN_DP_S 0
+#define UN_DP_M 0x0f
+
+#define GDMA_MAC_LSB_REG 0x008
+
+#define GDMA_MAC_MSB_REG 0x00c
+
+/* MYMAC_DP/BC_DP/MC_DP/UN_DP: Destination ports */
+#define DP_PDMA 0
+#define DP_GDMA1 1
+#define DP_GDMA2 2
+#define DP_PPE 4
+#define DP_QDMA 5
+#define DP_DISCARD 7
+
+/* GMAC Registers */
+
+#define GMAC_PIAC_REG 0x0004
+#define PHY_ACS_ST BIT(31)
+#define MDIO_REG_ADDR_S 25
+#define MDIO_REG_ADDR_M 0x3e000000
+#define MDIO_PHY_ADDR_S 20
+#define MDIO_PHY_ADDR_M 0x1f00000
+#define MDIO_CMD_S 18
+#define MDIO_CMD_M 0xc0000
+#define MDIO_ST_S 16
+#define MDIO_ST_M 0x30000
+#define MDIO_RW_DATA_S 0
+#define MDIO_RW_DATA_M 0xffff
+
+/* MDIO_CMD: MDIO commands */
+#define MDIO_CMD_ADDR 0
+#define MDIO_CMD_WRITE 1
+#define MDIO_CMD_READ 2
+#define MDIO_CMD_READ_C45 3
+
+/* MDIO_ST: MDIO start field */
+#define MDIO_ST_C45 0
+#define MDIO_ST_C22 1
+
+#define GMAC_PORT_MCR(p) (0x0100 + (p) * 0x100)
+#define MAC_RX_PKT_LEN_S 24
+#define MAC_RX_PKT_LEN_M 0x3000000
+#define IPG_CFG_S 18
+#define IPG_CFG_M 0xc0000
+#define MAC_MODE BIT(16)
+#define FORCE_MODE BIT(15)
+#define MAC_TX_EN BIT(14)
+#define MAC_RX_EN BIT(13)
+#define BKOFF_EN BIT(9)
+#define BACKPR_EN BIT(8)
+#define FORCE_RX_FC BIT(5)
+#define FORCE_TX_FC BIT(4)
+#define FORCE_SPD_S 2
+#define FORCE_SPD_M 0x0c
+#define FORCE_DPX BIT(1)
+#define FORCE_LINK BIT(0)
+
+/* MAC_RX_PKT_LEN: Max RX packet length */
+#define MAC_RX_PKT_LEN_1518 0
+#define MAC_RX_PKT_LEN_1536 1
+#define MAC_RX_PKT_LEN_1552 2
+#define MAC_RX_PKT_LEN_JUMBO 3
+
+/* FORCE_SPD: Forced link speed */
+#define SPEED_10M 0
+#define SPEED_100M 1
+#define SPEED_1000M 2
+
+#define GMAC_TRGMII_RCK_CTRL 0x300
+#define RX_RST BIT(31)
+#define RXC_DQSISEL BIT(30)
+
+#define GMAC_TRGMII_TD_ODT(n) (0x354 + (n) * 8)
+#define TD_DM_DRVN_S 4
+#define TD_DM_DRVN_M 0xf0
+#define TD_DM_DRVP_S 0
+#define TD_DM_DRVP_M 0x0f
+
+/* MT7530 Registers */
+
+#define PCR_REG(p) (0x2004 + (p) * 0x100)
+#define PORT_MATRIX_S 16
+#define PORT_MATRIX_M 0xff0000
+
+#define PVC_REG(p) (0x2010 + (p) * 0x100)
+#define STAG_VPID_S 16
+#define STAG_VPID_M 0xffff0000
+#define VLAN_ATTR_S 6
+#define VLAN_ATTR_M 0xc0
+
+/* VLAN_ATTR: VLAN attributes */
+#define VLAN_ATTR_USER 0
+#define VLAN_ATTR_STACK 1
+#define VLAN_ATTR_TRANSLATION 2
+#define VLAN_ATTR_TRANSPARENT 3
+
+#define PCMR_REG(p) (0x3000 + (p) * 0x100)
+/* XXX: all fields are defined under GMAC_PORT_MCR */
+
+#define SYS_CTRL_REG 0x7000
+#define SW_PHY_RST BIT(2)
+#define SW_SYS_RST BIT(1)
+#define SW_REG_RST BIT(0)
+
+#define NUM_TRGMII_CTRL 5
+
+#define HWTRAP_REG 0x7800
+#define MHWTRAP_REG 0x7804
+#define CHG_TRAP BIT(16)
+#define LOOPDET_DIS BIT(14)
+#define P5_INTF_SEL_S 13
+#define P5_INTF_SEL_M 0x2000
+#define SMI_ADDR_S 11
+#define SMI_ADDR_M 0x1800
+#define XTAL_FSEL_S 9
+#define XTAL_FSEL_M 0x600
+#define P6_INTF_DIS BIT(8)
+#define P5_INTF_MODE_S 7
+#define P5_INTF_MODE_M 0x80
+#define P5_INTF_DIS BIT(6)
+#define C_MDIO_BPS BIT(5)
+#define CHIP_MODE_S 0
+#define CHIP_MODE_M 0x0f
+
+/* P5_INTF_SEL: Interface type of Port5 */
+#define P5_INTF_SEL_GPHY 0
+#define P5_INTF_SEL_GMAC5 1
+
+/* P5_INTF_MODE: Interface mode of Port5 */
+#define P5_INTF_MODE_GMII_MII 0
+#define P5_INTF_MODE_RGMII 1
+
+#define MT7530_P6ECR 0x7830
+#define P6_INTF_MODE_M 0x3
+#define P6_INTF_MODE_S 0
+
+/* P6_INTF_MODE: Interface mode of Port6 */
+#define P6_INTF_MODE_RGMII 0
+#define P6_INTF_MODE_TRGMII 1
+
+#define MT7530_TRGMII_RD(n) (0x7a10 + (n) * 8)
+#define RD_TAP_S 0
+#define RD_TAP_M 0x7f
+
+#define MT7530_TRGMII_TD_ODT(n) (0x7a54 + (n) * 8)
+/* XXX: all fields are defined under GMAC_TRGMII_TD_ODT */
+
+/* MT7530 GPHY MDIO Indirect Access Registers */
+
+#define MII_MMD_ACC_CTL_REG 0x0d
+#define MMD_CMD_S 14
+#define MMD_CMD_M 0xc000
+#define MMD_DEVAD_S 0
+#define MMD_DEVAD_M 0x1f
+
+/* MMD_CMD: MMD commands */
+#define MMD_ADDR 0
+#define MMD_DATA 1
+#define MMD_DATA_RW_POST_INC 2
+#define MMD_DATA_W_POST_INC 3
+
+#define MII_MMD_ADDR_DATA_REG 0x0e
+
+/* MT7530 GPHY MDIO MMD Registers */
+
+#define CORE_PLL_GROUP2 0x401
+#define RG_SYSPLL_EN_NORMAL BIT(15)
+#define RG_SYSPLL_VODEN BIT(14)
+#define RG_SYSPLL_POSDIV_S 5
+#define RG_SYSPLL_POSDIV_M 0x60
+
+#define CORE_PLL_GROUP4 0x403
+#define RG_SYSPLL_DDSFBK_EN BIT(12)
+#define RG_SYSPLL_BIAS_EN BIT(11)
+#define RG_SYSPLL_BIAS_LPF_EN BIT(10)
+
+#define CORE_PLL_GROUP5 0x404
+#define RG_LCDDS_PCW_NCPO1_S 0
+#define RG_LCDDS_PCW_NCPO1_M 0xffff
+
+#define CORE_PLL_GROUP6 0x405
+#define RG_LCDDS_PCW_NCPO0_S 0
+#define RG_LCDDS_PCW_NCPO0_M 0xffff
+
+#define CORE_PLL_GROUP7 0x406
+#define RG_LCDDS_PWDB BIT(15)
+#define RG_LCDDS_ISO_EN BIT(13)
+#define RG_LCCDS_C_S 4
+#define RG_LCCDS_C_M 0x70
+#define RG_LCDDS_PCW_NCPO_CHG BIT(3)
+
+#define CORE_PLL_GROUP10 0x409
+#define RG_LCDDS_SSC_DELTA_S 0
+#define RG_LCDDS_SSC_DELTA_M 0xfff
+
+#define CORE_PLL_GROUP11 0x40a
+#define RG_LCDDS_SSC_DELTA1_S 0
+#define RG_LCDDS_SSC_DELTA1_M 0xfff
+
+#define CORE_GSWPLL_GRP1 0x40d
+#define RG_GSWPLL_POSDIV_200M_S 12
+#define RG_GSWPLL_POSDIV_200M_M 0x3000
+#define RG_GSWPLL_EN_PRE BIT(11)
+#define RG_GSWPLL_FBKDIV_200M_S 0
+#define RG_GSWPLL_FBKDIV_200M_M 0xff
+
+#define CORE_GSWPLL_GRP2 0x40e
+#define RG_GSWPLL_POSDIV_500M_S 8
+#define RG_GSWPLL_POSDIV_500M_M 0x300
+#define RG_GSWPLL_FBKDIV_500M_S 0
+#define RG_GSWPLL_FBKDIV_500M_M 0xff
+
+#define CORE_TRGMII_GSW_CLK_CG 0x410
+#define REG_GSWCK_EN BIT(0)
+#define REG_TRGMIICK_EN BIT(1)
+
+#endif /* _MTK_ETH_H_ */
diff --git a/drivers/net/sandbox-raw.c b/drivers/net/sandbox-raw.c
index 09cc678ebd..7e6625d020 100644
--- a/drivers/net/sandbox-raw.c
+++ b/drivers/net/sandbox-raw.c
@@ -152,7 +152,6 @@ static int sb_eth_raw_ofdata_to_platdata(struct udevice *dev)
struct eth_pdata *pdata = dev_get_platdata(dev);
struct eth_sandbox_raw_priv *priv = dev_get_priv(dev);
const char *ifname;
- u32 local;
int ret;
pdata->iobase = dev_read_addr(dev);
@@ -173,10 +172,10 @@ static int sb_eth_raw_ofdata_to_platdata(struct udevice *dev)
priv->host_ifindex, priv->host_ifname);
}
- local = sandbox_eth_raw_os_is_local(priv->host_ifname);
- if (local < 0)
- return local;
- priv->local = local;
+ ret = sandbox_eth_raw_os_is_local(priv->host_ifname);
+ if (ret < 0)
+ return ret;
+ priv->local = ret;
return 0;
}
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 9c5208b7da..3a6d61f440 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -106,4 +106,11 @@ config RESET_SOCFPGA
help
Support for reset controller on SoCFPGA platform.
+config RESET_MEDIATEK
+ bool "Reset controller driver for MediaTek SoCs"
+ depends on DM_RESET && ARCH_MEDIATEK && CLK
+ default y
+ help
+ Support for reset controller on MediaTek SoCs.
+
endmenu
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index f4520878b7..8a4dcab8f6 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o
obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o
obj-$(CONFIG_RESET_MESON) += reset-meson.o
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
+obj-$(CONFIG_RESET_MEDIATEK) += reset-mediatek.o
diff --git a/drivers/reset/reset-mediatek.c b/drivers/reset/reset-mediatek.c
new file mode 100644
index 0000000000..e3614e6e2a
--- /dev/null
+++ b/drivers/reset/reset-mediatek.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ *
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ * Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <regmap.h>
+#include <reset-uclass.h>
+#include <syscon.h>
+
+struct mediatek_reset_priv {
+ struct regmap *regmap;
+ u32 regofs;
+ u32 nr_resets;
+};
+
+static int mediatek_reset_request(struct reset_ctl *reset_ctl)
+{
+ return 0;
+}
+
+static int mediatek_reset_free(struct reset_ctl *reset_ctl)
+{
+ return 0;
+}
+
+static int mediatek_reset_assert(struct reset_ctl *reset_ctl)
+{
+ struct mediatek_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+ int id = reset_ctl->id;
+
+ if (id >= priv->nr_resets)
+ return -EINVAL;
+
+ return regmap_update_bits(priv->regmap,
+ priv->regofs + ((id / 32) << 2), BIT(id % 32), BIT(id % 32));
+}
+
+static int mediatek_reset_deassert(struct reset_ctl *reset_ctl)
+{
+ struct mediatek_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+ int id = reset_ctl->id;
+
+ if (id >= priv->nr_resets)
+ return -EINVAL;
+
+ return regmap_update_bits(priv->regmap,
+ priv->regofs + ((id / 32) << 2), BIT(id % 32), 0);
+}
+
+struct reset_ops mediatek_reset_ops = {
+ .request = mediatek_reset_request,
+ .free = mediatek_reset_free,
+ .rst_assert = mediatek_reset_assert,
+ .rst_deassert = mediatek_reset_deassert,
+};
+
+static int mediatek_reset_probe(struct udevice *dev)
+{
+ struct mediatek_reset_priv *priv = dev_get_priv(dev);
+
+ if (!priv->regofs && !priv->nr_resets)
+ return -EINVAL;
+
+ priv->regmap = syscon_node_to_regmap(dev_ofnode(dev));
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ return 0;
+}
+
+int mediatek_reset_bind(struct udevice *pdev, u32 regofs, u32 num_regs)
+{
+ struct udevice *rst_dev;
+ struct mediatek_reset_priv *priv;
+ int ret;
+
+ ret = device_bind_driver_to_node(pdev, "mediatek_reset", "reset",
+ dev_ofnode(pdev), &rst_dev);
+ if (ret)
+ return ret;
+
+ priv = malloc(sizeof(struct mediatek_reset_priv));
+ priv->regofs = regofs;
+ priv->nr_resets = num_regs * 32;
+ rst_dev->priv = priv;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(mediatek_reset) = {
+ .name = "mediatek_reset",
+ .id = UCLASS_RESET,
+ .probe = mediatek_reset_probe,
+ .ops = &mediatek_reset_ops,
+ .priv_auto_alloc_size = sizeof(struct mediatek_reset_priv),
+};
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index b7ff2960ab..887cd687c0 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -442,10 +442,23 @@ config DEBUG_UART_ANNOUNCE
config DEBUG_UART_SKIP_INIT
bool "Skip UART initialization"
+ depends on DEBUG_UART
help
Select this if the UART you want to use for debug output is already
initialized by the time U-Boot starts its execution.
+config DEBUG_UART_NS16550_CHECK_ENABLED
+ bool "Check if UART is enabled on output"
+ depends on DEBUG_UART
+ depends on DEBUG_UART_NS16550
+ help
+ Select this if puts()/putc() might be called before the debug UART
+ has been initialized. If this is disabled, putc() might sit in a
+ tight loop if it is called before debug_uart_init() has been called.
+
+ Note that this does not work for every ns16550-compatible UART and
+ so has to be enabled carefully or you might notice lost characters.
+
config ALTERA_JTAG_UART
bool "Altera JTAG UART support"
depends on DM_SERIAL
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 560ca2ae34..6cf2be8f2b 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -272,12 +272,28 @@ static inline void _debug_uart_init(void)
serial_dout(&com_port->lcr, UART_LCRVAL);
}
+static inline int NS16550_read_baud_divisor(struct NS16550 *com_port)
+{
+ int ret;
+
+ serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL);
+ ret = serial_din(&com_port->dll) & 0xff;
+ ret |= (serial_din(&com_port->dlm) & 0xff) << 8;
+ serial_dout(&com_port->lcr, UART_LCRVAL);
+
+ return ret;
+}
+
static inline void _debug_uart_putc(int ch)
{
struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
- while (!(serial_din(&com_port->lsr) & UART_LSR_THRE))
- ;
+ while (!(serial_din(&com_port->lsr) & UART_LSR_THRE)) {
+#ifdef CONFIG_DEBUG_UART_NS16550_CHECK_ENABLED
+ if (!NS16550_read_baud_divisor(com_port))
+ return;
+#endif
+ }
serial_dout(&com_port->thr, ch);
}
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index ffcd6d15af..d4488a2cc2 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -294,49 +294,40 @@ void serial_setbrg(void)
ops->setbrg(gd->cur_serial_dev, gd->baudrate);
}
-int serial_getconfig(uint *config)
+int serial_getconfig(struct udevice *dev, uint *config)
{
struct dm_serial_ops *ops;
- if (!gd->cur_serial_dev)
- return 0;
-
- ops = serial_get_ops(gd->cur_serial_dev);
+ ops = serial_get_ops(dev);
if (ops->getconfig)
- return ops->getconfig(gd->cur_serial_dev, config);
+ return ops->getconfig(dev, config);
return 0;
}
-int serial_setconfig(uint config)
+int serial_setconfig(struct udevice *dev, uint config)
{
struct dm_serial_ops *ops;
- if (!gd->cur_serial_dev)
- return 0;
-
- ops = serial_get_ops(gd->cur_serial_dev);
+ ops = serial_get_ops(dev);
if (ops->setconfig)
- return ops->setconfig(gd->cur_serial_dev, config);
+ return ops->setconfig(dev, config);
return 0;
}
-int serial_getinfo(struct serial_device_info *info)
+int serial_getinfo(struct udevice *dev, struct serial_device_info *info)
{
struct dm_serial_ops *ops;
- if (!gd->cur_serial_dev)
- return -ENODEV;
-
if (!info)
return -EINVAL;
info->baudrate = gd->baudrate;
- ops = serial_get_ops(gd->cur_serial_dev);
+ ops = serial_get_ops(dev);
if (ops->getinfo)
- return ops->getinfo(gd->cur_serial_dev, info);
+ return ops->getinfo(dev, info);
return -EINVAL;
}
diff --git a/dts/Makefile b/dts/Makefile
index cd6e9a968e..a7a604303c 100644
--- a/dts/Makefile
+++ b/dts/Makefile
@@ -43,9 +43,6 @@ endif
arch-dtbs:
$(Q)$(MAKE) $(build)=$(ARCH_PATH) dtbs
-.SECONDARY: $(obj)/dt.dtb.S $(obj)/dt-spl.dtb.S
-
-
ifeq ($(CONFIG_SPL_BUILD),y)
obj-$(CONFIG_OF_EMBED) := dt-spl.dtb.o
# support "out-of-tree" build for dtb-spl
diff --git a/env/common.c b/env/common.c
index 3317cef355..d1a6a52860 100644
--- a/env/common.c
+++ b/env/common.c
@@ -240,32 +240,76 @@ void env_relocate(void)
}
}
-#if defined(CONFIG_AUTO_COMPLETE) && !defined(CONFIG_SPL_BUILD)
-int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf)
+#ifdef CONFIG_AUTO_COMPLETE
+int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf,
+ bool dollar_comp)
{
ENTRY *match;
int found, idx;
+ if (dollar_comp) {
+ /*
+ * When doing $ completion, the first character should
+ * obviously be a '$'.
+ */
+ if (var[0] != '$')
+ return 0;
+
+ var++;
+
+ /*
+ * The second one, if present, should be a '{', as some
+ * configuration of the u-boot shell expand ${var} but not
+ * $var.
+ */
+ if (var[0] == '{')
+ var++;
+ else if (var[0] != '\0')
+ return 0;
+ }
+
idx = 0;
found = 0;
cmdv[0] = NULL;
+
while ((idx = hmatch_r(var, idx, &match, &env_htab))) {
int vallen = strlen(match->key) + 1;
- if (found >= maxv - 2 || bufsz < vallen)
+ if (found >= maxv - 2 ||
+ bufsz < vallen + (dollar_comp ? 3 : 0))
break;
cmdv[found++] = buf;
+
+ /* Add the '${' prefix to each var when doing $ completion. */
+ if (dollar_comp) {
+ strcpy(buf, "${");
+ buf += 2;
+ bufsz -= 3;
+ }
+
memcpy(buf, match->key, vallen);
buf += vallen;
bufsz -= vallen;
+
+ if (dollar_comp) {
+ /*
+ * This one is a bit odd: vallen already contains the
+ * '\0' character but we need to add the '}' suffix,
+ * hence the buf - 1 here. strcpy() will add the '\0'
+ * character just after '}'. buf is then incremented
+ * to account for the extra '}' we just added.
+ */
+ strcpy(buf - 1, "}");
+ buf++;
+ }
}
qsort(cmdv, found, sizeof(cmdv[0]), strcmp_compar);
if (idx)
- cmdv[found++] = "...";
+ cmdv[found++] = dollar_comp ? "${...}" : "...";
cmdv[found] = NULL;
return found;
diff --git a/env/sf.c b/env/sf.c
index 23cbad5d88..b3dec82c35 100644
--- a/env/sf.c
+++ b/env/sf.c
@@ -81,6 +81,40 @@ static int setup_flash_device(void)
return 0;
}
+static int is_end(const char *addr, size_t size)
+{
+ /* The end of env variables is marked by '\0\0' */
+ int i = 0;
+
+ for (i = 0; i < size - 1; ++i)
+ if (addr[i] == 0x0 && addr[i + 1] == 0x0)
+ return 1;
+ return 0;
+}
+
+static int spi_flash_read_env(struct spi_flash *flash, u32 offset, size_t len,
+ void *buf)
+{
+ u32 addr = 0;
+ u32 page_size = flash->page_size;
+
+ memset(buf, 0x0, len);
+ for (int i = 0; i < len / page_size; ++i) {
+ int ret = spi_flash_read(flash, offset, page_size,
+ &((char *)buf)[addr]);
+
+ if (ret < 0)
+ return ret;
+
+ if (is_end(&((char *)buf)[addr], page_size))
+ return 0;
+
+ addr += page_size;
+ offset += page_size;
+ }
+ return 0;
+}
+
#if defined(CONFIG_ENV_OFFSET_REDUND)
#ifdef CMD_SAVEENV
static int env_sf_save(void)
@@ -116,8 +150,8 @@ static int env_sf_save(void)
ret = -ENOMEM;
goto done;
}
- ret = spi_flash_read(env_flash, saved_offset,
- saved_size, saved_buffer);
+ ret = spi_flash_read_env(env_flash, saved_offset,
+ saved_size, saved_buffer);
if (ret)
goto done;
}
@@ -183,10 +217,10 @@ static int env_sf_load(void)
if (ret)
goto out;
- read1_fail = spi_flash_read(env_flash, CONFIG_ENV_OFFSET,
- CONFIG_ENV_SIZE, tmp_env1);
- read2_fail = spi_flash_read(env_flash, CONFIG_ENV_OFFSET_REDUND,
- CONFIG_ENV_SIZE, tmp_env2);
+ read1_fail = spi_flash_read_env(env_flash, CONFIG_ENV_OFFSET,
+ CONFIG_ENV_SIZE, tmp_env1);
+ read2_fail = spi_flash_read_env(env_flash, CONFIG_ENV_OFFSET_REDUND,
+ CONFIG_ENV_SIZE, tmp_env2);
ret = env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
read2_fail);
@@ -220,8 +254,8 @@ static int env_sf_save(void)
if (!saved_buffer)
goto done;
- ret = spi_flash_read(env_flash, saved_offset,
- saved_size, saved_buffer);
+ ret = spi_flash_read_env(env_flash, saved_offset,
+ saved_size, saved_buffer);
if (ret)
goto done;
}
@@ -277,10 +311,10 @@ static int env_sf_load(void)
if (ret)
goto out;
- ret = spi_flash_read(env_flash,
- CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, buf);
+ ret = spi_flash_read_env(env_flash, CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE,
+ buf);
if (ret) {
- set_default_env("spi_flash_read() failed", 0);
+ set_default_env("spi_flash_read_env() failed", 0);
goto err_read;
}
diff --git a/examples/standalone/Makefile b/examples/standalone/Makefile
index f01816f24f..0b17a91804 100644
--- a/examples/standalone/Makefile
+++ b/examples/standalone/Makefile
@@ -26,7 +26,6 @@ LIB = $(obj)/libstubs.o
LIBOBJS-$(CONFIG_PPC) += ppc_longjmp.o ppc_setjmp.o
LIBOBJS-y += stubs.o
-.SECONDARY: $(call objectify,$(COBJS))
targets += $(patsubst $(obj)/%,%,$(LIB)) $(COBJS) $(LIBOBJS-y)
LIBOBJS := $(addprefix $(obj)/,$(LIBOBJS-y))
diff --git a/examples/standalone/riscv.lds b/examples/standalone/riscv.lds
deleted file mode 100644
index 9a25861052..0000000000
--- a/examples/standalone/riscv.lds
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2017 Andes Technology Corporation
- * Rick Chen, Andes Technology Corporation <rick@andestech.com>
- */
-
-OUTPUT_ARCH(riscv)
-ENTRY(_start)
-SECTIONS
-{
- . = ALIGN(4);
- .text :
- {
- *(.text)
- }
-
- . = ALIGN(4);
- .data : {
- __global_pointer$ = . + 0x800;
- *(.data)
- }
-
- . = ALIGN(4);
-
- .got : {
- __got_start = .;
- *(.got)
- __got_end = .;
- }
-
- . = ALIGN(4);
- __bss_start = .;
- .bss : { *(.bss) }
- __bss_end = .;
-
- . = ALIGN(4);
- .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
-
- _end = .;
-}
diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c
index fadde669fa..0827bde35e 100644
--- a/examples/standalone/stubs.c
+++ b/examples/standalone/stubs.c
@@ -174,16 +174,27 @@ gd_t *global_data;
: : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "$r16");
#elif defined(CONFIG_RISCV)
/*
- * t7 holds the pointer to the global_data. gp is call clobbered.
+ * gp holds the pointer to the global_data. t0 is call clobbered.
*/
+#ifdef CONFIG_ARCH_RV64I
#define EXPORT_FUNC(f, a, x, ...) \
asm volatile ( \
" .globl " #x "\n" \
#x ":\n" \
-" lw x19, %0(gp)\n" \
-" lw x19, %1(x19)\n" \
-" jr x19\n" \
- : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "x19");
+" ld t0, %0(gp)\n" \
+" ld t0, %1(t0)\n" \
+" jr t0\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t0");
+#else
+#define EXPORT_FUNC(f, a, x, ...) \
+ asm volatile ( \
+" .globl " #x "\n" \
+#x ":\n" \
+" lw t0, %0(gp)\n" \
+" lw t0, %1(t0)\n" \
+" jr t0\n" \
+ : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t0");
+#endif
#elif defined(CONFIG_ARC)
/*
* r25 holds the pointer to the global_data. r10 is call clobbered.
diff --git a/fs/fs.c b/fs/fs.c
index cb265174e2..7fd22101ef 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -429,13 +429,57 @@ int fs_size(const char *filename, loff_t *size)
return ret;
}
-int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
- loff_t *actread)
+#ifdef CONFIG_LMB
+/* Check if a file may be read to the given address */
+static int fs_read_lmb_check(const char *filename, ulong addr, loff_t offset,
+ loff_t len, struct fstype_info *info)
+{
+ struct lmb lmb;
+ int ret;
+ loff_t size;
+ loff_t read_len;
+
+ /* get the actual size of the file */
+ ret = info->size(filename, &size);
+ if (ret)
+ return ret;
+ if (offset >= size) {
+ /* offset >= EOF, no bytes will be written */
+ return 0;
+ }
+ read_len = size - offset;
+
+ /* limit to 'len' if it is smaller */
+ if (len && len < read_len)
+ read_len = len;
+
+ lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start,
+ gd->bd->bi_dram[0].size, (void *)gd->fdt_blob);
+ lmb_dump_all(&lmb);
+
+ if (lmb_alloc_addr(&lmb, addr, read_len) == addr)
+ return 0;
+
+ printf("** Reading file would overwrite reserved memory **\n");
+ return -ENOSPC;
+}
+#endif
+
+static int _fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
+ int do_lmb_check, loff_t *actread)
{
struct fstype_info *info = fs_get_info(fs_type);
void *buf;
int ret;
+#ifdef CONFIG_LMB
+ if (do_lmb_check) {
+ ret = fs_read_lmb_check(filename, addr, offset, len, info);
+ if (ret)
+ return ret;
+ }
+#endif
+
/*
* We don't actually know how many bytes are being read, since len==0
* means read the whole file.
@@ -452,6 +496,12 @@ int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
return ret;
}
+int fs_read(const char *filename, ulong addr, loff_t offset, loff_t len,
+ loff_t *actread)
+{
+ return _fs_read(filename, addr, offset, len, 0, actread);
+}
+
int fs_write(const char *filename, ulong addr, loff_t offset, loff_t len,
loff_t *actwrite)
{
@@ -622,7 +672,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
pos = 0;
time = get_timer(0);
- ret = fs_read(filename, addr, pos, bytes, &len_read);
+ ret = _fs_read(filename, addr, pos, bytes, 1, &len_read);
time = get_timer(time);
if (ret < 0)
return 1;
diff --git a/include/command.h b/include/command.h
index 200c7a5e9f..461b17447c 100644
--- a/include/command.h
+++ b/include/command.h
@@ -29,7 +29,16 @@
struct cmd_tbl_s {
char *name; /* Command Name */
int maxargs; /* maximum number of arguments */
- int repeatable; /* autorepeat allowed? */
+ /*
+ * Same as ->cmd() except the command
+ * tells us if it can be repeated.
+ * Replaces the old ->repeatable field
+ * which was not able to make
+ * repeatable property different for
+ * the main command and sub-commands.
+ */
+ int (*cmd_rep)(struct cmd_tbl_s *cmd, int flags, int argc,
+ char * const argv[], int *repeatable);
/* Implementation function */
int (*cmd)(struct cmd_tbl_s *, int, int, char * const []);
char *usage; /* Usage message (short) */
@@ -54,9 +63,25 @@ int _do_help (cmd_tbl_t *cmd_start, int cmd_items, cmd_tbl_t * cmdtp, int
flag, int argc, char * const argv[]);
cmd_tbl_t *find_cmd(const char *cmd);
cmd_tbl_t *find_cmd_tbl (const char *cmd, cmd_tbl_t *table, int table_len);
+int complete_subcmdv(cmd_tbl_t *cmdtp, int count, int argc,
+ char * const argv[], char last_char, int maxv,
+ char *cmdv[]);
extern int cmd_usage(const cmd_tbl_t *cmdtp);
+/* Dummy ->cmd and ->cmd_rep wrappers. */
+int cmd_always_repeatable(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[], int *repeatable);
+int cmd_never_repeatable(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[], int *repeatable);
+int cmd_discard_repeatable(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[]);
+
+static inline bool cmd_is_repeatable(cmd_tbl_t *cmdtp)
+{
+ return cmdtp->cmd_rep == cmd_always_repeatable;
+}
+
#ifdef CONFIG_AUTO_COMPLETE
extern int var_complete(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]);
extern int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *colp);
@@ -184,17 +209,93 @@ int board_run_command(const char *cmdline);
# define _CMD_HELP(x)
#endif
+#ifdef CONFIG_NEEDS_MANUAL_RELOC
+#define U_BOOT_SUBCMDS_RELOC(_cmdname) \
+ static void _cmdname##_subcmds_reloc(void) \
+ { \
+ static int relocated; \
+ \
+ if (relocated) \
+ return; \
+ \
+ fixup_cmdtable(_cmdname##_subcmds, \
+ ARRAY_SIZE(_cmdname##_subcmds)); \
+ relocated = 1; \
+ }
+#else
+#define U_BOOT_SUBCMDS_RELOC(_cmdname) \
+ static void _cmdname##_subcmds_reloc(void) { }
+#endif
+
+#define U_BOOT_SUBCMDS_DO_CMD(_cmdname) \
+ static int do_##_cmdname(cmd_tbl_t *cmdtp, int flag, int argc, \
+ char * const argv[], int *repeatable) \
+ { \
+ cmd_tbl_t *subcmd; \
+ \
+ _cmdname##_subcmds_reloc(); \
+ \
+ /* We need at least the cmd and subcmd names. */ \
+ if (argc < 2 || argc > CONFIG_SYS_MAXARGS) \
+ return CMD_RET_USAGE; \
+ \
+ subcmd = find_cmd_tbl(argv[1], _cmdname##_subcmds, \
+ ARRAY_SIZE(_cmdname##_subcmds)); \
+ if (!subcmd || argc - 1 > subcmd->maxargs) \
+ return CMD_RET_USAGE; \
+ \
+ if (flag == CMD_FLAG_REPEAT && \
+ !cmd_is_repeatable(subcmd)) \
+ return CMD_RET_SUCCESS; \
+ \
+ return subcmd->cmd_rep(subcmd, flag, argc - 1, \
+ argv + 1, repeatable); \
+ }
+
+#ifdef CONFIG_AUTO_COMPLETE
+#define U_BOOT_SUBCMDS_COMPLETE(_cmdname) \
+ static int complete_##_cmdname(int argc, char * const argv[], \
+ char last_char, int maxv, \
+ char *cmdv[]) \
+ { \
+ return complete_subcmdv(_cmdname##_subcmds, \
+ ARRAY_SIZE(_cmdname##_subcmds), \
+ argc - 1, argv + 1, last_char, \
+ maxv, cmdv); \
+ }
+#else
+#define U_BOOT_SUBCMDS_COMPLETE(_cmdname)
+#endif
+
+#define U_BOOT_SUBCMDS(_cmdname, ...) \
+ static cmd_tbl_t _cmdname##_subcmds[] = { __VA_ARGS__ }; \
+ U_BOOT_SUBCMDS_RELOC(_cmdname) \
+ U_BOOT_SUBCMDS_DO_CMD(_cmdname) \
+ U_BOOT_SUBCMDS_COMPLETE(_cmdname)
+
#ifdef CONFIG_CMDLINE
+#define U_BOOT_CMDREP_MKENT_COMPLETE(_name, _maxargs, _cmd_rep, \
+ _usage, _help, _comp) \
+ { #_name, _maxargs, _cmd_rep, cmd_discard_repeatable, \
+ _usage, _CMD_HELP(_help) _CMD_COMPLETE(_comp) }
+
#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \
_usage, _help, _comp) \
- { #_name, _maxargs, _rep, _cmd, _usage, \
- _CMD_HELP(_help) _CMD_COMPLETE(_comp) }
+ { #_name, _maxargs, \
+ _rep ? cmd_always_repeatable : cmd_never_repeatable, \
+ _cmd, _usage, _CMD_HELP(_help) _CMD_COMPLETE(_comp) }
#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) \
ll_entry_declare(cmd_tbl_t, _name, cmd) = \
U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \
_usage, _help, _comp);
+#define U_BOOT_CMDREP_COMPLETE(_name, _maxargs, _cmd_rep, _usage, \
+ _help, _comp) \
+ ll_entry_declare(cmd_tbl_t, _name, cmd) = \
+ U_BOOT_CMDREP_MKENT_COMPLETE(_name, _maxargs, _cmd_rep, \
+ _usage, _help, _comp)
+
#else
#define U_BOOT_SUBCMD_START(name) static cmd_tbl_t name[] = {};
#define U_BOOT_SUBCMD_END
@@ -206,15 +307,25 @@ int board_run_command(const char *cmdline);
_cmd(NULL, 0, 0, NULL); \
return 0; \
}
+
+#define U_BOOT_CMDREP_MKENT_COMPLETE(_name, _maxargs, _cmd_rep, \
+ _usage, _help, _comp) \
+ { #_name, _maxargs, 0 ? _cmd_rep : NULL, NULL, _usage, \
+ _CMD_HELP(_help) _CMD_COMPLETE(_comp) }
+
#define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, \
_help, _comp) \
- { #_name, _maxargs, _rep, 0 ? _cmd : NULL, _usage, \
+ { #_name, _maxargs, NULL, 0 ? _cmd : NULL, _usage, \
_CMD_HELP(_help) _CMD_COMPLETE(_comp) }
#define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, \
_comp) \
_CMD_REMOVE(sub_ ## _name, _cmd)
+#define U_BOOT_CMDREP_COMPLETE(_name, _maxargs, _cmd_rep, _usage, \
+ _help, _comp) \
+ _CMD_REMOVE(sub_ ## _name, _cmd_rep)
+
#endif /* CONFIG_CMDLINE */
#define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help) \
@@ -224,4 +335,18 @@ int board_run_command(const char *cmdline);
U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \
_usage, _help, NULL)
+#define U_BOOT_SUBCMD_MKENT_COMPLETE(_name, _maxargs, _rep, _do_cmd, \
+ _comp) \
+ U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _do_cmd, \
+ "", "", _comp)
+
+#define U_BOOT_SUBCMD_MKENT(_name, _maxargs, _rep, _do_cmd) \
+ U_BOOT_SUBCMD_MKENT_COMPLETE(_name, _maxargs, _rep, _do_cmd, \
+ NULL)
+
+#define U_BOOT_CMD_WITH_SUBCMDS(_name, _usage, _help, ...) \
+ U_BOOT_SUBCMDS(_name, __VA_ARGS__) \
+ U_BOOT_CMDREP_COMPLETE(_name, CONFIG_SYS_MAXARGS, do_##_name, \
+ _usage, _help, complete_##_name)
+
#endif /* __COMMAND_H */
diff --git a/include/common.h b/include/common.h
index 657cc404cf..2c21dee850 100644
--- a/include/common.h
+++ b/include/common.h
@@ -248,7 +248,8 @@ static inline int env_set_addr(const char *varname, const void *addr)
}
#ifdef CONFIG_AUTO_COMPLETE
-int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf);
+int env_complete(char *var, int maxv, char *cmdv[], int maxsz, char *buf,
+ bool dollar_comp);
#endif
int get_env_id (void);
@@ -350,8 +351,6 @@ void smp_set_core_boot_addr(unsigned long addr, int corenr);
void smp_kick_all_cpus(void);
/* $(CPU)/serial.c */
-struct serial_device_info;
-
int serial_init (void);
void serial_setbrg (void);
void serial_putc (const char);
@@ -359,9 +358,6 @@ void serial_putc_raw(const char);
void serial_puts (const char *);
int serial_getc (void);
int serial_tstc (void);
-int serial_getconfig(uint *config);
-int serial_setconfig(uint config);
-int serial_getinfo(struct serial_device_info *info);
/* $(CPU)/speed.c */
int get_clocks (void);
diff --git a/include/configs/hikey.h b/include/configs/hikey.h
index 1376d6155d..572a52fad5 100644
--- a/include/configs/hikey.h
+++ b/include/configs/hikey.h
@@ -18,6 +18,8 @@
#define CONFIG_REMAKE_ELF
+#define CONFIG_SYS_BOOTM_LEN SZ_64M
+
/* Physical Memory Map */
/* CONFIG_SYS_TEXT_BASE needs to align with where ATF loads bl33.bin */
diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h
index ba763501cf..5129c83da8 100644
--- a/include/configs/mt7623.h
+++ b/include/configs/mt7623.h
@@ -24,6 +24,7 @@
/* Size of malloc() pool */
#define CONFIG_SYS_MALLOC_LEN SZ_4M
+#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M
/* Environment */
#define CONFIG_ENV_SIZE SZ_4K
@@ -53,4 +54,8 @@
#define CONFIG_EXTRA_ENV_SETTINGS \
FDT_HIGH
+/* Ethernet */
+#define CONFIG_IPADDR 192.168.1.1
+#define CONFIG_SERVERIP 192.168.1.2
+
#endif
diff --git a/include/configs/mt7629.h b/include/configs/mt7629.h
index a665a5eb7f..9910d8c89a 100644
--- a/include/configs/mt7629.h
+++ b/include/configs/mt7629.h
@@ -24,6 +24,7 @@
/* Size of malloc() pool */
#define CONFIG_SYS_MALLOC_LEN SZ_4M
+#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M
/* Environment */
#define CONFIG_ENV_SIZE SZ_4K
@@ -54,4 +55,8 @@
/* DRAM */
#define CONFIG_SYS_SDRAM_BASE 0x40000000
+/* Ethernet */
+#define CONFIG_IPADDR 192.168.1.1
+#define CONFIG_SERVERIP 192.168.1.2
+
#endif
diff --git a/include/configs/omap3_igep00x0.h b/include/configs/omap3_igep00x0.h
index 775374cf28..521e1675e0 100644
--- a/include/configs/omap3_igep00x0.h
+++ b/include/configs/omap3_igep00x0.h
@@ -32,16 +32,6 @@
#define GPIO_IGEP00X0_BOARD_DETECTION 28
#define GPIO_IGEP00X0_REVISION_DETECTION 129
-/* USB device configuration */
-#define CONFIG_USB_DEVICE 1
-#define CONFIG_USB_TTY 1
-
-/* Change these to suit your needs */
-#define CONFIG_USBD_VENDORID 0x0451
-#define CONFIG_USBD_PRODUCTID 0x5678
-#define CONFIG_USBD_MANUFACTURER "Texas Instruments"
-#define CONFIG_USBD_PRODUCT_NAME "IGEP"
-
#ifndef CONFIG_SPL_BUILD
/* Environment */
diff --git a/include/configs/qemu-riscv.h b/include/configs/qemu-riscv.h
index b29d155d09..2588c5a0b2 100644
--- a/include/configs/qemu-riscv.h
+++ b/include/configs/qemu-riscv.h
@@ -17,6 +17,8 @@
#define CONFIG_SYS_BOOTM_LEN SZ_16M
+#define CONFIG_STANDALONE_LOAD_ADDR 0x80200000
+
/* Environment options */
#define CONFIG_ENV_SIZE SZ_4K
diff --git a/include/dt-bindings/reset/mtk-reset.h b/include/dt-bindings/reset/mtk-reset.h
new file mode 100644
index 0000000000..5f0a74f280
--- /dev/null
+++ b/include/dt-bindings/reset/mtk-reset.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_MTK_RESET_H_
+#define _DT_BINDINGS_MTK_RESET_H_
+
+/* ETHSYS */
+#define ETHSYS_PPE_RST 31
+#define ETHSYS_EPHY_RST 24
+#define ETHSYS_GMAC_RST 23
+#define ETHSYS_ESW_RST 16
+#define ETHSYS_FE_RST 6
+#define ETHSYS_MCM_RST 2
+#define ETHSYS_SYS_RST 0
+
+#endif /* _DT_BINDINGS_MTK_RESET_H_ */
diff --git a/include/fs_loader.h b/include/fs_loader.h
index 0be4f17e63..b728c06fcf 100644
--- a/include/fs_loader.h
+++ b/include/fs_loader.h
@@ -9,21 +9,6 @@
#include <dm.h>
/**
- * struct firmware - A place for storing firmware and its attribute data.
- *
- * This holds information about a firmware and its content.
- *
- * @size: Size of a file
- * @data: Buffer for file
- * @priv: Firmware loader private fields
- */
-struct firmware {
- size_t size;
- const u8 *data;
- void *priv;
-};
-
-/**
* struct phandle_part - A place for storing phandle of node and its partition
*
* This holds information about a phandle of the block device, and its
@@ -53,27 +38,18 @@ struct device_platdata {
};
/**
- * release_firmware - Release the resource associated with a firmware image
- * @firmware: Firmware resource to release
- */
-void release_firmware(struct firmware *firmware);
-
-/**
* request_firmware_into_buf - Load firmware into a previously allocated buffer.
- * @plat: Platform data such as storage and partition firmware loading from.
+ * @dev: An instance of a driver.
* @name: Name of firmware file.
* @buf: Address of buffer to load firmware into.
* @size: Size of buffer.
* @offset: Offset of a file for start reading into buffer.
- * @firmwarep: Pointer to firmware image.
*
- * The firmware is loaded directly into the buffer pointed to by @buf and
- * the @firmwarep data member is pointed at @buf.
+ * The firmware is loaded directly into the buffer pointed to by @buf.
*
* Return: Size of total read, negative value when error.
*/
-int request_firmware_into_buf(struct device_platdata *plat,
+int request_firmware_into_buf(struct udevice *dev,
const char *name,
- void *buf, size_t size, u32 offset,
- struct firmware **firmwarep);
+ void *buf, size_t size, u32 offset);
#endif
diff --git a/include/lmb.h b/include/lmb.h
index f04d058093..1bb003e35e 100644
--- a/include/lmb.h
+++ b/include/lmb.h
@@ -28,9 +28,9 @@ struct lmb {
struct lmb_region reserved;
};
-extern struct lmb lmb;
-
extern void lmb_init(struct lmb *lmb);
+extern void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base,
+ phys_size_t size, void *fdt_blob);
extern long lmb_add(struct lmb *lmb, phys_addr_t base, phys_size_t size);
extern long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size);
extern phys_addr_t lmb_alloc(struct lmb *lmb, phys_size_t size, ulong align);
@@ -38,6 +38,9 @@ extern phys_addr_t lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align
phys_addr_t max_addr);
extern phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align,
phys_addr_t max_addr);
+extern phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base,
+ phys_size_t size);
+extern phys_size_t lmb_get_unreserved_size(struct lmb *lmb, phys_addr_t addr);
extern int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr);
extern long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size);
diff --git a/include/log.h b/include/log.h
index 0f2bc19477..d7f6471006 100644
--- a/include/log.h
+++ b/include/log.h
@@ -73,7 +73,8 @@ static inline int log_uc_cat(enum uclass_id id)
* @return 0 if log record was emitted, -ve on error
*/
int _log(enum log_category_t cat, enum log_level_t level, const char *file,
- int line, const char *func, const char *fmt, ...);
+ int line, const char *func, const char *fmt, ...)
+ __attribute__ ((format (__printf__, 6, 7)));
/* Define this at the top of a file to add a prefix to debug messages */
#ifndef pr_fmt
diff --git a/include/regmap.h b/include/regmap.h
index a3afb72df5..8359c511d2 100644
--- a/include/regmap.h
+++ b/include/regmap.h
@@ -248,6 +248,8 @@ int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
* @cond: Break condition (usually involving @val)
* @sleep_us: Maximum time to sleep between reads in us (0 tight-loops).
* @timeout_ms: Timeout in ms, 0 means never timeout
+ * @test_add_time: Used for sandbox testing - amount of time to add after
+ * starting the loop (0 if not testing)
*
* Returns 0 on success and -ETIMEDOUT upon a timeout or the regmap_read
* error return value in case of a error read. In the two former cases,
@@ -256,8 +258,12 @@ int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
*
* This is modelled after the regmap_read_poll_timeout macros in linux but
* with millisecond timeout.
+ *
+ * The _test version is for sandbox testing only. Do not use this in normal
+ * code as it advances the timer.
*/
-#define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_ms) \
+#define regmap_read_poll_timeout_test(map, addr, val, cond, sleep_us, \
+ timeout_ms, test_add_time) \
({ \
unsigned long __start = get_timer(0); \
int __ret; \
@@ -267,6 +273,8 @@ int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
break; \
if (cond) \
break; \
+ if (IS_ENABLED(CONFIG_SANDBOX) && test_add_time) \
+ sandbox_timer_add_offset(test_add_time); \
if ((timeout_ms) && get_timer(__start) > (timeout_ms)) { \
__ret = regmap_read((map), (addr), &(val)); \
break; \
@@ -277,6 +285,10 @@ int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset,
__ret ?: ((cond) ? 0 : -ETIMEDOUT); \
})
+#define regmap_read_poll_timeout(map, addr, val, cond, sleep_us, timeout_ms) \
+ regmap_read_poll_timeout_test(map, addr, val, cond, sleep_us, \
+ timeout_ms, 0) \
+
/**
* regmap_update_bits() - Perform a read/modify/write using a mask
*
diff --git a/include/serial.h b/include/serial.h
index c1a9fee250..c1368c68b6 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -235,9 +235,7 @@ struct dm_serial_ops {
* Get a current config for this device.
*
* @dev: Device pointer
- * @parity: parity to use
- * @bits: bits number to use
- * @stop: stop bits number to use
+ * @serial_config: Returns config information (see SERIAL_... above)
* @return 0 if OK, -ve on error
*/
int (*getconfig)(struct udevice *dev, uint *serial_config);
@@ -257,6 +255,7 @@ struct dm_serial_ops {
*
* @dev: Device pointer
* @info: struct serial_device_info to fill
+ * @return 0 if OK, -ve on error
*/
int (*getinfo)(struct udevice *dev, struct serial_device_info *info);
};
@@ -281,6 +280,39 @@ struct serial_dev_priv {
/* Access the serial operations for a device */
#define serial_get_ops(dev) ((struct dm_serial_ops *)(dev)->driver->ops)
+/**
+ * serial_getconfig() - Get the uart configuration
+ * (parity, 5/6/7/8 bits word length, stop bits)
+ *
+ * Get a current config for this device.
+ *
+ * @dev: Device pointer
+ * @serial_config: Returns config information (see SERIAL_... above)
+ * @return 0 if OK, -ve on error
+ */
+int serial_getconfig(struct udevice *dev, uint *config);
+
+/**
+ * serial_setconfig() - Set up the uart configuration
+ * (parity, 5/6/7/8 bits word length, stop bits)
+ *
+ * Set up a new config for this device.
+ *
+ * @dev: Device pointer
+ * @serial_config: number of bits, parity and number of stopbits to use
+ * @return 0 if OK, -ve on error
+ */
+int serial_setconfig(struct udevice *dev, uint config);
+
+/**
+ * serial_getinfo() - Get serial device information
+ *
+ * @dev: Device pointer
+ * @info: struct serial_device_info to fill
+ * @return 0 if OK, -ve on error
+ */
+int serial_getinfo(struct udevice *dev, struct serial_device_info *info);
+
void atmel_serial_initialize(void);
void mcf_serial_initialize(void);
void mpc85xx_serial_initialize(void);
diff --git a/lib/Makefile b/lib/Makefile
index a6dd928a92..61d7ff0678 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -36,12 +36,10 @@ obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o
obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += smbios.o
obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o
obj-y += initcall.o
-obj-$(CONFIG_LMB) += lmb.o
obj-y += ldiv.o
obj-$(CONFIG_MD5) += md5.o
obj-y += net_utils.o
obj-$(CONFIG_PHYSMEM) += physmem.o
-obj-y += qsort.o
obj-y += rc4.o
obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o
obj-$(CONFIG_RBTREE) += rbtree.o
@@ -67,7 +65,6 @@ obj-$(CONFIG_$(SPL_)LZ4) += lz4_wrapper.o
obj-$(CONFIG_LIBAVB) += libavb/
-obj-$(CONFIG_$(SPL_TPL_)SAVEENV) += qsort.o
obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += libfdt/
ifneq ($(CONFIG_$(SPL_TPL_)BUILD)$(CONFIG_$(SPL_TPL_)OF_PLATDATA),yy)
obj-$(CONFIG_$(SPL_TPL_)OF_CONTROL) += fdtdec_common.o
@@ -80,6 +77,7 @@ obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o
obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o
endif
obj-$(CONFIG_ADDR_MAP) += addr_map.o
+obj-y += qsort.o
obj-y += hashtable.o
obj-y += errno.o
obj-y += display_options.o
@@ -89,9 +87,11 @@ obj-y += crc32.o
obj-$(CONFIG_CRC32C) += crc32c.o
obj-y += ctype.o
obj-y += div64.o
+obj-$(CONFIG_OF_LIBFDT) += fdtdec.o
obj-y += hang.o
obj-y += linux_compat.o
obj-y += linux_string.o
+obj-$(CONFIG_LMB) += lmb.o
obj-y += membuff.o
obj-$(CONFIG_REGEX) += slre.o
obj-y += string.o
diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c
index 128cb0a627..8a4f3a9f40 100644
--- a/lib/efi_loader/efi_file.c
+++ b/lib/efi_loader/efi_file.c
@@ -221,8 +221,8 @@ static efi_status_t EFIAPI efi_file_open(struct efi_file_handle *file,
struct file_handle *fh = to_fh(file);
efi_status_t ret;
- EFI_ENTRY("%p, %p, \"%ls\", %llx, %llu", file, new_handle, file_name,
- open_mode, attributes);
+ EFI_ENTRY("%p, %p, \"%ls\", %llx, %llu", file, new_handle,
+ (wchar_t *)file_name, open_mode, attributes);
/* Check parameters */
if (!file || !new_handle || !file_name) {
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 6f8ec0dbed..18663ce6bd 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -95,16 +95,6 @@ fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node,
debug("%s: %s: ", __func__, prop_name);
- if (na > (sizeof(fdt_addr_t) / sizeof(fdt32_t))) {
- debug("(na too large for fdt_addr_t type)\n");
- return FDT_ADDR_T_NONE;
- }
-
- if (ns > (sizeof(fdt_size_t) / sizeof(fdt32_t))) {
- debug("(ns too large for fdt_size_t type)\n");
- return FDT_ADDR_T_NONE;
- }
-
prop = fdt_getprop(blob, node, prop_name, &len);
if (!prop) {
debug("(not found)\n");
diff --git a/lib/lmb.c b/lib/lmb.c
index 1705417348..3407705fa7 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -43,7 +43,10 @@ void lmb_dump_all(struct lmb *lmb)
static long lmb_addrs_overlap(phys_addr_t base1,
phys_size_t size1, phys_addr_t base2, phys_size_t size2)
{
- return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
+ const phys_addr_t base1_end = base1 + size1 - 1;
+ const phys_addr_t base2_end = base2 + size2 - 1;
+
+ return ((base1 <= base2_end) && (base2 <= base1_end));
}
static long lmb_addrs_adjacent(phys_addr_t base1, phys_size_t size1,
@@ -89,30 +92,35 @@ static void lmb_coalesce_regions(struct lmb_region *rgn,
void lmb_init(struct lmb *lmb)
{
- /* Create a dummy zero size LMB which will get coalesced away later.
- * This simplifies the lmb_add() code below...
- */
- lmb->memory.region[0].base = 0;
- lmb->memory.region[0].size = 0;
- lmb->memory.cnt = 1;
+ lmb->memory.cnt = 0;
lmb->memory.size = 0;
-
- /* Ditto. */
- lmb->reserved.region[0].base = 0;
- lmb->reserved.region[0].size = 0;
- lmb->reserved.cnt = 1;
+ lmb->reserved.cnt = 0;
lmb->reserved.size = 0;
}
+/* Initialize the struct, add memory and call arch/board reserve functions */
+void lmb_init_and_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size,
+ void *fdt_blob)
+{
+ lmb_init(lmb);
+ lmb_add(lmb, base, size);
+ arch_lmb_reserve(lmb);
+ board_lmb_reserve(lmb);
+
+ if (IMAGE_ENABLE_OF_LIBFDT && fdt_blob)
+ boot_fdt_add_mem_rsv_regions(lmb, fdt_blob);
+}
+
/* This routine called with relocation disabled. */
static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t size)
{
unsigned long coalesced = 0;
long adjacent, i;
- if ((rgn->cnt == 1) && (rgn->region[0].size == 0)) {
+ if (rgn->cnt == 0) {
rgn->region[0].base = base;
rgn->region[0].size = size;
+ rgn->cnt = 1;
return 0;
}
@@ -136,6 +144,9 @@ static long lmb_add_region(struct lmb_region *rgn, phys_addr_t base, phys_size_t
rgn->region[i].size += size;
coalesced++;
break;
+ } else if (lmb_addrs_overlap(base, size, rgnbase, rgnsize)) {
+ /* regions overlap */
+ return -1;
}
}
@@ -183,7 +194,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size)
{
struct lmb_region *rgn = &(lmb->reserved);
phys_addr_t rgnbegin, rgnend;
- phys_addr_t end = base + size;
+ phys_addr_t end = base + size - 1;
int i;
rgnbegin = rgnend = 0; /* supress gcc warnings */
@@ -191,7 +202,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size)
/* Find the region where (base, size) belongs to */
for (i=0; i < rgn->cnt; i++) {
rgnbegin = rgn->region[i].base;
- rgnend = rgnbegin + rgn->region[i].size;
+ rgnend = rgnbegin + rgn->region[i].size - 1;
if ((rgnbegin <= base) && (end <= rgnend))
break;
@@ -209,7 +220,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size)
/* Check to see if region is matching at the front */
if (rgnbegin == base) {
- rgn->region[i].base = end;
+ rgn->region[i].base = end + 1;
rgn->region[i].size -= size;
return 0;
}
@@ -225,7 +236,7 @@ long lmb_free(struct lmb *lmb, phys_addr_t base, phys_size_t size)
* beginging of the hole and add the region after hole.
*/
rgn->region[i].size = base - rgn->region[i].base;
- return lmb_add_region(rgn, end, rgnend - end);
+ return lmb_add_region(rgn, end + 1, rgnend - end);
}
long lmb_reserve(struct lmb *lmb, phys_addr_t base, phys_size_t size)
@@ -274,11 +285,6 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size)
return addr & ~(size - 1);
}
-static phys_addr_t lmb_align_up(phys_addr_t addr, ulong size)
-{
- return (addr + (size - 1)) & ~(size - 1);
-}
-
phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phys_addr_t max_addr)
{
long i, j;
@@ -307,8 +313,7 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy
if (j < 0) {
/* This area isn't reserved, take it */
if (lmb_add_region(&lmb->reserved, base,
- lmb_align_up(size,
- align)) < 0)
+ size) < 0)
return 0;
return base;
}
@@ -321,6 +326,59 @@ phys_addr_t __lmb_alloc_base(struct lmb *lmb, phys_size_t size, ulong align, phy
return 0;
}
+/*
+ * Try to allocate a specific address range: must be in defined memory but not
+ * reserved
+ */
+phys_addr_t lmb_alloc_addr(struct lmb *lmb, phys_addr_t base, phys_size_t size)
+{
+ long j;
+
+ /* Check if the requested address is in one of the memory regions */
+ j = lmb_overlaps_region(&lmb->memory, base, size);
+ if (j >= 0) {
+ /*
+ * Check if the requested end address is in the same memory
+ * region we found.
+ */
+ if (lmb_addrs_overlap(lmb->memory.region[j].base,
+ lmb->memory.region[j].size, base + size -
+ 1, 1)) {
+ /* ok, reserve the memory */
+ if (lmb_reserve(lmb, base, size) >= 0)
+ return base;
+ }
+ }
+ return 0;
+}
+
+/* Return number of bytes from a given address that are free */
+phys_size_t lmb_get_unreserved_size(struct lmb *lmb, phys_addr_t addr)
+{
+ int i;
+ long j;
+
+ /* check if the requested address is in the memory regions */
+ j = lmb_overlaps_region(&lmb->memory, addr, 1);
+ if (j >= 0) {
+ for (i = 0; i < lmb->reserved.cnt; i++) {
+ if (addr < lmb->reserved.region[i].base) {
+ /* first reserved range > requested address */
+ return lmb->reserved.region[i].base - addr;
+ }
+ if (lmb->reserved.region[i].base +
+ lmb->reserved.region[i].size > addr) {
+ /* requested addr is in this reserved range */
+ return 0;
+ }
+ }
+ /* if we come here: no reserved ranges above requested addr */
+ return lmb->memory.region[lmb->memory.cnt - 1].base +
+ lmb->memory.region[lmb->memory.cnt - 1].size - addr;
+ }
+ return 0;
+}
+
int lmb_is_reserved(struct lmb *lmb, phys_addr_t addr)
{
int i;
diff --git a/lib/uuid.c b/lib/uuid.c
index 5d5adf6b2d..fa20ee39fc 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -271,7 +271,7 @@ void gen_rand_uuid_str(char *uuid_str, int str_format)
uuid_bin_to_str(uuid_bin, uuid_str, str_format);
}
-#ifdef CONFIG_CMD_UUID
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_CMD_UUID)
int do_uuid(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
char uuid[UUID_STR_LEN + 1];
diff --git a/net/tftp.c b/net/tftp.c
index 68ffd81414..a9335b1b7e 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -17,6 +17,8 @@
#include <flash.h>
#endif
+DECLARE_GLOBAL_DATA_PTR;
+
/* Well known TFTP port # */
#define WELL_KNOWN_PORT 69
/* Millisecs to timeout for lost pkt */
@@ -81,6 +83,10 @@ static ulong tftp_block_wrap;
/* memory offset due to wrapping */
static ulong tftp_block_wrap_offset;
static int tftp_state;
+static ulong tftp_load_addr;
+#ifdef CONFIG_LMB
+static ulong tftp_load_size;
+#endif
#ifdef CONFIG_TFTP_TSIZE
/* The file size reported by the server */
static int tftp_tsize;
@@ -164,10 +170,11 @@ static void mcast_cleanup(void)
#endif /* CONFIG_MCAST_TFTP */
-static inline void store_block(int block, uchar *src, unsigned len)
+static inline int store_block(int block, uchar *src, unsigned int len)
{
ulong offset = block * tftp_block_size + tftp_block_wrap_offset;
ulong newsize = offset + len;
+ ulong store_addr = tftp_load_addr + offset;
#ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
int i, rc = 0;
@@ -175,24 +182,32 @@ static inline void store_block(int block, uchar *src, unsigned len)
/* start address in flash? */
if (flash_info[i].flash_id == FLASH_UNKNOWN)
continue;
- if (load_addr + offset >= flash_info[i].start[0]) {
+ if (store_addr >= flash_info[i].start[0]) {
rc = 1;
break;
}
}
if (rc) { /* Flash is destination for this packet */
- rc = flash_write((char *)src, (ulong)(load_addr+offset), len);
+ rc = flash_write((char *)src, store_addr, len);
if (rc) {
flash_perror(rc);
- net_set_state(NETLOOP_FAIL);
- return;
+ return rc;
}
} else
#endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */
{
- void *ptr = map_sysmem(load_addr + offset, len);
-
+ void *ptr;
+
+#ifdef CONFIG_LMB
+ if (store_addr < tftp_load_addr ||
+ store_addr + len > tftp_load_addr + tftp_load_size) {
+ puts("\nTFTP error: ");
+ puts("trying to overwrite reserved memory...\n");
+ return -1;
+ }
+#endif
+ ptr = map_sysmem(store_addr, len);
memcpy(ptr, src, len);
unmap_sysmem(ptr);
}
@@ -203,6 +218,8 @@ static inline void store_block(int block, uchar *src, unsigned len)
if (net_boot_file_size < newsize)
net_boot_file_size = newsize;
+
+ return 0;
}
/* Clear our state ready for a new transfer */
@@ -606,7 +623,11 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
timeout_count_max = tftp_timeout_count_max;
net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
- store_block(tftp_cur_block - 1, pkt + 2, len);
+ if (store_block(tftp_cur_block - 1, pkt + 2, len)) {
+ eth_halt();
+ net_set_state(NETLOOP_FAIL);
+ break;
+ }
/*
* Acknowledge the block just received, which will prompt
@@ -695,6 +716,25 @@ static void tftp_timeout_handler(void)
}
}
+/* Initialize tftp_load_addr and tftp_load_size from load_addr and lmb */
+static int tftp_init_load_addr(void)
+{
+#ifdef CONFIG_LMB
+ struct lmb lmb;
+ phys_size_t max_size;
+
+ lmb_init_and_reserve(&lmb, gd->bd->bi_dram[0].start,
+ gd->bd->bi_dram[0].size, (void *)gd->fdt_blob);
+
+ max_size = lmb_get_unreserved_size(&lmb, load_addr);
+ if (!max_size)
+ return -1;
+
+ tftp_load_size = max_size;
+#endif
+ tftp_load_addr = load_addr;
+ return 0;
+}
void tftp_start(enum proto_t protocol)
{
@@ -791,7 +831,14 @@ void tftp_start(enum proto_t protocol)
} else
#endif
{
- printf("Load address: 0x%lx\n", load_addr);
+ if (tftp_init_load_addr()) {
+ eth_halt();
+ net_set_state(NETLOOP_FAIL);
+ puts("\nTFTP error: ");
+ puts("trying to overwrite reserved memory...\n");
+ return;
+ }
+ printf("Load address: 0x%lx\n", tftp_load_addr);
puts("Loading: *\b");
tftp_state = STATE_SEND_RRQ;
#ifdef CONFIG_CMD_BOOTEFI
@@ -842,9 +889,15 @@ void tftp_start_server(void)
{
tftp_filename[0] = 0;
+ if (tftp_init_load_addr()) {
+ eth_halt();
+ net_set_state(NETLOOP_FAIL);
+ puts("\nTFTP error: trying to overwrite reserved memory...\n");
+ return;
+ }
printf("Using %s device\n", eth_get_name());
printf("Listening for TFTP transfer on %pI4\n", &net_ip);
- printf("Load address: 0x%lx\n", load_addr);
+ printf("Load address: 0x%lx\n", tftp_load_addr);
puts("Loading: *\b");
diff --git a/post/lib_powerpc/fpu/Makefile b/post/lib_powerpc/fpu/Makefile
index 404eefcfd0..9b2c1fadb6 100644
--- a/post/lib_powerpc/fpu/Makefile
+++ b/post/lib_powerpc/fpu/Makefile
@@ -11,9 +11,6 @@ targets += $(objs-before-objcopy)
$(foreach m, $(objs-before-objcopy), $(eval CFLAGS_REMOVE_$m := -msoft-float))
ccflags-y := -mhard-float -fkeep-inline-functions
-# Do not delete intermidiate files (*.o)
-.SECONDARY: $(call objectify, $(objs-before-objcopy))
-
obj-y := $(objs-before-objcopy:.o=_.o)
OBJCOPYFLAGS := -R .gnu.attributes
diff --git a/scripts/Kbuild.include b/scripts/Kbuild.include
index 13ebddda65..b8969e2a75 100644
--- a/scripts/Kbuild.include
+++ b/scripts/Kbuild.include
@@ -315,6 +315,12 @@ why = \
echo-why = $(call escsq, $(strip $(why)))
endif
+# delete partially updated (i.e. corrupted) files on error
+.DELETE_ON_ERROR:
+
+# do not delete intermediate files automatically
+.SECONDARY:
+
ifdef CONFIG_SPL_BUILD
SPL_ := SPL_
ifeq ($(CONFIG_TPL_BUILD),y)
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 482ed0c8d8..f7a041296d 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -331,8 +331,6 @@ quiet_cmd_asn1_compiler = ASN.1 $@
cmd_asn1_compiler = $(objtree)/scripts/asn1_compiler $< \
$(subst .h,.c,$@) $(subst .c,.h,$@)
-.PRECIOUS: $(objtree)/$(obj)/%-asn1.c $(objtree)/$(obj)/%-asn1.h
-
$(obj)/%-asn1.c $(obj)/%-asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler
$(call cmd,asn1_compiler)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index a4f16bb4bb..a5b57fc6b9 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -214,7 +214,6 @@ endef
quiet_cmd_flex = LEX $@
cmd_flex = $(LEX) -o$@ -L $<
-.PRECIOUS: $(obj)/%.lex.c
$(obj)/%.lex.c: $(src)/%.l FORCE
$(call if_changed,flex)
@@ -223,14 +222,12 @@ $(obj)/%.lex.c: $(src)/%.l FORCE
quiet_cmd_bison = YACC $@
cmd_bison = $(YACC) -o$@ -t -l $<
-.PRECIOUS: $(obj)/%.tab.c
$(obj)/%.tab.c: $(src)/%.y FORCE
$(call if_changed,bison)
quiet_cmd_bison_h = YACC $@
cmd_bison_h = $(YACC) -o/dev/null --defines=$@ -t -l $<
-.PRECIOUS: $(obj)/%.tab.h
$(obj)/%.tab.h: $(src)/%.y FORCE
$(call if_changed,bison_h)
diff --git a/scripts/dtc/pylibfdt/Makefile b/scripts/dtc/pylibfdt/Makefile
index c769d7db06..15e66ad44d 100644
--- a/scripts/dtc/pylibfdt/Makefile
+++ b/scripts/dtc/pylibfdt/Makefile
@@ -21,7 +21,7 @@ quiet_cmd_pymod = PYMOD $@
CPPFLAGS="$(HOSTCFLAGS) -I$(LIBFDT_srcdir)" OBJDIR=$(obj) \
SOURCES="$(PYLIBFDT_srcs)" \
SWIG_OPTS="-I$(LIBFDT_srcdir) -I$(LIBFDT_srcdir)/.." \
- $(PYTHON) $< --quiet build_ext --inplace
+ $(PYTHON2) $< --quiet build_ext --inplace
$(obj)/_libfdt.so: $(src)/setup.py $(PYLIBFDT_srcs) FORCE
$(call if_changed,pymod)
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 7dc80be25e..1b089960cb 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -15,6 +15,7 @@ ifneq ($(CONFIG_SANDBOX),)
obj-$(CONFIG_SOUND) += audio.o
obj-$(CONFIG_BLK) += blk.o
obj-$(CONFIG_BOARD) += board.o
+obj-$(CONFIG_DM_BOOTCOUNT) += bootcount.o
obj-$(CONFIG_CLK) += clk.o
obj-$(CONFIG_DM_ETH) += eth.o
obj-$(CONFIG_FIRMWARE) += firmware.o
diff --git a/test/dm/bootcount.c b/test/dm/bootcount.c
new file mode 100644
index 0000000000..0817b7d3ec
--- /dev/null
+++ b/test/dm/bootcount.c
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) 2018 Theobroma Systems Design und Consulting GmbH
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <bootcount.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+static int dm_test_bootcount(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ u32 val;
+
+ ut_assertok(uclass_get_device(UCLASS_BOOTCOUNT, 0, &dev));
+ ut_assertok(dm_bootcount_set(dev, 0));
+ ut_assertok(dm_bootcount_get(dev, &val));
+ ut_assert(val == 0);
+ ut_assertok(dm_bootcount_set(dev, 0xab));
+ ut_assertok(dm_bootcount_get(dev, &val));
+ ut_assert(val == 0xab);
+
+ return 0;
+}
+
+DM_TEST(dm_test_bootcount, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
diff --git a/test/dm/regmap.c b/test/dm/regmap.c
index 9a70c159dd..82de295cb8 100644
--- a/test/dm/regmap.c
+++ b/test/dm/regmap.c
@@ -160,9 +160,10 @@ static int dm_test_regmap_poll(struct unit_test_state *uts)
start = get_timer(0);
ut_asserteq(-ETIMEDOUT,
- regmap_read_poll_timeout(map, 0, reg,
- (reg == 0xcacafafa),
- 1, 5 * CONFIG_SYS_HZ));
+ regmap_read_poll_timeout_test(map, 0, reg,
+ (reg == 0xcacafafa),
+ 1, 5 * CONFIG_SYS_HZ,
+ 5 * CONFIG_SYS_HZ));
ut_assert(get_timer(start) > (5 * CONFIG_SYS_HZ));
diff --git a/test/dm/serial.c b/test/dm/serial.c
index 19a15d5d95..3d741a8c36 100644
--- a/test/dm/serial.c
+++ b/test/dm/serial.c
@@ -23,23 +23,24 @@ static int dm_test_serial(struct unit_test_state *uts)
* test with default config which is the only one supported by
* sandbox_serial driver
*/
- ut_assertok(serial_setconfig(SERIAL_DEFAULT_CONFIG));
- ut_assertok(serial_getconfig(&value_serial));
+ ut_assertok(serial_setconfig(dev_serial, SERIAL_DEFAULT_CONFIG));
+ ut_assertok(serial_getconfig(dev_serial, &value_serial));
ut_assert(value_serial == SERIAL_DEFAULT_CONFIG);
- ut_assertok(serial_getinfo(&info_serial));
+ ut_assertok(serial_getinfo(dev_serial, &info_serial));
ut_assert(info_serial.type == SERIAL_CHIP_UNKNOWN);
ut_assert(info_serial.addr == SERIAL_DEFAULT_ADDRESS);
/*
* test with a parameter which is NULL pointer
*/
- ut_asserteq(-EINVAL, serial_getconfig(NULL));
- ut_asserteq(-EINVAL, serial_getinfo(NULL));
+ ut_asserteq(-EINVAL, serial_getconfig(dev_serial, NULL));
+ ut_asserteq(-EINVAL, serial_getinfo(dev_serial, NULL));
/*
* test with a serial config which is not supported by
* sandbox_serial driver: test with wrong parity
*/
ut_asserteq(-ENOTSUPP,
- serial_setconfig(SERIAL_CONFIG(SERIAL_PAR_ODD,
+ serial_setconfig(dev_serial,
+ SERIAL_CONFIG(SERIAL_PAR_ODD,
SERIAL_8_BITS,
SERIAL_ONE_STOP)));
/*
@@ -47,7 +48,8 @@ static int dm_test_serial(struct unit_test_state *uts)
* sandbox_serial driver: test with wrong bits number
*/
ut_asserteq(-ENOTSUPP,
- serial_setconfig(SERIAL_CONFIG(SERIAL_PAR_NONE,
+ serial_setconfig(dev_serial,
+ SERIAL_CONFIG(SERIAL_PAR_NONE,
SERIAL_6_BITS,
SERIAL_ONE_STOP)));
@@ -56,7 +58,8 @@ static int dm_test_serial(struct unit_test_state *uts)
* sandbox_serial driver: test with wrong stop bits number
*/
ut_asserteq(-ENOTSUPP,
- serial_setconfig(SERIAL_CONFIG(SERIAL_PAR_NONE,
+ serial_setconfig(dev_serial,
+ SERIAL_CONFIG(SERIAL_PAR_NONE,
SERIAL_8_BITS,
SERIAL_TWO_STOP)));
diff --git a/test/lib/Makefile b/test/lib/Makefile
index ea68fae566..5a636aac74 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -3,3 +3,4 @@
# (C) Copyright 2018
# Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
obj-y += hexdump.o
+obj-y += lmb.o
diff --git a/test/lib/lmb.c b/test/lib/lmb.c
new file mode 100644
index 0000000000..058d3c332b
--- /dev/null
+++ b/test/lib/lmb.c
@@ -0,0 +1,601 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2018 Simon Goldschmidt
+ */
+
+#include <common.h>
+#include <lmb.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+static int check_lmb(struct unit_test_state *uts, struct lmb *lmb,
+ phys_addr_t ram_base, phys_size_t ram_size,
+ unsigned long num_reserved,
+ phys_addr_t base1, phys_size_t size1,
+ phys_addr_t base2, phys_size_t size2,
+ phys_addr_t base3, phys_size_t size3)
+{
+ ut_asserteq(lmb->memory.cnt, 1);
+ ut_asserteq(lmb->memory.region[0].base, ram_base);
+ ut_asserteq(lmb->memory.region[0].size, ram_size);
+
+ ut_asserteq(lmb->reserved.cnt, num_reserved);
+ if (num_reserved > 0) {
+ ut_asserteq(lmb->reserved.region[0].base, base1);
+ ut_asserteq(lmb->reserved.region[0].size, size1);
+ }
+ if (num_reserved > 1) {
+ ut_asserteq(lmb->reserved.region[1].base, base2);
+ ut_asserteq(lmb->reserved.region[1].size, size2);
+ }
+ if (num_reserved > 2) {
+ ut_asserteq(lmb->reserved.region[2].base, base3);
+ ut_asserteq(lmb->reserved.region[2].size, size3);
+ }
+ return 0;
+}
+
+#define ASSERT_LMB(lmb, ram_base, ram_size, num_reserved, base1, size1, \
+ base2, size2, base3, size3) \
+ ut_assert(!check_lmb(uts, lmb, ram_base, ram_size, \
+ num_reserved, base1, size1, base2, size2, base3, \
+ size3))
+
+/*
+ * Test helper function that reserves 64 KiB somewhere in the simulated RAM and
+ * then does some alloc + free tests.
+ */
+static int test_multi_alloc(struct unit_test_state *uts,
+ const phys_addr_t ram, const phys_size_t ram_size,
+ const phys_addr_t alloc_64k_addr)
+{
+ const phys_addr_t ram_end = ram + ram_size;
+ const phys_addr_t alloc_64k_end = alloc_64k_addr + 0x10000;
+
+ struct lmb lmb;
+ long ret;
+ phys_addr_t a, a2, b, b2, c, d;
+
+ /* check for overflow */
+ ut_assert(ram_end == 0 || ram_end > ram);
+ ut_assert(alloc_64k_end > alloc_64k_addr);
+ /* check input addresses + size */
+ ut_assert(alloc_64k_addr >= ram + 8);
+ ut_assert(alloc_64k_end <= ram_end - 8);
+
+ lmb_init(&lmb);
+
+ ret = lmb_add(&lmb, ram, ram_size);
+ ut_asserteq(ret, 0);
+
+ /* reserve 64KiB somewhere */
+ ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
+ 0, 0, 0, 0);
+
+ /* allocate somewhere, should be at the end of RAM */
+ a = lmb_alloc(&lmb, 4, 1);
+ ut_asserteq(a, ram_end - 4);
+ ASSERT_LMB(&lmb, ram, ram_size, 2, alloc_64k_addr, 0x10000,
+ ram_end - 4, 4, 0, 0);
+ /* alloc below end of reserved region -> below reserved region */
+ b = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end);
+ ut_asserteq(b, alloc_64k_addr - 4);
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
+ alloc_64k_addr - 4, 0x10000 + 4, ram_end - 4, 4, 0, 0);
+
+ /* 2nd time */
+ c = lmb_alloc(&lmb, 4, 1);
+ ut_asserteq(c, ram_end - 8);
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
+ alloc_64k_addr - 4, 0x10000 + 4, ram_end - 8, 8, 0, 0);
+ d = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end);
+ ut_asserteq(d, alloc_64k_addr - 8);
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0);
+
+ ret = lmb_free(&lmb, a, 4);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
+ /* allocate again to ensure we get the same address */
+ a2 = lmb_alloc(&lmb, 4, 1);
+ ut_asserteq(a, a2);
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 8, 0, 0);
+ ret = lmb_free(&lmb, a2, 4);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
+
+ ret = lmb_free(&lmb, b, 4);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 3,
+ alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000,
+ ram_end - 8, 4);
+ /* allocate again to ensure we get the same address */
+ b2 = lmb_alloc_base(&lmb, 4, 1, alloc_64k_end);
+ ut_asserteq(b, b2);
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
+ alloc_64k_addr - 8, 0x10000 + 8, ram_end - 8, 4, 0, 0);
+ ret = lmb_free(&lmb, b2, 4);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 3,
+ alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000,
+ ram_end - 8, 4);
+
+ ret = lmb_free(&lmb, c, 4);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 2,
+ alloc_64k_addr - 8, 4, alloc_64k_addr, 0x10000, 0, 0);
+ ret = lmb_free(&lmb, d, 4);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
+ 0, 0, 0, 0);
+
+ return 0;
+}
+
+static int test_multi_alloc_512mb(struct unit_test_state *uts,
+ const phys_addr_t ram)
+{
+ return test_multi_alloc(uts, ram, 0x20000000, ram + 0x10000000);
+}
+
+/* Create a memory region with one reserved region and allocate */
+static int lib_test_lmb_simple(struct unit_test_state *uts)
+{
+ int ret;
+
+ /* simulate 512 MiB RAM beginning at 1GiB */
+ ret = test_multi_alloc_512mb(uts, 0x40000000);
+ if (ret)
+ return ret;
+
+ /* simulate 512 MiB RAM beginning at 1.5GiB */
+ return test_multi_alloc_512mb(uts, 0xE0000000);
+}
+
+DM_TEST(lib_test_lmb_simple, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Simulate 512 MiB RAM, allocate some blocks that fit/don't fit */
+static int test_bigblock(struct unit_test_state *uts, const phys_addr_t ram)
+{
+ const phys_size_t ram_size = 0x20000000;
+ const phys_size_t big_block_size = 0x10000000;
+ const phys_addr_t ram_end = ram + ram_size;
+ const phys_addr_t alloc_64k_addr = ram + 0x10000000;
+ struct lmb lmb;
+ long ret;
+ phys_addr_t a, b;
+
+ /* check for overflow */
+ ut_assert(ram_end == 0 || ram_end > ram);
+
+ lmb_init(&lmb);
+
+ ret = lmb_add(&lmb, ram, ram_size);
+ ut_asserteq(ret, 0);
+
+ /* reserve 64KiB in the middle of RAM */
+ ret = lmb_reserve(&lmb, alloc_64k_addr, 0x10000);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
+ 0, 0, 0, 0);
+
+ /* allocate a big block, should be below reserved */
+ a = lmb_alloc(&lmb, big_block_size, 1);
+ ut_asserteq(a, ram);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, a,
+ big_block_size + 0x10000, 0, 0, 0, 0);
+ /* allocate 2nd big block */
+ /* This should fail, printing an error */
+ b = lmb_alloc(&lmb, big_block_size, 1);
+ ut_asserteq(b, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, a,
+ big_block_size + 0x10000, 0, 0, 0, 0);
+
+ ret = lmb_free(&lmb, a, big_block_size);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
+ 0, 0, 0, 0);
+
+ /* allocate too big block */
+ /* This should fail, printing an error */
+ a = lmb_alloc(&lmb, ram_size, 1);
+ ut_asserteq(a, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, alloc_64k_addr, 0x10000,
+ 0, 0, 0, 0);
+
+ return 0;
+}
+
+static int lib_test_lmb_big(struct unit_test_state *uts)
+{
+ int ret;
+
+ /* simulate 512 MiB RAM beginning at 1GiB */
+ ret = test_bigblock(uts, 0x40000000);
+ if (ret)
+ return ret;
+
+ /* simulate 512 MiB RAM beginning at 1.5GiB */
+ return test_bigblock(uts, 0xE0000000);
+}
+
+DM_TEST(lib_test_lmb_big, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Simulate 512 MiB RAM, allocate a block without previous reservation */
+static int test_noreserved(struct unit_test_state *uts, const phys_addr_t ram,
+ const phys_addr_t alloc_size, const ulong align)
+{
+ const phys_size_t ram_size = 0x20000000;
+ const phys_addr_t ram_end = ram + ram_size;
+ struct lmb lmb;
+ long ret;
+ phys_addr_t a, b;
+ const phys_addr_t alloc_size_aligned = (alloc_size + align - 1) &
+ ~(align - 1);
+
+ /* check for overflow */
+ ut_assert(ram_end == 0 || ram_end > ram);
+
+ lmb_init(&lmb);
+
+ ret = lmb_add(&lmb, ram, ram_size);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
+
+ /* allocate a block */
+ a = lmb_alloc(&lmb, alloc_size, align);
+ ut_assert(a != 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
+ alloc_size, 0, 0, 0, 0);
+ /* allocate another block */
+ b = lmb_alloc(&lmb, alloc_size, align);
+ ut_assert(b != 0);
+ if (alloc_size == alloc_size_aligned) {
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size -
+ (alloc_size_aligned * 2), alloc_size * 2, 0, 0, 0,
+ 0);
+ } else {
+ ASSERT_LMB(&lmb, ram, ram_size, 2, ram + ram_size -
+ (alloc_size_aligned * 2), alloc_size, ram + ram_size
+ - alloc_size_aligned, alloc_size, 0, 0);
+ }
+ /* and free them */
+ ret = lmb_free(&lmb, b, alloc_size);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
+ alloc_size, 0, 0, 0, 0);
+ ret = lmb_free(&lmb, a, alloc_size);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
+
+ /* allocate a block with base*/
+ b = lmb_alloc_base(&lmb, alloc_size, align, ram_end);
+ ut_assert(a == b);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + ram_size - alloc_size_aligned,
+ alloc_size, 0, 0, 0, 0);
+ /* and free it */
+ ret = lmb_free(&lmb, b, alloc_size);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
+
+ return 0;
+}
+
+static int lib_test_lmb_noreserved(struct unit_test_state *uts)
+{
+ int ret;
+
+ /* simulate 512 MiB RAM beginning at 1GiB */
+ ret = test_noreserved(uts, 0x40000000, 4, 1);
+ if (ret)
+ return ret;
+
+ /* simulate 512 MiB RAM beginning at 1.5GiB */
+ return test_noreserved(uts, 0xE0000000, 4, 1);
+}
+
+DM_TEST(lib_test_lmb_noreserved, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+static int lib_test_lmb_unaligned_size(struct unit_test_state *uts)
+{
+ int ret;
+
+ /* simulate 512 MiB RAM beginning at 1GiB */
+ ret = test_noreserved(uts, 0x40000000, 5, 8);
+ if (ret)
+ return ret;
+
+ /* simulate 512 MiB RAM beginning at 1.5GiB */
+ return test_noreserved(uts, 0xE0000000, 5, 8);
+}
+
+DM_TEST(lib_test_lmb_unaligned_size, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+/*
+ * Simulate a RAM that starts at 0 and allocate down to address 0, which must
+ * fail as '0' means failure for the lmb_alloc functions.
+ */
+static int lib_test_lmb_at_0(struct unit_test_state *uts)
+{
+ const phys_addr_t ram = 0;
+ const phys_size_t ram_size = 0x20000000;
+ struct lmb lmb;
+ long ret;
+ phys_addr_t a, b;
+
+ lmb_init(&lmb);
+
+ ret = lmb_add(&lmb, ram, ram_size);
+ ut_asserteq(ret, 0);
+
+ /* allocate nearly everything */
+ a = lmb_alloc(&lmb, ram_size - 4, 1);
+ ut_asserteq(a, ram + 4);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
+ 0, 0, 0, 0);
+ /* allocate the rest */
+ /* This should fail as the allocated address would be 0 */
+ b = lmb_alloc(&lmb, 4, 1);
+ ut_asserteq(b, 0);
+ /* check that this was an error by checking lmb */
+ ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
+ 0, 0, 0, 0);
+ /* check that this was an error by freeing b */
+ ret = lmb_free(&lmb, b, 4);
+ ut_asserteq(ret, -1);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, a, ram_size - 4,
+ 0, 0, 0, 0);
+
+ ret = lmb_free(&lmb, a, ram_size - 4);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 0, 0, 0, 0, 0, 0, 0);
+
+ return 0;
+}
+
+DM_TEST(lib_test_lmb_at_0, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Check that calling lmb_reserve with overlapping regions fails. */
+static int lib_test_lmb_overlapping_reserve(struct unit_test_state *uts)
+{
+ const phys_addr_t ram = 0x40000000;
+ const phys_size_t ram_size = 0x20000000;
+ struct lmb lmb;
+ long ret;
+
+ lmb_init(&lmb);
+
+ ret = lmb_add(&lmb, ram, ram_size);
+ ut_asserteq(ret, 0);
+
+ ret = lmb_reserve(&lmb, 0x40010000, 0x10000);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000,
+ 0, 0, 0, 0);
+ /* allocate overlapping region should fail */
+ ret = lmb_reserve(&lmb, 0x40011000, 0x10000);
+ ut_asserteq(ret, -1);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x10000,
+ 0, 0, 0, 0);
+ /* allocate 3nd region */
+ ret = lmb_reserve(&lmb, 0x40030000, 0x10000);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 2, 0x40010000, 0x10000,
+ 0x40030000, 0x10000, 0, 0);
+ /* allocate 2nd region */
+ ret = lmb_reserve(&lmb, 0x40020000, 0x10000);
+ ut_assert(ret >= 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, 0x40010000, 0x30000,
+ 0, 0, 0, 0);
+
+ return 0;
+}
+
+DM_TEST(lib_test_lmb_overlapping_reserve,
+ DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/*
+ * Simulate 512 MiB RAM, reserve 3 blocks, allocate addresses in between.
+ * Expect addresses outside the memory range to fail.
+ */
+static int test_alloc_addr(struct unit_test_state *uts, const phys_addr_t ram)
+{
+ const phys_size_t ram_size = 0x20000000;
+ const phys_addr_t ram_end = ram + ram_size;
+ const phys_size_t alloc_addr_a = ram + 0x8000000;
+ const phys_size_t alloc_addr_b = ram + 0x8000000 * 2;
+ const phys_size_t alloc_addr_c = ram + 0x8000000 * 3;
+ struct lmb lmb;
+ long ret;
+ phys_addr_t a, b, c, d, e;
+
+ /* check for overflow */
+ ut_assert(ram_end == 0 || ram_end > ram);
+
+ lmb_init(&lmb);
+
+ ret = lmb_add(&lmb, ram, ram_size);
+ ut_asserteq(ret, 0);
+
+ /* reserve 3 blocks */
+ ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000);
+ ut_asserteq(ret, 0);
+ ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000);
+ ut_asserteq(ret, 0);
+ ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000,
+ alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
+
+ /* allocate blocks */
+ a = lmb_alloc_addr(&lmb, ram, alloc_addr_a - ram);
+ ut_asserteq(a, ram);
+ ASSERT_LMB(&lmb, ram, ram_size, 3, ram, 0x8010000,
+ alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
+ b = lmb_alloc_addr(&lmb, alloc_addr_a + 0x10000,
+ alloc_addr_b - alloc_addr_a - 0x10000);
+ ut_asserteq(b, alloc_addr_a + 0x10000);
+ ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x10010000,
+ alloc_addr_c, 0x10000, 0, 0);
+ c = lmb_alloc_addr(&lmb, alloc_addr_b + 0x10000,
+ alloc_addr_c - alloc_addr_b - 0x10000);
+ ut_asserteq(c, alloc_addr_b + 0x10000);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
+ 0, 0, 0, 0);
+ d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000,
+ ram_end - alloc_addr_c - 0x10000);
+ ut_asserteq(d, alloc_addr_c + 0x10000);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size,
+ 0, 0, 0, 0);
+
+ /* allocating anything else should fail */
+ e = lmb_alloc(&lmb, 1, 1);
+ ut_asserteq(e, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, ram_size,
+ 0, 0, 0, 0);
+
+ ret = lmb_free(&lmb, d, ram_end - alloc_addr_c - 0x10000);
+ ut_asserteq(ret, 0);
+
+ /* allocate at 3 points in free range */
+
+ d = lmb_alloc_addr(&lmb, ram_end - 4, 4);
+ ut_asserteq(d, ram_end - 4);
+ ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000,
+ d, 4, 0, 0);
+ ret = lmb_free(&lmb, d, 4);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
+ 0, 0, 0, 0);
+
+ d = lmb_alloc_addr(&lmb, ram_end - 128, 4);
+ ut_asserteq(d, ram_end - 128);
+ ASSERT_LMB(&lmb, ram, ram_size, 2, ram, 0x18010000,
+ d, 4, 0, 0);
+ ret = lmb_free(&lmb, d, 4);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
+ 0, 0, 0, 0);
+
+ d = lmb_alloc_addr(&lmb, alloc_addr_c + 0x10000, 4);
+ ut_asserteq(d, alloc_addr_c + 0x10000);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010004,
+ 0, 0, 0, 0);
+ ret = lmb_free(&lmb, d, 4);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram, 0x18010000,
+ 0, 0, 0, 0);
+
+ /* allocate at the bottom */
+ ret = lmb_free(&lmb, a, alloc_addr_a - ram);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 1, ram + 0x8000000, 0x10010000,
+ 0, 0, 0, 0);
+ d = lmb_alloc_addr(&lmb, ram, 4);
+ ut_asserteq(d, ram);
+ ASSERT_LMB(&lmb, ram, ram_size, 2, d, 4,
+ ram + 0x8000000, 0x10010000, 0, 0);
+
+ /* check that allocating outside memory fails */
+ if (ram_end != 0) {
+ ret = lmb_alloc_addr(&lmb, ram_end, 1);
+ ut_asserteq(ret, 0);
+ }
+ if (ram != 0) {
+ ret = lmb_alloc_addr(&lmb, ram - 1, 1);
+ ut_asserteq(ret, 0);
+ }
+
+ return 0;
+}
+
+static int lib_test_lmb_alloc_addr(struct unit_test_state *uts)
+{
+ int ret;
+
+ /* simulate 512 MiB RAM beginning at 1GiB */
+ ret = test_alloc_addr(uts, 0x40000000);
+ if (ret)
+ return ret;
+
+ /* simulate 512 MiB RAM beginning at 1.5GiB */
+ return test_alloc_addr(uts, 0xE0000000);
+}
+
+DM_TEST(lib_test_lmb_alloc_addr, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Simulate 512 MiB RAM, reserve 3 blocks, check addresses in between */
+static int test_get_unreserved_size(struct unit_test_state *uts,
+ const phys_addr_t ram)
+{
+ const phys_size_t ram_size = 0x20000000;
+ const phys_addr_t ram_end = ram + ram_size;
+ const phys_size_t alloc_addr_a = ram + 0x8000000;
+ const phys_size_t alloc_addr_b = ram + 0x8000000 * 2;
+ const phys_size_t alloc_addr_c = ram + 0x8000000 * 3;
+ struct lmb lmb;
+ long ret;
+ phys_size_t s;
+
+ /* check for overflow */
+ ut_assert(ram_end == 0 || ram_end > ram);
+
+ lmb_init(&lmb);
+
+ ret = lmb_add(&lmb, ram, ram_size);
+ ut_asserteq(ret, 0);
+
+ /* reserve 3 blocks */
+ ret = lmb_reserve(&lmb, alloc_addr_a, 0x10000);
+ ut_asserteq(ret, 0);
+ ret = lmb_reserve(&lmb, alloc_addr_b, 0x10000);
+ ut_asserteq(ret, 0);
+ ret = lmb_reserve(&lmb, alloc_addr_c, 0x10000);
+ ut_asserteq(ret, 0);
+ ASSERT_LMB(&lmb, ram, ram_size, 3, alloc_addr_a, 0x10000,
+ alloc_addr_b, 0x10000, alloc_addr_c, 0x10000);
+
+ /* check addresses in between blocks */
+ s = lmb_get_unreserved_size(&lmb, ram);
+ ut_asserteq(s, alloc_addr_a - ram);
+ s = lmb_get_unreserved_size(&lmb, ram + 0x10000);
+ ut_asserteq(s, alloc_addr_a - ram - 0x10000);
+ s = lmb_get_unreserved_size(&lmb, alloc_addr_a - 4);
+ ut_asserteq(s, 4);
+
+ s = lmb_get_unreserved_size(&lmb, alloc_addr_a + 0x10000);
+ ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x10000);
+ s = lmb_get_unreserved_size(&lmb, alloc_addr_a + 0x20000);
+ ut_asserteq(s, alloc_addr_b - alloc_addr_a - 0x20000);
+ s = lmb_get_unreserved_size(&lmb, alloc_addr_b - 4);
+ ut_asserteq(s, 4);
+
+ s = lmb_get_unreserved_size(&lmb, alloc_addr_c + 0x10000);
+ ut_asserteq(s, ram_end - alloc_addr_c - 0x10000);
+ s = lmb_get_unreserved_size(&lmb, alloc_addr_c + 0x20000);
+ ut_asserteq(s, ram_end - alloc_addr_c - 0x20000);
+ s = lmb_get_unreserved_size(&lmb, ram_end - 4);
+ ut_asserteq(s, 4);
+
+ return 0;
+}
+
+static int lib_test_lmb_get_unreserved_size(struct unit_test_state *uts)
+{
+ int ret;
+
+ /* simulate 512 MiB RAM beginning at 1GiB */
+ ret = test_get_unreserved_size(uts, 0x40000000);
+ if (ret)
+ return ret;
+
+ /* simulate 512 MiB RAM beginning at 1.5GiB */
+ return test_get_unreserved_size(uts, 0xE0000000);
+}
+
+DM_TEST(lib_test_lmb_get_unreserved_size,
+ DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/py/tests/test_avb.py b/test/py/tests/test_avb.py
index 9683fd80d0..e70a010c9a 100644
--- a/test/py/tests/test_avb.py
+++ b/test/py/tests/test_avb.py
@@ -51,22 +51,22 @@ def test_avb_mmc_uuid(u_boot_console):
part_lines = u_boot_console.run_command('mmc part').splitlines()
part_list = {}
- cur_partname = ""
+ cur_partname = ''
for line in part_lines:
- if "\"" in line:
- start_pt = line.find("\"")
- end_pt = line.find("\"", start_pt + 1)
+ if '"' in line:
+ start_pt = line.find('"')
+ end_pt = line.find('"', start_pt + 1)
cur_partname = line[start_pt + 1: end_pt]
- if "guid:" in line:
- guid_to_check = line.split("guid:\t")
+ if 'guid:' in line:
+ guid_to_check = line.split('guid:\t')
part_list[cur_partname] = guid_to_check[1]
# lets check all guids with avb get_guid
for part, guid in part_list.iteritems():
avb_guid_resp = u_boot_console.run_command('avb get_uuid %s' % part)
- assert guid == avb_guid_resp.split("UUID: ")[1]
+ assert guid == avb_guid_resp.split('UUID: ')[1]
@pytest.mark.buildconfigspec('cmd_avb')
diff --git a/test/py/tests/test_bind.py b/test/py/tests/test_bind.py
index dee3fee566..ccf6d62ea8 100644
--- a/test/py/tests/test_bind.py
+++ b/test/py/tests/test_bind.py
@@ -13,7 +13,8 @@ def in_tree(response, name, uclass, drv, depth, last_child):
else:
leaf = leaf + '`'
leaf = leaf + '-- ' + name
- line = ' *{:10.10} [0-9]* \[ [ +] \] {:20.20} {}$'.format(uclass, drv, leaf)
+ line = (' *{:10.10} [0-9]* \[ [ +] \] {:20.20} {}$'
+ .format(uclass, drv, leaf))
prog = re.compile(line)
for l in lines:
if prog.match(l):
@@ -25,82 +26,82 @@ def in_tree(response, name, uclass, drv, depth, last_child):
def test_bind_unbind_with_node(u_boot_console):
#bind /bind-test. Device should come up as well as its children
- response = u_boot_console.run_command("bind /bind-test generic_simple_bus")
+ response = u_boot_console.run_command('bind /bind-test generic_simple_bus')
assert response == ''
- tree = u_boot_console.run_command("dm tree")
- assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
- assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False)
- assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
+ tree = u_boot_console.run_command('dm tree')
+ assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+ assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False)
+ assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
#Unbind child #1. No error expected and all devices should be there except for bind-test-child1
- response = u_boot_console.run_command("unbind /bind-test/bind-test-child1")
+ response = u_boot_console.run_command('unbind /bind-test/bind-test-child1')
assert response == ''
- tree = u_boot_console.run_command("dm tree")
- assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
- assert "bind-test-child1" not in tree
- assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
+ tree = u_boot_console.run_command('dm tree')
+ assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+ assert 'bind-test-child1' not in tree
+ assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
#bind child #1. No error expected and all devices should be there
- response = u_boot_console.run_command("bind /bind-test/bind-test-child1 phy_sandbox")
+ response = u_boot_console.run_command('bind /bind-test/bind-test-child1 phy_sandbox')
assert response == ''
- tree = u_boot_console.run_command("dm tree")
- assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
- assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, True)
- assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, False)
+ tree = u_boot_console.run_command('dm tree')
+ assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+ assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True)
+ assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, False)
#Unbind child #2. No error expected and all devices should be there except for bind-test-child2
- response = u_boot_console.run_command("unbind /bind-test/bind-test-child2")
+ response = u_boot_console.run_command('unbind /bind-test/bind-test-child2')
assert response == ''
- tree = u_boot_console.run_command("dm tree")
- assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
- assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, True)
- assert "bind-test-child2" not in tree
+ tree = u_boot_console.run_command('dm tree')
+ assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+ assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True)
+ assert 'bind-test-child2' not in tree
#Bind child #2. No error expected and all devices should be there
- response = u_boot_console.run_command("bind /bind-test/bind-test-child2 generic_simple_bus")
+ response = u_boot_console.run_command('bind /bind-test/bind-test-child2 generic_simple_bus')
assert response == ''
- tree = u_boot_console.run_command("dm tree")
- assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
- assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False)
- assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
+ tree = u_boot_console.run_command('dm tree')
+ assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+ assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False)
+ assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
#Unbind parent. No error expected. All devices should be removed and unbound
- response = u_boot_console.run_command("unbind /bind-test")
+ response = u_boot_console.run_command('unbind /bind-test')
assert response == ''
- tree = u_boot_console.run_command("dm tree")
- assert "bind-test" not in tree
- assert "bind-test-child1" not in tree
- assert "bind-test-child2" not in tree
+ tree = u_boot_console.run_command('dm tree')
+ assert 'bind-test' not in tree
+ assert 'bind-test-child1' not in tree
+ assert 'bind-test-child2' not in tree
#try binding invalid node with valid driver
- response = u_boot_console.run_command("bind /not-a-valid-node generic_simple_bus")
+ response = u_boot_console.run_command('bind /not-a-valid-node generic_simple_bus')
assert response != ''
- tree = u_boot_console.run_command("dm tree")
- assert "not-a-valid-node" not in tree
+ tree = u_boot_console.run_command('dm tree')
+ assert 'not-a-valid-node' not in tree
#try binding valid node with invalid driver
- response = u_boot_console.run_command("bind /bind-test not_a_driver")
+ response = u_boot_console.run_command('bind /bind-test not_a_driver')
assert response != ''
- tree = u_boot_console.run_command("dm tree")
- assert "bind-test" not in tree
+ tree = u_boot_console.run_command('dm tree')
+ assert 'bind-test' not in tree
#bind /bind-test. Device should come up as well as its children
- response = u_boot_console.run_command("bind /bind-test generic_simple_bus")
+ response = u_boot_console.run_command('bind /bind-test generic_simple_bus')
assert response == ''
- tree = u_boot_console.run_command("dm tree")
- assert in_tree(tree, "bind-test", "simple_bus", "generic_simple_bus", 0, True)
- assert in_tree(tree, "bind-test-child1", "phy", "phy_sandbox", 1, False)
- assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
+ tree = u_boot_console.run_command('dm tree')
+ assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
+ assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False)
+ assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
- response = u_boot_console.run_command("unbind /bind-test")
+ response = u_boot_console.run_command('unbind /bind-test')
assert response == ''
def get_next_line(tree, name):
treelines = [x.strip() for x in tree.splitlines() if x.strip()]
- child_line = ""
+ child_line = ''
for idx, line in enumerate(treelines):
- if ("-- " + name) in line:
+ if ('-- ' + name) in line:
try:
child_line = treelines[idx+1]
except:
@@ -111,68 +112,68 @@ def get_next_line(tree, name):
@pytest.mark.buildconfigspec('cmd_bind')
def test_bind_unbind_with_uclass(u_boot_console):
#bind /bind-test
- response = u_boot_console.run_command("bind /bind-test generic_simple_bus")
+ response = u_boot_console.run_command('bind /bind-test generic_simple_bus')
assert response == ''
#make sure bind-test-child2 is there and get its uclass/index pair
- tree = u_boot_console.run_command("dm tree")
- child2_line = [x.strip() for x in tree.splitlines() if "-- bind-test-child2" in x]
+ tree = u_boot_console.run_command('dm tree')
+ child2_line = [x.strip() for x in tree.splitlines() if '-- bind-test-child2' in x]
assert len(child2_line) == 1
child2_uclass = child2_line[0].split()[0]
child2_index = int(child2_line[0].split()[1])
#bind generic_simple_bus as a child of bind-test-child2
- response = u_boot_console.run_command("bind {} {} generic_simple_bus".format(child2_uclass, child2_index, "generic_simple_bus"))
+ response = u_boot_console.run_command('bind {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
#check that the child is there and its uclass/index pair is right
- tree = u_boot_console.run_command("dm tree")
+ tree = u_boot_console.run_command('dm tree')
- child_of_child2_line = get_next_line(tree, "bind-test-child2")
+ child_of_child2_line = get_next_line(tree, 'bind-test-child2')
assert child_of_child2_line
child_of_child2_index = int(child_of_child2_line.split()[1])
- assert in_tree(tree, "generic_simple_bus", "simple_bus", "generic_simple_bus", 2, True)
+ assert in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True)
assert child_of_child2_index == child2_index + 1
#unbind the child and check it has been removed
- response = u_boot_console.run_command("unbind simple_bus {}".format(child_of_child2_index))
+ response = u_boot_console.run_command('unbind simple_bus {}'.format(child_of_child2_index))
assert response == ''
- tree = u_boot_console.run_command("dm tree")
- assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
- assert not in_tree(tree, "generic_simple_bus", "simple_bus", "generic_simple_bus", 2, True)
- child_of_child2_line = get_next_line(tree, "bind-test-child2")
- assert child_of_child2_line == ""
+ tree = u_boot_console.run_command('dm tree')
+ assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
+ assert not in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True)
+ child_of_child2_line = get_next_line(tree, 'bind-test-child2')
+ assert child_of_child2_line == ''
#bind generic_simple_bus as a child of bind-test-child2
- response = u_boot_console.run_command("bind {} {} generic_simple_bus".format(child2_uclass, child2_index, "generic_simple_bus"))
+ response = u_boot_console.run_command('bind {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
#check that the child is there and its uclass/index pair is right
- tree = u_boot_console.run_command("dm tree")
+ tree = u_boot_console.run_command('dm tree')
treelines = [x.strip() for x in tree.splitlines() if x.strip()]
- child_of_child2_line = get_next_line(tree, "bind-test-child2")
+ child_of_child2_line = get_next_line(tree, 'bind-test-child2')
assert child_of_child2_line
child_of_child2_index = int(child_of_child2_line.split()[1])
- assert in_tree(tree, "generic_simple_bus", "simple_bus", "generic_simple_bus", 2, True)
+ assert in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True)
assert child_of_child2_index == child2_index + 1
#unbind the child and check it has been removed
- response = u_boot_console.run_command("unbind {} {} generic_simple_bus".format(child2_uclass, child2_index, "generic_simple_bus"))
+ response = u_boot_console.run_command('unbind {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
assert response == ''
- tree = u_boot_console.run_command("dm tree")
- assert in_tree(tree, "bind-test-child2", "simple_bus", "generic_simple_bus", 1, True)
+ tree = u_boot_console.run_command('dm tree')
+ assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
- child_of_child2_line = get_next_line(tree, "bind-test-child2")
- assert child_of_child2_line == ""
+ child_of_child2_line = get_next_line(tree, 'bind-test-child2')
+ assert child_of_child2_line == ''
#unbind the child again and check it doesn't change the tree
- tree_old = u_boot_console.run_command("dm tree")
- response = u_boot_console.run_command("unbind {} {} generic_simple_bus".format(child2_uclass, child2_index, "generic_simple_bus"))
- tree_new = u_boot_console.run_command("dm tree")
+ tree_old = u_boot_console.run_command('dm tree')
+ response = u_boot_console.run_command('unbind {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
+ tree_new = u_boot_console.run_command('dm tree')
assert response == ''
assert tree_old == tree_new
- response = u_boot_console.run_command("unbind /bind-test")
+ response = u_boot_console.run_command('unbind /bind-test')
assert response == ''
diff --git a/test/py/tests/test_dfu.py b/test/py/tests/test_dfu.py
index a24600376c..5d87eb349b 100644
--- a/test/py/tests/test_dfu.py
+++ b/test/py/tests/test_dfu.py
@@ -20,28 +20,28 @@ For example:
env__usb_dev_ports = (
{
- "fixture_id": "micro_b",
- "tgt_usb_ctlr": "0",
- "host_usb_dev_node": "/dev/usbdev-p2371-2180",
+ 'fixture_id': 'micro_b',
+ 'tgt_usb_ctlr': '0',
+ 'host_usb_dev_node': '/dev/usbdev-p2371-2180',
# This parameter is optional /if/ you only have a single board
# attached to your host at a time.
- "host_usb_port_path": "3-13",
+ 'host_usb_port_path': '3-13',
},
)
-# Optional entries (required only when "alt_id_test_file" and
-# "alt_id_dummy_file" are specified).
-test_file_name = "/dfu_test.bin"
-dummy_file_name = "/dfu_dummy.bin"
-# Above files are used to generate proper "alt_info" entry
-"alt_info": "/%s ext4 0 2;/%s ext4 0 2" % (test_file_name, dummy_file_name),
+# Optional entries (required only when 'alt_id_test_file' and
+# 'alt_id_dummy_file' are specified).
+test_file_name = '/dfu_test.bin'
+dummy_file_name = '/dfu_dummy.bin'
+# Above files are used to generate proper 'alt_info' entry
+'alt_info': '/%s ext4 0 2;/%s ext4 0 2' % (test_file_name, dummy_file_name),
env__dfu_configs = (
# eMMC, partition 1
{
- "fixture_id": "emmc",
- "alt_info": "/dfu_test.bin ext4 0 1;/dfu_dummy.bin ext4 0 1",
- "cmd_params": "mmc 0",
+ 'fixture_id': 'emmc',
+ 'alt_info': '/dfu_test.bin ext4 0 1;/dfu_dummy.bin ext4 0 1',
+ 'cmd_params': 'mmc 0',
# This value is optional.
# If present, it specified the set of transfer sizes tested.
# If missing, a default list of sizes will be used, which covers
@@ -49,7 +49,7 @@ env__dfu_configs = (
# Manually specifying test sizes is useful if you wish to test 4 DFU
# configurations, but don't want to test every single transfer size
# on each, to avoid bloating the overall time taken by testing.
- "test_sizes": (63, 64, 65),
+ 'test_sizes': (63, 64, 65),
# This value is optional.
# The name of the environment variable that the the dfu command reads
# alt info from. If unspecified, this defaults to dfu_alt_info, which is
@@ -57,17 +57,17 @@ env__dfu_configs = (
# One example is the Odroid XU3, which automatically generates
# $dfu_alt_info, each time the dfu command is run, by concatenating
# $dfu_alt_boot and $dfu_alt_system.
- "alt_info_env_name": "dfu_alt_system",
+ 'alt_info_env_name': 'dfu_alt_system',
# This value is optional.
- # For boards which require the "test file" alt setting number other than
+ # For boards which require the 'test file' alt setting number other than
# default (0) it is possible to specify exact file name to be used as
# this parameter.
- "alt_id_test_file": test_file_name,
+ 'alt_id_test_file': test_file_name,
# This value is optional.
- # For boards which require the "dummy file" alt setting number other
+ # For boards which require the 'dummy file' alt setting number other
# than default (1) it is possible to specify exact file name to be used
# as this parameter.
- "alt_id_dummy_file": dummy_file_name,
+ 'alt_id_dummy_file': dummy_file_name,
},
)
diff --git a/test/py/tests/test_efi_loader.py b/test/py/tests/test_efi_loader.py
index a66c6e6f94..d6b214f845 100644
--- a/test/py/tests/test_efi_loader.py
+++ b/test/py/tests/test_efi_loader.py
@@ -35,17 +35,17 @@ env__net_dhcp_server = True
# static IP. If solely relying on DHCP, this variable may be omitted or set to
# an empty list.
env__net_static_env_vars = [
- ("ipaddr", "10.0.0.100"),
- ("netmask", "255.255.255.0"),
- ("serverip", "10.0.0.1"),
+ ('ipaddr', '10.0.0.100'),
+ ('netmask', '255.255.255.0'),
+ ('serverip', '10.0.0.1'),
]
# Details regarding a file that may be read from a TFTP server. This variable
# may be omitted or set to None if TFTP testing is not possible or desired.
env__efi_loader_helloworld_file = {
- "fn": "lib/efi_loader/helloworld.efi",
- "size": 5058624,
- "crc32": "c2244b26",
+ 'fn': 'lib/efi_loader/helloworld.efi',
+ 'size': 5058624,
+ 'crc32': 'c2244b26',
}
"""
diff --git a/test/py/tests/test_fpga.py b/test/py/tests/test_fpga.py
index 7459ce5867..798f6eed3d 100644
--- a/test/py/tests/test_fpga.py
+++ b/test/py/tests/test_fpga.py
@@ -24,40 +24,40 @@ env__net_dhcp_server = True
# static IP. In this test case we atleast need serverip for performing tftpb
# to get required files.
env__net_static_env_vars = [
- ("ipaddr", "10.0.0.100"),
- ("netmask", "255.255.255.0"),
- ("serverip", "10.0.0.1"),
+ ('ipaddr', '10.0.0.100'),
+ ('netmask', '255.255.255.0'),
+ ('serverip', '10.0.0.1'),
]
# Details regarding the files that may be read from a TFTP server. .
env__fpga_secure_readable_file = {
- "fn": "auth_bhdr_ppk1_bit.bin",
- "enckupfn": "auth_bhdr_enc_kup_load_bit.bin",
- "addr": 0x1000000,
- "keyaddr": 0x100000,
- "keyfn": "key.txt",
+ 'fn': 'auth_bhdr_ppk1_bit.bin',
+ 'enckupfn': 'auth_bhdr_enc_kup_load_bit.bin',
+ 'addr': 0x1000000,
+ 'keyaddr': 0x100000,
+ 'keyfn': 'key.txt',
}
env__fpga_under_test = {
- "dev": 0,
- "addr" : 0x1000000,
- "bitstream_load": "compress.bin",
- "bitstream_load_size": 1831960,
- "bitstream_loadp": "compress_pr.bin",
- "bitstream_loadp_size": 423352,
- "bitstream_loadb": "compress.bit",
- "bitstream_loadb_size": 1832086,
- "bitstream_loadbp": "compress_pr.bit",
- "bitstream_loadbp_size": 423491,
- "mkimage_legacy": "download.ub",
- "mkimage_legacy_size": 13321468,
- "mkimage_legacy_gz": "download.gz.ub",
- "mkimage_legacy_gz_size": 53632,
- "mkimage_fit": "download-fit.ub",
- "mkimage_fit_size": 13322784,
- "loadfs": "mmc 0 compress.bin",
- "loadfs_size": 1831960,
- "loadfs_block_size": 0x10000,
+ 'dev': 0,
+ 'addr' : 0x1000000,
+ 'bitstream_load': 'compress.bin',
+ 'bitstream_load_size': 1831960,
+ 'bitstream_loadp': 'compress_pr.bin',
+ 'bitstream_loadp_size': 423352,
+ 'bitstream_loadb': 'compress.bit',
+ 'bitstream_loadb_size': 1832086,
+ 'bitstream_loadbp': 'compress_pr.bit',
+ 'bitstream_loadbp_size': 423491,
+ 'mkimage_legacy': 'download.ub',
+ 'mkimage_legacy_size': 13321468,
+ 'mkimage_legacy_gz': 'download.gz.ub',
+ 'mkimage_legacy_gz_size': 53632,
+ 'mkimage_fit': 'download-fit.ub',
+ 'mkimage_fit_size': 13322784,
+ 'loadfs': 'mmc 0 compress.bin',
+ 'loadfs_size': 1831960,
+ 'loadfs_block_size': 0x10000,
}
"""
diff --git a/test/py/tests/test_fs/conftest.py b/test/py/tests/test_fs/conftest.py
index 60b4a2d737..43eeb4be0b 100644
--- a/test/py/tests/test_fs/conftest.py
+++ b/test/py/tests/test_fs/conftest.py
@@ -54,7 +54,7 @@ def pytest_configure(config):
supported_fs = config.getoption('fs_type')
if supported_fs:
- print("*** FS TYPE modified: %s" % supported_fs)
+ print('*** FS TYPE modified: %s' % supported_fs)
supported_fs_basic = intersect(supported_fs, supported_fs_basic)
supported_fs_ext = intersect(supported_fs, supported_fs_ext)
supported_fs_mkdir = intersect(supported_fs, supported_fs_mkdir)
@@ -174,7 +174,7 @@ def tool_is_in_path(tool):
Return:
True if available, False if not.
"""
- for path in os.environ["PATH"].split(os.pathsep):
+ for path in os.environ['PATH'].split(os.pathsep):
fn = os.path.join(path, tool)
if os.path.isfile(fn) and os.access(fn, os.X_OK):
return True
@@ -202,9 +202,9 @@ def mount_fs(fs_type, device, mount_point):
check_call('guestmount -a %s -m /dev/sda %s'
% (device, mount_point), shell=True)
else:
- mount_opt = "loop,rw"
+ mount_opt = 'loop,rw'
if re.match('fat', fs_type):
- mount_opt += ",umask=0000"
+ mount_opt += ',umask=0000'
check_call('sudo mount -o %s %s %s'
% (mount_opt, device, mount_point), shell=True)
diff --git a/test/py/tests/test_mmc_rd.py b/test/py/tests/test_mmc_rd.py
index c5858cb089..a13bc0a5f6 100644
--- a/test/py/tests/test_mmc_rd.py
+++ b/test/py/tests/test_mmc_rd.py
@@ -14,45 +14,45 @@ which MMC devices should be tested. For example:
env__mmc_rd_configs = (
{
- "fixture_id": "emmc-boot0",
- "is_emmc": True,
- "devid": 0,
- "partid": 1,
- "sector": 0x10,
- "count": 1,
+ 'fixture_id': 'emmc-boot0',
+ 'is_emmc': True,
+ 'devid': 0,
+ 'partid': 1,
+ 'sector': 0x10,
+ 'count': 1,
},
{
- "fixture_id": "emmc-boot1",
- "is_emmc": True,
- "devid": 0,
- "partid": 2,
- "sector": 0x10,
- "count": 1,
+ 'fixture_id': 'emmc-boot1',
+ 'is_emmc': True,
+ 'devid': 0,
+ 'partid': 2,
+ 'sector': 0x10,
+ 'count': 1,
},
{
- "fixture_id": "emmc-data",
- "is_emmc": True,
- "devid": 0,
- "partid": 0,
- "sector": 0x10,
- "count": 0x1000,
+ 'fixture_id': 'emmc-data',
+ 'is_emmc': True,
+ 'devid': 0,
+ 'partid': 0,
+ 'sector': 0x10,
+ 'count': 0x1000,
},
{
- "fixture_id": "sd-mbr",
- "is_emmc": False,
- "devid": 1,
- "partid": None,
- "sector": 0,
- "count": 1,
- "crc32": "8f6ecf0d",
+ 'fixture_id': 'sd-mbr',
+ 'is_emmc': False,
+ 'devid': 1,
+ 'partid': None,
+ 'sector': 0,
+ 'count': 1,
+ 'crc32': '8f6ecf0d',
},
{
- "fixture_id": "sd-large",
- "is_emmc": False,
- "devid": 1,
- "partid": None,
- "sector": 0x10,
- "count": 0x1000,
+ 'fixture_id': 'sd-large',
+ 'is_emmc': False,
+ 'devid': 1,
+ 'partid': None,
+ 'sector': 0x10,
+ 'count': 0x1000,
},
)
"""
@@ -92,9 +92,9 @@ def test_mmc_rd(u_boot_console, env__mmc_rd_config):
response = u_boot_console.run_command(cmd)
assert 'no card present' not in response
if is_emmc:
- partid_response = "(part %d)" % partid
+ partid_response = '(part %d)' % partid
else:
- partid_response = ""
+ partid_response = ''
good_response = 'mmc%d%s is current device' % (devid, partid_response)
assert good_response in response
diff --git a/test/py/tests/test_net.py b/test/py/tests/test_net.py
index 2821ce65da..9c395e69fa 100644
--- a/test/py/tests/test_net.py
+++ b/test/py/tests/test_net.py
@@ -33,27 +33,27 @@ env__net_dhcp_server = True
# static IP. If solely relying on DHCP, this variable may be omitted or set to
# an empty list.
env__net_static_env_vars = [
- ("ipaddr", "10.0.0.100"),
- ("netmask", "255.255.255.0"),
- ("serverip", "10.0.0.1"),
+ ('ipaddr', '10.0.0.100'),
+ ('netmask', '255.255.255.0'),
+ ('serverip', '10.0.0.1'),
]
# Details regarding a file that may be read from a TFTP server. This variable
# may be omitted or set to None if TFTP testing is not possible or desired.
env__net_tftp_readable_file = {
- "fn": "ubtest-readable.bin",
- "addr": 0x10000000,
- "size": 5058624,
- "crc32": "c2244b26",
+ 'fn': 'ubtest-readable.bin',
+ 'addr': 0x10000000,
+ 'size': 5058624,
+ 'crc32': 'c2244b26',
}
# Details regarding a file that may be read from a NFS server. This variable
# may be omitted or set to None if NFS testing is not possible or desired.
env__net_nfs_readable_file = {
- "fn": "ubtest-readable.bin",
- "addr": 0x10000000,
- "size": 5058624,
- "crc32": "c2244b26",
+ 'fn': 'ubtest-readable.bin',
+ 'addr': 0x10000000,
+ 'size': 5058624,
+ 'crc32': 'c2244b26',
}
"""
diff --git a/test/py/tests/test_ums.py b/test/py/tests/test_ums.py
index e8eb43c76b..749b160623 100644
--- a/test/py/tests/test_ums.py
+++ b/test/py/tests/test_ums.py
@@ -23,35 +23,35 @@ For example:
# Leave this list empty if you have no block_devs below with writable
# partitions defined.
env__mount_points = (
- "/mnt/ubtest-mnt-p2371-2180-na",
+ '/mnt/ubtest-mnt-p2371-2180-na',
)
env__usb_dev_ports = (
{
- "fixture_id": "micro_b",
- "tgt_usb_ctlr": "0",
- "host_ums_dev_node": "/dev/disk/by-path/pci-0000:00:14.0-usb-0:13:1.0-scsi-0:0:0:0",
+ 'fixture_id': 'micro_b',
+ 'tgt_usb_ctlr': '0',
+ 'host_ums_dev_node': '/dev/disk/by-path/pci-0000:00:14.0-usb-0:13:1.0-scsi-0:0:0:0',
},
)
env__block_devs = (
# eMMC; always present
{
- "fixture_id": "emmc",
- "type": "mmc",
- "id": "0",
+ 'fixture_id': 'emmc',
+ 'type': 'mmc',
+ 'id': '0',
# The following two properties are optional.
# If present, the partition will be mounted and a file written-to and
# read-from it. If missing, only a simple block read test will be
# performed.
- "writable_fs_partition": 1,
- "writable_fs_subdir": "tmp/",
+ 'writable_fs_partition': 1,
+ 'writable_fs_subdir': 'tmp/',
},
# SD card; present since I plugged one in
{
- "fixture_id": "sd",
- "type": "mmc",
- "id": "1"
+ 'fixture_id': 'sd',
+ 'type': 'mmc',
+ 'id': '1'
},
)
diff --git a/tools/buildman/README b/tools/buildman/README
index 5a709c6ff9..56a99c70a2 100644
--- a/tools/buildman/README
+++ b/tools/buildman/README
@@ -1046,6 +1046,16 @@ value for 'altbootcmd', but lost one for ' altbootcmd'.
The -U option uses the u-boot.env files which are produced by a build.
+
+Building with clang
+===================
+
+To build with clang (sandbox only), use the -O option to override the
+toolchain. For example:
+
+ buildman -O clang-7 --board sandbox
+
+
Other options
=============
@@ -1169,8 +1179,6 @@ access to log files. Also it would be nice if buildman could 'hunt' for
problems, perhaps by building a few boards for each arch, or checking
commits for changed files and building only boards which use those files.
-A specific problem to fix is that Ctrl-C does not exit buildman cleanly when
-multiple builder threads are active.
Credits
=======
diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py
index c84ba6acf1..6b156f152d 100644
--- a/tools/buildman/builderthread.py
+++ b/tools/buildman/builderthread.py
@@ -156,7 +156,12 @@ class BuilderThread(threading.Thread):
if result.already_done:
# Get the return code from that build and use it
with open(done_file, 'r') as fd:
- result.return_code = int(fd.readline())
+ try:
+ result.return_code = int(fd.readline())
+ except ValueError:
+ # The file may be empty due to running out of disk space.
+ # Try a rebuild
+ result.return_code = RETURN_CODE_RETRY
# Check the signal that the build needs to be retried
if result.return_code == RETURN_CODE_RETRY:
@@ -224,6 +229,7 @@ class BuilderThread(threading.Thread):
config_args = ['%s_defconfig' % brd.target]
config_out = ''
args.extend(self.builder.toolchains.GetMakeArguments(brd))
+ args.extend(self.toolchain.MakeArgs())
# If we need to reconfigure, do that now
if do_config:
diff --git a/tools/buildman/cmdline.py b/tools/buildman/cmdline.py
index 93d09ca08d..832a5145d2 100644
--- a/tools/buildman/cmdline.py
+++ b/tools/buildman/cmdline.py
@@ -74,6 +74,8 @@ def ParseArgs():
parser.add_option('-o', '--output-dir', type='string',
dest='output_dir', default='..',
help='Directory where all builds happen and buildman has its workspace (default is ../)')
+ parser.add_option('-O', '--override-toolchain', type='string',
+ help="Override host toochain to use for sandbox (e.g. 'clang-7')")
parser.add_option('-Q', '--quick', action='store_true',
default=False, help='Do a rough build, with limited warning resolution')
parser.add_option('-p', '--full-path', action='store_true',
diff --git a/tools/buildman/control.py b/tools/buildman/control.py
index c900211510..27916d3c35 100644
--- a/tools/buildman/control.py
+++ b/tools/buildman/control.py
@@ -141,7 +141,7 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
no_toolchains = toolchains is None
if no_toolchains:
- toolchains = toolchain.Toolchains()
+ toolchains = toolchain.Toolchains(options.override_toolchain)
if options.fetch_arch:
if options.fetch_arch == 'list':
diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py
index c62ce136fa..a65737fdf8 100644
--- a/tools/buildman/toolchain.py
+++ b/tools/buildman/toolchain.py
@@ -54,9 +54,11 @@ class Toolchain:
arch: Architecture of toolchain as determined from the first
component of the filename. E.g. arm-linux-gcc becomes arm
priority: Toolchain priority (0=highest, 20=lowest)
+ override_toolchain: Toolchain to use for sandbox, overriding the normal
+ one
"""
def __init__(self, fname, test, verbose=False, priority=PRIORITY_CALC,
- arch=None):
+ arch=None, override_toolchain=None):
"""Create a new toolchain object.
Args:
@@ -68,6 +70,7 @@ class Toolchain:
"""
self.gcc = fname
self.path = os.path.dirname(fname)
+ self.override_toolchain = override_toolchain
# Find the CROSS_COMPILE prefix to use for U-Boot. For example,
# 'arm-linux-gnueabihf-gcc' turns into 'arm-linux-gnueabihf-'.
@@ -81,6 +84,8 @@ class Toolchain:
self.arch = arch
else:
self.arch = self.cross[:pos] if pos != -1 else 'sandbox'
+ if self.arch == 'sandbox' and override_toolchain:
+ self.gcc = override_toolchain
env = self.MakeEnvironment(False)
@@ -130,8 +135,8 @@ class Toolchain:
def GetWrapper(self, show_warning=True):
"""Get toolchain wrapper from the setting file.
"""
- value = ''
- for name, value in bsettings.GetItems('toolchain-wrapper'):
+ value = ''
+ for name, value in bsettings.GetItems('toolchain-wrapper'):
if not value:
print "Warning: Wrapper not found"
if value:
@@ -150,11 +155,18 @@ class Toolchain:
Args:
full_path: Return the full path in CROSS_COMPILE and don't set
PATH
+ Returns:
+ Dict containing the environemnt to use. This is based on the current
+ environment, with changes as needed to CROSS_COMPILE, PATH and
+ LC_ALL.
"""
env = dict(os.environ)
wrapper = self.GetWrapper()
- if full_path:
+ if self.override_toolchain:
+ # We'll use MakeArgs() to provide this
+ pass
+ elif full_path:
env['CROSS_COMPILE'] = wrapper + os.path.join(self.path, self.cross)
else:
env['CROSS_COMPILE'] = wrapper + self.cross
@@ -164,6 +176,22 @@ class Toolchain:
return env
+ def MakeArgs(self):
+ """Create the 'make' arguments for a toolchain
+
+ This is only used when the toolchain is being overridden. Since the
+ U-Boot Makefile sets CC and HOSTCC explicitly we cannot rely on the
+ environment (and MakeEnvironment()) to override these values. This
+ function returns the arguments to accomplish this.
+
+ Returns:
+ List of arguments to pass to 'make'
+ """
+ if self.override_toolchain:
+ return ['HOSTCC=%s' % self.override_toolchain,
+ 'CC=%s' % self.override_toolchain]
+ return []
+
class Toolchains:
"""Manage a list of toolchains for building U-Boot
@@ -180,10 +208,11 @@ class Toolchains:
paths: List of paths to check for toolchains (may contain wildcards)
"""
- def __init__(self):
+ def __init__(self, override_toolchain=None):
self.toolchains = {}
self.prefixes = {}
self.paths = []
+ self.override_toolchain = override_toolchain
self._make_flags = dict(bsettings.GetItems('make-flags'))
def GetPathList(self, show_warning=True):
@@ -234,7 +263,8 @@ class Toolchains:
priority: Priority to use for this toolchain
arch: Toolchain architecture, or None if not known
"""
- toolchain = Toolchain(fname, test, verbose, priority, arch)
+ toolchain = Toolchain(fname, test, verbose, priority, arch,
+ self.override_toolchain)
add_it = toolchain.ok
if toolchain.arch in self.toolchains:
add_it = (toolchain.priority <
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index 6cb1259446..ca580b45d4 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -461,7 +461,7 @@ class DtbPlatdata(object):
"""
struct_name, _ = get_compat_name(node)
var_name = conv_name_to_c(node.name)
- self.buf('static struct %s%s %s%s = {\n' %
+ self.buf('static const struct %s%s %s%s = {\n' %
(STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
for pname, prop in node.props.items():
if pname in PROP_IGNORE_LIST or pname[0] == '#':
diff --git a/tools/imx8image.c b/tools/imx8image.c
index 0d856b9d94..435f308b99 100644
--- a/tools/imx8image.c
+++ b/tools/imx8image.c
@@ -674,7 +674,7 @@ static int get_container_image_start_pos(image_t *image_stack, uint32_t align)
fclose(fd);
if (header.tag != IVT_HEADER_TAG_B0) {
- fprintf(stderr, "header tag missmatched \n");
+ fprintf(stderr, "header tag mismatched \n");
exit(EXIT_FAILURE);
} else {
file_off +=