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