Merge tag 'mips-pull-2019-11-16' of git://git.denx.de/u-boot-mips
authorTom Rini <trini@konsulko.com>
Fri, 18 Jan 2019 00:12:55 +0000 (19:12 -0500)
committerTom Rini <trini@konsulko.com>
Fri, 18 Jan 2019 00:12:55 +0000 (19:12 -0500)
- MIPS: mscc: various enhancements for Luton and Ocelot platforms
- MIPS: mscc: added support for Jaguar2 platform
- MIPS: optimised SPL linker script
- MIPS: bcm6368: fix restart flow issues
- MIPS: fixed CONFIG_OF_EMBED warnings for all MIPS boards
- MIPS: mt7688: small fixes and enhancements
- mmc: compile-out write support if disabled

150 files changed:
.travis.yml
MAINTAINERS
Makefile
arch/arm/dts/Makefile
arch/arm/dts/am335x-base0033.dts [new file with mode: 0644]
arch/arm/dts/am335x-igep0033.dtsi [new file with mode: 0644]
arch/arm/dts/am335x-sl50.dts [new file with mode: 0644]
arch/arm/dts/hi6220-hikey-u-boot.dtsi [new file with mode: 0644]
arch/arm/dts/hi6220-hikey.dts
arch/arm/dts/hi6220.dtsi
arch/arm/dts/mt7623.dtsi
arch/arm/dts/mt7623n-bananapi-bpi-r2.dts
arch/arm/dts/mt7629-rfb.dts
arch/arm/dts/mt7629.dtsi
arch/arm/dts/omap3-igep.dtsi [new file with mode: 0644]
arch/arm/dts/omap3-igep0020-common.dtsi [new file with mode: 0644]
arch/arm/dts/omap3-igep0020-u-boot.dtsi [new file with mode: 0644]
arch/arm/dts/omap3-igep0020.dts [new file with mode: 0644]
arch/arm/include/asm/arch-hi3798cv200/hi3798cv200.h
arch/arm/include/asm/arch-mediatek/reset.h [new file with mode: 0644]
arch/arm/lib/bootm.c
arch/riscv/config.mk
arch/riscv/cpu/ax25/cache.c
arch/riscv/lib/cache.c
arch/riscv/lib/interrupts.c
arch/sandbox/config.mk
arch/sandbox/cpu/sdl.c
arch/sandbox/dts/sandbox.dts
arch/sandbox/dts/sandbox64.dts
arch/sandbox/dts/test.dts
arch/sandbox/include/asm/io.h
arch/x86/lib/acpi_table.c
board/hisilicon/poplar/poplar.c
board/isee/igep00x0/Kconfig
board/isee/igep00x0/MAINTAINERS
cmd/adc.c
cmd/dtimg.c
cmd/gpio.c
cmd/help.c
cmd/mmc.c
cmd/mtd.c
cmd/nvedit.c
cmd/sf.c
cmd/tpm-v2.c
cmd/ubi.c
cmd/unzip.c
cmd/zip.c
common/Kconfig
common/bootm.c
common/command.c
common/fdt_support.c
common/image-fdt.c
common/spl/spl_ymodem.c
common/xyzModem.c
configs/am335x_igep003x_defconfig
configs/am335x_sl50_defconfig
configs/am57xx_evm_defconfig
configs/hikey_defconfig
configs/igep0032_defconfig [deleted file]
configs/igep00x0_defconfig
configs/mt7623n_bpir2_defconfig
configs/mt7629_rfb_defconfig
configs/poplar_defconfig
configs/sandbox_defconfig
configs/stm32f429-discovery_defconfig
configs/stm32f429-evaluation_defconfig
configs/stm32f469-discovery_defconfig
configs/stm32h743-disco_defconfig
configs/stm32h743-eval_defconfig
doc/driver-model/fs_firmware_loader.txt
drivers/block/blkcache.c
drivers/clk/mediatek/clk-mt7623.c
drivers/clk/mediatek/clk-mt7629.c
drivers/clk/mediatek/clk-mtk.h
drivers/core/dump.c
drivers/i2c/Kconfig
drivers/i2c/Makefile
drivers/i2c/i2c-cdns.c
drivers/i2c/muxes/i2c-mux-uclass.c
drivers/i2c/muxes/pca954x.c
drivers/i2c/xilinx_xiic.c [new file with mode: 0644]
drivers/misc/fs_loader.c
drivers/mmc/hi6220_dw_mmc.c
drivers/mmc/mmc.c
drivers/mtd/nand/raw/Kconfig
drivers/mtd/nand/raw/nand_base.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/mtk_eth.c [new file with mode: 0644]
drivers/net/mtk_eth.h [new file with mode: 0644]
drivers/net/sandbox-raw.c
drivers/reset/Kconfig
drivers/reset/Makefile
drivers/reset/reset-mediatek.c [new file with mode: 0644]
drivers/serial/Kconfig
drivers/serial/ns16550.c
drivers/serial/serial-uclass.c
dts/Makefile
env/common.c
env/sf.c
examples/standalone/Makefile
examples/standalone/riscv.lds [deleted file]
examples/standalone/stubs.c
fs/fs.c
include/command.h
include/common.h
include/configs/hikey.h
include/configs/mt7623.h
include/configs/mt7629.h
include/configs/omap3_igep00x0.h
include/configs/qemu-riscv.h
include/dt-bindings/reset/mtk-reset.h [new file with mode: 0644]
include/fs_loader.h
include/lmb.h
include/log.h
include/regmap.h
include/serial.h
lib/Makefile
lib/efi_loader/efi_file.c
lib/fdtdec.c
lib/lmb.c
lib/uuid.c
net/tftp.c
post/lib_powerpc/fpu/Makefile
scripts/Kbuild.include
scripts/Makefile.build
scripts/Makefile.lib
scripts/dtc/pylibfdt/Makefile
test/dm/Makefile
test/dm/bootcount.c [new file with mode: 0644]
test/dm/regmap.c
test/dm/serial.c
test/lib/Makefile
test/lib/lmb.c [new file with mode: 0644]
test/py/tests/test_avb.py
test/py/tests/test_bind.py
test/py/tests/test_dfu.py
test/py/tests/test_efi_loader.py
test/py/tests/test_fpga.py
test/py/tests/test_fs/conftest.py
test/py/tests/test_mmc_rd.py
test/py/tests/test_net.py
test/py/tests/test_ums.py
tools/buildman/README
tools/buildman/builderthread.py
tools/buildman/cmdline.py
tools/buildman/control.py
tools/buildman/toolchain.py
tools/dtoc/dtb_platdata.py
tools/imx8image.c

index 321fd793a756df98a9188f453c07570ac955c5c3..fc4d5a1d5ccc30c78f53301ede12aa08ee73c94f 100644 (file)
@@ -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"
index 3fa5d3e96f5cac7c367890054c644efe888c414b..399a839e071306fc357d6b786e7c2eca498e801a 100644 (file)
@@ -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
index 6aa08964fff47274f6d4b54343e5071a78eaffa4..3be9fc5c340c0f549389db7e8876aa7de0d7f39d 100644 (file)
--- 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
index dda4e594914b009b2a50697d96a1a3c288769dde..b2ca87deefd9026894821a2113c1794ba5e3574d 100644 (file)
@@ -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 (file)
index 0000000..29782be
--- /dev/null
@@ -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 (file)
index 0000000..a5769a8
--- /dev/null
@@ -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 (file)
index 0000000..1bcc604
--- /dev/null
@@ -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 (file)
index 0000000..3113983
--- /dev/null
@@ -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;
+};
index 24f09257af00ebd451de67b10468aa13a9dbbaa8..d63929348bb30b04fe613b6d51669fab84560615 100644 (file)
        };
 };
 
+&mmc0 {
+       status = "okay";
+       non-removable;
+       bus-width = <8>;
+};
+
+&mmc1 {
+       status = "okay";
+       bus-width = <4>;
+};
+
 &uart2 {
        label = "LS-UART0";
 };
index a610ccb63463ccbbb2bf58ada4edf8f1796c71c2..501c8906fd61d38fbc5941f3be67a25bdcc1252f 100644 (file)
                        #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>;
index f50f4ef1b92f62bb1ea28bdd33e1a43acbae9abb..448d1d73810e549bc7c02fb6cadc7d759b315187 100644 (file)
@@ -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"
 
 / {
        };
 
        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";
        };
 };
index 84a77fde443a8ed050cf5522fc1332568044174c..51628bb63995b78f7082217491d8c85668aad9b2 100644 (file)
        };
 };
 
+&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>;
index a6d28a060f3a79ec58e44ac899220ccd4a26e30f..95d10aa6d324fa37266f5e8c562d6ca2cd37e1ae 100644 (file)
        };
 };
 
+&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 {
index e6052bbdcf3e5ef92639bcfd8f1dbe94daa7255a..c87115e0fe4ce382fbfce1077f51df627c465173 100644 (file)
@@ -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"
 
 / {
                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 (file)
index 0000000..f33cc80
--- /dev/null
@@ -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 (file)
index 0000000..ecbec23
--- /dev/null
@@ -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 (file)
index 0000000..41beaf0
--- /dev/null
@@ -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 (file)
index 0000000..33d6b4e
--- /dev/null
@@ -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;
+};
index f97b1eb29f841d7bc5cf930cc3d0c871813891d6..bb221e17e0ed9efa82774ebfedc1734b518f4cdd 100644 (file)
 /* 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 (file)
index 0000000..9704666
--- /dev/null
@@ -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 */
index c3c1d2fdfa2d8ab9d4eacd4a8218f3455fe3a8fc..329f20c2bfe50e2a466d41839bf35da9e47ed64d 100644 (file)
@@ -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;
        }
 }
index ff4fe6400170c4adbab8ceec7e76871af30c8d77..84654eb3ed87e72a153f43ee3831377f323f0755 100644 (file)
@@ -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 \
index 8d6ae170b8c5a02463c14f6a0e7eacc28a40eab4..228fc55f56bc9bf9667a400474d87c66e1e8d2e4 100644 (file)
@@ -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
index ae5c60716ffdd82742dc783095eebd54a0dde7eb..5437a122a100480881b3c66f8e1c24cf12eb3a58 100644 (file)
@@ -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)
index e185933b01ef04cde12988058d137dda9bd363cd..74c1e561c713b04c456ff2cade618817ad805c10 100644 (file)
@@ -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();
index 7226b7be4286dcc24863c0afad76a1eebe3b3499..31a12db103d77259c32c2f6cba4d0e0d178a7af2 100644 (file)
@@ -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 \
index f668f5379a4d648dc0cba4586da8ec72e93e2252..080c7c8d74d21dcf892e8aec7748823cf350f9ed 100644 (file)
@@ -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>
 
 /**
index ae3189ec8cfad3d5d1b35fa150d4706613b26c44..a41b5f052d7b47a7e845cfc421305c399f6d5f68 100644 (file)
                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>;
                };
 
                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";
                        };
                };
index d30fd62a2a489d7c34b49811d2b8c045d44143e2..a3c95f2cdb2173899dd250f34c86df2a2e340d6a 100644 (file)
                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>;
                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";
                        };
                };
index 3790b4c5208e96f7e3dc4c2a0a0b0e06bd9e0004..1d011ded7cc0ec3bb79c8a17a7d81de9db3cd824 100644 (file)
                };
        };
 
+       bootcount@0 {
+               compatible = "u-boot,bootcount-rtc";
+               rtc = <&rtc_1>;
+               offset = <0x13>;
+       };
+
        adc@0 {
                compatible = "sandbox,adc";
                vdd-supply = <&buck2>;
index 81b77506286d26a208aaa9cd1b71849a4bf9be84..2a350a826c4bc240a61479273f0cb1fc43c4e90a 100644 (file)
@@ -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)
 
index 79bc2000bdaa14df5370681e498d2a957bb670f0..04058a60d75eb59c20dce160cf751cb11f9b8ad9 100644 (file)
@@ -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);
index 8adc750962a10f35626d778eb31394bc98ed3223..155dfbb401f1239bedb5807db263ca84b0346d25 100644 (file)
@@ -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();
index aa46882b051da2b90374e37f06cb6cafe69b9796..597d6d92cfe1c8ea86cb4a4735b4944ba83c9e83 100644 (file)
@@ -9,4 +9,6 @@ config SYS_VENDOR
 config SYS_CONFIG_NAME
        default "omap3_igep00x0"
 
+source "board/ti/common/Kconfig"
+
 endif
index d75d400eed0285099fe2159bf6dca25323d63226..a07c9f49a8545390928905d592a9a9100a969759 100644 (file)
@@ -4,4 +4,3 @@ S:      Maintained
 F:     board/isee/igep00x0/
 F:     include/configs/omap3_igep00x0.h
 F:     configs/igep00x0_defconfig
-F:     configs/igep0032_defconfig
index 2d635acbd950d0261f43a10b436911dda387380d..381961cf51a41f2959c8148a1fb21bb169b50f04 100644 (file)
--- 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));
index 65c8d101b98ecd3b3ee7458483857ad744533f2d..ae7d82f26dd2880d3ac9d15998fbd760edc25dcf 100644 (file)
@@ -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);
index ecdc453918f48e1e9390b20f21a8010530315f97..c60946bc06934cdf71d03029dd5a4121993a8b3c 100644 (file)
@@ -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
index 503fa632e74eb2da30585cc7d45cf645b6faca61..fa2010c67eb1379eedc1c5d85dc580f030039f7f 100644 (file)
@@ -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
        ""
index 3920a1836a594903116841f809676f34ff022061..8bc3648193cf33a26d0376867cad5dfc3028bd22 100644 (file)
--- 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) {
index 6142223984672a1dc1afa457dcdae0d12b2065c9..cda702d18b1636c6ec1ae3af0c599a85e1e45c0b 100644 (file)
--- a/cmd/mtd.c
+++ b/cmd/mtd.c
 #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));
index de16c72c23f2eab154265b9dbed54181645bf77a..ebaa16b75459abc5ae1409adddaa6d40c83cf85a 100644 (file)
@@ -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;
        }
index 84bb0575f233892e22f8cb9162cbde2cc5a22f8e..738ef0e46dc14fde1ae1550b0873a2a818b7abb6 100644 (file)
--- 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);
 }
index bb51834c478895657ae11c305b38cd29186e3185..459a955d2907394cfec1df03a8c86d12af2c8f39 100644 (file)
@@ -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);
        }
 
index a12ac703ebe54ffe840d0452589f16ee2fe1ff20..c511a2fb7601f8d49b2a4353b48f289f04d23770 100644 (file)
--- 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;
index f7aabf72d1e73ae64c5255adf8299bac3aeb45da..6c0f97cb4bb5d6fe1d6c456d7f3ea5b538d518a1 100644 (file)
@@ -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;
index d105d84e380c6c36c84e50eb5e999d8af8a0dcf2..9cd400a7e80f2053edfa7054a164b44c971ebf90 100644 (file)
--- 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;
index 57bd16d9623c091196d102f0405df040603b5d78..2c017df4087ca9f666a588d4ce2b3f4e5389ee00 100644 (file)
@@ -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"
index 8bf84ebcb7e82e798f1a718625e2938e1b773bd4..a4618b6d2e176cd4dc46a828299c697af79bfc1f 100644 (file)
@@ -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
index 2433a89e0a8e10f3098eb453e25db33f574436f5..e14d1fa1d6b4c4425f9c5b74e65ada06a67524b5 100644 (file)
@@ -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);
index 3440e42a257b203d8e8f3255206c39eaf63118e5..42583e3ed8c895d5b2b081bccc846be48d17bde4 100644 (file)
@@ -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;
index 95748f0ae108035cc71845d2d7d99e7ff2118115..5988808f1872c6e0c84520f56e55e29857e0ea26 100644 (file)
@@ -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:
index 3b1bd71bda0cdc0ca3c30ed5204e5708d882e9b7..577fdc69afe08078cec7a0386dd06d9f53bf50c9 100644 (file)
@@ -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);
index e5c65b480a2b64837f18b41cfef3c59aa74a40bd..e85da74a698f373c837987228f2a99b4a318a136 100644 (file)
@@ -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)
index 186c65f0bf662ca0b58c0f2556070b3066d43ba6..0a8feadc753f61d44fbe92fe07ab43f5e91344ae 100644 (file)
@@ -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
index 822f73d114283ae989d073e464d2e13c68e1a5dc..8c622471da829a7593d438753459629848e6a2a9 100644 (file)
@@ -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
index 91293daee7ed2310eb4cfb83262d6cf3d9071eb7..51dedc6111ce4dd34430305648600528acdf54ea 100644 (file)
@@ -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
index 3bc5ceb5d8c7afbc40e3558242c9f4d2deffec77..e9a9857322b02a7eb8f5e6265a5b2b780211b2d4 100644 (file)
@@ -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 (file)
index 20d2cf5..0000000
+++ /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
index 330350c32acec80e06ee002ffe3298cb32f22151..efd8519d1416fdc19c4fc9817969772c2830d474 100644 (file)
@@ -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
index ae4fb280dc4efc76c10179d4a922968680e06650..8cb490732692a8f9c25213952d9bd7c817bed4d7 100644 (file)
@@ -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
index 1729d13c3d38b93741393f0b672adbadb9583cd3..1da9932dcd93cc9ae270622c186c6df33a1d2ef0 100644 (file)
@@ -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
index 239783a5926942129d80e514020fc439b486aada..81bd3702e42ad8bd7fd094c8e3e3a5bff6fbce63 100644 (file)
@@ -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
index 90146f64cd1e9f556874f384fbcf7e0be23bdb12..78a684b5ec42312372191c39da4e3215d4377d1d 100644 (file)
@@ -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
index ef0f6f7373dd988283c849c6b6afbd268e4d79b5..265b1ec06826b54e8a529bee9c9e25bb1f9e13b2 100644 (file)
@@ -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
index 6a2ed2a9b06e035b0a022de7f5bb50a57a7731e3..9f1a7680ad08da3837992624ba4172fac569981f 100644 (file)
@@ -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
index 0b36c0fc5838522d1ea8c66ce1d22e842e6400b1..801af6bb618a6009076dd1205ee72cd446ca3b0e 100644 (file)
@@ -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
index 92d21d180b6419196cdd328c1d4f40ae39b50cf1..5460ad029a39ed8ed600d5d59f7b1665566dc425 100644 (file)
@@ -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
index c08363d1368065ee0058e34dd61c064c02a8cc2f..2884c96648dcb590d35756689898d7f6814f2a0e 100644 (file)
@@ -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
index 290915a9598818ba31291b10781aa2dc4fe45f01..b9aee848cc5eecdcbe937a8156a9acba7669161a 100644 (file)
@@ -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
index 294511fcdb596796e9f3418734eee6822aa62a9b..1fa64989d3f2fcc5c9e0b3e6991f72b1fc5d96d5 100644 (file)
@@ -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
 };
 
index c6b09d8e18dce994882dc1c69e4a9ff0066a714c..87ad4f79ced8e1d994aed6a9bc0c3ad2d4cdf555 100644 (file)
@@ -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,
 };
index 2601b6cf30daf418287f3104ffbb40d9f0d15b48..6a9f60139c024f4b4c446cf2853862492f6b8b65 100644 (file)
@@ -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,
 };
index 74152ed9c6e19f7b090eed45a45c7ee977fbcded..7847388b2a10e0bc297cf88cc14b05199bff49ff 100644 (file)
@@ -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;
index 04217cbde876b34ef2925fd49a0581ff317a0176..8fbfd93fb5e4ef5e79657e5c702404aef012ab70 100644 (file)
@@ -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);
        }
index 1ef22e6bcde2ffcefef7b3ba07118558f5e9af32..7579eb8755cb770666008157e452d879f122eafe 100644 (file)
@@ -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.
 
index d3637bcd8d65745c9c73b479119da4fe5392e324..ec2d1964c32eba6c2d9656d262604d9b407e022f 100644 (file)
@@ -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
 
index 30be173343dd7ba03a8e7b4fe613eb0353888a60..f2c4b2073c48aa552c3679dd3902c20ca5ca7db7 100644 (file)
@@ -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;
 }
index 10336919adb556ba15290e268aad5c6187d5ffa4..a680ee1762539acb8e542f8c9bc7a5d01f3a9c46 100644 (file)
@@ -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;
index ab8b4000afbc6ac65e8d3aee14adc5d072038ca0..bd4e9abe5f3c0ca6d913aed522e3dcc868ff6e25 100644 (file)
@@ -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 (file)
index 0000000..83114ed
--- /dev/null
@@ -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,
+};
index baa5f8302aeb8c050cbbdacf819fc3e02e095e8d..57a14a3479a39bf0b6f9282e545e54788660da55 100644 (file)
 
 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) = {
index ce395d53c9421a592102c375ae09cc5b99629ca5..cc58aff38cc415db07f6330111a040251a8c5ebc 100644 (file)
@@ -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),
+};
index d8581271321228d0634cdec5e5df31ffcc922a6c..84d157ff4033518f98073ed9d5f094bf85ce1811 100644 (file)
@@ -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;
 
index fd1723fedadfea17fdf3067c09a75ba740931b64..ffc6cc98aa024b613bb73b4fbb7bf493ee5e806c 100644 (file)
@@ -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
index 92daebe120bffb496e0d6614a5921c8d3a75f358..6d2ff58d86a557a1f64ad01f3385f6c033d5c5d0 100644 (file)
@@ -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);
index 7044c6adf3273985b0675d79094c15830955bb73..ff55e03d3fd22ba98d5ffcd6ec185b1bada60c22 100644 (file)
@@ -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
index 0dbfa0330688402318b3a4d03f82e7abac8a6c37..ee7f3e71a8dda6f99bca20c2834156dfa327aeb2 100644 (file)
@@ -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 (file)
index 0000000..cc09404
--- /dev/null
@@ -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 (file)
index 0000000..fe89a03
--- /dev/null
@@ -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_ */
index 09cc678ebde72657c3f6e51b631c8dcad2b8bd57..7e6625d0202fcf074a1706705d4e4c0a2915af59 100644 (file)
@@ -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;
 }
index 9c5208b7da52d03d9cde0d0338e06ae338e2c7ab..3a6d61f440cda46cb80d16c67757666552d4be99 100644 (file)
@@ -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
index f4520878b7c7878c82b7bd1c91ccd446fd8141e8..8a4dcab8f6472d39eb5b80c32581f5167464499a 100644 (file)
@@ -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 (file)
index 0000000..e3614e6
--- /dev/null
@@ -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),
+};
index b7ff2960abfef26787c3bbb1b53dc5deb7647413..887cd687c027dbbe59820f239ddeb43d01f0c2c0 100644 (file)
@@ -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
index 560ca2ae349b4314911d6636f2d2c3dd9d358c0b..6cf2be8f2b892eb0fd7cfea13ddf825b4380724b 100644 (file)
@@ -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);
 }
 
index ffcd6d15af2b07049fc5973a68c4478b2fc510ce..d4488a2cc288a55c977825a4c92d575388e9a41f 100644 (file)
@@ -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;
 }
index cd6e9a968eec8c14c521d268c0023635298bdf53..a7a604303cc63ae836b8c4c16635514c24e6c3ef 100644 (file)
@@ -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
index 3317cef3552264cae2870df6ad1cedaa0096fb75..d1a6a5286013a6669f1b8c69e1fa4425a941714e 100644 (file)
@@ -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;
index 23cbad5d8885c54168237dc8fcb14b719faeb4ad..b3dec82c353afea75ef183145c689b34560445e2 100644 (file)
--- 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;
        }
 
index f01816f24f4a3851f1c9e1eada5a1fe42b75e430..0b17a91804cf7fdd0f0e3f4e9361295d463bfdc7 100644 (file)
@@ -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 (file)
index 9a25861..0000000
+++ /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 = .;
-}
index fadde669fa94ff185b97d594427d3072a73006f5..0827bde35e581b27b9b7d081fef35ae296c4f698 100644 (file)
@@ -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 cb265174e2f2eb446bd6003903cb1e1408aa6f4e..7fd22101efe657b72b48c472a4d9dd100c4aedc9 100644 (file)
--- 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;
index 200c7a5e9f4ed90e05474e69f7437f703e60e8c4..461b17447c0dc23d9f1cdf4839dee0b281977eea 100644 (file)
 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 */
index 657cc404cfaf3335fa206b1c1158ba39da19529b..2c21dee8505cf6ba0d2c3815fe1ef2362e9e60f0 100644 (file)
@@ -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);
index 1376d6155deca5cc0b84d924900acdbfd8c774eb..572a52fad597e95e319ec2bb7f885668d5e747db 100644 (file)
@@ -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 */
index ba763501cf2eb0cdaa88efaf1ded7e22f0b147bd..5129c83da8fd7a2ece14a8c696f99249c7bb0036 100644 (file)
@@ -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
index a665a5eb7f2b546f60249060472953d5d22214de..9910d8c89a6afa6d497054b3ba11b6d92f2e197f 100644 (file)
@@ -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
index 775374cf2888ea196fb25700b0af0c0cf7272aa5..521e1675e0ef7cac6509ad0e5404c61c5b3b366d 100644 (file)
 #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 */
index b29d155d095c4704655ba9c974329fee8c169a52..2588c5a0b25d917f5f37a003bec7d298d59837cc 100644 (file)
@@ -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 (file)
index 0000000..5f0a74f
--- /dev/null
@@ -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_ */
index 0be4f17e6320d8385650f4921c20d2536e92dfbf..b728c06fcff3eaa5c990a6437358ef6684d57736 100644 (file)
@@ -8,21 +8,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
  *
@@ -52,28 +37,19 @@ struct device_platdata {
        char *ubivol;
 };
 
-/**
- * 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
index f04d058093785615d7e93e76f0a188defda537db..1bb003e35e877cbe5bcb8acdd6ec50e9ed21149c 100644 (file)
@@ -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);
 
index 0f2bc19477fc868d0682009265ea5e8cb33a2d38..d7f647100618c3a568ff15295158f75eff16cb6f 100644 (file)
@@ -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
index a3afb72df51b2250cd1eaaf2a38b56da5dee16aa..8359c511d25f77e6cacd99b2da066f9d485b40d7 100644 (file)
@@ -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
  *
index c1a9fee250e93456b25138d6a6966e81c94a2b8d..c1368c68b6473bee38e19d766d08324185b3fa47 100644 (file)
@@ -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);
index a6dd928a9265f1a823965edb54095d968730b97a..61d7ff06783ed2bfd47a7e33aa52151fef441c12 100644 (file)
@@ -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
index 128cb0a6273a688e0359845826741a2024e7ada5..8a4f3a9f408b0e7b894ead59244485c6536db9c1 100644 (file)
@@ -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) {
index 6f8ec0dbed7dae2857b8320b9ec0f1af47b01e01..18663ce6bdac4ba37ed6863ec8f01ac4756b44ea 100644 (file)
@@ -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");
index 170541734869c52e47c32b23c7c353b3ec01cd6c..3407705fa7030029baf97d03cf5beec1eb9187c5 100644 (file)
--- 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;
index 5d5adf6b2dfcf90f7794a14fbffd251d712deae0..fa20ee39fc3205e24b77f6faf86b5960b1ae0560 100644 (file)
@@ -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];
index 68ffd814146c8ded1ec8c613980f4c2d45ba8f2c..a9335b1b7e0b2a20ccb0757e5c3b81edc7e1a2c2 100644 (file)
@@ -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");
 
index 404eefcfd0f4bd2e9c23214d29b877ddd5b64a2b..9b2c1fadb654efa2519f17c2bd0b6c862dfc3100 100644 (file)
@@ -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
index 13ebddda65c8672f6e211f4fa737a88deae115f9..b8969e2a75e61f1d1a62ed34aa2ad956aa9ca46e 100644 (file)
@@ -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)
index 482ed0c8d80482c8bbf81e7a46adbfd2c96c9e9a..f7a041296d3d9972d3a9a933c1dd0267f4b3aa9c 100644 (file)
@@ -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)
 
index a4f16bb4bb5bb744cf323533140d982315220f3f..a5b57fc6b98a7c16116fd89d4bde9f32de7b3a29 100644 (file)
@@ -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)
 
index c769d7db062c4f49c27428cadd5323005b2625f3..15e66ad44d76004f15f08d014ed03a5d101e14e2 100644 (file)
@@ -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)
index 7dc80be25e366c820d9866e88ad5f5ec4f5cd940..1b089960cbbc8bfb589286423cee36e585934be4 100644 (file)
@@ -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 (file)
index 0000000..0817b7d
--- /dev/null
@@ -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);
+
index 9a70c159ddb9e9b4eec49f2c40088002c9cca667..82de295cb8f651940876d58867f1423b4fd436fc 100644 (file)
@@ -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));
 
index 19a15d5d95235d21f82cbbae3cf796dba7bcdc91..3d741a8c363cd38d37046582bcb66876e9e50602 100644 (file)
@@ -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)));
 
index ea68fae566f928898099c18fa44a7e0037cfef1b..5a636aac740200d64494ab9779e4d255c1b2df19 100644 (file)
@@ -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 (file)
index 0000000..058d3c3
--- /dev/null
@@ -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);
index 9683fd80d0744f65d50e2ebc8805f6e43fc9ab06..e70a010c9ac018439746c915a0b966c4f0ed4579 100644 (file)
@@ -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')
index dee3fee56619a24d7e72e1d24424c3e0ca26d5c7..ccf6d62ea8acf23e5fac4acda029288f75609a31 100644 (file)
@@ -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 == ''
index a24600376cb73e663d43dd40bc8d44f9daf6cf45..5d87eb349bf4d9d7925154c0cf4be64b82c93b92 100644 (file)
@@ -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,
     },
 )
 
index a66c6e6f947c7fb5319cff985eff44e266c7b4c4..d6b214f845279ca703c6e6f1e01110dc3e98bb2a 100644 (file)
@@ -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',
 }
 """
 
index 7459ce5867403920d87407a6fcb80446a57922e5..798f6eed3dc941b7451f0bdcdcf2414d5d0c8d7f 100644 (file)
@@ -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,
 }
 """
 
index 60b4a2d737b968070b4f3a6331d29eb6ef497399..43eeb4be0baf0a7b127996782d5a570b7874c3fd 100644 (file)
@@ -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)
index c5858cb0892c6684d82070aa810121a8d5c00d04..a13bc0a5f6089ec9ad168e3a9d9347ae800732bd 100644 (file)
@@ -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
 
index 2821ce65da80c1b4efb3b6886af5386cb5ed4d02..9c395e69fafb5ab48c494bc9c3e37791b268d7e3 100644 (file)
@@ -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',
 }
 """
 
index e8eb43c76b7c5b3cf531b4ac7cd2067042d5e086..749b1606235c78e88e84b311f636657e08a4fb60 100644 (file)
@@ -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'
     },
 )
 
index 5a709c6ff9e3b5ea270b1890dd3d02e0e1b87b20..56a99c70a2ac129c11297a53aa60a136c17bab1c 100644 (file)
@@ -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
 =======
index c84ba6acf11a64a611ae2e7a8d209391da38ccd3..6b156f152de514d20aed4b1be9a9e783d3c4a8d4 100644 (file)
@@ -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:
index 93d09ca08d739f915912c1fdb609446d65b0b44f..832a5145d28429675e851bec32d35c27d71f9f42 100644 (file)
@@ -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',
index c900211510e42ef5d15e4f93f7c2b6a33f83c261..27916d3c355daad98451bc5bd88fc31b313bdab9 100644 (file)
@@ -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':
index c62ce136fa1fc6da4c9d652ab62f8313e8bee813..a65737fdf84b586e04791b8c9e8b5c507c68effe 100644 (file)
@@ -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 <
index 6cb125944660ca090e224b35b94a4bbf9c4981bf..ca580b45d4a25f3da9390569b5f46d6a56846ecb 100644 (file)
@@ -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] == '#':
index 0d856b9d94f967d8549589d21302e13ad221497f..435f308b99e0ea481e0deba07c63937c10499fff 100644 (file)
@@ -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 +=