diff options
286 files changed, 12018 insertions, 5132 deletions
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index d476d8d0e9..862cced1cc 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -1,7 +1,7 @@ variables: windows_vm: vs2015-win2012r2 ubuntu_vm: ubuntu-18.04 - ci_runner_image: trini/u-boot-gitlab-ci-runner:bionic-20190912.1-03Oct2019 + ci_runner_image: trini/u-boot-gitlab-ci-runner:bionic-20191010-20Oct2019 # Add '-u 0' options for Azure pipelines, otherwise we get "permission # denied" error when it tries to "useradd -m -u 1001 vsts_azpcontainer", # since our $(ci_runner_image) user is not root. @@ -245,11 +245,6 @@ jobs: git clone --depth=1 git://github.com/swarren/uboot-test-hooks.git /tmp/uboot-test-hooks ln -s travis-ci /tmp/uboot-test-hooks/bin/`hostname` ln -s travis-ci /tmp/uboot-test-hooks/py/`hostname` - virtualenv /tmp/venv - . /tmp/venv/bin/activate - pip install pytest==2.8.7 - pip install python-subunit - pip install coverage grub-mkimage --prefix=\"\" -o ~/grub_x86.efi -O i386-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd grub-mkimage --prefix=\"\" -o ~/grub_x64.efi -O x86_64-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd mkdir ~/grub2-arm @@ -266,8 +261,11 @@ jobs: exit $ret; fi; fi + virtualenv -p /usr/bin/python3 /tmp/venv + . /tmp/venv/bin/activate + pip install -r test/py/requirements.txt export UBOOT_TRAVIS_BUILD_DIR=/tmp/.bm-work/${TEST_PY_BD}; - export PATH=/opt/qemu/bin:/tmp/uboot-test-hooks/bin:/usr/bin:/bin; + export PATH=/opt/qemu/bin:/tmp/uboot-test-hooks/bin:${PATH}; export PYTHONPATH=/tmp/uboot-test-hooks/py/travis-ci; if [[ "${TEST_PY_BD}" != "" ]]; then ./test/py/test.py --bd ${TEST_PY_BD} ${TEST_PY_ID} -k "${TEST_PY_TEST_SPEC:-not a_test_which_does_not_exist}" --build-dir "$UBOOT_TRAVIS_BUILD_DIR"; diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 967abed9f2..9b295ac710 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -2,7 +2,7 @@ # Grab our configured image. The source for this is found at: # https://gitlab.denx.de/u-boot/gitlab-ci-runner -image: trini/u-boot-gitlab-ci-runner:bionic-20190912.1-03Oct2019 +image: trini/u-boot-gitlab-ci-runner:bionic-20191010-20Oct2019 # We run some tests in different order, to catch some failures quicker. stages: @@ -18,11 +18,6 @@ stages: - git clone --depth=1 git://github.com/swarren/uboot-test-hooks.git /tmp/uboot-test-hooks - ln -s travis-ci /tmp/uboot-test-hooks/bin/`hostname` - ln -s travis-ci /tmp/uboot-test-hooks/py/`hostname` - - virtualenv /tmp/venv - - . /tmp/venv/bin/activate - - pip install pytest==2.8.7 - - pip install python-subunit - - pip install coverage - grub-mkimage --prefix="" -o ~/grub_x86.efi -O i386-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd - grub-mkimage --prefix="" -o ~/grub_x64.efi -O x86_64-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd - mkdir ~/grub2-arm @@ -47,8 +42,11 @@ stages: # never prevent any test from running. That way, we can always pass # "-k something" even when $TEST_PY_TEST_SPEC doesnt need a custom # value. + - virtualenv -p /usr/bin/python3 /tmp/venv + - . /tmp/venv/bin/activate + - pip install -r test/py/requirements.txt - export UBOOT_TRAVIS_BUILD_DIR=/tmp/.bm-work/${TEST_PY_BD}; - export PATH=/opt/qemu/bin:/tmp/uboot-test-hooks/bin:/usr/bin:/bin; + export PATH=/opt/qemu/bin:/tmp/uboot-test-hooks/bin:${PATH}; export PYTHONPATH=/tmp/uboot-test-hooks/py/travis-ci; if [[ "${TEST_PY_BD}" != "" ]]; then ./test/py/test.py --bd ${TEST_PY_BD} ${TEST_PY_ID} @@ -65,11 +63,11 @@ build all 32bit ARM platforms: stage: world build script: - ret=0; - ./tools/buildman/buildman -o /tmp -P -E arm -x aarch64 || ret=$?; - if [[ $ret -ne 0 && $ret -ne 129 ]]; then - ./tools/buildman/buildman -o /tmp -sdeP; - exit $ret; - fi; + ./tools/buildman/buildman -o /tmp -P -E arm -x aarch64 || ret=$?; + if [[ $ret -ne 0 && $ret -ne 129 ]]; then + ./tools/buildman/buildman -o /tmp -sdeP; + exit $ret; + fi; build all 64bit ARM platforms: tags: [ 'all' ] @@ -79,33 +77,33 @@ build all 64bit ARM platforms: - . /tmp/venv/bin/activate - pip install pyelftools - ret=0; - ./tools/buildman/buildman -o /tmp -P -E aarch64 || ret=$?; - if [[ $ret -ne 0 && $ret -ne 129 ]]; then - ./tools/buildman/buildman -o /tmp -sdeP; - exit $ret; - fi; + ./tools/buildman/buildman -o /tmp -P -E aarch64 || ret=$?; + if [[ $ret -ne 0 && $ret -ne 129 ]]; then + ./tools/buildman/buildman -o /tmp -sdeP; + exit $ret; + fi; build all PowerPC platforms: tags: [ 'all' ] stage: world build script: - ret=0; - ./tools/buildman/buildman -o /tmp -P -E powerpc || ret=$?; - if [[ $ret -ne 0 && $ret -ne 129 ]]; then - ./tools/buildman/buildman -o /tmp -sdeP; - exit $ret; - fi; + ./tools/buildman/buildman -o /tmp -P -E powerpc || ret=$?; + if [[ $ret -ne 0 && $ret -ne 129 ]]; then + ./tools/buildman/buildman -o /tmp -sdeP; + exit $ret; + fi; build all other platforms: tags: [ 'all' ] stage: world build script: - ret=0; - ./tools/buildman/buildman -o /tmp -P -E -x arm,powerpc || ret=$?; - if [[ $ret -ne 0 && $ret -ne 129 ]]; then - ./tools/buildman/buildman -o /tmp -sdeP; - exit $ret; - fi; + ./tools/buildman/buildman -o /tmp -P -E -x arm,powerpc || ret=$?; + if [[ $ret -ne 0 && $ret -ne 129 ]]; then + ./tools/buildman/buildman -o /tmp -sdeP; + exit $ret; + fi; # QA jobs for code analytics # static code analysis with cppcheck (we can add --enable=all later) diff --git a/.travis.yml b/.travis.yml index 3aaed93346..1e98378695 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,9 @@ addons: - build-essential - libsdl1.2-dev - python - - python-virtualenv + - python-pyelftools + - python3-virtualenv + - python3-pip - swig - libpython-dev - iasl @@ -45,13 +47,10 @@ install: # prepare buildman environment - echo -e "[toolchain]\nroot = /usr" > ~/.buildman - echo -e "arc = /tmp/arc_gnu_2018.09_prebuilt_uclibc_le_archs_linux_install" >> ~/.buildman - - echo -e "\n[toolchain-alias]\nsh = sh2\n" >> ~/.buildman + - echo -e "\n[toolchain-alias]\nsh = sh2" >> ~/.buildman + - echo -e "x86 = i386" >> ~/.buildman; + - echo -e "riscv = riscv64" >> ~/.buildman; - cat ~/.buildman - - virtualenv /tmp/venv - - . /tmp/venv/bin/activate - - pip install pytest==2.8.7 - - pip install python-subunit - - pip install pyelftools - grub-mkimage --prefix="" -o ~/grub_x86.efi -O i386-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd - grub-mkimage --prefix="" -o ~/grub_x64.efi -O x86_64-efi normal echo lsefimmap lsefi lsefisystab efinet tftp minicmd - mkdir ~/grub2-arm @@ -77,7 +76,6 @@ before_script: - if [[ "${TOOLCHAIN}" == *sh* ]]; then ./tools/buildman/buildman --fetch-arch sh2 ; fi - if [[ "${TOOLCHAIN}" == *i386* ]]; then ./tools/buildman/buildman --fetch-arch i386; - echo -e "\n[toolchain-alias]\nx86 = i386" >> ~/.buildman; fi - if [[ "${TOOLCHAIN}" == arc ]]; then wget https://github.com/foss-for-synopsys-dwc-arc-processors/toolchain/releases/download/arc-2018.09-release/arc_gnu_2018.09_prebuilt_uclibc_le_archs_linux_install.tar.gz && @@ -101,7 +99,6 @@ before_script: - if [[ "${TOOLCHAIN}" == "powerpc" ]]; then ./tools/buildman/buildman --fetch-arch powerpc; fi - if [[ "${TOOLCHAIN}" == "riscv" ]]; then ./tools/buildman/buildman --fetch-arch riscv64; - echo -e "\n[toolchain-alias]\nriscv = riscv64" >> ~/.buildman; fi - if [[ "${QEMU_TARGET}" != "" ]]; then git clone git://git.qemu.org/qemu.git /tmp/qemu; @@ -136,15 +133,6 @@ script: cp ~/grub_x64.efi $UBOOT_TRAVIS_BUILD_DIR/; cp ~/grub2-arm/usr/lib/grub2/arm-efi/grub.efi $UBOOT_TRAVIS_BUILD_DIR/grub_arm.efi; cp ~/grub2-arm64/usr/lib/grub2/arm64-efi/grub.efi $UBOOT_TRAVIS_BUILD_DIR/grub_arm64.efi; - if [[ "${TEST_PY_BD}" != "" ]]; then - ./test/py/test.py --bd ${TEST_PY_BD} ${TEST_PY_ID} - -k "${TEST_PY_TEST_SPEC:-not a_test_which_does_not_exist}" - --build-dir "$UBOOT_TRAVIS_BUILD_DIR"; - ret=$?; - if [[ $ret -ne 0 ]]; then - exit $ret; - fi; - fi; if [[ -n "${TEST_PY_TOOLS}" ]]; then PYTHONPATH="${UBOOT_TRAVIS_BUILD_DIR}/scripts/dtc/pylibfdt" PATH="${UBOOT_TRAVIS_BUILD_DIR}/scripts/dtc:${PATH}" @@ -154,6 +142,18 @@ script: PYTHONPATH="${UBOOT_TRAVIS_BUILD_DIR}/scripts/dtc/pylibfdt" PATH="${UBOOT_TRAVIS_BUILD_DIR}/scripts/dtc:${PATH}" ./tools/dtoc/dtoc -t; + fi; + if [[ "${TEST_PY_BD}" != "" ]]; then + virtualenv -p /usr/bin/python3 /tmp/venv; + . /tmp/venv/bin/activate; + pip install -r test/py/requirements.txt; + ./test/py/test.py --bd ${TEST_PY_BD} ${TEST_PY_ID} + -k "${TEST_PY_TEST_SPEC:-not a_test_which_does_not_exist}" + --build-dir "$UBOOT_TRAVIS_BUILD_DIR"; + ret=$?; + if [[ $ret -ne 0 ]]; then + exit $ret; + fi; fi matrix: diff --git a/MAINTAINERS b/MAINTAINERS index 42b5959d90..a310b8478f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -94,6 +94,13 @@ L: uboot-snps-arc@synopsys.com F: doc/device-tree-bindings/gpio/snps,creg-gpio.txt F: drivers/gpio/hsdk-creg-gpio.c +ARC HSDK RESET +M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> +S: Maintained +L: uboot-snps-arc@synopsys.com +F: include/dt-bindings/reset/snps,hsdk-reset.h +F: drivers/reset/reset-hsdk.c + ARC SYNOPSYS DW MMC EXTENSIONS M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> S: Maintained @@ -346,7 +346,7 @@ define size_check limit=$$( printf "%d" $2 ); \ if test $$actual -gt $$limit; then \ echo "$1 exceeds file size limit:" >&2; \ - echo " limit: $$(printf %#x bytes $$limit) bytes" >&2; \ + echo " limit: $$(printf %#x $$limit) bytes" >&2; \ echo " actual: $$(printf %#x $$actual) bytes" >&2; \ echo " excess: $$(printf %#x $$((actual - limit))) bytes" >&2;\ exit 1; \ @@ -806,6 +806,12 @@ else SPL_SIZE_CHECK = endif +ifneq ($(CONFIG_TPL_SIZE_LIMIT),0) +TPL_SIZE_CHECK = @$(call size_check,$@,$(CONFIG_TPL_SIZE_LIMIT)) +else +TPL_SIZE_CHECK = +endif + # Statically apply RELA-style relocations (currently arm64 only) # This is useful for arm64 where static relocation needs to be performed on # the raw binary, but certain simulators only accept an ELF file (but don't @@ -1806,6 +1812,7 @@ spl/boot.bin: spl/u-boot-spl tpl/u-boot-tpl.bin: tools prepare \ $(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_SPL_OF_PLATDATA),dts/dt.dtb) $(Q)$(MAKE) obj=tpl -f $(srctree)/scripts/Makefile.spl all + $(TPL_SIZE_CHECK) TAG_SUBDIRS := $(patsubst %,$(srctree)/%,$(u-boot-dirs) include) diff --git a/arch/arc/dts/emsdp.dts b/arch/arc/dts/emsdp.dts index d307b95d8e..dbebdb4e76 100644 --- a/arch/arc/dts/emsdp.dts +++ b/arch/arc/dts/emsdp.dts @@ -32,4 +32,27 @@ reg-shift = <2>; reg-io-width = <4>; }; + + mmcclk_biu: mmcclk-biu { + compatible = "fixed-clock"; + clock-frequency = <50000000>; + #clock-cells = <0>; + }; + + mmcclk_ciu: mmcclk-ciu { + compatible = "fixed-clock"; + clock-frequency = <100000000>; + #clock-cells = <0>; + }; + + mmc: mmc0@f0010000 { + compatible = "snps,dw-mshc"; + reg = <0xf0010000 0x400>; + bus-width = <4>; + fifo-depth = <256>; + clocks = <&mmcclk_biu>, <&mmcclk_ciu>; + clock-names = "biu", "ciu"; + max-frequency = <25000000>; + }; + }; diff --git a/arch/arc/dts/iot_devkit.dts b/arch/arc/dts/iot_devkit.dts index ebf5a950f0..c0173fa5ab 100644 --- a/arch/arc/dts/iot_devkit.dts +++ b/arch/arc/dts/iot_devkit.dts @@ -42,4 +42,26 @@ compatible = "nop-phy"; #phy-cells = <0>; }; + + mmcclk_biu: mmcclk-biu { + compatible = "fixed-clock"; + clock-frequency = <50000000>; + #clock-cells = <0>; + }; + + mmcclk_ciu: mmcclk-ciu { + compatible = "fixed-clock"; + clock-frequency = <50000000>; + #clock-cells = <0>; + }; + + mmc: mmc0@f000b000 { + compatible = "snps,dw-mshc"; + reg = <0xf000b000 0x400>; + bus-width = <4>; + fifo-depth = <128>; + clocks = <&mmcclk_biu>, <&mmcclk_ciu>; + clock-names = "biu", "ciu"; + max-frequency = <25000000>; + }; }; diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c index a5c528a18d..7a1b39844e 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c @@ -1254,8 +1254,8 @@ void mxs_power_init(void) debug("SPL: Setting VDDIO to 3V3 (brownout @ 3v15)\n"); mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150); - debug("SPL: Setting VDDD to 1V5 (brownout @ 1v315)\n"); - mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1315); + debug("SPL: Setting VDDD to 1V55 (brownout @ 1v400)\n"); + mxs_power_set_vddx(&mxs_vddd_cfg, 1550, 1400); #ifdef CONFIG_MX23 debug("SPL: Setting mx23 VDDMEM to 2V5 (brownout @ 1v7)\n"); mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700); diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 47978e7685..251d32ca62 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -565,6 +565,7 @@ dtb-$(CONFIG_MX53) += imx53-cx9020.dtb \ ifneq ($(CONFIG_MX6DL)$(CONFIG_MX6QDL)$(CONFIG_MX6S),) dtb-y += \ + imx6dl-brppt2.dtb \ imx6dl-dhcom-pdk2.dtb \ imx6dl-icore.dtb \ imx6dl-icore-mipi.dtb \ @@ -589,6 +590,7 @@ dtb-y += \ imx6q-icore-rqs.dtb \ imx6q-kp.dtb \ imx6q-logicpd.dtb \ + imx6q-mccmon6.dtb\ imx6q-nitrogen6x.dtb \ imx6q-novena.dtb \ imx6q-pico.dtb \ @@ -651,11 +653,14 @@ dtb-$(CONFIG_ARCH_MX7ULP) += imx7ulp-evk.dtb dtb-$(CONFIG_ARCH_IMX8) += \ fsl-imx8qm-apalis.dtb \ fsl-imx8qm-mek.dtb \ + imx8qm-rom7720-a1.dtb \ + fsl-imx8qxp-ai_ml.dtb \ fsl-imx8qxp-colibri.dtb \ fsl-imx8qxp-mek.dtb -dtb-$(CONFIG_ARCH_IMX8M) += fsl-imx8mq-evk.dtb \ - imx8mm-evk.dtb +dtb-$(CONFIG_ARCH_IMX8M) += \ + imx8mm-evk.dtb \ + imx8mq-evk.dtb dtb-$(CONFIG_RCAR_GEN2) += \ r8a7790-lager-u-boot.dtb \ diff --git a/arch/arm/dts/am335x-baltos.dts b/arch/arm/dts/am335x-baltos.dts index f939cf6406..b3c13c9a9d 100644 --- a/arch/arm/dts/am335x-baltos.dts +++ b/arch/arm/dts/am335x-baltos.dts @@ -409,16 +409,26 @@ pinctrl-1 = <&davinci_mdio_sleep>; status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + }; + + phy1: ethernet-phy@7 { + reg = <7>; + eee-broken-100tx; + eee-broken-1000t; + }; }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; + phy-handle = <&phy0>; phy-mode = "rmii"; dual_emac_res_vlan = <1>; }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <7>; + phy-handle = <&phy1>; phy-mode = "rgmii-txid"; dual_emac_res_vlan = <2>; }; diff --git a/arch/arm/dts/am335x-bone-common.dtsi b/arch/arm/dts/am335x-bone-common.dtsi index 40a3c35ff8..5b8230e281 100644 --- a/arch/arm/dts/am335x-bone-common.dtsi +++ b/arch/arm/dts/am335x-bone-common.dtsi @@ -360,16 +360,12 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; - phy-mode = "mii"; -}; - -&cpsw_emac1 { - phy_id = <&davinci_mdio>, <1>; + phy-handle = <ðphy0>; phy-mode = "mii"; }; &mac { + slaves = <1>; pinctrl-names = "default", "sleep"; pinctrl-0 = <&cpsw_default>; pinctrl-1 = <&cpsw_sleep>; @@ -381,6 +377,10 @@ pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; status = "okay"; + + ethphy0: ethernet-phy@0 { + reg = <0>; + }; }; &mmc1 { diff --git a/arch/arm/dts/am335x-brsmarc1.dts b/arch/arm/dts/am335x-brsmarc1.dts index 1a7f9a5365..e1738b6dde 100644 --- a/arch/arm/dts/am335x-brsmarc1.dts +++ b/arch/arm/dts/am335x-brsmarc1.dts @@ -247,6 +247,14 @@ &davinci_mdio { status = "okay"; + + ethphy0: ethernet-phy@1 { + reg = <1>; + }; + + ethphy1: ethernet-phy@3 { + reg = <3>; + }; }; &mac { @@ -258,13 +266,13 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <1>; + phy-handle = <ðphy0>; phy-mode = "rmii"; ti,ledcr = <0x0480>; }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <3>; + phy-handle = <ðphy1>; phy-mode = "rmii"; ti,ledcr = <0x0480>; }; diff --git a/arch/arm/dts/am335x-brxre1.dts b/arch/arm/dts/am335x-brxre1.dts index 708407daf2..a0d046d07a 100644 --- a/arch/arm/dts/am335x-brxre1.dts +++ b/arch/arm/dts/am335x-brxre1.dts @@ -206,6 +206,14 @@ &davinci_mdio { status = "okay"; + + ethphy0: ethernet-phy@1 { + reg = <1>; + }; + + ethphy1: ethernet-phy@2 { + reg = <2>; + }; }; &mac { @@ -213,12 +221,12 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <1>; + phy-handle = <ðphy0>; phy-mode = "mii"; }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <2>; + phy-handle = <ðphy1>; phy-mode = "mii"; }; diff --git a/arch/arm/dts/am335x-chiliboard.dts b/arch/arm/dts/am335x-chiliboard.dts index 59431b2359..9c2a947aac 100644 --- a/arch/arm/dts/am335x-chiliboard.dts +++ b/arch/arm/dts/am335x-chiliboard.dts @@ -140,10 +140,14 @@ pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; status = "okay"; + + ethphy0: ethernet-phy@0 { + reg = <0>; + }; }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; + phy-handle = <ðphy0>; phy-mode = "rmii"; }; diff --git a/arch/arm/dts/am335x-draco.dts b/arch/arm/dts/am335x-draco.dts index 25d0480ecd..f8faa8f7c4 100644 --- a/arch/arm/dts/am335x-draco.dts +++ b/arch/arm/dts/am335x-draco.dts @@ -143,7 +143,7 @@ }; &cpsw_emac0 { - phy_id = <&mdio0>, <0>; + phy-handle = <&phy0>; phy-mode = "rmii"; }; diff --git a/arch/arm/dts/am335x-evm.dts b/arch/arm/dts/am335x-evm.dts index fe27207588..0bda4d4429 100644 --- a/arch/arm/dts/am335x-evm.dts +++ b/arch/arm/dts/am335x-evm.dts @@ -675,6 +675,7 @@ pinctrl-0 = <&cpsw_default>; pinctrl-1 = <&cpsw_sleep>; status = "okay"; + slaves = <1>; }; &davinci_mdio { @@ -682,16 +683,15 @@ pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; status = "okay"; -}; -&cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; - phy-mode = "rgmii-txid"; + ethphy0: ethernet-phy@0 { + reg = <0>; + }; }; -&cpsw_emac1 { - phy_id = <&davinci_mdio>, <1>; - phy-mode = "rgmii-txid"; +&cpsw_emac0 { + phy-handle = <ðphy0>; + phy-mode = "rgmii-id"; }; &tscadc { diff --git a/arch/arm/dts/am335x-evmsk.dts b/arch/arm/dts/am335x-evmsk.dts index 0767578aee..5762967cf7 100644 --- a/arch/arm/dts/am335x-evmsk.dts +++ b/arch/arm/dts/am335x-evmsk.dts @@ -630,17 +630,25 @@ pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; status = "okay"; + + ethphy0: ethernet-phy@0 { + reg = <0>; + }; + + ethphy1: ethernet-phy@1 { + reg = <1>; + }; }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; - phy-mode = "rgmii-txid"; + phy-handle = <ðphy0>; + phy-mode = "rgmii-id"; dual_emac_res_vlan = <1>; }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <1>; - phy-mode = "rgmii-txid"; + phy-handle = <ðphy1>; + phy-mode = "rgmii-id"; dual_emac_res_vlan = <2>; }; diff --git a/arch/arm/dts/am335x-icev2.dts b/arch/arm/dts/am335x-icev2.dts index debc6f6132..37484cb6f5 100644 --- a/arch/arm/dts/am335x-icev2.dts +++ b/arch/arm/dts/am335x-icev2.dts @@ -397,13 +397,13 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <1>; + phy-handle = <ðphy0>; phy-mode = "rmii"; dual_emac_res_vlan = <1>; }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <3>; + phy-handle = <ðphy1>; phy-mode = "rmii"; dual_emac_res_vlan = <2>; }; @@ -427,4 +427,12 @@ status = "okay"; reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; reset-delay-us = <2>; /* PHY datasheet states 1uS min */ + + ethphy0: ethernet-phy@1 { + reg = <1>; + }; + + ethphy1: ethernet-phy@3 { + reg = <3>; + }; }; diff --git a/arch/arm/dts/am335x-igep0033.dtsi b/arch/arm/dts/am335x-igep0033.dtsi index a5769a8f5f..f102f6adad 100644 --- a/arch/arm/dts/am335x-igep0033.dtsi +++ b/arch/arm/dts/am335x-igep0033.dtsi @@ -102,15 +102,23 @@ &davinci_mdio { status = "okay"; + + ethphy0: ethernet-phy@0 { + reg = <0>; + }; + + ethphy1: ethernet-phy@1 { + reg = <1>; + }; }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; + phy-handle = <ðphy0>; phy-mode = "rmii"; }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <1>; + phy-handle = <ðphy1>; phy-mode = "rmii"; }; diff --git a/arch/arm/dts/am335x-pxm2.dtsi b/arch/arm/dts/am335x-pxm2.dtsi index d9243d5d3d..19bd7e2420 100644 --- a/arch/arm/dts/am335x-pxm2.dtsi +++ b/arch/arm/dts/am335x-pxm2.dtsi @@ -117,12 +117,12 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; + phy-handle = <ðphy0>; phy-mode = "rgmii-txid"; }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <1>; + phy-handle = <ðphy1>; phy-mode = "rgmii-txid"; }; @@ -131,6 +131,14 @@ pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; status = "okay"; + + ethphy0: ethernet-phy@0 { + reg = <0>; + }; + + ethphy1: ethernet-phy@1 { + reg = <1>; + }; }; &elm { diff --git a/arch/arm/dts/am335x-rut.dts b/arch/arm/dts/am335x-rut.dts index a5716a929f..145247344f 100644 --- a/arch/arm/dts/am335x-rut.dts +++ b/arch/arm/dts/am335x-rut.dts @@ -149,13 +149,8 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <1>; - phy-mode = "rmii"; -}; - -&cpsw_emac1 { - phy_id = <&davinci_mdio>, <0>; phy-mode = "rmii"; + phy-handle = <ðernet_phy>; }; &davinci_mdio { diff --git a/arch/arm/dts/am335x-shc.dts b/arch/arm/dts/am335x-shc.dts index 5cdd309b90..8e35c439e5 100644 --- a/arch/arm/dts/am335x-shc.dts +++ b/arch/arm/dts/am335x-shc.dts @@ -197,17 +197,17 @@ }; }; +&cpsw_emac0 { + phy-mode = "mii"; + phy-handle = <ðernetphy0>; +}; + &mac { pinctrl-names = "default", "sleep"; pinctrl-0 = <&cpsw_default>; pinctrl-1 = <&cpsw_sleep>; status = "okay"; slaves = <1>; - cpsw_emac0: slave@4a100200 { - phy_id = <&davinci_mdio>, <0>; - phy-mode = "mii"; - phy-handle = <ðernetphy0>; - }; }; &mmc1 { diff --git a/arch/arm/dts/am335x-sl50.dts b/arch/arm/dts/am335x-sl50.dts index 1bcc60424e..ebb56bdaad 100644 --- a/arch/arm/dts/am335x-sl50.dts +++ b/arch/arm/dts/am335x-sl50.dts @@ -507,13 +507,8 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; - phy-mode = "mii"; -}; - -&cpsw_emac1 { - phy_id = <&davinci_mdio>, <1>; phy-mode = "mii"; + phy-handle = <ðphy0>; }; &mac { @@ -528,6 +523,12 @@ pinctrl-names = "default", "sleep"; pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; + reset-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>; + reset-delay-us = <100>; /* PHY datasheet states 100us min */ + + ethphy0: ethernet-phy@0 { + reg = <0>; + }; }; &sham { diff --git a/arch/arm/dts/am437x-gp-evm.dts b/arch/arm/dts/am437x-gp-evm.dts index 142bfc52a1..3c500d52db 100644 --- a/arch/arm/dts/am437x-gp-evm.dts +++ b/arch/arm/dts/am437x-gp-evm.dts @@ -645,10 +645,14 @@ pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; status = "okay"; + + ethphy0: ethernet-phy@0 { + reg = <0>; + }; }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; + phy-handle = <ðphy0>; phy-mode = "rgmii"; }; diff --git a/arch/arm/dts/am437x-idk-evm.dts b/arch/arm/dts/am437x-idk-evm.dts index 19d1462d15..8f6824c198 100644 --- a/arch/arm/dts/am437x-idk-evm.dts +++ b/arch/arm/dts/am437x-idk-evm.dts @@ -385,6 +385,7 @@ }; &mac { + slaves = <1>; pinctrl-names = "default", "sleep"; pinctrl-0 = <&cpsw_default>; pinctrl-1 = <&cpsw_sleep>; @@ -396,10 +397,14 @@ pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; status = "okay"; + + ethphy0: ethernet-phy@0 { + reg = <0>; + }; }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; + phy-handle = <ðphy0>; phy-mode = "rgmii"; }; diff --git a/arch/arm/dts/am437x-sk-evm.dts b/arch/arm/dts/am437x-sk-evm.dts index dc8fcde458..66a3bd1dfa 100644 --- a/arch/arm/dts/am437x-sk-evm.dts +++ b/arch/arm/dts/am437x-sk-evm.dts @@ -626,16 +626,24 @@ pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; status = "okay"; + + ethphy0: ethernet-phy@4 { + reg = <4>; + }; + + ethphy1: ethernet-phy@5 { + reg = <5>; + }; }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <4>; + phy-handle = <ðphy0>; phy-mode = "rgmii"; dual_emac_res_vlan = <1>; }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <5>; + phy-handle = <ðphy1>; phy-mode = "rgmii"; dual_emac_res_vlan = <2>; }; diff --git a/arch/arm/dts/am43x-epos-evm.dts b/arch/arm/dts/am43x-epos-evm.dts index fa4d1e3f32..65f157ed59 100644 --- a/arch/arm/dts/am43x-epos-evm.dts +++ b/arch/arm/dts/am43x-epos-evm.dts @@ -389,6 +389,7 @@ pinctrl-0 = <&cpsw_default>; pinctrl-1 = <&cpsw_sleep>; status = "okay"; + slaves = <1>; }; &davinci_mdio { @@ -396,15 +397,14 @@ pinctrl-0 = <&davinci_mdio_default>; pinctrl-1 = <&davinci_mdio_sleep>; status = "okay"; -}; -&cpsw_emac0 { - phy_id = <&davinci_mdio>, <16>; - phy-mode = "rmii"; + ethphy0: ethernet-phy@16 { + reg = <16>; + }; }; -&cpsw_emac1 { - phy_id = <&davinci_mdio>, <1>; +&cpsw_emac0 { + phy-handle = <ðphy0>; phy-mode = "rmii"; }; diff --git a/arch/arm/dts/am57xx-idk-common.dtsi b/arch/arm/dts/am57xx-idk-common.dtsi index fdb4e0e47c..590fb14caf 100644 --- a/arch/arm/dts/am57xx-idk-common.dtsi +++ b/arch/arm/dts/am57xx-idk-common.dtsi @@ -372,17 +372,27 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <0>; + phy-handle = <ðphy0>; phy-mode = "rgmii"; dual_emac_res_vlan = <1>; }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <1>; + phy-handle = <ðphy1>; phy-mode = "rgmii"; dual_emac_res_vlan = <2>; }; +&davinci_mdio { + ethphy0: ethernet-phy@0 { + reg = <0>; + }; + + ethphy1: ethernet-phy@1 { + reg = <1>; + }; +}; + &usb2_phy1 { phy-supply = <&ldousb_reg>; }; diff --git a/arch/arm/dts/dra7-evm.dts b/arch/arm/dts/dra7-evm.dts index aa426dabb6..43de9638e3 100644 --- a/arch/arm/dts/dra7-evm.dts +++ b/arch/arm/dts/dra7-evm.dts @@ -479,17 +479,27 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <2>; + phy-handle = <ðphy0>; phy-mode = "rgmii"; dual_emac_res_vlan = <1>; }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <3>; + phy-handle = <ðphy1>; phy-mode = "rgmii"; dual_emac_res_vlan = <2>; }; +&davinci_mdio { + ethphy0: ethernet-phy@2 { + reg = <2>; + }; + + ethphy1: ethernet-phy@3 { + reg = <3>; + }; +}; + &dcan1 { status = "ok"; pinctrl-names = "default", "sleep", "active"; diff --git a/arch/arm/dts/dra71-evm.dts b/arch/arm/dts/dra71-evm.dts index 64363f75c0..9bf08294b2 100644 --- a/arch/arm/dts/dra71-evm.dts +++ b/arch/arm/dts/dra71-evm.dts @@ -201,13 +201,13 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <2>; + phy-handle = <&dp83867_0>; phy-mode = "rgmii-id"; dual_emac_res_vlan = <1>; }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <3>; + phy-handle = <&dp83867_1>; phy-mode = "rgmii-id"; dual_emac_res_vlan = <2>; }; diff --git a/arch/arm/dts/dra72-evm-revc.dts b/arch/arm/dts/dra72-evm-revc.dts index bf588d0072..fafc2a4d7b 100644 --- a/arch/arm/dts/dra72-evm-revc.dts +++ b/arch/arm/dts/dra72-evm-revc.dts @@ -61,13 +61,13 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <2>; + phy-handle = <&dp83867_0>; phy-mode = "rgmii-id"; dual_emac_res_vlan = <1>; }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <3>; + phy-handle = <&dp83867_1>; phy-mode = "rgmii-id"; dual_emac_res_vlan = <2>; }; diff --git a/arch/arm/dts/dra72-evm.dts b/arch/arm/dts/dra72-evm.dts index c572693b16..154b0a0ceb 100644 --- a/arch/arm/dts/dra72-evm.dts +++ b/arch/arm/dts/dra72-evm.dts @@ -51,10 +51,16 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <3>; + phy-handle = <ðphy0>; phy-mode = "rgmii"; }; +&davinci_mdio { + ethphy0: ethernet-phy@3 { + reg = <3>; + }; +}; + &mmc1 { pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104"; pinctrl-0 = <&mmc1_pins_default>; diff --git a/arch/arm/dts/dra76-evm.dts b/arch/arm/dts/dra76-evm.dts index a1f289f345..e3da17ac97 100644 --- a/arch/arm/dts/dra76-evm.dts +++ b/arch/arm/dts/dra76-evm.dts @@ -341,13 +341,13 @@ }; &cpsw_emac0 { - phy_id = <&davinci_mdio>, <2>; + phy-handle = <&dp83867_0>; phy-mode = "rgmii-id"; dual_emac_res_vlan = <1>; }; &cpsw_emac1 { - phy_id = <&davinci_mdio>, <3>; + phy-handle = <&dp83867_1>; phy-mode = "rgmii-id"; dual_emac_res_vlan = <2>; }; diff --git a/arch/arm/dts/fsl-imx8mq-evk.dts b/arch/arm/dts/fsl-imx8mq-evk.dts deleted file mode 100644 index 4a08099b3c..0000000000 --- a/arch/arm/dts/fsl-imx8mq-evk.dts +++ /dev/null @@ -1,414 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2018 NXP - */ - -/dts-v1/; - -/* First 128KB is for PSCI ATF. */ -/memreserve/ 0x40000000 0x00020000; - -#include "fsl-imx8mq.dtsi" - -/ { - model = "Freescale i.MX8MQ EVK"; - compatible = "fsl,imx8mq-evk", "fsl,imx8mq"; - - chosen { - bootargs = "console=ttymxc0,115200 earlycon=ec_imx6q,0x30860000,115200"; - }; - - regulators { - compatible = "simple-bus"; - #address-cells = <1>; - #size-cells = <0>; - - reg_usdhc2_vmmc: usdhc2_vmmc { - compatible = "regulator-fixed"; - regulator-name = "VSD_3V3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - }; - - pwmleds { - compatible = "pwm-leds"; - - ledpwm2 { - label = "PWM2"; - pwms = <&pwm2 0 50000>; - max-brightness = <255>; - }; - }; -}; - -&iomuxc { - pinctrl-names = "default"; - - imx8mq-evk { - pinctrl_fec1: fec1grp { - fsl,pins = < - MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x3 - MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO 0x23 - MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f - MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f - MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f - MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f - MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91 - MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 - MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 - MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 - MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f - MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 - MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 - MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f - MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 - >; - }; - - pinctrl_i2c1: i2c1grp { - fsl,pins = < - MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x4000007f - MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x4000007f - >; - }; - - pinctrl_i2c2: i2c2grp { - fsl,pins = < - MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL 0x4000007f - MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA 0x4000007f - >; - }; - - pinctrl_pwm2: pwm2grp { - fsl,pins = < - MX8MQ_IOMUXC_GPIO1_IO13_PWM2_OUT 0x16 - >; - }; - - pinctrl_qspi: qspigrp { - fsl,pins = < - MX8MQ_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x82 - MX8MQ_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x82 - MX8MQ_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x82 - MX8MQ_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x82 - MX8MQ_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x82 - MX8MQ_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x82 - - >; - }; - - pinctrl_usdhc1: usdhc1grp { - fsl,pins = < - MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x83 - MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc3 - MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc3 - MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc3 - MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc3 - MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc3 - MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc3 - MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc3 - MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc3 - MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc3 - MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x83 - MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 - >; - }; - - pinctrl_usdhc1_100mhz: usdhc1grp100mhz { - fsl,pins = < - MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x85 - MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc5 - MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc5 - MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc5 - MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc5 - MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc5 - MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc5 - MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc5 - MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc5 - MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc5 - MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x85 - MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 - >; - }; - - pinctrl_usdhc1_200mhz: usdhc1grp200mhz { - fsl,pins = < - MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x87 - MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc7 - MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc7 - MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc7 - MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc7 - MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc7 - MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc7 - MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc7 - MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc7 - MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc7 - MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x87 - MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 - >; - }; - - pinctrl_usdhc2_gpio: usdhc2grpgpio { - fsl,pins = < - MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12 0x41 - MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 - >; - }; - - pinctrl_usdhc2: usdhc2grp { - fsl,pins = < - MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x83 - MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc3 - MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc3 - MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc3 - MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc3 - MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc3 - MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 - >; - }; - - pinctrl_usdhc2_100mhz: usdhc2grp100mhz { - fsl,pins = < - MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x85 - MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc5 - MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc5 - MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc5 - MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc5 - MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc5 - MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 - >; - }; - - pinctrl_usdhc2_200mhz: usdhc2grp200mhz { - fsl,pins = < - MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x87 - MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc7 - MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc7 - MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc7 - MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc7 - MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc7 - MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 - >; - }; - - pinctrl_sai2: sai2grp { - fsl,pins = < - MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6 - MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6 - MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6 - MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6 - MX8MQ_IOMUXC_GPIO1_IO08_GPIO1_IO8 0xd6 - >; - }; - - pinctrl_wdog: wdoggrp { - fsl,pins = < - MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 - >; - }; - }; -}; - -&fec1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_fec1>; - phy-mode = "rgmii-id"; - phy-handle = <ðphy0>; - fsl,magic-packet; - status = "okay"; - - mdio { - #address-cells = <1>; - #size-cells = <0>; - - ethphy0: ethernet-phy@0 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0>; - at803x,led-act-blind-workaround; - at803x,eee-disabled; - }; - }; -}; - -&i2c1 { - clock-frequency = <100000>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c1>; - status = "okay"; - - pmic: pfuze100@08 { - compatible = "fsl,pfuze100"; - reg = <0x08>; - - regulators { - sw1a_reg: sw1ab { - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1875000>; - regulator-always-on; - }; - - sw1c_reg: sw1c { - regulator-min-microvolt = <300000>; - regulator-max-microvolt = <1875000>; - regulator-always-on; - }; - - sw2_reg: sw2 { - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - }; - - sw3a_reg: sw3ab { - regulator-min-microvolt = <400000>; - regulator-max-microvolt = <1975000>; - regulator-always-on; - }; - - sw4_reg: sw4 { - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - }; - - swbst_reg: swbst { - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5150000>; - }; - - snvs_reg: vsnvs { - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <3000000>; - regulator-always-on; - }; - - vref_reg: vrefddr { - regulator-always-on; - }; - - vgen1_reg: vgen1 { - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <1550000>; - }; - - vgen2_reg: vgen2 { - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <1550000>; - regulator-always-on; - }; - - vgen3_reg: vgen3 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - }; - - vgen4_reg: vgen4 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - }; - - vgen5_reg: vgen5 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - }; - - vgen6_reg: vgen6 { - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - }; - }; - }; -}; - -&i2c2 { - clock-frequency = <100000>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c2>; - status = "disabled"; -}; - -&pwm2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm2>; - status = "okay"; -}; - -&lcdif { - status = "okay"; - disp-dev = "mipi_dsi_northwest"; - display = <&display0>; - - display0: display@0 { - bits-per-pixel = <24>; - bus-width = <24>; - - display-timings { - native-mode = <&timing0>; - timing0: timing0 { - clock-frequency = <9200000>; - hactive = <480>; - vactive = <272>; - hfront-porch = <8>; - hback-porch = <4>; - hsync-len = <41>; - vback-porch = <2>; - vfront-porch = <4>; - vsync-len = <10>; - - hsync-active = <0>; - vsync-active = <0>; - de-active = <1>; - pixelclk-active = <0>; - }; - }; - }; -}; - -&qspi { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_qspi>; - status = "okay"; - - flash0: n25q256a@0 { - reg = <0>; - #address-cells = <1>; - #size-cells = <1>; - compatible = "micron,n25q256a"; - spi-max-frequency = <29000000>; - spi-nor,ddr-quad-read-dummy = <6>; - }; -}; - -&usdhc1 { - pinctrl-names = "default", "state_100mhz", "state_200mhz"; - pinctrl-0 = <&pinctrl_usdhc1>; - pinctrl-1 = <&pinctrl_usdhc1_100mhz>; - pinctrl-2 = <&pinctrl_usdhc1_200mhz>; - bus-width = <8>; - non-removable; - status = "okay"; -}; - -&usdhc2 { - pinctrl-names = "default", "state_100mhz", "state_200mhz"; - pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; - pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; - pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; - bus-width = <4>; - cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; - vmmc-supply = <®_usdhc2_vmmc>; - status = "okay"; -}; - -&wdog1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_wdog>; - fsl,ext-reset-output; - status = "okay"; -}; diff --git a/arch/arm/dts/fsl-imx8mq.dtsi b/arch/arm/dts/fsl-imx8mq.dtsi deleted file mode 100644 index d0206c9dbe..0000000000 --- a/arch/arm/dts/fsl-imx8mq.dtsi +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright (C) 2016 Freescale Semiconductor, Inc. - * Copyright 2017 NXP - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "fsl-imx8-ca53.dtsi" -#include <dt-bindings/clock/imx8mq-clock.h> -#include <dt-bindings/gpio/gpio.h> -#include <dt-bindings/input/input.h> -#include <dt-bindings/interrupt-controller/arm-gic.h> -#include <dt-bindings/pinctrl/pins-imx8mq.h> -#include <dt-bindings/reset/imx8mq-reset.h> -#include <dt-bindings/power/imx8mq-power.h> -#include <dt-bindings/thermal/thermal.h> - -/ { - compatible = "fsl,imx8mq"; - interrupt-parent = <&gpc>; - #address-cells = <2>; - #size-cells = <2>; - - aliases { - ethernet0 = &fec1; - mmc0 = &usdhc1; - mmc1 = &usdhc2; - gpio0 = &gpio1; - gpio1 = &gpio2; - gpio2 = &gpio3; - gpio3 = &gpio4; - gpio4 = &gpio5; - i2c0 = &i2c1; - i2c1 = &i2c2; - i2c2 = &i2c3; - i2c3 = &i2c4; - }; - - memory@40000000 { - device_type = "memory"; - reg = <0x00000000 0x40000000 0 0xc0000000>; - }; - - gic: interrupt-controller@38800000 { - compatible = "arm,gic-v3"; - reg = <0x0 0x38800000 0 0x10000>, /* GIC Dist */ - <0x0 0x38880000 0 0xC0000>; /* GICR (RD_base + SGI_base) */ - #interrupt-cells = <3>; - interrupt-controller; - interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; - interrupt-parent = <&gic>; - }; - - timer { - compatible = "arm,armv8-timer"; - interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | - IRQ_TYPE_LEVEL_LOW)>, /* Physical Secure */ - <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | - IRQ_TYPE_LEVEL_LOW)>, /* Physical Non-Secure */ - <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | - IRQ_TYPE_LEVEL_LOW)>, /* Virtual */ - <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | - IRQ_TYPE_LEVEL_LOW)>; /* Hypervisor */ - clock-frequency = <8333333>; - interrupt-parent = <&gic>; - }; - - pwm2: pwm@30670000 { - compatible = "fsl,imx8mq-pwm", "fsl,imx27-pwm"; - reg = <0x0 0x30670000 0x0 0x10000>; - interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MQ_CLK_PWM2_ROOT>, - <&clk IMX8MQ_CLK_PWM2_ROOT>; - clock-names = "ipg", "per"; - #pwm-cells = <2>; - status = "disabled"; - }; - - gpio1: gpio@30200000 { - compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; - reg = <0x0 0x30200000 0x0 0x10000>; - interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - gpio2: gpio@30210000 { - compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; - reg = <0x0 0x30210000 0x0 0x10000>; - interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - gpio3: gpio@30220000 { - compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; - reg = <0x0 0x30220000 0x0 0x10000>; - interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - gpio4: gpio@30230000 { - compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; - reg = <0x0 0x30230000 0x0 0x10000>; - interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - gpio5: gpio@30240000 { - compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; - reg = <0x0 0x30240000 0x0 0x10000>; - interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - }; - - tmu: tmu@30260000 { - compatible = "fsl,imx8mq-tmu"; - reg = <0x0 0x30260000 0x0 0x10000>; - interrupt = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; - little-endian; - u-boot,dm-pre-reloc; - fsl,tmu-range = <0xa0000 0x90026 0x8004a 0x1006a>; - fsl,tmu-calibration = <0x00000000 0x00000020 - 0x00000001 0x00000028 - 0x00000002 0x00000030 - 0x00000003 0x00000038 - 0x00000004 0x00000040 - 0x00000005 0x00000048 - 0x00000006 0x00000050 - 0x00000007 0x00000058 - 0x00000008 0x00000060 - 0x00000009 0x00000068 - 0x0000000a 0x00000070 - 0x0000000b 0x00000077 - - 0x00010000 0x00000057 - 0x00010001 0x0000005b - 0x00010002 0x0000005f - 0x00010003 0x00000063 - 0x00010004 0x00000067 - 0x00010005 0x0000006b - 0x00010006 0x0000006f - 0x00010007 0x00000073 - 0x00010008 0x00000077 - 0x00010009 0x0000007b - 0x0001000a 0x0000007f - - 0x00020000 0x00000002 - 0x00020001 0x0000000e - 0x00020002 0x0000001a - 0x00020003 0x00000026 - 0x00020004 0x00000032 - 0x00020005 0x0000003e - 0x00020006 0x0000004a - 0x00020007 0x00000056 - 0x00020008 0x00000062 - - 0x00030000 0x00000000 - 0x00030001 0x00000008 - 0x00030002 0x00000010 - 0x00030003 0x00000018 - 0x00030004 0x00000020 - 0x00030005 0x00000028 - 0x00030006 0x00000030 - 0x00030007 0x00000038>; - #thermal-sensor-cells = <0>; - }; - - thermal-zones { - /* cpu thermal */ - cpu-thermal { - polling-delay-passive = <250>; - polling-delay = <2000>; - thermal-sensors = <&tmu>; - trips { - cpu_alert0: trip0 { - temperature = <85000>; - hysteresis = <2000>; - type = "passive"; - }; - cpu_crit0: trip1 { - temperature = <125000>; - hysteresis = <2000>; - type = "critical"; - }; - }; - - cooling-maps { - map0 { - trip = <&cpu_alert0>; - cooling-device = - <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; - }; - }; - }; - }; - - lcdif: lcdif@30320000 { - compatible = "fsl,imx8mq-lcdif", "fsl,imx28-lcdif"; - reg = <0x0 0x30320000 0x0 0x10000>; - clocks = <&clk IMX8MQ_CLK_LCDIF_PIXEL_DIV>, - <&clk IMX8MQ_CLK_DUMMY>, - <&clk IMX8MQ_CLK_DUMMY>; - clock-names = "pix", "axi", "disp_axi"; - assigned-clocks = <&clk IMX8MQ_CLK_LCDIF_PIXEL_SRC>; - assigned-clock-parents = <&clk IMX8MQ_VIDEO_PLL1_OUT>; - assigned-clock-rate = <594000000>; - interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; - status = "disabled"; - }; - - iomuxc: iomuxc@30330000 { - compatible = "fsl,imx8mq-iomuxc"; - reg = <0x0 0x30330000 0x0 0x10000>; - }; - - gpr: iomuxc-gpr@30340000 { - compatible = "fsl,imx8mq-iomuxc-gpr", "fsl,imx7d-iomuxc-gpr", "syscon"; - reg = <0x0 0x30340000 0x0 0x10000>; - }; - - ocotp: ocotp-ctrl@30350000 { - compatible = "fsl,imx8mq-ocotp", "fsl,imx7d-ocotp", "syscon"; - reg = <0x0 0x30350000 0x0 0x10000>; - }; - - anatop: anatop@30360000 { - compatible = "fsl,imx8mq-anatop", "fsl,imx6q-anatop", - "syscon", "simple-bus"; - reg = <0x0 0x30360000 0x0 0x10000>; - interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; - }; - - clk: ccm@30380000 { - compatible = "fsl,imx8mq-ccm"; - reg = <0x0 0x30380000 0x0 0x10000>; - interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; - #clock-cells = <1>; - }; - - src: reset-controller@30390000 { - compatible = "fsl,imx8mq-src", "syscon"; - reg = <0x0 0x30390000 0x0 0x10000>; - #reset-cells = <1>; - }; - - gpc: gpc@303a0000 { - compatible = "fsl,imx8mq-gpc", "fsl,imx7d-gpc", "syscon"; - reg = <0x0 0x303a0000 0x0 0x10000>; - interrupt-controller; - interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; - #interrupt-cells = <3>; - interrupt-parent = <&gic>; - - pgc { - #address-cells = <1>; - #size-cells = <0>; - - /* - * As per comment in ATF source code: - * - * PCIE1 and PCIE2 share the - * same reset signal, if we - * power down PCIE2, PCIE1 - * will be held in reset too. - * - * So instead of creating two - * separate power domains for - * PCIE1 and PCIE2 we create a - * link between both and use - * it as a shared PCIE power - * domain. - */ - pgc_pcie: power-domain@1 { - #power-domain-cells = <0>; - reg = <IMX8M_POWER_DOMAIN_PCIE1>; - power-domains = <&pgc_pcie2>; - }; - - pgc_pcie2: power-domain@a { - #power-domain-cells = <0>; - reg = <IMX8M_POWER_DOMAIN_PCIE2>; - }; - }; - }; - - usdhc1: usdhc@30b40000 { - compatible = "fsl,imx8mq-usdhc", "fsl,imx7d-usdhc"; - reg = <0x0 0x30b40000 0x0 0x10000>; - interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MQ_CLK_DUMMY>, - <&clk IMX8MQ_CLK_NAND_USDHC_BUS_DIV>, - <&clk IMX8MQ_CLK_USDHC1_ROOT>; - clock-names = "ipg", "ahb", "per"; - assigned-clocks = <&clk IMX8MQ_CLK_USDHC1_DIV>; - assigned-clock-rates = <400000000>; - fsl,tuning-start-tap = <20>; - fsl,tuning-step= <2>; - bus-width = <4>; - status = "disabled"; - }; - - usdhc2: usdhc@30b50000 { - compatible = "fsl,imx8mq-usdhc", "fsl,imx7d-usdhc"; - reg = <0x0 0x30b50000 0x0 0x10000>; - interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MQ_CLK_DUMMY>, - <&clk IMX8MQ_CLK_NAND_USDHC_BUS_DIV>, - <&clk IMX8MQ_CLK_USDHC2_ROOT>; - clock-names = "ipg", "ahb", "per"; - fsl,tuning-start-tap = <20>; - fsl,tuning-step= <2>; - bus-width = <4>; - status = "disabled"; - }; - - fec1: ethernet@30be0000 { - compatible = "fsl,imx8mq-fec", "fsl,imx6sx-fec"; - reg = <0x0 0x30be0000 0x0 0x10000>; - interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MQ_CLK_ENET1_ROOT>, - <&clk IMX8MQ_CLK_ENET1_ROOT>, - <&clk IMX8MQ_CLK_ENET_TIMER_DIV>, - <&clk IMX8MQ_CLK_ENET_REF_DIV>, - <&clk IMX8MQ_CLK_ENET_PHY_REF_DIV>; - clock-names = "ipg", "ahb", "ptp", - "enet_clk_ref", "enet_out"; - assigned-clocks = <&clk IMX8MQ_CLK_ENET_AXI_SRC>, - <&clk IMX8MQ_CLK_ENET_TIMER_SRC>, - <&clk IMX8MQ_CLK_ENET_REF_SRC>, - <&clk IMX8MQ_CLK_ENET_TIMER_DIV>; - assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_266M>, - <&clk IMX8MQ_SYS2_PLL_100M>, - <&clk IMX8MQ_SYS2_PLL_125M>; - assigned-clock-rates = <0>, <0>, <125000000>, <100000000>; - stop-mode = <&gpr 0x10 3>; - fsl,num-tx-queues=<3>; - fsl,num-rx-queues=<3>; - fsl,wakeup_irq = <2>; - status = "disabled"; - }; - - imx_ion { - compatible = "fsl,mxc-ion"; - fsl,heap-id = <0>; - }; - - i2c1: i2c@30a20000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,imx21-i2c"; - reg = <0x0 0x30a20000 0x0 0x10000>; - interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MQ_CLK_I2C1_ROOT>; - status = "disabled"; - }; - - i2c2: i2c@30a30000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,imx21-i2c"; - reg = <0x0 0x30a30000 0x0 0x10000>; - interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MQ_CLK_I2C2_ROOT>; - status = "disabled"; - }; - - i2c3: i2c@30a40000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,imx21-i2c"; - reg = <0x0 0x30a40000 0x0 0x10000>; - interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MQ_CLK_I2C3_ROOT>; - status = "disabled"; - }; - - i2c4: i2c@30a50000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,imx21-i2c"; - reg = <0x0 0x30a50000 0x0 0x10000>; - interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MQ_CLK_I2C4_ROOT>; - status = "disabled"; - }; - - wdog1: wdog@30280000 { - compatible = "fsl,imx21-wdt"; - reg = <0 0x30280000 0 0x10000>; - interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MQ_CLK_WDOG1_ROOT>; - status = "disabled"; - }; - - wdog2: wdog@30290000 { - compatible = "fsl,imx21-wdt"; - reg = <0 0x30290000 0 0x10000>; - interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MQ_CLK_WDOG2_ROOT>; - status = "disabled"; - }; - - wdog3: wdog@302a0000 { - compatible = "fsl,imx21-wdt"; - reg = <0 0x302a0000 0 0x10000>; - interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MQ_CLK_WDOG3_ROOT>; - status = "disabled"; - }; - - dma_cap: dma_cap { - compatible = "dma-capability"; - only-dma-mask32 = <1>; - }; - - qspi: qspi@30bb0000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,imx7d-qspi"; - reg = <0 0x30bb0000 0 0x10000>, <0 0x08000000 0 0x10000000>; - reg-names = "QuadSPI", "QuadSPI-memory"; - interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MQ_CLK_QSPI_ROOT>, - <&clk IMX8MQ_CLK_QSPI_ROOT>; - clock-names = "qspi_en", "qspi"; - status = "disabled"; - }; -}; - -&A53_0 { - #cooling-cells = <2>; -}; diff --git a/arch/arm/dts/fsl-imx8qxp-ai_ml-u-boot.dtsi b/arch/arm/dts/fsl-imx8qxp-ai_ml-u-boot.dtsi new file mode 100644 index 0000000000..3ca53bb945 --- /dev/null +++ b/arch/arm/dts/fsl-imx8qxp-ai_ml-u-boot.dtsi @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 Linaro Ltd. + */ + +&{/imx8qx-pm} { + + u-boot,dm-spl; +}; + +&mu { + u-boot,dm-spl; +}; + +&clk { + u-boot,dm-spl; +}; + +&iomuxc { + u-boot,dm-spl; +}; + +&pd_lsio { + u-boot,dm-spl; +}; + +&pd_lsio_gpio0 { + u-boot,dm-spl; +}; + +&pd_lsio_gpio1 { + u-boot,dm-spl; +}; + +&pd_lsio_gpio2 { + u-boot,dm-spl; +}; + +&pd_lsio_gpio3 { + u-boot,dm-spl; +}; + +&pd_lsio_gpio4 { + u-boot,dm-spl; +}; + +&pd_lsio_gpio5 { + u-boot,dm-spl; +}; + +&pd_lsio_gpio6 { + u-boot,dm-spl; +}; + +&pd_lsio_gpio7 { + u-boot,dm-spl; +}; + +&pd_conn { + u-boot,dm-spl; +}; + +&pd_conn_sdch0 { + u-boot,dm-spl; +}; + +&pd_conn_sdch1 { + u-boot,dm-spl; +}; + +&pd_conn_sdch2 { + u-boot,dm-spl; +}; + +&gpio0 { + u-boot,dm-spl; +}; + +&gpio1 { + u-boot,dm-spl; +}; + +&gpio2 { + u-boot,dm-spl; +}; + +&gpio3 { + u-boot,dm-spl; +}; + +&gpio4 { + u-boot,dm-spl; +}; + +&gpio5 { + u-boot,dm-spl; +}; + +&gpio6 { + u-boot,dm-spl; +}; + +&gpio7 { + u-boot,dm-spl; +}; + +&lpuart2 { + u-boot,dm-spl; +}; + +&usdhc1 { + u-boot,dm-spl; +}; + +&usdhc2 { + u-boot,dm-spl; +}; diff --git a/arch/arm/dts/fsl-imx8qxp-ai_ml.dts b/arch/arm/dts/fsl-imx8qxp-ai_ml.dts new file mode 100644 index 0000000000..aa85caaff5 --- /dev/null +++ b/arch/arm/dts/fsl-imx8qxp-ai_ml.dts @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 Einfochips + * Copyright 2019 Linaro Ltd. + */ + +/dts-v1/; + +#include "fsl-imx8qxp.dtsi" +#include "fsl-imx8qxp-ai_ml-u-boot.dtsi" + +/ { + model = "Einfochips i.MX8QXP AI_ML"; + compatible = "einfochips,imx8qxp-ai_ml", "fsl,imx8qxp"; + + chosen { + bootargs = "console=ttyLP2,115200 earlycon=lpuart32,0x5a080000,115200"; + stdout-path = &lpuart2; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x00000000 0x80000000 0 0x80000000>; + }; +}; + +&lpuart0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpuart0>; + status = "okay"; +}; + +&lpuart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpuart1>; + status = "okay"; +}; + +&lpuart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpuart2>; + status = "okay"; +}; + +&lpuart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpuart3>; + status = "okay"; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1>; + phy-mode = "rgmii"; + phy-handle = <ðphy0>; + fsl,ar8031-phy-fixup; + fsl,magic-packet; + phy-reset-gpios = <&gpio4 14 GPIO_ACTIVE_LOW>; + phy-reset-duration = <10>; + phy-reset-post-delay = <150>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; + }; +}; + +/* LS-I2C1 */ +&i2c1 { + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpi2c1>; + status = "okay"; +}; + +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>; + bus-width = <4>; + no-sd; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + bus-width = <4>; + cd-gpios = <&gpio4 22 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&iomuxc { + pinctrl_fec1: fec1grp { + fsl,pins = < + SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB0_PAD 0x000014a0 + SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB1_PAD 0x000014a0 + SC_P_ENET0_MDC_CONN_ENET0_MDC 0x06000020 + SC_P_ENET0_MDIO_CONN_ENET0_MDIO 0x06000020 + SC_P_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL 0x06000020 + SC_P_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC 0x06000020 + SC_P_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 0x06000020 + SC_P_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 0x06000020 + SC_P_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2 0x06000020 + SC_P_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3 0x06000020 + SC_P_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC 0x06000020 + SC_P_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL 0x06000020 + SC_P_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 0x06000020 + SC_P_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 0x06000020 + SC_P_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2 0x06000020 + SC_P_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3 0x06000020 + >; + }; + + pinctrl_lpi2c1: lpi2c1grp { + fsl,pins = < + SC_P_USB_SS3_TC1_ADMA_I2C1_SCL 0x06000021 + SC_P_USB_SS3_TC3_ADMA_I2C1_SDA 0x06000021 + >; + }; + + pinctrl_lpuart0: lpuart0grp { + fsl,pins = < + SC_P_UART0_RX_ADMA_UART0_RX 0X06000020 + SC_P_UART0_TX_ADMA_UART0_TX 0X06000020 + >; + }; + + pinctrl_lpuart1: lpuart1grp { + fsl,pins = < + SC_P_UART1_RX_ADMA_UART1_RX 0X06000020 + SC_P_UART1_TX_ADMA_UART1_TX 0X06000020 + >; + }; + + pinctrl_lpuart2: lpuart2grp { + fsl,pins = < + SC_P_UART2_RX_ADMA_UART2_RX 0X06000020 + SC_P_UART2_TX_ADMA_UART2_TX 0X06000020 + >; + }; + + pinctrl_lpuart3: lpuart3grp { + fsl,pins = < + SC_P_FLEXCAN2_RX_ADMA_UART3_RX 0X06000020 + SC_P_FLEXCAN2_TX_ADMA_UART3_TX 0X06000020 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041 + SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021 + SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021 + SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021 + SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021 + SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041 + SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021 + SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021 + SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021 + SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021 + SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021 + SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021 + >; + }; +}; diff --git a/arch/arm/dts/imx6dl-brppt2.dts b/arch/arm/dts/imx6dl-brppt2.dts new file mode 100644 index 0000000000..4f1c52bff8 --- /dev/null +++ b/arch/arm/dts/imx6dl-brppt2.dts @@ -0,0 +1,278 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 B&R Industrial Automation GmbH + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2011 Linaro Ltd. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; + +#include "imx6dl.dtsi" +#include "imx6qdl-u-boot.dtsi" +#include <dt-bindings/pwm/pwm.h> +#include <include/dt-bindings/gpio/gpio.h> + +/ { + model = "PPT50"; + compatible = "fsl,imx6dl"; + + config { + u-boot,spl-payload-offset = <0x100000>; + }; + + fset: factory-settings { + bl-version = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + order-no = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + hw-revision = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + serial-no = <0>; + device-id = <0x0>; + parent-id = <0x0>; + hw-variant = <0x0>; + }; + + aliases { + ds1timing0 = &timing0; + ds1timing1 = &timing1; + ds1bkl = &backlight; + fset = &fset; + mxcfb0 = &mxcfb0; + touch0 = &touch0; + touch1 = &touch1; + touch2 = &touch2; + display_regulator = &display_regulator; + ldb = &ldb; + mmc0 = &usdhc4; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + mxcfb0: fb@0 { + compatible = "fsl,mxc_sdc_fb"; + disp_dev = "ldb"; + interface_pix_fmt = "RGB24"; + default_bpp = <32>; + int_clk = <0>; + late_init = <0>; + rotation = <0>; + status = "okay"; + }; + + lcd@0 { + compatible = "fsl,lcd"; + vlcd-supply = <&display_regulator>; + ipu_id = <0>; + disp_id = <0>; + default_ifmt = "RGB24"; + status = "disabled"; + + display-timings { + native-mode = <&timing1>; + timing1: lcd { + }; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pwm4 0 5000000>; + brightness-levels = <0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100>; + default-brightness-level = <0>; + status = "okay"; + + enable-gpios = <&gpio1 15 GPIO_ACTIVE_HIGH>; + }; + + beeper: pwm-beep { + compatible = "pwm-beeper"; + pwms = <&pwm3 0 0 0>; + }; + + vbus1_regulator: regulator@1 { + u-boot,dm-preloc; + compatible = "regulator-fixed"; + regulator-name = "vbus1_regulator"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + vbus2_regulator: regulator@2 { + compatible = "regulator-fixed"; + regulator-name = "vbus2_regulator"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + usbhub_regulator: gpio-regulator@3 { + compatible = "regulator-gpio"; + regulator-name = "ushbub_regulator"; + enable-gpio = <&gpio1 16 GPIO_ACTIVE_HIGH>; + enable-active-high; + enable-at-boot; + states = <0 0 1 1>; + }; + display_regulator: regulator@4 { + compatible = "regulator-fixed"; + regulator-name = "display_regulator"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio5 18 GPIO_ACTIVE_HIGH>; + enable-active-high; + startup-delay-us = <1000>; + }; +}; + +&fec { + phy-mode = "rgmii-id"; + status = "okay"; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&uart1 { + u-boot,dm-spl; + u-boot,dm-preloc; + status = "okay"; +}; + +&pwm3 { + status = "okay"; +}; + +&pwm4 { + status = "okay"; +}; + +&ldb { + status = "disabled"; + vldb-supply = <&display_regulator>; + + lvds-channel@0 { + fsl,data-mapping = "spwg"; + fsl,data-width = <24>; + primary; + status = "okay"; + crtc = "ipu1-di0"; + + display-timings { + native-mode = <&timing0>; + timing0: lcd { + }; + }; + }; +}; + +&usdhc4 { + non-removable; + bus-width = <8>; + status = "okay"; +}; + +&usbotg { + vbus-supply = <&vbus1_regulator>; + dr_mode = "host"; + status = "okay"; +}; + +&usbh1 { + vbus-supply = <&vbus2_regulator>; + dr_mode = "host"; + status = "okay"; +}; + +&i2c3 { + clock-frequency = <400000>; + status = "okay"; + + touch0: egalax_i2c@2a { + compatible = "eeti,egalax_i2c"; + reg = <0x2a>; + interrupt-parent = <&gpio4>; + interrupts = <9 2>; + int-gpios = <&gpio4 9 GPIO_ACTIVE_HIGH>; + }; + + touch1: gt911@5d { + compatible = "goodix,gt911"; + reg = <0x5d>; + interrupt-parent = <&gpio4>; + interrupts = <9 2>; + irq-gpios = <&gpio4 9 GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio4 11 GPIO_ACTIVE_HIGH>; + status = "disabled"; + }; + + touch2: i2c-hid-dev@2c { + compatible = "hid-over-i2c"; + reg = <0x2c>; + hid-descr-addr = <0x0001>; + interrupt-parent = <&gpio4>; + interrupts = <9 2>; + status = "disabled"; + }; +}; + +&gpio1 { + u-boot,dm-spl; + status = "okay"; +}; + +&gpio2 { + u-boot,dm-spl; + status = "okay"; +}; + +&gpio3 { + u-boot,dm-spl; + status = "okay"; +}; + +&gpio4 { + u-boot,dm-spl; + status = "okay"; +}; + +&usdhc4 { + status = "okay"; +}; + +&ecspi1 { + u-boot,dm-spl; + cs-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>, <&gpio3 19 GPIO_ACTIVE_LOW>; + status = "okay"; + spi-max-frequency = <25000000>; + + m25p32@1 { + u-boot,dm-spl; + #address-cells = <1>; + #size-cells = <1>; + compatible = "st,m25p", "jedec,spi-nor"; + spi-max-frequency = <25000000>; + reg = <1>; + }; +}; diff --git a/arch/arm/dts/imx6q-kp.dts b/arch/arm/dts/imx6q-kp.dts index 12d6db6f80..48ade9eeac 100644 --- a/arch/arm/dts/imx6q-kp.dts +++ b/arch/arm/dts/imx6q-kp.dts @@ -76,6 +76,11 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; + + ds1307: rtc@32 { + compatible = "dallas,ds1307"; + reg = <0x32>; + }; }; &i2c2 { diff --git a/arch/arm/dts/imx6q-mccmon6.dts b/arch/arm/dts/imx6q-mccmon6.dts new file mode 100644 index 0000000000..27cde56115 --- /dev/null +++ b/arch/arm/dts/imx6q-mccmon6.dts @@ -0,0 +1,382 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2019 + * Lukasz Majewski, DENX Software Engineering, lukma@denx.de + * + * SPDX-License-Identifier: GPL-2.0+ or X11 + */ + +/dts-v1/; +#include <dt-bindings/gpio/gpio.h> +#include "imx6q.dtsi" + +/ { + model = "Liebherr Nenzig (LWN) iMX6Q"; + compatible = "lwn,imx6-mccmon6", "fsl,imx6"; + + aliases { + mmc0 = &usdhc3; + mmc1 = &usdhc2; + spi0 = &ecspi3; + }; + + chosen { + stdout-path = &uart1; + }; + + memory@10000000 { + reg = <0x10000000 0x80000000>; + }; +}; + +&ecspi3 { + cs-gpios = <&gpio4 24 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi3 &pinctrl_ecspi3_cs &pinctrl_ecspi3_flwp>; + spi-max-frequency = <25000000>; + status = "okay"; + + s25sl032p: flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + spi-max-frequency = <40000000>; + reg = <0>; + }; +}; + +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet>; + phy-mode = "rgmii"; + phy-reset-gpios = <&gpio1 27 GPIO_ACTIVE_LOW>; + phy-reset-duration = <10>; + phy-reset-post-delay = <1>; + /* KSZ9031 PHY SKEW setup - old values * 60 ps */ + rxc-skew-ps = <1860>; + txc-skew-ps = <1860>; + txen-skew-ps = <900>; + rxdv-skew-ps = <900>; + rxd0-skew-ps = <180>; + rxd1-skew-ps = <180>; + rxd2-skew-ps = <180>; + rxd3-skew-ps = <180>; + txd0-skew-ps = <120>; + txd1-skew-ps = <300>; + txd2-skew-ps = <0>; + txd3-skew-ps = <120>; + status = "okay"; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; +}; + +&i2c2 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + pfuze100: pmic@8 { + compatible = "fsl,pfuze100"; + reg = <0x08>; + + regulators { + sw1a_reg: sw1ab { + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + sw1c_reg: sw1c { + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1875000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + sw2_reg: sw2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3950000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3a_reg: sw3a { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1975000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3b_reg: sw3b { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1975000>; + regulator-boot-on; + regulator-always-on; + }; + + sw4_reg: sw4 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + }; + + swbst_reg: swbst { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5150000>; + }; + + snvs_reg: vsnvs { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-always-on; + }; + + vref_reg: vrefddr { + regulator-boot-on; + regulator-always-on; + }; + + vgen1_reg: vgen1 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + }; + + vgen2_reg: vgen2 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + }; + + vgen3_reg: vgen3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + }; + + vgen4_reg: vgen4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen5_reg: vgen5 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen6_reg: vgen6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + }; +}; + +&weim { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_weim_nor &pinctrl_weim_cs0>; + ranges = <0 0 0x08000000 0x08000000>; + status = "okay"; + + nor@0,0 { + compatible = "cfi-flash"; + reg = <0 0 0x02000000>; + #address-cells = <1>; + #size-cells = <1>; + bank-width = <2>; + use-advanced-sector-protection; + fsl,weim-cs-timing = <0x00620081 0x00000001 0x1c022000 + 0x0000c000 0x1404a38e 0x00000000>; + }; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + pinctrl_ecspi3: ecspi3grp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1 + MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1 + MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1 + >; + }; + + pinctrl_ecspi3_cs: ecspi3csgrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24 0x80000000 + >; + }; + + pinctrl_ecspi3_flwp: ecspi3flwpgrp { + fsl,pins = < + MX6QDL_PAD_DISP0_DAT6__GPIO4_IO27 0x80000000 + >; + }; + + pinctrl_enet: enetgrp { + fsl,pins = < + MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0 + MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0 + MX6QDL_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0 + MX6QDL_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0 + MX6QDL_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0 + MX6QDL_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0 + MX6QDL_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0 + MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0 + MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0 + MX6QDL_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0 + MX6QDL_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0 + MX6QDL_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0 + MX6QDL_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0 + MX6QDL_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0 + MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0 + MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8 + MX6QDL_PAD_GPIO_6__ENET_IRQ 0x000b1 + MX6QDL_PAD_ENET_RXD0__GPIO1_IO27 0x1b0b0 + >; + }; + + pinctrl_hog: hoggrp { + fsl,pins = < + MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0 + MX6QDL_PAD_GPIO_1__GPIO1_IO01 0x1b0b0 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1 + MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1 + MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1 + MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17059 + MX6QDL_PAD_SD2_CLK__SD2_CLK 0x10059 + MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17059 + MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17059 + MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17059 + MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17059 + MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b1 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 + MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 + MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 + MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 + MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 + MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 + MX6QDL_PAD_SD3_DAT4__SD3_DATA4 0x17059 + MX6QDL_PAD_SD3_DAT5__SD3_DATA5 0x17059 + MX6QDL_PAD_SD3_DAT6__SD3_DATA6 0x17059 + MX6QDL_PAD_SD3_DAT7__SD3_DATA7 0x17059 + MX6QDL_PAD_SD3_RST__SD3_RESET 0x17059 + >; + }; + + pinctrl_weim_cs0: weimcs0grp { + fsl,pins = < + MX6QDL_PAD_EIM_CS0__EIM_CS0_B 0xb0b1 + >; + }; + + pinctrl_weim_nor: weimnorgrp { + fsl,pins = < + MX6QDL_PAD_EIM_OE__EIM_OE_B 0xb0b1 + MX6QDL_PAD_EIM_RW__EIM_RW 0xb0b1 + MX6QDL_PAD_EIM_WAIT__EIM_WAIT_B 0xb060 + MX6QDL_PAD_EIM_D16__EIM_DATA16 0x1b0b0 + MX6QDL_PAD_EIM_D17__EIM_DATA17 0x1b0b0 + MX6QDL_PAD_EIM_D18__EIM_DATA18 0x1b0b0 + MX6QDL_PAD_EIM_D19__EIM_DATA19 0x1b0b0 + MX6QDL_PAD_EIM_D20__EIM_DATA20 0x1b0b0 + MX6QDL_PAD_EIM_D21__EIM_DATA21 0x1b0b0 + MX6QDL_PAD_EIM_D22__EIM_DATA22 0x1b0b0 + MX6QDL_PAD_EIM_D23__EIM_DATA23 0x1b0b0 + MX6QDL_PAD_EIM_D24__EIM_DATA24 0x1b0b0 + MX6QDL_PAD_EIM_D25__EIM_DATA25 0x1b0b0 + MX6QDL_PAD_EIM_D26__EIM_DATA26 0x1b0b0 + MX6QDL_PAD_EIM_D27__EIM_DATA27 0x1b0b0 + MX6QDL_PAD_EIM_D28__EIM_DATA28 0x1b0b0 + MX6QDL_PAD_EIM_D29__EIM_DATA29 0x1b0b0 + MX6QDL_PAD_EIM_D30__EIM_DATA30 0x1b0b0 + MX6QDL_PAD_EIM_D31__EIM_DATA31 0x1b0b0 + MX6QDL_PAD_EIM_A23__EIM_ADDR23 0xb0b1 + MX6QDL_PAD_EIM_A22__EIM_ADDR22 0xb0b1 + MX6QDL_PAD_EIM_A21__EIM_ADDR21 0xb0b1 + MX6QDL_PAD_EIM_A20__EIM_ADDR20 0xb0b1 + MX6QDL_PAD_EIM_A19__EIM_ADDR19 0xb0b1 + MX6QDL_PAD_EIM_A18__EIM_ADDR18 0xb0b1 + MX6QDL_PAD_EIM_A17__EIM_ADDR17 0xb0b1 + MX6QDL_PAD_EIM_A16__EIM_ADDR16 0xb0b1 + MX6QDL_PAD_EIM_DA15__EIM_AD15 0xb0b1 + MX6QDL_PAD_EIM_DA14__EIM_AD14 0xb0b1 + MX6QDL_PAD_EIM_DA13__EIM_AD13 0xb0b1 + MX6QDL_PAD_EIM_DA12__EIM_AD12 0xb0b1 + MX6QDL_PAD_EIM_DA11__EIM_AD11 0xb0b1 + MX6QDL_PAD_EIM_DA10__EIM_AD10 0xb0b1 + MX6QDL_PAD_EIM_DA9__EIM_AD09 0xb0b1 + MX6QDL_PAD_EIM_DA8__EIM_AD08 0xb0b1 + MX6QDL_PAD_EIM_DA7__EIM_AD07 0xb0b1 + MX6QDL_PAD_EIM_DA6__EIM_AD06 0xb0b1 + MX6QDL_PAD_EIM_DA5__EIM_AD05 0xb0b1 + MX6QDL_PAD_EIM_DA4__EIM_AD04 0xb0b1 + MX6QDL_PAD_EIM_DA3__EIM_AD03 0xb0b1 + MX6QDL_PAD_EIM_DA2__EIM_AD02 0xb0b1 + MX6QDL_PAD_EIM_DA1__EIM_AD01 0xb0b1 + MX6QDL_PAD_EIM_DA0__EIM_AD00 0xb0b1 + >; + }; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc2>; + bus-width = <4>; + cd-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3>; + bus-width = <8>; + non-removable; + no-1-8-v; + keep-power-in-suspend; + status = "okay"; +}; diff --git a/arch/arm/dts/imx6ul-opos6uldev-u-boot.dtsi b/arch/arm/dts/imx6ul-opos6uldev-u-boot.dtsi index da8b0392ef..3f351ef0c4 100644 --- a/arch/arm/dts/imx6ul-opos6uldev-u-boot.dtsi +++ b/arch/arm/dts/imx6ul-opos6uldev-u-boot.dtsi @@ -7,6 +7,12 @@ #include "imx6ul-opos6ul-u-boot.dtsi" +/ { + aliases { + display0 = &lcdif; + }; +}; + &aips1 { u-boot,dm-spl; @@ -15,6 +21,10 @@ }; }; +&lcdif { + u-boot,dm-pre-proper; +}; + &pinctrl_uart1 { u-boot,dm-spl; }; diff --git a/arch/arm/dts/imx6ul-opos6uldev.dts b/arch/arm/dts/imx6ul-opos6uldev.dts index 0e59ee57fd..4a541be6b0 100644 --- a/arch/arm/dts/imx6ul-opos6uldev.dts +++ b/arch/arm/dts/imx6ul-opos6uldev.dts @@ -187,7 +187,7 @@ status = "okay"; display0: display0 { - bits-per-pixel = <32>; + bits-per-pixel = <18>; bus-width = <18>; display-timings { @@ -202,7 +202,7 @@ hsync-len = <64>; vsync-len = <4>; de-active = <1>; - pixelclk-active = <0>; + pixelclk-active = <1>; }; }; }; diff --git a/arch/arm/dts/imx6ull-colibri-u-boot.dtsi b/arch/arm/dts/imx6ull-colibri-u-boot.dtsi new file mode 100644 index 0000000000..531cdcc4da --- /dev/null +++ b/arch/arm/dts/imx6ull-colibri-u-boot.dtsi @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2019 Toradex AG + */ + +&pinctrl_uart1 { + u-boot,dm-pre-reloc; +}; + +&pinctrl_uart1_ctrl1 { + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/dts/imx6ull-colibri.dts b/arch/arm/dts/imx6ull-colibri.dts index 262205ac5e..15338a1ae3 100644 --- a/arch/arm/dts/imx6ull-colibri.dts +++ b/arch/arm/dts/imx6ull-colibri.dts @@ -3,634 +3,10 @@ * Copyright 2018-2019 Toradex AG */ -/dts-v1/; -#include <dt-bindings/gpio/gpio.h> -#include "imx6ull.dtsi" +#include "imx6ull-colibri.dtsi" +#include "imx6ull-colibri-u-boot.dtsi" / { model = "Toradex Colibri iMX6ULL"; compatible = "toradex,colibri-imx6ull", "fsl,imx6ull"; - - aliases { - u-boot,dm-pre-reloc; - mmc0 = &usdhc1; - usb0 = &usbotg1; /* required for ums */ - display0 = &lcdif; - }; - - chosen { - stdout-path = &uart1; - }; - - reg_module_3v3: regulator-module-3v3 { - compatible = "regulator-fixed"; - regulator-always-on; - regulator-name = "+V3.3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - reg_module_3v3_avdd: regulator-module-3v3-avdd { - compatible = "regulator-fixed"; - regulator-always-on; - regulator-name = "+V3.3_AVDD_AUDIO"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - reg_5v0: regulator-5v0 { - compatible = "regulator-fixed"; - regulator-name = "5V"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - }; - - reg_sd1_vmmc: regulator-sd1-vmmc { - compatible = "regulator-gpio"; - gpio = <&gpio5 9 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_snvs_reg_sd>; - regulator-always-on; - regulator-name = "+V3.3_1.8_SD"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - states = <1800000 0x1 3300000 0x0>; - vin-supply = <®_module_3v3>; - }; - - reg_usbh_vbus: regulator-usbh-vbus { - compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_usbh_reg>; - regulator-name = "VCC_USB[1-4]"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - gpio = <&gpio1 2 GPIO_ACTIVE_LOW>; /* USBH_PEN */ - vin-supply = <®_5v0>; - }; -}; - -&adc1 { - num-channels = <10>; - vref-supply = <®_module_3v3_avdd>; -}; - -/* Colibri SPI */ -&ecspi1 { - cs-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>; -}; - -/* Ethernet */ -&fec2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_enet2>; - phy-mode = "rmii"; - phy-handle = <ðphy1>; - status = "okay"; - - mdio { - #address-cells = <1>; - #size-cells = <0>; - - ethphy1: ethernet-phy@2 { - compatible = "ethernet-phy-ieee802.3-c22"; - max-speed = <100>; - reg = <2>; - }; - }; -}; - -/* NAND */ -&gpmi { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_gpmi_nand>; - nand-on-flash-bbt; - nand-ecc-mode = "hw"; - nand-ecc-strength = <8>; - nand-ecc-step-size = <512>; - status = "okay"; -}; - -/* - * I2C3_SDA/SCL on SODIMM 194/196 (e.g. RTC on carrier board) - */ -&i2c1 { - pinctrl-names = "default", "gpio"; - pinctrl-0 = <&pinctrl_i2c1>; - pinctrl-1 = <&pinctrl_i2c1_gpio>; - sda-gpios = <&gpio1 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; - scl-gpios = <&gpio1 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; - status = "okay"; -}; - -/* - * PWR_I2C: power I2C to audio codec, PMIC, temperature sensor and - * touch screen controller - */ -&i2c2 { - pinctrl-names = "default", "gpio"; - pinctrl-0 = <&pinctrl_i2c2>; - pinctrl-1 = <&pinctrl_i2c2_gpio>; - sda-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; - scl-gpios = <&gpio1 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; - status = "okay"; - - ad7879@2c { - compatible = "adi,ad7879-1"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_snvs_ad7879_int>; - reg = <0x2c>; - interrupt-parent = <&gpio5>; - interrupts = <7 IRQ_TYPE_EDGE_FALLING>; - touchscreen-max-pressure = <4096>; - adi,resistance-plate-x = <120>; - adi,first-conversion-delay = /bits/ 8 <3>; - adi,acquisition-time = /bits/ 8 <1>; - adi,median-filter-size = /bits/ 8 <2>; - adi,averaging = /bits/ 8 <1>; - adi,conversion-interval = /bits/ 8 <255>; - }; -}; - -&lcdif { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_lcdif_dat - &pinctrl_lcdif_ctrl>; - status = "okay"; - display = <&display0>; - u-boot,dm-pre-reloc; - - display0: display0 { - bits-per-pixel = <18>; - bus-width = <24>; - status = "okay"; - - display-timings { - native-mode = <&timing_vga>; - timing_vga: 640x480 { - u-boot,dm-pre-reloc; - clock-frequency = <25175000>; - hactive = <640>; - vactive = <480>; - hback-porch = <48>; - hfront-porch = <16>; - vback-porch = <33>; - vfront-porch = <10>; - hsync-len = <96>; - vsync-len = <2>; - - de-active = <1>; - hsync-active = <0>; - vsync-active = <0>; - pixelclk-active = <0>; - }; - }; - }; -}; - -/* PWM <A> */ -&pwm4 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm4>; - #pwm-cells = <3>; -}; - -/* PWM <B> */ -&pwm5 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm5>; - #pwm-cells = <3>; -}; - -/* PWM <C> */ -&pwm6 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm6>; - #pwm-cells = <3>; -}; - -/* PWM <D> */ -&pwm7 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_pwm7>; - #pwm-cells = <3>; -}; - -&sdma { - status = "okay"; -}; - -&snvs_pwrkey { - status = "disabled"; -}; - -/* Colibri UART_A */ -&uart1 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart1 &pinctrl_uart1_ctrl1>; - uart-has-rtscts; - fsl,dte-mode; - status = "okay"; -}; - -/* Colibri UART_B */ -&uart2 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart2>; - uart-has-rtscts; - fsl,dte-mode; -}; - -/* Colibri UART_C */ -&uart5 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart5>; - fsl,dte-mode; -}; - -/* Colibri USBC */ -&usbotg1 { - dr_mode = "host"; - srp-disable; - hnp-disable; - adp-disable; - status = "okay"; -}; - -/* Colibri USBH */ -&usbotg2 { - dr_mode = "host"; - vbus-supply = <®_usbh_vbus>; - status = "okay"; -}; - -/* Colibri MMC */ -&usdhc1 { - assigned-clocks = <&clks IMX6UL_CLK_USDHC1_SEL>, <&clks IMX6UL_CLK_USDHC1>; - assigned-clock-parents = <&clks IMX6UL_CLK_PLL2_PFD2>; - assigned-clock-rates = <0>, <198000000>; - cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; /* MMC_CD */ - pinctrl-names = "default", "state_100mhz", "state_200mhz"; - pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_snvs_usdhc1_cd>; - pinctrl-1 = <&pinctrl_usdhc1_100mhz>; - pinctrl-2 = <&pinctrl_usdhc1_200mhz>; - vmmc-supply = <®_sd1_vmmc>; - status = "okay"; -}; - -&iomuxc { - pinctrl_can_int: canint-grp { - fsl,pins = < - /* SODIMM 73 */ - MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04 0X14 - >; - }; - - pinctrl_enet2: enet2-grp { - fsl,pins = < - MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0 - MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0 - MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0 - MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0 - MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0 - MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0 - MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031 - MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0 - MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0 - MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0 - >; - }; - - pinctrl_ecspi1_cs: ecspi1-cs-grp { - fsl,pins = < - MX6UL_PAD_LCD_DATA21__GPIO3_IO26 0x000a0 - >; - }; - - pinctrl_ecspi1: ecspi1-grp { - fsl,pins = < - MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK 0x000a0 - MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI 0x000a0 - MX6UL_PAD_LCD_DATA23__ECSPI1_MISO 0x100a0 - >; - }; - - pinctrl_flexcan2: flexcan2-grp { - fsl,pins = < - MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX 0x1b020 - MX6UL_PAD_ENET1_RX_EN__FLEXCAN2_TX 0x1b020 - >; - }; - - pinctrl_gpio_bl_on: gpio-bl-on-grp { - fsl,pins = < - MX6UL_PAD_JTAG_TMS__GPIO1_IO11 0x000a0 - >; - }; - - pinctrl_gpio1: gpio1-grp { - fsl,pins = < - MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00 0x74 /* SODIMM 55 */ - MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01 0x74 /* SODIMM 63 */ - MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25 0X14 /* SODIMM 77 */ - MX6UL_PAD_JTAG_TCK__GPIO1_IO14 0x14 /* SODIMM 99 */ - MX6UL_PAD_NAND_CE1_B__GPIO4_IO14 0x14 /* SODIMM 133 */ - MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24 0x14 /* SODIMM 135 */ - MX6UL_PAD_UART3_CTS_B__GPIO1_IO26 0x14 /* SODIMM 100 */ - MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15 0x14 /* SODIMM 102 */ - MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07 0x14 /* SODIMM 104 */ - MX6UL_PAD_UART3_RTS_B__GPIO1_IO27 0x14 /* SODIMM 186 */ - >; - }; - - pinctrl_gpio2: gpio2-grp { /* Camera */ - fsl,pins = < - MX6UL_PAD_CSI_DATA04__GPIO4_IO25 0x74 /* SODIMM 69 */ - MX6UL_PAD_CSI_MCLK__GPIO4_IO17 0x14 /* SODIMM 75 */ - MX6UL_PAD_CSI_DATA06__GPIO4_IO27 0x14 /* SODIMM 85 */ - MX6UL_PAD_CSI_PIXCLK__GPIO4_IO18 0x14 /* SODIMM 96 */ - MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x14 /* SODIMM 98 */ - >; - }; - - pinctrl_gpio3: gpio3-grp { /* CAN2 */ - fsl,pins = < - MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02 0x14 /* SODIMM 178 */ - MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03 0x14 /* SODIMM 188 */ - >; - }; - - pinctrl_gpio4: gpio4-grp { - fsl,pins = < - MX6UL_PAD_CSI_DATA07__GPIO4_IO28 0x74 /* SODIMM 65 */ - >; - }; - - pinctrl_gpio5: gpio5-grp { /* ATMEL MXT TOUCH */ - fsl,pins = < - MX6UL_PAD_JTAG_MOD__GPIO1_IO10 0x74 /* SODIMM 106 */ - >; - }; - - pinctrl_gpio6: gpio6-grp { /* Wifi pins */ - fsl,pins = < - MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x14 /* SODIMM 89 */ - MX6UL_PAD_CSI_DATA02__GPIO4_IO23 0x14 /* SODIMM 79 */ - MX6UL_PAD_CSI_VSYNC__GPIO4_IO19 0x14 /* SODIMM 81 */ - MX6UL_PAD_CSI_DATA03__GPIO4_IO24 0x14 /* SODIMM 97 */ - MX6UL_PAD_CSI_DATA00__GPIO4_IO21 0x14 /* SODIMM 101 */ - MX6UL_PAD_CSI_DATA01__GPIO4_IO22 0x14 /* SODIMM 103 */ - MX6UL_PAD_CSI_HSYNC__GPIO4_IO20 0x14 /* SODIMM 94 */ - >; - }; - - pinctrl_gpmi_nand: gpmi-nand-grp { - fsl,pins = < - MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0x100a9 - MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0x100a9 - MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0x100a9 - MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0x100a9 - MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0x100a9 - MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0x100a9 - MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0x100a9 - MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0x100a9 - MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0x100a9 - MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0x100a9 - MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0x100a9 - MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0x100a9 - MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0x100a9 - MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0x100a9 - >; - }; - - pinctrl_i2c1: i2c1-grp { - fsl,pins = < - MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0 - MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0 - >; - }; - - pinctrl_i2c1_gpio: i2c1-gpio-grp { - fsl,pins = < - MX6UL_PAD_UART4_TX_DATA__GPIO1_IO28 0x4001b8b0 - MX6UL_PAD_UART4_RX_DATA__GPIO1_IO29 0x4001b8b0 - >; - }; - - pinctrl_i2c2: i2c2-grp { - fsl,pins = < - MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0 - MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0 - >; - }; - - pinctrl_i2c2_gpio: i2c2-gpio-grp { - fsl,pins = < - MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30 0x4001b8b0 - MX6UL_PAD_UART5_RX_DATA__GPIO1_IO31 0x4001b8b0 - >; - }; - - pinctrl_lcdif_dat: lcdif-dat-grp { - fsl,pins = < - MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x00079 - MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x00079 - MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x00079 - MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x00079 - MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x00079 - MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x00079 - MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x00079 - MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x00079 - MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x00079 - MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x00079 - MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x00079 - MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x00079 - MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x00079 - MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x00079 - MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x00079 - MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x00079 - MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x00079 - MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x00079 - >; - }; - - pinctrl_lcdif_ctrl: lcdif-ctrl-grp { - fsl,pins = < - MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x00079 - MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x00079 - MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x00079 - MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x00079 - >; - }; - - pinctrl_pwm4: pwm4-grp { - fsl,pins = < - MX6UL_PAD_NAND_WP_B__PWM4_OUT 0x00079 - >; - }; - - pinctrl_pwm5: pwm5-grp { - fsl,pins = < - MX6UL_PAD_NAND_DQS__PWM5_OUT 0x00079 - >; - }; - - pinctrl_pwm6: pwm6-grp { - fsl,pins = < - MX6UL_PAD_ENET1_TX_EN__PWM6_OUT 0x00079 - >; - }; - - pinctrl_pwm7: pwm7-grp { - fsl,pins = < - MX6UL_PAD_ENET1_TX_CLK__PWM7_OUT 0x00079 - >; - }; - - pinctrl_uart1: uart1-grp { - fsl,pins = < - MX6UL_PAD_UART1_TX_DATA__UART1_DTE_RX 0x1b0b1 - MX6UL_PAD_UART1_RX_DATA__UART1_DTE_TX 0x1b0b1 - MX6UL_PAD_UART1_RTS_B__UART1_DTE_CTS 0x1b0b1 - MX6UL_PAD_UART1_CTS_B__UART1_DTE_RTS 0x1b0b1 - >; - }; - - pinctrl_uart1_ctrl1: uart1-ctrl1-grp { /* Additional DTR, DCD */ - fsl,pins = < - MX6UL_PAD_JTAG_TDI__GPIO1_IO13 0x1b0b1 /* DCD */ - MX6UL_PAD_LCD_DATA18__GPIO3_IO23 0x1b0b1 /* DSR */ - MX6UL_PAD_JTAG_TDO__GPIO1_IO12 0x1b0b1 /* DTR */ - MX6UL_PAD_LCD_DATA19__GPIO3_IO24 0x1b0b1 /* RI */ - >; - }; - - pinctrl_uart2: uart2-grp { - fsl,pins = < - MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x1b0b1 - MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x1b0b1 - MX6UL_PAD_UART2_CTS_B__UART2_DTE_RTS 0x1b0b1 - MX6UL_PAD_UART2_RTS_B__UART2_DTE_CTS 0x1b0b1 - >; - }; - pinctrl_uart5: uart5-grp { - fsl,pins = < - MX6UL_PAD_GPIO1_IO04__UART5_DTE_RX 0x1b0b1 - MX6UL_PAD_GPIO1_IO05__UART5_DTE_TX 0x1b0b1 - >; - }; - - pinctrl_usbh_reg: gpio-usbh-reg { - fsl,pins = < - MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0x1b0b1 /* SODIMM 129 USBH PEN */ - >; - }; - - pinctrl_usdhc1: usdhc1-grp { - fsl,pins = < - MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x17059 - MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x10059 - MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059 - MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059 - MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059 - MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059 - >; - }; - - pinctrl_usdhc1_100mhz: usdhc1-100mhz-grp { - fsl,pins = < - MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x170b9 - MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x100b9 - MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9 - MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9 - MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9 - MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9 - >; - }; - - pinctrl_usdhc1_200mhz: usdhc1-200mhz-grp { - fsl,pins = < - MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x170f9 - MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x100f9 - MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9 - MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9 - MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9 - MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9 - >; - }; - - pinctrl_usdhc2: usdhc2-grp { - fsl,pins = < - MX6UL_PAD_CSI_DATA00__USDHC2_DATA0 0x17059 - MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x17059 - MX6UL_PAD_CSI_DATA02__USDHC2_DATA2 0x17059 - MX6UL_PAD_CSI_DATA03__USDHC2_DATA3 0x17059 - MX6UL_PAD_CSI_HSYNC__USDHC2_CMD 0x17059 - MX6UL_PAD_CSI_VSYNC__USDHC2_CLK 0x17059 - - MX6UL_PAD_GPIO1_IO03__OSC32K_32K_OUT 0x14 - >; - }; -}; - -&iomuxc_snvs { - pinctrl_snvs_gpio1: snvs-gpio1-grp { - fsl,pins = < - MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06 0x14 /* SODIMM 93 */ - MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x14 /* SODIMM 95 */ - MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10 0x74 /* SODIMM 105 */ - MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x14 /* SODIMM 131 USBH OC */ - MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x74 /* SODIMM 138 */ - >; - }; - - pinctrl_snvs_gpio2: snvs-gpio2-grp { /* ATMEL MXT TOUCH */ - fsl,pins = < - MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x74 /* SODIMM 107 */ - >; - }; - - pinctrl_snvs_gpio3: snvs-gpio3-grp { /* Wifi pins */ - fsl,pins = < - MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x14 /* SODIMM 127 */ - >; - }; - - pinctrl_snvs_ad7879_int: snvs-ad7879-int-grp { /* TOUCH Interrupt */ - fsl,pins = < - MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x1b0b0 - >; - }; - - pinctrl_snvs_reg_sd: snvs-reg-sd-grp { - fsl,pins = < - MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x4001b8b0 - >; - }; - - pinctrl_snvs_usbc_det: snvs-usbc-det-grp { - fsl,pins = < - MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x1b0b0 - >; - }; - - pinctrl_snvs_gpiokeys: snvs-gpiokeys-grp { - fsl,pins = < - MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x130b0 - >; - }; - - pinctrl_snvs_usdhc1_cd: snvs-usdhc1-cd-grp { - fsl,pins = < - MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x1b0b0 /* CD */ - >; - }; - - pinctrl_snvs_wifi_pdn: snvs-wifi-pdn-grp { - fsl,pins = < - MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x14 - >; - }; }; diff --git a/arch/arm/dts/imx6ull-colibri.dtsi b/arch/arm/dts/imx6ull-colibri.dtsi new file mode 100644 index 0000000000..fca53119fe --- /dev/null +++ b/arch/arm/dts/imx6ull-colibri.dtsi @@ -0,0 +1,633 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2019 Toradex AG + */ + +/dts-v1/; +#include <dt-bindings/gpio/gpio.h> +#include "imx6ull.dtsi" + +/ { + aliases { + u-boot,dm-pre-reloc; + mmc0 = &usdhc1; + usb0 = &usbotg1; /* required for ums */ + display0 = &lcdif; + }; + + chosen { + stdout-path = &uart1; + }; + + reg_module_3v3: regulator-module-3v3 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-name = "+V3.3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_module_3v3_avdd: regulator-module-3v3-avdd { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-name = "+V3.3_AVDD_AUDIO"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_5v0: regulator-5v0 { + compatible = "regulator-fixed"; + regulator-name = "5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_sd1_vmmc: regulator-sd1-vmmc { + compatible = "regulator-gpio"; + gpio = <&gpio5 9 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_snvs_reg_sd>; + regulator-always-on; + regulator-name = "+V3.3_1.8_SD"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + states = <1800000 0x1 3300000 0x0>; + vin-supply = <®_module_3v3>; + }; + + reg_usbh_vbus: regulator-usbh-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh_reg>; + regulator-name = "VCC_USB[1-4]"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio1 2 GPIO_ACTIVE_LOW>; /* USBH_PEN */ + vin-supply = <®_5v0>; + }; +}; + +&adc1 { + num-channels = <10>; + vref-supply = <®_module_3v3_avdd>; +}; + +/* Colibri SPI */ +&ecspi1 { + cs-gpios = <&gpio3 26 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi1 &pinctrl_ecspi1_cs>; +}; + +/* Ethernet */ +&fec2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_enet2>; + phy-mode = "rmii"; + phy-handle = <ðphy1>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy1: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + max-speed = <100>; + reg = <2>; + }; + }; +}; + +/* NAND */ +&gpmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpmi_nand>; + nand-on-flash-bbt; + nand-ecc-mode = "hw"; + nand-ecc-strength = <8>; + nand-ecc-step-size = <512>; + status = "okay"; +}; + +/* + * I2C3_SDA/SCL on SODIMM 194/196 (e.g. RTC on carrier board) + */ +&i2c1 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + sda-gpios = <&gpio1 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpio1 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + status = "okay"; +}; + +/* + * PWR_I2C: power I2C to audio codec, PMIC, temperature sensor and + * touch screen controller + */ +&i2c2 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c2>; + pinctrl-1 = <&pinctrl_i2c2_gpio>; + sda-gpios = <&gpio1 31 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + scl-gpios = <&gpio1 30 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + status = "okay"; + + ad7879@2c { + compatible = "adi,ad7879-1"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_snvs_ad7879_int>; + reg = <0x2c>; + interrupt-parent = <&gpio5>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + touchscreen-max-pressure = <4096>; + adi,resistance-plate-x = <120>; + adi,first-conversion-delay = /bits/ 8 <3>; + adi,acquisition-time = /bits/ 8 <1>; + adi,median-filter-size = /bits/ 8 <2>; + adi,averaging = /bits/ 8 <1>; + adi,conversion-interval = /bits/ 8 <255>; + }; +}; + +&lcdif { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcdif_dat + &pinctrl_lcdif_ctrl>; + status = "okay"; + display = <&display0>; + u-boot,dm-pre-reloc; + + display0: display0 { + bits-per-pixel = <18>; + bus-width = <24>; + status = "okay"; + + display-timings { + native-mode = <&timing_vga>; + timing_vga: 640x480 { + u-boot,dm-pre-reloc; + clock-frequency = <25175000>; + hactive = <640>; + vactive = <480>; + hback-porch = <48>; + hfront-porch = <16>; + vback-porch = <33>; + vfront-porch = <10>; + hsync-len = <96>; + vsync-len = <2>; + + de-active = <1>; + hsync-active = <0>; + vsync-active = <0>; + pixelclk-active = <0>; + }; + }; + }; +}; + +/* PWM <A> */ +&pwm4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm4>; + #pwm-cells = <3>; +}; + +/* PWM <B> */ +&pwm5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm5>; + #pwm-cells = <3>; +}; + +/* PWM <C> */ +&pwm6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm6>; + #pwm-cells = <3>; +}; + +/* PWM <D> */ +&pwm7 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm7>; + #pwm-cells = <3>; +}; + +&sdma { + status = "okay"; +}; + +&snvs_pwrkey { + status = "disabled"; +}; + +/* Colibri UART_A */ +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1 &pinctrl_uart1_ctrl1>; + uart-has-rtscts; + fsl,dte-mode; + status = "okay"; +}; + +/* Colibri UART_B */ +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + uart-has-rtscts; + fsl,dte-mode; +}; + +/* Colibri UART_C */ +&uart5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart5>; + fsl,dte-mode; +}; + +/* Colibri USBC */ +&usbotg1 { + dr_mode = "host"; + srp-disable; + hnp-disable; + adp-disable; + status = "okay"; +}; + +/* Colibri USBH */ +&usbotg2 { + dr_mode = "host"; + vbus-supply = <®_usbh_vbus>; + status = "okay"; +}; + +/* Colibri MMC */ +&usdhc1 { + assigned-clocks = <&clks IMX6UL_CLK_USDHC1_SEL>, <&clks IMX6UL_CLK_USDHC1>; + assigned-clock-parents = <&clks IMX6UL_CLK_PLL2_PFD2>; + assigned-clock-rates = <0>, <198000000>; + cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; /* MMC_CD */ + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1 &pinctrl_snvs_usdhc1_cd>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + vmmc-supply = <®_sd1_vmmc>; + status = "okay"; +}; + +&iomuxc { + pinctrl_can_int: canint-grp { + fsl,pins = < + /* SODIMM 73 */ + MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04 0X14 + >; + }; + + pinctrl_enet2: enet2-grp { + fsl,pins = < + MX6UL_PAD_GPIO1_IO06__ENET2_MDIO 0x1b0b0 + MX6UL_PAD_GPIO1_IO07__ENET2_MDC 0x1b0b0 + MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0 + MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0 + MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN 0x1b0b0 + MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER 0x1b0b0 + MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2 0x4001b031 + MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0 + MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0 + MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN 0x1b0b0 + >; + }; + + pinctrl_ecspi1_cs: ecspi1-cs-grp { + fsl,pins = < + MX6UL_PAD_LCD_DATA21__GPIO3_IO26 0x000a0 + >; + }; + + pinctrl_ecspi1: ecspi1-grp { + fsl,pins = < + MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK 0x000a0 + MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI 0x000a0 + MX6UL_PAD_LCD_DATA23__ECSPI1_MISO 0x100a0 + >; + }; + + pinctrl_flexcan2: flexcan2-grp { + fsl,pins = < + MX6UL_PAD_ENET1_TX_DATA0__FLEXCAN2_RX 0x1b020 + MX6UL_PAD_ENET1_RX_EN__FLEXCAN2_TX 0x1b020 + >; + }; + + pinctrl_gpio_bl_on: gpio-bl-on-grp { + fsl,pins = < + MX6UL_PAD_JTAG_TMS__GPIO1_IO11 0x000a0 + >; + }; + + pinctrl_gpio1: gpio1-grp { + fsl,pins = < + MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00 0x74 /* SODIMM 55 */ + MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01 0x74 /* SODIMM 63 */ + MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25 0X14 /* SODIMM 77 */ + MX6UL_PAD_JTAG_TCK__GPIO1_IO14 0x14 /* SODIMM 99 */ + MX6UL_PAD_NAND_CE1_B__GPIO4_IO14 0x14 /* SODIMM 133 */ + MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24 0x14 /* SODIMM 135 */ + MX6UL_PAD_UART3_CTS_B__GPIO1_IO26 0x14 /* SODIMM 100 */ + MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15 0x14 /* SODIMM 102 */ + MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07 0x14 /* SODIMM 104 */ + MX6UL_PAD_UART3_RTS_B__GPIO1_IO27 0x14 /* SODIMM 186 */ + >; + }; + + pinctrl_gpio2: gpio2-grp { /* Camera */ + fsl,pins = < + MX6UL_PAD_CSI_DATA04__GPIO4_IO25 0x74 /* SODIMM 69 */ + MX6UL_PAD_CSI_MCLK__GPIO4_IO17 0x14 /* SODIMM 75 */ + MX6UL_PAD_CSI_DATA06__GPIO4_IO27 0x14 /* SODIMM 85 */ + MX6UL_PAD_CSI_PIXCLK__GPIO4_IO18 0x14 /* SODIMM 96 */ + MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x14 /* SODIMM 98 */ + >; + }; + + pinctrl_gpio3: gpio3-grp { /* CAN2 */ + fsl,pins = < + MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02 0x14 /* SODIMM 178 */ + MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03 0x14 /* SODIMM 188 */ + >; + }; + + pinctrl_gpio4: gpio4-grp { + fsl,pins = < + MX6UL_PAD_CSI_DATA07__GPIO4_IO28 0x74 /* SODIMM 65 */ + >; + }; + + pinctrl_gpio5: gpio5-grp { /* ATMEL MXT TOUCH */ + fsl,pins = < + MX6UL_PAD_JTAG_MOD__GPIO1_IO10 0x74 /* SODIMM 106 */ + >; + }; + + pinctrl_gpio6: gpio6-grp { /* Wifi pins */ + fsl,pins = < + MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0x14 /* SODIMM 89 */ + MX6UL_PAD_CSI_DATA02__GPIO4_IO23 0x14 /* SODIMM 79 */ + MX6UL_PAD_CSI_VSYNC__GPIO4_IO19 0x14 /* SODIMM 81 */ + MX6UL_PAD_CSI_DATA03__GPIO4_IO24 0x14 /* SODIMM 97 */ + MX6UL_PAD_CSI_DATA00__GPIO4_IO21 0x14 /* SODIMM 101 */ + MX6UL_PAD_CSI_DATA01__GPIO4_IO22 0x14 /* SODIMM 103 */ + MX6UL_PAD_CSI_HSYNC__GPIO4_IO20 0x14 /* SODIMM 94 */ + >; + }; + + pinctrl_gpmi_nand: gpmi-nand-grp { + fsl,pins = < + MX6UL_PAD_NAND_DATA00__RAWNAND_DATA00 0x100a9 + MX6UL_PAD_NAND_DATA01__RAWNAND_DATA01 0x100a9 + MX6UL_PAD_NAND_DATA02__RAWNAND_DATA02 0x100a9 + MX6UL_PAD_NAND_DATA03__RAWNAND_DATA03 0x100a9 + MX6UL_PAD_NAND_DATA04__RAWNAND_DATA04 0x100a9 + MX6UL_PAD_NAND_DATA05__RAWNAND_DATA05 0x100a9 + MX6UL_PAD_NAND_DATA06__RAWNAND_DATA06 0x100a9 + MX6UL_PAD_NAND_DATA07__RAWNAND_DATA07 0x100a9 + MX6UL_PAD_NAND_CLE__RAWNAND_CLE 0x100a9 + MX6UL_PAD_NAND_ALE__RAWNAND_ALE 0x100a9 + MX6UL_PAD_NAND_RE_B__RAWNAND_RE_B 0x100a9 + MX6UL_PAD_NAND_WE_B__RAWNAND_WE_B 0x100a9 + MX6UL_PAD_NAND_CE0_B__RAWNAND_CE0_B 0x100a9 + MX6UL_PAD_NAND_READY_B__RAWNAND_READY_B 0x100a9 + >; + }; + + pinctrl_i2c1: i2c1-grp { + fsl,pins = < + MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0 + MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0 + >; + }; + + pinctrl_i2c1_gpio: i2c1-gpio-grp { + fsl,pins = < + MX6UL_PAD_UART4_TX_DATA__GPIO1_IO28 0x4001b8b0 + MX6UL_PAD_UART4_RX_DATA__GPIO1_IO29 0x4001b8b0 + >; + }; + + pinctrl_i2c2: i2c2-grp { + fsl,pins = < + MX6UL_PAD_UART5_TX_DATA__I2C2_SCL 0x4001b8b0 + MX6UL_PAD_UART5_RX_DATA__I2C2_SDA 0x4001b8b0 + >; + }; + + pinctrl_i2c2_gpio: i2c2-gpio-grp { + fsl,pins = < + MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30 0x4001b8b0 + MX6UL_PAD_UART5_RX_DATA__GPIO1_IO31 0x4001b8b0 + >; + }; + + pinctrl_lcdif_dat: lcdif-dat-grp { + fsl,pins = < + MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x00079 + MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x00079 + MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x00079 + MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x00079 + MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x00079 + MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x00079 + MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x00079 + MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x00079 + MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x00079 + MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x00079 + MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x00079 + MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x00079 + MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x00079 + MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x00079 + MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x00079 + MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x00079 + MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x00079 + MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x00079 + >; + }; + + pinctrl_lcdif_ctrl: lcdif-ctrl-grp { + fsl,pins = < + MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x00079 + MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x00079 + MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x00079 + MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x00079 + >; + }; + + pinctrl_pwm4: pwm4-grp { + fsl,pins = < + MX6UL_PAD_NAND_WP_B__PWM4_OUT 0x00079 + >; + }; + + pinctrl_pwm5: pwm5-grp { + fsl,pins = < + MX6UL_PAD_NAND_DQS__PWM5_OUT 0x00079 + >; + }; + + pinctrl_pwm6: pwm6-grp { + fsl,pins = < + MX6UL_PAD_ENET1_TX_EN__PWM6_OUT 0x00079 + >; + }; + + pinctrl_pwm7: pwm7-grp { + fsl,pins = < + MX6UL_PAD_ENET1_TX_CLK__PWM7_OUT 0x00079 + >; + }; + + pinctrl_uart1: uart1-grp { + fsl,pins = < + MX6UL_PAD_UART1_TX_DATA__UART1_DTE_RX 0x1b0b1 + MX6UL_PAD_UART1_RX_DATA__UART1_DTE_TX 0x1b0b1 + MX6UL_PAD_UART1_RTS_B__UART1_DTE_CTS 0x1b0b1 + MX6UL_PAD_UART1_CTS_B__UART1_DTE_RTS 0x1b0b1 + >; + }; + + pinctrl_uart1_ctrl1: uart1-ctrl1-grp { /* Additional DTR, DCD */ + fsl,pins = < + MX6UL_PAD_JTAG_TDI__GPIO1_IO13 0x1b0b1 /* DCD */ + MX6UL_PAD_LCD_DATA18__GPIO3_IO23 0x1b0b1 /* DSR */ + MX6UL_PAD_JTAG_TDO__GPIO1_IO12 0x1b0b1 /* DTR */ + MX6UL_PAD_LCD_DATA19__GPIO3_IO24 0x1b0b1 /* RI */ + >; + }; + + pinctrl_uart2: uart2-grp { + fsl,pins = < + MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX 0x1b0b1 + MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX 0x1b0b1 + MX6UL_PAD_UART2_CTS_B__UART2_DTE_RTS 0x1b0b1 + MX6UL_PAD_UART2_RTS_B__UART2_DTE_CTS 0x1b0b1 + >; + }; + pinctrl_uart5: uart5-grp { + fsl,pins = < + MX6UL_PAD_GPIO1_IO04__UART5_DTE_RX 0x1b0b1 + MX6UL_PAD_GPIO1_IO05__UART5_DTE_TX 0x1b0b1 + >; + }; + + pinctrl_usbh_reg: gpio-usbh-reg { + fsl,pins = < + MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0x1b0b1 /* SODIMM 129 USBH PEN */ + >; + }; + + pinctrl_usdhc1: usdhc1-grp { + fsl,pins = < + MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x17059 + MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x10059 + MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x17059 + MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x17059 + MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x17059 + MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x17059 + >; + }; + + pinctrl_usdhc1_100mhz: usdhc1-100mhz-grp { + fsl,pins = < + MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x170b9 + MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x100b9 + MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9 + MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9 + MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9 + MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9 + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1-200mhz-grp { + fsl,pins = < + MX6UL_PAD_SD1_CLK__USDHC1_CLK 0x170f9 + MX6UL_PAD_SD1_CMD__USDHC1_CMD 0x100f9 + MX6UL_PAD_SD1_DATA0__USDHC1_DATA0 0x170b9 + MX6UL_PAD_SD1_DATA1__USDHC1_DATA1 0x170b9 + MX6UL_PAD_SD1_DATA2__USDHC1_DATA2 0x170b9 + MX6UL_PAD_SD1_DATA3__USDHC1_DATA3 0x170b9 + >; + }; + + pinctrl_usdhc2: usdhc2-grp { + fsl,pins = < + MX6UL_PAD_CSI_DATA00__USDHC2_DATA0 0x17059 + MX6UL_PAD_CSI_DATA01__USDHC2_DATA1 0x17059 + MX6UL_PAD_CSI_DATA02__USDHC2_DATA2 0x17059 + MX6UL_PAD_CSI_DATA03__USDHC2_DATA3 0x17059 + MX6UL_PAD_CSI_HSYNC__USDHC2_CMD 0x17059 + MX6UL_PAD_CSI_VSYNC__USDHC2_CLK 0x17059 + + MX6UL_PAD_GPIO1_IO03__OSC32K_32K_OUT 0x14 + >; + }; +}; + +&iomuxc_snvs { + pinctrl_snvs_gpio1: snvs-gpio1-grp { + fsl,pins = < + MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06 0x14 /* SODIMM 93 */ + MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03 0x14 /* SODIMM 95 */ + MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10 0x74 /* SODIMM 105 */ + MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x14 /* SODIMM 131 USBH OC */ + MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08 0x74 /* SODIMM 138 */ + >; + }; + + pinctrl_snvs_gpio2: snvs-gpio2-grp { /* ATMEL MXT TOUCH */ + fsl,pins = < + MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x74 /* SODIMM 107 */ + >; + }; + + pinctrl_snvs_gpio3: snvs-gpio3-grp { /* Wifi pins */ + fsl,pins = < + MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x14 /* SODIMM 127 */ + >; + }; + + pinctrl_snvs_ad7879_int: snvs-ad7879-int-grp { /* TOUCH Interrupt */ + fsl,pins = < + MX6ULL_PAD_SNVS_TAMPER7__GPIO5_IO07 0x1b0b0 + >; + }; + + pinctrl_snvs_reg_sd: snvs-reg-sd-grp { + fsl,pins = < + MX6ULL_PAD_SNVS_TAMPER9__GPIO5_IO09 0x4001b8b0 + >; + }; + + pinctrl_snvs_usbc_det: snvs-usbc-det-grp { + fsl,pins = < + MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02 0x1b0b0 + >; + }; + + pinctrl_snvs_gpiokeys: snvs-gpiokeys-grp { + fsl,pins = < + MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x130b0 + >; + }; + + pinctrl_snvs_usdhc1_cd: snvs-usdhc1-cd-grp { + fsl,pins = < + MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x1b0b0 /* CD */ + >; + }; + + pinctrl_snvs_wifi_pdn: snvs-wifi-pdn-grp { + fsl,pins = < + MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11 0x14 + >; + }; +}; diff --git a/arch/arm/dts/imx8mm-evk-u-boot.dtsi b/arch/arm/dts/imx8mm-evk-u-boot.dtsi index 1095d36e31..16093f2067 100644 --- a/arch/arm/dts/imx8mm-evk-u-boot.dtsi +++ b/arch/arm/dts/imx8mm-evk-u-boot.dtsi @@ -3,7 +3,7 @@ * Copyright 2019 NXP */ -&{/soc} { +&{/soc@0} { u-boot,dm-pre-reloc; u-boot,dm-spl; }; @@ -90,3 +90,23 @@ &usdhc3 { u-boot,dm-spl; }; + +&i2c1 { + u-boot,dm-spl; +}; + +&{/soc@0/bus@30800000/i2c@30a20000/pmic@4b} { + u-boot,dm-spl; +}; + +&{/soc@0/bus@30800000/i2c@30a20000/pmic@4b/regulators} { + u-boot,dm-spl; +}; + +&pinctrl_i2c1 { + u-boot,dm-spl; +}; + +&pinctrl_pmic { + u-boot,dm-spl; +}; diff --git a/arch/arm/dts/imx8mm-evk.dts b/arch/arm/dts/imx8mm-evk.dts index 2d5d89475b..faefb7182a 100644 --- a/arch/arm/dts/imx8mm-evk.dts +++ b/arch/arm/dts/imx8mm-evk.dts @@ -5,6 +5,7 @@ /dts-v1/; +#include <dt-bindings/usb/pd.h> #include "imx8mm.dtsi" / { @@ -37,6 +38,41 @@ gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; enable-active-high; }; + + wm8524: audio-codec { + #sound-dai-cells = <0>; + compatible = "wlf,wm8524"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_wlf>; + wlf,mute-gpios = <&gpio5 21 GPIO_ACTIVE_LOW>; + }; + + sound-wm8524 { + compatible = "simple-audio-card"; + simple-audio-card,name = "wm8524-audio"; + simple-audio-card,format = "i2s"; + simple-audio-card,frame-master = <&cpudai>; + simple-audio-card,bitclock-master = <&cpudai>; + simple-audio-card,widgets = + "Line", "Left Line Out Jack", + "Line", "Right Line Out Jack"; + simple-audio-card,routing = + "Left Line Out Jack", "LINEVOUTL", + "Right Line Out Jack", "LINEVOUTR"; + + cpudai: simple-audio-card,cpu { + sound-dai = <&sai3>; + }; + + simple-audio-card,codec { + sound-dai = <&wm8524>; + clocks = <&clk IMX8MM_CLK_SAI3_ROOT>; + }; + }; +}; + +&A53_0 { + cpu-supply = <&buck2_reg>; }; &fec1 { @@ -54,19 +90,208 @@ ethphy0: ethernet-phy@0 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <0>; - at803x,led-act-blind-workaround; - at803x,eee-okay; - at803x,vddio-1p8v; }; }; }; +&i2c1 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + pmic@4b { + compatible = "rohm,bd71847"; + reg = <0x4b>; + pinctrl-0 = <&pinctrl_pmic>; + interrupt-parent = <&gpio1>; + interrupts = <3 GPIO_ACTIVE_LOW>; + rohm,reset-snvs-powered; + + regulators { + buck1_reg: BUCK1 { + regulator-name = "BUCK1"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <1250>; + }; + + buck2_reg: BUCK2 { + regulator-name = "BUCK2"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <1000000>; + rohm,dvs-idle-voltage = <900000>; + }; + + buck3_reg: BUCK3 { + // BUCK5 in datasheet + regulator-name = "BUCK3"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1350000>; + regulator-boot-on; + regulator-always-on; + }; + + buck4_reg: BUCK4 { + // BUCK6 in datasheet + regulator-name = "BUCK4"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + buck5_reg: BUCK5 { + // BUCK7 in datasheet + regulator-name = "BUCK5"; + regulator-min-microvolt = <1605000>; + regulator-max-microvolt = <1995000>; + regulator-boot-on; + regulator-always-on; + }; + + buck6_reg: BUCK6 { + // BUCK8 in datasheet + regulator-name = "BUCK6"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo1_reg: LDO1 { + regulator-name = "LDO1"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo2_reg: LDO2 { + regulator-name = "LDO2"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo3_reg: LDO3 { + regulator-name = "LDO3"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo4_reg: LDO4 { + regulator-name = "LDO4"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo6_reg: LDO6 { + regulator-name = "LDO6"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; +}; + +&i2c2 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2>; + status = "okay"; + + ptn5110: tcpc@50 { + compatible = "nxp,ptn5110"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_typec1>; + reg = <0x50>; + interrupt-parent = <&gpio2>; + interrupts = <11 8>; + status = "okay"; + + port { + typec1_dr_sw: endpoint { + remote-endpoint = <&usb1_drd_sw>; + }; + }; + + typec1_con: connector { + compatible = "usb-c-connector"; + label = "USB-C"; + power-role = "dual"; + data-role = "dual"; + try-power-role = "sink"; + source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; + sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM) + PDO_VAR(5000, 20000, 3000)>; + op-sink-microwatt = <15000000>; + self-powered; + }; + }; +}; + +&i2c3 { + clock-frequency = <400000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3>; + status = "okay"; + + pca6416: gpio@20 { + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + }; +}; + +&sai3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai3>; + assigned-clocks = <&clk IMX8MM_CLK_SAI3>; + assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>; + assigned-clock-rates = <24576000>; + status = "okay"; +}; + +&snvs_pwrkey { + status = "okay"; +}; + &uart2 { /* console */ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart2>; status = "okay"; }; +&usbotg1 { + dr_mode = "otg"; + hnp-disable; + srp-disable; + adp-disable; + usb-role-switch; + status = "okay"; + + port { + usb1_drd_sw: endpoint { + remote-endpoint = <&typec1_dr_sw>; + }; + }; +}; + &usdhc2 { pinctrl-names = "default", "state_100mhz", "state_200mhz"; pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; @@ -124,12 +349,60 @@ >; }; + pinctrl_gpio_wlf: gpiowlfgrp { + fsl,pins = < + MX8MM_IOMUXC_I2C4_SDA_GPIO5_IO21 0xd6 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL 0x400001c3 + MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA 0x400001c3 + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL 0x400001c3 + MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA 0x400001c3 + >; + }; + + pinctrl_i2c3: i2c3grp { + fsl,pins = < + MX8MM_IOMUXC_I2C3_SCL_I2C3_SCL 0x400001c3 + MX8MM_IOMUXC_I2C3_SDA_I2C3_SDA 0x400001c3 + >; + }; + + pinctrl_pmic: pmicirq { + fsl,pins = < + MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x41 + >; + }; + pinctrl_reg_usdhc2_vmmc: regusdhc2vmmc { fsl,pins = < MX8MM_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 >; }; + pinctrl_sai3: sai3grp { + fsl,pins = < + MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6 + MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6 + MX8MM_IOMUXC_SAI3_MCLK_SAI3_MCLK 0xd6 + MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6 + >; + }; + + pinctrl_typec1: typec1grp { + fsl,pins = < + MX8MM_IOMUXC_SD1_STROBE_GPIO2_IO11 0x159 + >; + }; + pinctrl_uart2: uart2grp { fsl,pins = < MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX 0x140 diff --git a/arch/arm/dts/imx8mm.dtsi b/arch/arm/dts/imx8mm.dtsi index 6b407a94c0..8aafad2449 100644 --- a/arch/arm/dts/imx8mm.dtsi +++ b/arch/arm/dts/imx8mm.dtsi @@ -44,6 +44,19 @@ #address-cells = <1>; #size-cells = <0>; + idle-states { + entry-method = "psci"; + + cpu_pd_wait: cpu-pd-wait { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010033>; + local-timer-stop; + entry-latency-us = <1000>; + exit-latency-us = <700>; + min-residency-us = <2700>; + }; + }; + A53_0: cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a53"; @@ -53,6 +66,9 @@ enable-method = "psci"; next-level-cache = <&A53_L2>; operating-points-v2 = <&a53_opp_table>; + nvmem-cells = <&cpu_speed_grade>; + nvmem-cell-names = "speed_grade"; + cpu-idle-states = <&cpu_pd_wait>; }; A53_1: cpu@1 { @@ -64,6 +80,7 @@ enable-method = "psci"; next-level-cache = <&A53_L2>; operating-points-v2 = <&a53_opp_table>; + cpu-idle-states = <&cpu_pd_wait>; }; A53_2: cpu@2 { @@ -75,6 +92,7 @@ enable-method = "psci"; next-level-cache = <&A53_L2>; operating-points-v2 = <&a53_opp_table>; + cpu-idle-states = <&cpu_pd_wait>; }; A53_3: cpu@3 { @@ -86,6 +104,7 @@ enable-method = "psci"; next-level-cache = <&A53_L2>; operating-points-v2 = <&a53_opp_table>; + cpu-idle-states = <&cpu_pd_wait>; }; A53_L2: l2-cache0 { @@ -100,12 +119,23 @@ opp-1200000000 { opp-hz = /bits/ 64 <1200000000>; opp-microvolt = <850000>; + opp-supported-hw = <0xe>, <0x7>; clock-latency-ns = <150000>; + opp-suspend; }; opp-1600000000 { opp-hz = /bits/ 64 <1600000000>; opp-microvolt = <900000>; + opp-supported-hw = <0xc>, <0x7>; + clock-latency-ns = <150000>; + opp-suspend; + }; + + opp-1800000000 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1000000>; + opp-supported-hw = <0x8>, <0x3>; clock-latency-ns = <150000>; opp-suspend; }; @@ -158,15 +188,6 @@ clock-output-names = "clk_ext4"; }; - gic: interrupt-controller@38800000 { - compatible = "arm,gic-v3"; - reg = <0x0 0x38800000 0 0x10000>, /* GIC Dist */ - <0x0 0x38880000 0 0xC0000>; /* GICR (RD_base + SGI_base) */ - #interrupt-cells = <3>; - interrupt-controller; - interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; - }; - psci { compatible = "arm,psci-1.0"; method = "smc"; @@ -189,7 +210,23 @@ arm,no-tick-in-suspend; }; - soc { + usbphynop1: usbphynop1 { + compatible = "usb-nop-xceiv"; + clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; + assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; + assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>; + clock-names = "main_clk"; + }; + + usbphynop2: usbphynop2 { + compatible = "usb-nop-xceiv"; + clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; + assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; + assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>; + clock-names = "main_clk"; + }; + + soc@0 { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; @@ -199,17 +236,85 @@ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges; + ranges = <0x30000000 0x30000000 0x400000>; + + sai1: sai@30010000 { + compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; + reg = <0x30010000 0x10000>; + interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_SAI1_IPG>, + <&clk IMX8MM_CLK_SAI1_ROOT>, + <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma2 0 2 0>, <&sdma2 1 2 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + sai2: sai@30020000 { + compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; + reg = <0x30020000 0x10000>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_SAI2_IPG>, + <&clk IMX8MM_CLK_SAI2_ROOT>, + <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma2 2 2 0>, <&sdma2 3 2 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + sai3: sai@30030000 { + #sound-dai-cells = <0>; + compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; + reg = <0x30030000 0x10000>; + interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_SAI3_IPG>, + <&clk IMX8MM_CLK_SAI3_ROOT>, + <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma2 4 2 0>, <&sdma2 5 2 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + sai5: sai@30050000 { + compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; + reg = <0x30050000 0x10000>; + interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_SAI5_IPG>, + <&clk IMX8MM_CLK_SAI5_ROOT>, + <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma2 8 2 0>, <&sdma2 9 2 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + sai6: sai@30060000 { + compatible = "fsl,imx8mm-sai", "fsl,imx8mq-sai"; + reg = <0x30060000 0x10000>; + interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_SAI6_IPG>, + <&clk IMX8MM_CLK_SAI6_ROOT>, + <&clk IMX8MM_CLK_DUMMY>, <&clk IMX8MM_CLK_DUMMY>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma2 10 2 0>, <&sdma2 11 2 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; gpio1: gpio@30200000 { compatible = "fsl,imx8mm-gpio", "fsl,imx35-gpio"; reg = <0x30200000 0x10000>; interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_GPIO1_ROOT>; gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 10 30>; }; gpio2: gpio@30210000 { @@ -217,10 +322,12 @@ reg = <0x30210000 0x10000>; interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_GPIO2_ROOT>; gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 40 21>; }; gpio3: gpio@30220000 { @@ -228,10 +335,12 @@ reg = <0x30220000 0x10000>; interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_GPIO3_ROOT>; gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 61 26>; }; gpio4: gpio@30230000 { @@ -239,10 +348,12 @@ reg = <0x30230000 0x10000>; interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_GPIO4_ROOT>; gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 87 32>; }; gpio5: gpio@30240000 { @@ -250,10 +361,12 @@ reg = <0x30240000 0x10000>; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_GPIO5_ROOT>; gpio-controller; #gpio-cells = <2>; interrupt-controller; #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 119 30>; }; wdog1: watchdog@30280000 { @@ -313,12 +426,16 @@ }; ocotp: ocotp-ctrl@30350000 { - compatible = "fsl,imx8mm-ocotp", "fsl,imx7d-ocotp", "syscon"; + compatible = "fsl,imx8mm-ocotp", "syscon"; reg = <0x30350000 0x10000>; clocks = <&clk IMX8MM_CLK_OCOTP_ROOT>; /* For nvmem subnodes */ #address-cells = <1>; #size-cells = <1>; + + cpu_speed_grade: speed-grade@10 { + reg = <0x10 4>; + }; }; anatop: anatop@30360000 { @@ -336,6 +453,8 @@ offset = <0x34>; interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MM_CLK_SNVS_ROOT>; + clock-names = "snvs-rtc"; }; snvs_pwrkey: snvs-powerkey { @@ -344,6 +463,7 @@ interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; linux,keycode = <KEY_POWER>; wakeup-source; + status = "disabled"; }; }; @@ -355,10 +475,22 @@ <&clk_ext3>, <&clk_ext4>; clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2", "clk_ext3", "clk_ext4"; + assigned-clocks = <&clk IMX8MM_CLK_NOC>, + <&clk IMX8MM_CLK_AUDIO_AHB>, + <&clk IMX8MM_CLK_IPG_AUDIO_ROOT>, + <&clk IMX8MM_SYS_PLL3>, + <&clk IMX8MM_VIDEO_PLL1>; + assigned-clock-parents = <&clk IMX8MM_SYS_PLL3_OUT>, + <&clk IMX8MM_SYS_PLL1_800M>; + assigned-clock-rates = <0>, + <400000000>, + <400000000>, + <750000000>, + <594000000>; }; src: reset-controller@30390000 { - compatible = "fsl,imx8mm-src", "syscon"; + compatible = "fsl,imx8mm-src", "fsl,imx8mq-src", "syscon"; reg = <0x30390000 0x10000>; interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>; #reset-cells = <1>; @@ -369,7 +501,7 @@ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges; + ranges = <0x30400000 0x30400000 0x400000>; pwm1: pwm@30660000 { compatible = "fsl,imx8mm-pwm", "fsl,imx27-pwm"; @@ -414,13 +546,21 @@ #pwm-cells = <2>; status = "disabled"; }; + + system_counter: timer@306a0000 { + compatible = "nxp,sysctr-timer"; + reg = <0x306a0000 0x20000>; + interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&osc_24m>; + clock-names = "per"; + }; }; aips3: bus@30800000 { compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges; + ranges = <0x30800000 0x30800000 0x400000>; ecspi1: spi@30820000 { compatible = "fsl,imx8mm-ecspi", "fsl,imx51-ecspi"; @@ -554,7 +694,7 @@ compatible = "fsl,imx8mm-usdhc", "fsl,imx7d-usdhc"; reg = <0x30b40000 0x10000>; interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MM_CLK_DUMMY>, + clocks = <&clk IMX8MM_CLK_IPG_ROOT>, <&clk IMX8MM_CLK_NAND_USDHC_BUS>, <&clk IMX8MM_CLK_USDHC1_ROOT>; clock-names = "ipg", "ahb", "per"; @@ -570,7 +710,7 @@ compatible = "fsl,imx8mm-usdhc", "fsl,imx7d-usdhc"; reg = <0x30b50000 0x10000>; interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MM_CLK_DUMMY>, + clocks = <&clk IMX8MM_CLK_IPG_ROOT>, <&clk IMX8MM_CLK_NAND_USDHC_BUS>, <&clk IMX8MM_CLK_USDHC2_ROOT>; clock-names = "ipg", "ahb", "per"; @@ -584,7 +724,7 @@ compatible = "fsl,imx8mm-usdhc", "fsl,imx7d-usdhc"; reg = <0x30b60000 0x10000>; interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clk IMX8MM_CLK_DUMMY>, + clocks = <&clk IMX8MM_CLK_IPG_ROOT>, <&clk IMX8MM_CLK_NAND_USDHC_BUS>, <&clk IMX8MM_CLK_USDHC3_ROOT>; clock-names = "ipg", "ahb", "per"; @@ -639,7 +779,7 @@ compatible = "fsl,aips-bus", "simple-bus"; #address-cells = <1>; #size-cells = <1>; - ranges; + ranges = <0x32c00000 0x32c00000 0x400000>; usbotg1: usb@32e40000 { compatible = "fsl,imx8mm-usb", "fsl,imx7d-usb"; @@ -647,23 +787,13 @@ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MM_CLK_USB1_CTRL_ROOT>; clock-names = "usb1_ctrl_root_clk"; - assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>, - <&clk IMX8MM_CLK_USB_CORE_REF>; - assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>, - <&clk IMX8MM_SYS_PLL1_100M>; + assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>; + assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; fsl,usbphy = <&usbphynop1>; fsl,usbmisc = <&usbmisc1 0>; status = "disabled"; }; - usbphynop1: usbphynop1 { - compatible = "usb-nop-xceiv"; - clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; - assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; - assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>; - clock-names = "main_clk"; - }; - usbmisc1: usbmisc@32e40200 { compatible = "fsl,imx8mm-usbmisc", "fsl,imx7d-usbmisc"; #index-cells = <1>; @@ -676,23 +806,13 @@ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MM_CLK_USB1_CTRL_ROOT>; clock-names = "usb1_ctrl_root_clk"; - assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>, - <&clk IMX8MM_CLK_USB_CORE_REF>; - assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>, - <&clk IMX8MM_SYS_PLL1_100M>; + assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>; + assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>; fsl,usbphy = <&usbphynop2>; fsl,usbmisc = <&usbmisc2 0>; status = "disabled"; }; - usbphynop2: usbphynop2 { - compatible = "usb-nop-xceiv"; - clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; - assigned-clocks = <&clk IMX8MM_CLK_USB_PHY_REF>; - assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_100M>; - clock-names = "main_clk"; - }; - usbmisc2: usbmisc@32e50200 { compatible = "fsl,imx8mm-usbmisc", "fsl,imx7d-usbmisc"; #index-cells = <1>; @@ -729,5 +849,21 @@ dma-names = "rx-tx"; status = "disabled"; }; + + gic: interrupt-controller@38800000 { + compatible = "arm,gic-v3"; + reg = <0x38800000 0x10000>, /* GIC Dist */ + <0x38880000 0xc0000>; /* GICR (RD_base + SGI_base) */ + #interrupt-cells = <3>; + interrupt-controller; + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + }; + + ddr-pmu@3d800000 { + compatible = "fsl,imx8mm-ddr-pmu", "fsl,imx8m-ddr-pmu"; + reg = <0x3d800000 0x400000>; + interrupt-parent = <&gic>; + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; + }; }; }; diff --git a/arch/arm/dts/imx8mq-evk.dts b/arch/arm/dts/imx8mq-evk.dts new file mode 100644 index 0000000000..3693933451 --- /dev/null +++ b/arch/arm/dts/imx8mq-evk.dts @@ -0,0 +1,486 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright 2017 NXP + * Copyright (C) 2017-2018 Pengutronix, Lucas Stach <kernel@pengutronix.de> + */ + +/dts-v1/; + +/* First 128KB is for PSCI ATF. */ +/memreserve/ 0x40000000 0x00020000; + +#include "imx8mq.dtsi" + +/ { + model = "NXP i.MX8MQ EVK"; + compatible = "fsl,imx8mq-evk", "fsl,imx8mq"; + + chosen { + stdout-path = &uart1; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0x00000000 0x40000000 0 0xc0000000>; + }; + + pcie0_refclk: pcie0-refclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + }; + + reg_usdhc2_vmmc: regulator-vsd-3v3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_reg_usdhc2>; + compatible = "regulator-fixed"; + regulator-name = "VSD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + buck2_reg: regulator-buck2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_buck2>; + compatible = "regulator-gpio"; + regulator-name = "vdd_arm"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1000000>; + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; + states = <1000000 0x0 + 900000 0x1>; + }; + + wm8524: audio-codec { + #sound-dai-cells = <0>; + compatible = "wlf,wm8524"; + wlf,mute-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; + }; + + sound-wm8524 { + compatible = "simple-audio-card"; + simple-audio-card,name = "wm8524-audio"; + simple-audio-card,format = "i2s"; + simple-audio-card,frame-master = <&cpudai>; + simple-audio-card,bitclock-master = <&cpudai>; + simple-audio-card,widgets = + "Line", "Left Line Out Jack", + "Line", "Right Line Out Jack"; + simple-audio-card,routing = + "Left Line Out Jack", "LINEVOUTL", + "Right Line Out Jack", "LINEVOUTR"; + + cpudai: simple-audio-card,cpu { + sound-dai = <&sai2>; + }; + + link_codec: simple-audio-card,codec { + sound-dai = <&wm8524>; + clocks = <&clk IMX8MQ_CLK_SAI2_ROOT>; + }; + }; +}; + +&A53_0 { + cpu-supply = <&buck2_reg>; +}; + +&A53_1 { + cpu-supply = <&buck2_reg>; +}; + +&A53_2 { + cpu-supply = <&buck2_reg>; +}; + +&A53_3 { + cpu-supply = <&buck2_reg>; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1>; + phy-mode = "rgmii-id"; + phy-handle = <ðphy0>; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; + }; +}; + +&sai2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai2>; + assigned-clocks = <&clk IMX8MQ_AUDIO_PLL1_BYPASS>, <&clk IMX8MQ_CLK_SAI2>; + assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1>, <&clk IMX8MQ_AUDIO_PLL1_OUT>; + assigned-clock-rates = <0>, <24576000>; + status = "okay"; +}; + +&gpio5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wifi_reset>; + + wl-reg-on { + gpio-hog; + gpios = <29 GPIO_ACTIVE_HIGH>; + output-high; + }; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1>; + status = "okay"; + + pmic@8 { + compatible = "fsl,pfuze100"; + reg = <0x8>; + + regulators { + sw1a_reg: sw1ab { + regulator-min-microvolt = <825000>; + regulator-max-microvolt = <1100000>; + }; + + sw1c_reg: sw1c { + regulator-min-microvolt = <825000>; + regulator-max-microvolt = <1100000>; + }; + + sw2_reg: sw2 { + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + }; + + sw3a_reg: sw3ab { + regulator-min-microvolt = <825000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + }; + + sw4_reg: sw4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + swbst_reg: swbst { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5150000>; + }; + + snvs_reg: vsnvs { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + }; + + vref_reg: vrefddr { + regulator-always-on; + }; + + vgen1_reg: vgen1 { + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1550000>; + }; + + vgen2_reg: vgen2 { + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <975000>; + regulator-always-on; + }; + + vgen3_reg: vgen3 { + regulator-min-microvolt = <1675000>; + regulator-max-microvolt = <1975000>; + regulator-always-on; + }; + + vgen4_reg: vgen4 { + regulator-min-microvolt = <1625000>; + regulator-max-microvolt = <1875000>; + regulator-always-on; + }; + + vgen5_reg: vgen5 { + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3625000>; + regulator-always-on; + }; + + vgen6_reg: vgen6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + }; + }; + }; +}; + +&pcie0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie0>; + reset-gpio = <&gpio5 28 GPIO_ACTIVE_LOW>; + clocks = <&clk IMX8MQ_CLK_PCIE1_ROOT>, + <&clk IMX8MQ_CLK_PCIE1_AUX>, + <&clk IMX8MQ_CLK_PCIE1_PHY>, + <&pcie0_refclk>; + clock-names = "pcie", "pcie_aux", "pcie_phy", "pcie_bus"; + status = "okay"; +}; + +&pgc_gpu { + power-supply = <&sw1a_reg>; +}; + +&snvs_pwrkey { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&usb3_phy1 { + status = "okay"; +}; + +&usb_dwc3_1 { + dr_mode = "host"; + status = "okay"; +}; + +&qspi0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_qspi>; + status = "okay"; + + n25q256a: flash@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + compatible = "micron,n25q256a", "jedec,spi-nor"; + spi-max-frequency = <29000000>; + }; +}; + +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + vqmmc-supply = <&sw4_reg>; + bus-width = <8>; + non-removable; + no-sd; + no-sdio; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>; + cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; + vmmc-supply = <®_usdhc2_vmmc>; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; + +&iomuxc { + pinctrl_buck2: vddarmgrp { + fsl,pins = < + MX8MQ_IOMUXC_GPIO1_IO13_GPIO1_IO13 0x19 + >; + + }; + + pinctrl_fec1: fec1grp { + fsl,pins = < + MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC 0x3 + MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO 0x23 + MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3 0x1f + MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2 0x1f + MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1 0x1f + MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0 0x1f + MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3 0x91 + MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2 0x91 + MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1 0x91 + MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0 0x91 + MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f + MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 + MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 + MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f + MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL 0x4000007f + MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA 0x4000007f + >; + }; + + pinctrl_pcie0: pcie0grp { + fsl,pins = < + MX8MQ_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B 0x76 + MX8MQ_IOMUXC_UART4_RXD_GPIO5_IO28 0x16 + >; + }; + + pinctrl_qspi: qspigrp { + fsl,pins = < + MX8MQ_IOMUXC_NAND_ALE_QSPI_A_SCLK 0x82 + MX8MQ_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B 0x82 + MX8MQ_IOMUXC_NAND_DATA00_QSPI_A_DATA0 0x82 + MX8MQ_IOMUXC_NAND_DATA01_QSPI_A_DATA1 0x82 + MX8MQ_IOMUXC_NAND_DATA02_QSPI_A_DATA2 0x82 + MX8MQ_IOMUXC_NAND_DATA03_QSPI_A_DATA3 0x82 + + >; + }; + + pinctrl_reg_usdhc2: regusdhc2grpgpio { + fsl,pins = < + MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19 0x41 + >; + }; + + pinctrl_sai2: sai2grp { + fsl,pins = < + MX8MQ_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0xd6 + MX8MQ_IOMUXC_SAI2_TXC_SAI2_TX_BCLK 0xd6 + MX8MQ_IOMUXC_SAI2_MCLK_SAI2_MCLK 0xd6 + MX8MQ_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0xd6 + MX8MQ_IOMUXC_GPIO1_IO08_GPIO1_IO8 0xd6 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX 0x49 + MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX 0x49 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x83 + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xc3 + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xc3 + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xc3 + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xc3 + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xc3 + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xc3 + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xc3 + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xc3 + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xc3 + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x83 + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc1_100mhz: usdhc1-100grp { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x8d + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xcd + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xcd + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xcd + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xcd + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xcd + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xcd + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xcd + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xcd + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xcd + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x8d + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1-200grp { + fsl,pins = < + MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK 0x9f + MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD 0xdf + MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0 0xdf + MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1 0xdf + MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2 0xdf + MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3 0xdf + MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4 0xdf + MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5 0xdf + MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6 0xdf + MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7 0xdf + MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE 0x9f + MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B 0xc1 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x83 + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc3 + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc3 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc3 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc3 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc3 + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2-100grp { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x85 + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc5 + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc5 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc5 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc5 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc5 + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2-200grp { + fsl,pins = < + MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK 0x87 + MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD 0xc7 + MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0 0xc7 + MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1 0xc7 + MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2 0xc7 + MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3 0xc7 + MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xc1 + >; + }; + + pinctrl_wdog: wdog1grp { + fsl,pins = < + MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6 + >; + }; + + pinctrl_wifi_reset: wifiresetgrp { + fsl,pins = < + MX8MQ_IOMUXC_UART4_TXD_GPIO5_IO29 0x16 + >; + }; +}; diff --git a/arch/arm/dts/imx8mq.dtsi b/arch/arm/dts/imx8mq.dtsi new file mode 100644 index 0000000000..621e9593ec --- /dev/null +++ b/arch/arm/dts/imx8mq.dtsi @@ -0,0 +1,1111 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2017 NXP + * Copyright (C) 2017-2018 Pengutronix, Lucas Stach <kernel@pengutronix.de> + */ + +#include <dt-bindings/clock/imx8mq-clock.h> +#include <dt-bindings/pinctrl/pins-imx8mq.h> +#include <dt-bindings/power/imx8mq-power.h> +#include <dt-bindings/reset/imx8mq-reset.h> +#include <dt-bindings/gpio/gpio.h> +#include "dt-bindings/input/input.h" +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/thermal/thermal.h> + +/ { + interrupt-parent = <&gpc>; + + #address-cells = <2>; + #size-cells = <2>; + + aliases { + ethernet0 = &fec1; + gpio0 = &gpio1; + gpio1 = &gpio2; + gpio2 = &gpio3; + gpio3 = &gpio4; + gpio4 = &gpio5; + i2c0 = &i2c1; + i2c1 = &i2c2; + i2c2 = &i2c3; + i2c3 = &i2c4; + serial0 = &uart1; + serial1 = &uart2; + serial2 = &uart3; + serial3 = &uart4; + spi0 = &ecspi1; + spi1 = &ecspi2; + spi2 = &ecspi3; + }; + + ckil: clock-ckil { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "ckil"; + }; + + osc_25m: clock-osc-25m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + clock-output-names = "osc_25m"; + }; + + osc_27m: clock-osc-27m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <27000000>; + clock-output-names = "osc_27m"; + }; + + clk_ext1: clock-ext1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <133000000>; + clock-output-names = "clk_ext1"; + }; + + clk_ext2: clock-ext2 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <133000000>; + clock-output-names = "clk_ext2"; + }; + + clk_ext3: clock-ext3 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <133000000>; + clock-output-names = "clk_ext3"; + }; + + clk_ext4: clock-ext4 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency= <133000000>; + clock-output-names = "clk_ext4"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + A53_0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0>; + clock-latency = <61036>; /* two CLK32 periods */ + clocks = <&clk IMX8MQ_CLK_ARM>; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + operating-points-v2 = <&a53_opp_table>; + #cooling-cells = <2>; + nvmem-cells = <&cpu_speed_grade>; + nvmem-cell-names = "speed_grade"; + }; + + A53_1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x1>; + clock-latency = <61036>; /* two CLK32 periods */ + clocks = <&clk IMX8MQ_CLK_ARM>; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + operating-points-v2 = <&a53_opp_table>; + #cooling-cells = <2>; + }; + + A53_2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x2>; + clock-latency = <61036>; /* two CLK32 periods */ + clocks = <&clk IMX8MQ_CLK_ARM>; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + operating-points-v2 = <&a53_opp_table>; + #cooling-cells = <2>; + }; + + A53_3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x3>; + clock-latency = <61036>; /* two CLK32 periods */ + clocks = <&clk IMX8MQ_CLK_ARM>; + enable-method = "psci"; + next-level-cache = <&A53_L2>; + operating-points-v2 = <&a53_opp_table>; + #cooling-cells = <2>; + }; + + A53_L2: l2-cache0 { + compatible = "cache"; + }; + }; + + a53_opp_table: opp-table { + compatible = "operating-points-v2"; + opp-shared; + + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <900000>; + /* Industrial only */ + opp-supported-hw = <0xf>, <0x4>; + clock-latency-ns = <150000>; + opp-suspend; + }; + + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <900000>; + /* Consumer only */ + opp-supported-hw = <0xe>, <0x3>; + clock-latency-ns = <150000>; + opp-suspend; + }; + + opp-1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-microvolt = <1000000>; + opp-supported-hw = <0xc>, <0x4>; + clock-latency-ns = <150000>; + opp-suspend; + }; + + opp-1500000000 { + opp-hz = /bits/ 64 <1500000000>; + opp-microvolt = <1000000>; + opp-supported-hw = <0x8>, <0x3>; + clock-latency-ns = <150000>; + opp-suspend; + }; + }; + + pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&gic>; + interrupt-affinity = <&A53_0>, <&A53_1>, <&A53_2>, <&A53_3>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + thermal-zones { + cpu-thermal { + polling-delay-passive = <250>; + polling-delay = <2000>; + thermal-sensors = <&tmu 0>; + + trips { + cpu_alert: cpu-alert { + temperature = <80000>; + hysteresis = <2000>; + type = "passive"; + }; + + cpu-crit { + temperature = <90000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&cpu_alert>; + cooling-device = + <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A53_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + gpu-thermal { + polling-delay-passive = <250>; + polling-delay = <2000>; + thermal-sensors = <&tmu 1>; + + trips { + gpu-crit { + temperature = <90000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + + vpu-thermal { + polling-delay-passive = <250>; + polling-delay = <2000>; + thermal-sensors = <&tmu 2>; + + trips { + vpu-crit { + temperature = <90000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* Physical Secure */ + <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* Physical Non-Secure */ + <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* Virtual */ + <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* Hypervisor */ + interrupt-parent = <&gic>; + arm,no-tick-in-suspend; + }; + + soc@0 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x0 0x3e000000>; + dma-ranges = <0x40000000 0x0 0x40000000 0xc0000000>; + + bus@30000000 { /* AIPS1 */ + compatible = "fsl,imx8mq-aips-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x30000000 0x30000000 0x400000>; + + gpio1: gpio@30200000 { + compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; + reg = <0x30200000 0x10000>; + interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_GPIO1_ROOT>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 10 30>; + }; + + gpio2: gpio@30210000 { + compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; + reg = <0x30210000 0x10000>; + interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_GPIO2_ROOT>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 40 21>; + }; + + gpio3: gpio@30220000 { + compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; + reg = <0x30220000 0x10000>; + interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_GPIO3_ROOT>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 61 26>; + }; + + gpio4: gpio@30230000 { + compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; + reg = <0x30230000 0x10000>; + interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_GPIO4_ROOT>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 87 32>; + }; + + gpio5: gpio@30240000 { + compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; + reg = <0x30240000 0x10000>; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_GPIO5_ROOT>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&iomuxc 0 119 30>; + }; + + tmu: tmu@30260000 { + compatible = "fsl,imx8mq-tmu"; + reg = <0x30260000 0x10000>; + interrupt = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_TMU_ROOT>; + little-endian; + fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x70061>; + fsl,tmu-calibration = <0x00000000 0x00000023 + 0x00000001 0x00000029 + 0x00000002 0x0000002f + 0x00000003 0x00000035 + 0x00000004 0x0000003d + 0x00000005 0x00000043 + 0x00000006 0x0000004b + 0x00000007 0x00000051 + 0x00000008 0x00000057 + 0x00000009 0x0000005f + 0x0000000a 0x00000067 + 0x0000000b 0x0000006f + + 0x00010000 0x0000001b + 0x00010001 0x00000023 + 0x00010002 0x0000002b + 0x00010003 0x00000033 + 0x00010004 0x0000003b + 0x00010005 0x00000043 + 0x00010006 0x0000004b + 0x00010007 0x00000055 + 0x00010008 0x0000005d + 0x00010009 0x00000067 + 0x0001000a 0x00000070 + + 0x00020000 0x00000017 + 0x00020001 0x00000023 + 0x00020002 0x0000002d + 0x00020003 0x00000037 + 0x00020004 0x00000041 + 0x00020005 0x0000004b + 0x00020006 0x00000057 + 0x00020007 0x00000063 + 0x00020008 0x0000006f + + 0x00030000 0x00000015 + 0x00030001 0x00000021 + 0x00030002 0x0000002d + 0x00030003 0x00000039 + 0x00030004 0x00000045 + 0x00030005 0x00000053 + 0x00030006 0x0000005f + 0x00030007 0x00000071>; + #thermal-sensor-cells = <1>; + }; + + wdog1: watchdog@30280000 { + compatible = "fsl,imx8mq-wdt", "fsl,imx21-wdt"; + reg = <0x30280000 0x10000>; + interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_WDOG1_ROOT>; + status = "disabled"; + }; + + wdog2: watchdog@30290000 { + compatible = "fsl,imx8mq-wdt", "fsl,imx21-wdt"; + reg = <0x30290000 0x10000>; + interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_WDOG2_ROOT>; + status = "disabled"; + }; + + wdog3: watchdog@302a0000 { + compatible = "fsl,imx8mq-wdt", "fsl,imx21-wdt"; + reg = <0x302a0000 0x10000>; + interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_WDOG3_ROOT>; + status = "disabled"; + }; + + sdma2: sdma@302c0000 { + compatible = "fsl,imx8mq-sdma","fsl,imx7d-sdma"; + reg = <0x302c0000 0x10000>; + interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_SDMA2_ROOT>, + <&clk IMX8MQ_CLK_SDMA2_ROOT>; + clock-names = "ipg", "ahb"; + #dma-cells = <3>; + fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin"; + }; + + iomuxc: iomuxc@30330000 { + compatible = "fsl,imx8mq-iomuxc"; + reg = <0x30330000 0x10000>; + }; + + iomuxc_gpr: syscon@30340000 { + compatible = "fsl,imx8mq-iomuxc-gpr", "fsl,imx6q-iomuxc-gpr", + "syscon", "simple-mfd"; + reg = <0x30340000 0x10000>; + + mux: mux-controller { + compatible = "mmio-mux"; + #mux-control-cells = <1>; + mux-reg-masks = <0x34 0x00000004>; /* MIPI_MUX_SEL */ + }; + }; + + ocotp: ocotp-ctrl@30350000 { + compatible = "fsl,imx8mq-ocotp", "syscon"; + reg = <0x30350000 0x10000>; + clocks = <&clk IMX8MQ_CLK_OCOTP_ROOT>; + #address-cells = <1>; + #size-cells = <1>; + + cpu_speed_grade: speed-grade@10 { + reg = <0x10 4>; + }; + }; + + anatop: syscon@30360000 { + compatible = "fsl,imx8mq-anatop", "syscon"; + reg = <0x30360000 0x10000>; + interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; + }; + + snvs: snvs@30370000 { + compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd"; + reg = <0x30370000 0x10000>; + + snvs_rtc: snvs-rtc-lp{ + compatible = "fsl,sec-v4.0-mon-rtc-lp"; + regmap =<&snvs>; + offset = <0x34>; + interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_SNVS_ROOT>; + clock-names = "snvs-rtc"; + }; + + snvs_pwrkey: snvs-powerkey { + compatible = "fsl,sec-v4.0-pwrkey"; + regmap = <&snvs>; + interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>; + linux,keycode = <KEY_POWER>; + wakeup-source; + status = "disabled"; + }; + }; + + clk: clock-controller@30380000 { + compatible = "fsl,imx8mq-ccm"; + reg = <0x30380000 0x10000>; + interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; + #clock-cells = <1>; + clocks = <&ckil>, <&osc_25m>, <&osc_27m>, + <&clk_ext1>, <&clk_ext2>, + <&clk_ext3>, <&clk_ext4>; + clock-names = "ckil", "osc_25m", "osc_27m", + "clk_ext1", "clk_ext2", + "clk_ext3", "clk_ext4"; + }; + + src: reset-controller@30390000 { + compatible = "fsl,imx8mq-src", "syscon"; + reg = <0x30390000 0x10000>; + #reset-cells = <1>; + }; + + gpc: gpc@303a0000 { + compatible = "fsl,imx8mq-gpc"; + reg = <0x303a0000 0x10000>; + interrupt-parent = <&gic>; + interrupt-controller; + #interrupt-cells = <3>; + + pgc { + #address-cells = <1>; + #size-cells = <0>; + + pgc_mipi: power-domain@0 { + #power-domain-cells = <0>; + reg = <IMX8M_POWER_DOMAIN_MIPI>; + }; + + /* + * As per comment in ATF source code: + * + * PCIE1 and PCIE2 share the + * same reset signal, if we + * power down PCIE2, PCIE1 + * will be held in reset too. + * + * So instead of creating two + * separate power domains for + * PCIE1 and PCIE2 we create a + * link between both and use + * it as a shared PCIE power + * domain. + */ + pgc_pcie: power-domain@1 { + #power-domain-cells = <0>; + reg = <IMX8M_POWER_DOMAIN_PCIE1>; + power-domains = <&pgc_pcie2>; + }; + + pgc_otg1: power-domain@2 { + #power-domain-cells = <0>; + reg = <IMX8M_POWER_DOMAIN_USB_OTG1>; + }; + + pgc_otg2: power-domain@3 { + #power-domain-cells = <0>; + reg = <IMX8M_POWER_DOMAIN_USB_OTG2>; + }; + + pgc_ddr1: power-domain@4 { + #power-domain-cells = <0>; + reg = <IMX8M_POWER_DOMAIN_DDR1>; + }; + + pgc_gpu: power-domain@5 { + #power-domain-cells = <0>; + reg = <IMX8M_POWER_DOMAIN_GPU>; + clocks = <&clk IMX8MQ_CLK_GPU_ROOT>, + <&clk IMX8MQ_CLK_GPU_SHADER_DIV>, + <&clk IMX8MQ_CLK_GPU_AXI>, + <&clk IMX8MQ_CLK_GPU_AHB>; + }; + + pgc_vpu: power-domain@6 { + #power-domain-cells = <0>; + reg = <IMX8M_POWER_DOMAIN_VPU>; + }; + + pgc_disp: power-domain@7 { + #power-domain-cells = <0>; + reg = <IMX8M_POWER_DOMAIN_DISP>; + }; + + pgc_mipi_csi1: power-domain@8 { + #power-domain-cells = <0>; + reg = <IMX8M_POWER_DOMAIN_MIPI_CSI1>; + }; + + pgc_mipi_csi2: power-domain@9 { + #power-domain-cells = <0>; + reg = <IMX8M_POWER_DOMAIN_MIPI_CSI2>; + }; + + pgc_pcie2: power-domain@a { + #power-domain-cells = <0>; + reg = <IMX8M_POWER_DOMAIN_PCIE2>; + }; + }; + }; + }; + + bus@30400000 { /* AIPS2 */ + compatible = "fsl,imx8mq-aips-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x30400000 0x30400000 0x400000>; + + pwm1: pwm@30660000 { + compatible = "fsl,imx8mq-pwm", "fsl,imx27-pwm"; + reg = <0x30660000 0x10000>; + interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_PWM1_ROOT>, + <&clk IMX8MQ_CLK_PWM1_ROOT>; + clock-names = "ipg", "per"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm2: pwm@30670000 { + compatible = "fsl,imx8mq-pwm", "fsl,imx27-pwm"; + reg = <0x30670000 0x10000>; + interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_PWM2_ROOT>, + <&clk IMX8MQ_CLK_PWM2_ROOT>; + clock-names = "ipg", "per"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm3: pwm@30680000 { + compatible = "fsl,imx8mq-pwm", "fsl,imx27-pwm"; + reg = <0x30680000 0x10000>; + interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_PWM3_ROOT>, + <&clk IMX8MQ_CLK_PWM3_ROOT>; + clock-names = "ipg", "per"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm4: pwm@30690000 { + compatible = "fsl,imx8mq-pwm", "fsl,imx27-pwm"; + reg = <0x30690000 0x10000>; + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_PWM4_ROOT>, + <&clk IMX8MQ_CLK_PWM4_ROOT>; + clock-names = "ipg", "per"; + #pwm-cells = <2>; + status = "disabled"; + }; + + system_counter: timer@306a0000 { + compatible = "nxp,sysctr-timer"; + reg = <0x306a0000 0x20000>; + interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&osc_25m>; + clock-names = "per"; + }; + }; + + bus@30800000 { /* AIPS3 */ + compatible = "fsl,imx8mq-aips-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x30800000 0x30800000 0x400000>, + <0x08000000 0x08000000 0x10000000>; + + ecspi1: spi@30820000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx8mq-ecspi", "fsl,imx51-ecspi"; + reg = <0x30820000 0x10000>; + interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_ECSPI1_ROOT>, + <&clk IMX8MQ_CLK_ECSPI1_ROOT>; + clock-names = "ipg", "per"; + status = "disabled"; + }; + + ecspi2: spi@30830000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx8mq-ecspi", "fsl,imx51-ecspi"; + reg = <0x30830000 0x10000>; + interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_ECSPI2_ROOT>, + <&clk IMX8MQ_CLK_ECSPI2_ROOT>; + clock-names = "ipg", "per"; + status = "disabled"; + }; + + ecspi3: spi@30840000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx8mq-ecspi", "fsl,imx51-ecspi"; + reg = <0x30840000 0x10000>; + interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_ECSPI3_ROOT>, + <&clk IMX8MQ_CLK_ECSPI3_ROOT>; + clock-names = "ipg", "per"; + status = "disabled"; + }; + + uart1: serial@30860000 { + compatible = "fsl,imx8mq-uart", + "fsl,imx6q-uart"; + reg = <0x30860000 0x10000>; + interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_UART1_ROOT>, + <&clk IMX8MQ_CLK_UART1_ROOT>; + clock-names = "ipg", "per"; + status = "disabled"; + }; + + uart3: serial@30880000 { + compatible = "fsl,imx8mq-uart", + "fsl,imx6q-uart"; + reg = <0x30880000 0x10000>; + interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_UART3_ROOT>, + <&clk IMX8MQ_CLK_UART3_ROOT>; + clock-names = "ipg", "per"; + status = "disabled"; + }; + + uart2: serial@30890000 { + compatible = "fsl,imx8mq-uart", + "fsl,imx6q-uart"; + reg = <0x30890000 0x10000>; + interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_UART2_ROOT>, + <&clk IMX8MQ_CLK_UART2_ROOT>; + clock-names = "ipg", "per"; + status = "disabled"; + }; + + sai2: sai@308b0000 { + #sound-dai-cells = <0>; + compatible = "fsl,imx8mq-sai"; + reg = <0x308b0000 0x10000>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_SAI2_IPG>, + <&clk IMX8MQ_CLK_SAI2_ROOT>, + <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>; + clock-names = "bus", "mclk1", "mclk2", "mclk3"; + dmas = <&sdma1 10 24 0>, <&sdma1 11 24 0>; + dma-names = "rx", "tx"; + status = "disabled"; + }; + + crypto: crypto@30900000 { + compatible = "fsl,sec-v4.0"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x30900000 0x40000>; + ranges = <0 0x30900000 0x40000>; + interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_AHB>, + <&clk IMX8MQ_CLK_IPG_ROOT>; + clock-names = "aclk", "ipg"; + + sec_jr0: jr@1000 { + compatible = "fsl,sec-v4.0-job-ring"; + reg = <0x1000 0x1000>; + interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>; + }; + + sec_jr1: jr@2000 { + compatible = "fsl,sec-v4.0-job-ring"; + reg = <0x2000 0x1000>; + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; + }; + + sec_jr2: jr@3000 { + compatible = "fsl,sec-v4.0-job-ring"; + reg = <0x3000 0x1000>; + interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; + }; + }; + + dphy: dphy@30a00300 { + compatible = "fsl,imx8mq-mipi-dphy"; + reg = <0x30a00300 0x100>; + clocks = <&clk IMX8MQ_CLK_DSI_PHY_REF>; + clock-names = "phy_ref"; + assigned-clocks = <&clk IMX8MQ_CLK_DSI_PHY_REF>; + assigned-clock-parents = <&clk IMX8MQ_VIDEO_PLL1_OUT>; + assigned-clock-rates = <24000000>; + #phy-cells = <0>; + power-domains = <&pgc_mipi>; + status = "disabled"; + }; + + i2c1: i2c@30a20000 { + compatible = "fsl,imx8mq-i2c", "fsl,imx21-i2c"; + reg = <0x30a20000 0x10000>; + interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_I2C1_ROOT>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c@30a30000 { + compatible = "fsl,imx8mq-i2c", "fsl,imx21-i2c"; + reg = <0x30a30000 0x10000>; + interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_I2C2_ROOT>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c3: i2c@30a40000 { + compatible = "fsl,imx8mq-i2c", "fsl,imx21-i2c"; + reg = <0x30a40000 0x10000>; + interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_I2C3_ROOT>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c4: i2c@30a50000 { + compatible = "fsl,imx8mq-i2c", "fsl,imx21-i2c"; + reg = <0x30a50000 0x10000>; + interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_I2C4_ROOT>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + uart4: serial@30a60000 { + compatible = "fsl,imx8mq-uart", + "fsl,imx6q-uart"; + reg = <0x30a60000 0x10000>; + interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_UART4_ROOT>, + <&clk IMX8MQ_CLK_UART4_ROOT>; + clock-names = "ipg", "per"; + status = "disabled"; + }; + + usdhc1: mmc@30b40000 { + compatible = "fsl,imx8mq-usdhc", + "fsl,imx7d-usdhc"; + reg = <0x30b40000 0x10000>; + interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_DUMMY>, + <&clk IMX8MQ_CLK_NAND_USDHC_BUS>, + <&clk IMX8MQ_CLK_USDHC1_ROOT>; + clock-names = "ipg", "ahb", "per"; + assigned-clocks = <&clk IMX8MQ_CLK_USDHC1>; + assigned-clock-rates = <400000000>; + fsl,tuning-start-tap = <20>; + fsl,tuning-step = <2>; + bus-width = <4>; + status = "disabled"; + }; + + usdhc2: mmc@30b50000 { + compatible = "fsl,imx8mq-usdhc", + "fsl,imx7d-usdhc"; + reg = <0x30b50000 0x10000>; + interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_DUMMY>, + <&clk IMX8MQ_CLK_NAND_USDHC_BUS>, + <&clk IMX8MQ_CLK_USDHC2_ROOT>; + clock-names = "ipg", "ahb", "per"; + fsl,tuning-start-tap = <20>; + fsl,tuning-step = <2>; + bus-width = <4>; + status = "disabled"; + }; + + qspi0: spi@30bb0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "fsl,imx8mq-qspi", "fsl,imx7d-qspi"; + reg = <0x30bb0000 0x10000>, + <0x08000000 0x10000000>; + reg-names = "QuadSPI", "QuadSPI-memory"; + interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_QSPI_ROOT>, + <&clk IMX8MQ_CLK_QSPI_ROOT>; + clock-names = "qspi_en", "qspi"; + status = "disabled"; + }; + + sdma1: sdma@30bd0000 { + compatible = "fsl,imx8mq-sdma","fsl,imx7d-sdma"; + reg = <0x30bd0000 0x10000>; + interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_SDMA1_ROOT>, + <&clk IMX8MQ_CLK_AHB>; + clock-names = "ipg", "ahb"; + #dma-cells = <3>; + fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin"; + }; + + fec1: ethernet@30be0000 { + compatible = "fsl,imx8mq-fec", "fsl,imx6sx-fec"; + reg = <0x30be0000 0x10000>; + interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_ENET1_ROOT>, + <&clk IMX8MQ_CLK_ENET1_ROOT>, + <&clk IMX8MQ_CLK_ENET_TIMER>, + <&clk IMX8MQ_CLK_ENET_REF>, + <&clk IMX8MQ_CLK_ENET_PHY_REF>; + clock-names = "ipg", "ahb", "ptp", + "enet_clk_ref", "enet_out"; + fsl,num-tx-queues = <3>; + fsl,num-rx-queues = <3>; + status = "disabled"; + }; + }; + + bus@32c00000 { /* AIPS4 */ + compatible = "fsl,imx8mq-aips-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x32c00000 0x32c00000 0x400000>; + + irqsteer: interrupt-controller@32e2d000 { + compatible = "fsl,imx8m-irqsteer", "fsl,imx-irqsteer"; + reg = <0x32e2d000 0x1000>; + interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_DISP_APB_ROOT>; + clock-names = "ipg"; + fsl,channel = <0>; + fsl,num-irqs = <64>; + interrupt-controller; + #interrupt-cells = <1>; + }; + }; + + gpu: gpu@38000000 { + compatible = "vivante,gc"; + reg = <0x38000000 0x40000>; + interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk IMX8MQ_CLK_GPU_ROOT>, + <&clk IMX8MQ_CLK_GPU_SHADER_DIV>, + <&clk IMX8MQ_CLK_GPU_AXI>, + <&clk IMX8MQ_CLK_GPU_AHB>; + clock-names = "core", "shader", "bus", "reg"; + assigned-clocks = <&clk IMX8MQ_CLK_GPU_CORE_SRC>, + <&clk IMX8MQ_CLK_GPU_SHADER_SRC>, + <&clk IMX8MQ_CLK_GPU_AXI>, + <&clk IMX8MQ_CLK_GPU_AHB>, + <&clk IMX8MQ_GPU_PLL_BYPASS>; + assigned-clock-parents = <&clk IMX8MQ_GPU_PLL_OUT>, + <&clk IMX8MQ_GPU_PLL_OUT>, + <&clk IMX8MQ_GPU_PLL_OUT>, + <&clk IMX8MQ_GPU_PLL_OUT>, + <&clk IMX8MQ_GPU_PLL>; + assigned-clock-rates = <800000000>, <800000000>, + <800000000>, <800000000>, <0>; + power-domains = <&pgc_gpu>; + }; + + usb_dwc3_0: usb@38100000 { + compatible = "fsl,imx8mq-dwc3", "snps,dwc3"; + reg = <0x38100000 0x10000>; + clocks = <&clk IMX8MQ_CLK_USB1_CTRL_ROOT>, + <&clk IMX8MQ_CLK_USB_CORE_REF>, + <&clk IMX8MQ_CLK_32K>; + clock-names = "bus_early", "ref", "suspend"; + assigned-clocks = <&clk IMX8MQ_CLK_USB_BUS>, + <&clk IMX8MQ_CLK_USB_CORE_REF>; + assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_500M>, + <&clk IMX8MQ_SYS1_PLL_100M>; + assigned-clock-rates = <500000000>, <100000000>; + interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; + phys = <&usb3_phy0>, <&usb3_phy0>; + phy-names = "usb2-phy", "usb3-phy"; + power-domains = <&pgc_otg1>; + usb3-resume-missing-cas; + status = "disabled"; + }; + + usb3_phy0: usb-phy@381f0040 { + compatible = "fsl,imx8mq-usb-phy"; + reg = <0x381f0040 0x40>; + clocks = <&clk IMX8MQ_CLK_USB1_PHY_ROOT>; + clock-names = "phy"; + assigned-clocks = <&clk IMX8MQ_CLK_USB_PHY_REF>; + assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_100M>; + assigned-clock-rates = <100000000>; + #phy-cells = <0>; + status = "disabled"; + }; + + usb_dwc3_1: usb@38200000 { + compatible = "fsl,imx8mq-dwc3", "snps,dwc3"; + reg = <0x38200000 0x10000>; + clocks = <&clk IMX8MQ_CLK_USB2_CTRL_ROOT>, + <&clk IMX8MQ_CLK_USB_CORE_REF>, + <&clk IMX8MQ_CLK_32K>; + clock-names = "bus_early", "ref", "suspend"; + assigned-clocks = <&clk IMX8MQ_CLK_USB_BUS>, + <&clk IMX8MQ_CLK_USB_CORE_REF>; + assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_500M>, + <&clk IMX8MQ_SYS1_PLL_100M>; + assigned-clock-rates = <500000000>, <100000000>; + interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; + phys = <&usb3_phy1>, <&usb3_phy1>; + phy-names = "usb2-phy", "usb3-phy"; + power-domains = <&pgc_otg2>; + usb3-resume-missing-cas; + status = "disabled"; + }; + + usb3_phy1: usb-phy@382f0040 { + compatible = "fsl,imx8mq-usb-phy"; + reg = <0x382f0040 0x40>; + clocks = <&clk IMX8MQ_CLK_USB2_PHY_ROOT>; + clock-names = "phy"; + assigned-clocks = <&clk IMX8MQ_CLK_USB_PHY_REF>; + assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_100M>; + assigned-clock-rates = <100000000>; + #phy-cells = <0>; + status = "disabled"; + }; + + pcie0: pcie@33800000 { + compatible = "fsl,imx8mq-pcie"; + reg = <0x33800000 0x400000>, + <0x1ff00000 0x80000>; + reg-names = "dbi", "config"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + bus-range = <0x00 0xff>; + ranges = <0x81000000 0 0x00000000 0x1ff80000 0 0x00010000 /* downstream I/O 64KB */ + 0x82000000 0 0x18000000 0x18000000 0 0x07f00000>; /* non-prefetchable memory */ + num-lanes = <1>; + num-viewport = <4>; + interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "msi"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; + fsl,max-link-speed = <2>; + power-domains = <&pgc_pcie>; + resets = <&src IMX8MQ_RESET_PCIEPHY>, + <&src IMX8MQ_RESET_PCIE_CTRL_APPS_EN>, + <&src IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF>; + reset-names = "pciephy", "apps", "turnoff"; + status = "disabled"; + }; + + pcie1: pcie@33c00000 { + compatible = "fsl,imx8mq-pcie"; + reg = <0x33c00000 0x400000>, + <0x27f00000 0x80000>; + reg-names = "dbi", "config"; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges = <0x81000000 0 0x00000000 0x27f80000 0 0x00010000 /* downstream I/O 64KB */ + 0x82000000 0 0x20000000 0x20000000 0 0x07f00000>; /* non-prefetchable memory */ + num-lanes = <1>; + num-viewport = <4>; + interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "msi"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; + fsl,max-link-speed = <2>; + power-domains = <&pgc_pcie>; + resets = <&src IMX8MQ_RESET_PCIEPHY2>, + <&src IMX8MQ_RESET_PCIE2_CTRL_APPS_EN>, + <&src IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF>; + reset-names = "pciephy", "apps", "turnoff"; + status = "disabled"; + }; + + gic: interrupt-controller@38800000 { + compatible = "arm,gic-v3"; + reg = <0x38800000 0x10000>, /* GIC Dist */ + <0x38880000 0xc0000>, /* GICR */ + <0x31000000 0x2000>, /* GICC */ + <0x31010000 0x2000>, /* GICV */ + <0x31020000 0x2000>; /* GICH */ + #interrupt-cells = <3>; + interrupt-controller; + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&gic>; + }; + + ddr-pmu@3d800000 { + compatible = "fsl,imx8mq-ddr-pmu", "fsl,imx8m-ddr-pmu"; + reg = <0x3d800000 0x400000>; + interrupt-parent = <&gic>; + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; + }; + }; +}; diff --git a/arch/arm/dts/imx8qm-rom7720-a1.dts b/arch/arm/dts/imx8qm-rom7720-a1.dts new file mode 100644 index 0000000000..5f9ac955ed --- /dev/null +++ b/arch/arm/dts/imx8qm-rom7720-a1.dts @@ -0,0 +1,373 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + */ + +/dts-v1/; + +/* First 128KB is for PSCI ATF. */ +/memreserve/ 0x80000000 0x00020000; + +#include "fsl-imx8qm.dtsi" + +/ { + model = "Advantech iMX8QM Qseven series"; + compatible = "fsl,imx8qm-mek", "fsl,imx8qm"; + + chosen { + bootargs = "console=ttyLP0,115200 earlycon=lpuart32,0x5a060000,115200"; + stdout-path = &lpuart0; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_leds>; + user { + label = "heartbeat"; + gpios = <&gpio2 15 0>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + reg_usb_otg1_vbus: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "usb_otg1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio4 3 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usdhc2_vmmc: usdhc2_vmmc { + compatible = "regulator-fixed"; + regulator-name = "sw-3p3-sd1"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio4 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; +}; + +&iomuxc { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog_1>; + + imx8qm-mek { + pinctrl_hog_1: hoggrp-1 { + fsl,pins = < + SC_P_USB_SS3_TC0_LSIO_GPIO4_IO03 0x06000048 + >; + }; + + pinctrl_fec1: fec1grp { + fsl,pins = < + SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETB_PAD 0x000014a0 + SC_P_ENET0_MDC_CONN_ENET0_MDC 0x06000048 + SC_P_ENET0_MDIO_CONN_ENET0_MDIO 0x06000048 + SC_P_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL 0x00000060 + SC_P_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC 0x00000060 + SC_P_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0 0x00000060 + SC_P_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1 0x00000060 + SC_P_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2 0x00000060 + SC_P_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3 0x00000060 + SC_P_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC 0x00000060 + SC_P_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL 0x00000060 + SC_P_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0 0x00000060 + SC_P_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1 0x00000060 + SC_P_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2 0x00000060 + SC_P_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3 0x00000060 + >; + }; + + pinctrl_fec2: fec2grp { + fsl,pins = < + SC_P_COMP_CTL_GPIO_1V8_3V3_ENET_ENETA_PAD 0x000014a0 + SC_P_ENET1_RGMII_TX_CTL_CONN_ENET1_RGMII_TX_CTL 0x00000060 + SC_P_ENET1_RGMII_TXC_CONN_ENET1_RGMII_TXC 0x00000060 + SC_P_ENET1_RGMII_TXD0_CONN_ENET1_RGMII_TXD0 0x00000060 + SC_P_ENET1_RGMII_TXD1_CONN_ENET1_RGMII_TXD1 0x00000060 + SC_P_ENET1_RGMII_TXD2_CONN_ENET1_RGMII_TXD2 0x00000060 + SC_P_ENET1_RGMII_TXD3_CONN_ENET1_RGMII_TXD3 0x00000060 + SC_P_ENET1_RGMII_RXC_CONN_ENET1_RGMII_RXC 0x00000060 + SC_P_ENET1_RGMII_RX_CTL_CONN_ENET1_RGMII_RX_CTL 0x00000060 + SC_P_ENET1_RGMII_RXD0_CONN_ENET1_RGMII_RXD0 0x00000060 + SC_P_ENET1_RGMII_RXD1_CONN_ENET1_RGMII_RXD1 0x00000060 + SC_P_ENET1_RGMII_RXD2_CONN_ENET1_RGMII_RXD2 0x00000060 + SC_P_ENET1_RGMII_RXD3_CONN_ENET1_RGMII_RXD3 0x00000060 + >; + }; + + pinctrl_lpuart0: lpuart0grp { + fsl,pins = < + SC_P_UART0_RX_DMA_UART0_RX 0x06000020 + SC_P_UART0_TX_DMA_UART0_TX 0x06000020 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000041 + SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000021 + SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000021 + SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000021 + SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000021 + SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000021 + SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000021 + SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000021 + SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000021 + SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000021 + SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000041 + SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000021 + >; + }; + + pinctrl_usdhc1_100mhz: usdhc1grp100mhz { + fsl,pins = < + SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040 + SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020 + SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020 + SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020 + SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020 + SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020 + SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020 + SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020 + SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020 + SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020 + SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000040 + SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020 + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1grp200mhz { + fsl,pins = < + SC_P_EMMC0_CLK_CONN_EMMC0_CLK 0x06000040 + SC_P_EMMC0_CMD_CONN_EMMC0_CMD 0x00000020 + SC_P_EMMC0_DATA0_CONN_EMMC0_DATA0 0x00000020 + SC_P_EMMC0_DATA1_CONN_EMMC0_DATA1 0x00000020 + SC_P_EMMC0_DATA2_CONN_EMMC0_DATA2 0x00000020 + SC_P_EMMC0_DATA3_CONN_EMMC0_DATA3 0x00000020 + SC_P_EMMC0_DATA4_CONN_EMMC0_DATA4 0x00000020 + SC_P_EMMC0_DATA5_CONN_EMMC0_DATA5 0x00000020 + SC_P_EMMC0_DATA6_CONN_EMMC0_DATA6 0x00000020 + SC_P_EMMC0_DATA7_CONN_EMMC0_DATA7 0x00000020 + SC_P_EMMC0_STROBE_CONN_EMMC0_STROBE 0x06000040 + SC_P_EMMC0_RESET_B_CONN_EMMC0_RESET_B 0x00000020 + >; + }; + + pinctrl_usdhc2_gpio: usdhc2grpgpio { + fsl,pins = < + SC_P_USDHC1_DATA6_LSIO_GPIO5_IO21 0x00000021 + SC_P_USDHC1_DATA7_LSIO_GPIO5_IO22 0x00000021 + SC_P_USDHC1_RESET_B_LSIO_GPIO4_IO07 0x00000021 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000041 + SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000021 + SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000021 + SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000021 + SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000021 + SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000021 + SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000021 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2grp100mhz { + fsl,pins = < + SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000040 + SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000020 + SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000020 + SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000020 + SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000020 + SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000020 + SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000020 + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2grp200mhz { + fsl,pins = < + SC_P_USDHC1_CLK_CONN_USDHC1_CLK 0x06000040 + SC_P_USDHC1_CMD_CONN_USDHC1_CMD 0x00000020 + SC_P_USDHC1_DATA0_CONN_USDHC1_DATA0 0x00000020 + SC_P_USDHC1_DATA1_CONN_USDHC1_DATA1 0x00000020 + SC_P_USDHC1_DATA2_CONN_USDHC1_DATA2 0x00000020 + SC_P_USDHC1_DATA3_CONN_USDHC1_DATA3 0x00000020 + SC_P_USDHC1_VSELECT_CONN_USDHC1_VSELECT 0x00000020 + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + SC_P_USDHC2_CLK_CONN_USDHC2_CLK 0x06000041 + SC_P_USDHC2_CMD_CONN_USDHC2_CMD 0x00000021 + SC_P_USDHC2_DATA0_CONN_USDHC2_DATA0 0x00000021 + SC_P_USDHC2_DATA1_CONN_USDHC2_DATA1 0x00000021 + SC_P_USDHC2_DATA2_CONN_USDHC2_DATA2 0x00000021 + SC_P_USDHC2_DATA3_CONN_USDHC2_DATA3 0x00000021 + /* WP */ + SC_P_USDHC2_WP_LSIO_GPIO4_IO11 0x00000021 + /* CD */ + SC_P_USDHC2_CD_B_LSIO_GPIO4_IO12 0x00000021 + >; + }; + + pinctrl_lpi2c1: lpi2c1grp { + fsl,pins = < + SC_P_GPT0_CLK_DMA_I2C1_SCL 0x06000020 + SC_P_GPT0_CAPTURE_DMA_I2C1_SDA 0x06000020 + /* + * Change the default alt function from SCL/SDA to others, + * to avoid select input conflict with GPT0 + */ + SC_P_USB_SS3_TC0_LSIO_GPIO4_IO03 0x0700004c + SC_P_USB_SS3_TC1_LSIO_GPIO4_IO04 0x0700004c + SC_P_USB_SS3_TC2_LSIO_GPIO4_IO05 0x0700004c + SC_P_USB_SS3_TC3_LSIO_GPIO4_IO06 0x0700004c + >; + }; + + pinctrl_gpio_leds: gpioledsgrp { + fsl,pins = < + SC_P_SPDIF0_TX_LSIO_GPIO2_IO15 0x00000021 + >; + }; + }; +}; + +&gpio2 { + status = "okay"; +}; + +&gpio4 { + status = "okay"; +}; + +&gpio5 { + status = "okay"; +}; + +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + bus-width = <8>; + non-removable; + status = "okay"; +}; + +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; + bus-width = <4>; + cd-gpios = <&gpio5 22 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio5 21 GPIO_ACTIVE_HIGH>; + vmmc-supply = <®_usdhc2_vmmc>; + status = "okay"; +}; + +&usdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc3>; + bus-width = <4>; + cd-gpios = <&gpio4 12 GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio4 11 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&fec1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec1>; + phy-mode = "rgmii"; + phy-handle = <ðphy0>; + fsl,ar8031-phy-fixup; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + }; + + ethphy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + }; + }; +}; + +&fec2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fec2>; + phy-mode = "rgmii"; + phy-handle = <ðphy1>; + fsl,ar8031-phy-fixup; + fsl,magic-packet; + status = "okay"; +}; + +&i2c1 { + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpi2c1>; + status = "okay"; + + pca9557_a: gpio@18 { + compatible = "nxp,pca9557"; + reg = <0x18>; + gpio-controller; + #gpio-cells = <2>; + }; + + pca9557_b: gpio@19 { + compatible = "nxp,pca9557"; + reg = <0x19>; + gpio-controller; + #gpio-cells = <2>; + }; + + pca9557_c: gpio@1b { + compatible = "nxp,pca9557"; + reg = <0x1b>; + gpio-controller; + #gpio-cells = <2>; + }; + + pca9557_d: gpio@1f { + compatible = "nxp,pca9557"; + reg = <0x1f>; + gpio-controller; + #gpio-cells = <2>; + }; +}; + +&lpuart0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lpuart0>; + status = "okay"; +}; + +&lpuart1 { + status = "okay"; +}; diff --git a/arch/arm/include/asm/arch-imx8m/clock_imx8mq.h b/arch/arm/include/asm/arch-imx8m/clock_imx8mq.h index 9fa9eb2687..38a6f5966b 100644 --- a/arch/arm/include/asm/arch-imx8m/clock_imx8mq.h +++ b/arch/arm/include/asm/arch-imx8m/clock_imx8mq.h @@ -421,4 +421,6 @@ enum frac_pll_out_val { FRAC_PLL_OUT_1000M, FRAC_PLL_OUT_1600M, }; + +void init_nand_clk(void); #endif diff --git a/arch/arm/include/asm/arch-mx6/clock.h b/arch/arm/include/asm/arch-mx6/clock.h index a9481a5fea..f7760541a4 100644 --- a/arch/arm/include/asm/arch-mx6/clock.h +++ b/arch/arm/include/asm/arch-mx6/clock.h @@ -71,6 +71,7 @@ int enable_pcie_clock(void); int enable_i2c_clk(unsigned char enable, unsigned i2c_num); int enable_spi_clk(unsigned char enable, unsigned spi_num); void enable_ipu_clock(void); +void disable_ipu_clock(void); int enable_fec_anatop_clock(int fec_id, enum enet_freq freq); void enable_enet_clk(unsigned char enable); int enable_lcdif_clock(u32 base_addr, bool enable); diff --git a/arch/arm/include/asm/mach-imx/imx-nandbcb.h b/arch/arm/include/asm/mach-imx/imx-nandbcb.h index 033659a038..907e7ed8f9 100644 --- a/arch/arm/include/asm/mach-imx/imx-nandbcb.h +++ b/arch/arm/include/asm/mach-imx/imx-nandbcb.h @@ -106,6 +106,18 @@ struct fcb_block { /* The swap position of main area in spare area */ u32 spare_offset; + + /* Actual for iMX7 only */ + u32 onfi_sync_enable; + u32 onfi_sync_speed; + u32 onfi_sync_nand_data; + u32 reserved2[6]; + u32 disbbm_search; + u32 disbbm_search_limit; + u32 reserved3[15]; + u32 read_retry_enable; + u32 reserved4[1]; + u32 fill_to_1024[183]; }; #endif /* _IMX_NAND_BCB_H_ */ diff --git a/arch/arm/include/asm/mach-imx/regs-gpmi.h b/arch/arm/include/asm/mach-imx/regs-gpmi.h index 80cb731724..33daa53c45 100644 --- a/arch/arm/include/asm/mach-imx/regs-gpmi.h +++ b/arch/arm/include/asm/mach-imx/regs-gpmi.h @@ -70,6 +70,11 @@ struct mxs_gpmi_regs { #define GPMI_ECCCTRL_ECC_CMD_OFFSET 13 #define GPMI_ECCCTRL_ECC_CMD_DECODE (0x0 << 13) #define GPMI_ECCCTRL_ECC_CMD_ENCODE (0x1 << 13) +#define GPMI_ECCCTRL_RANDOMIZER_ENABLE (1 << 11) +#define GPMI_ECCCTRL_RANDOMIZER_TYPE0 0 +#define GPMI_ECCCTRL_RANDOMIZER_TYPE1 (1 << 9) +#define GPMI_ECCCTRL_RANDOMIZER_TYPE2 (2 << 9) + #define GPMI_ECCCTRL_ENABLE_ECC (1 << 12) #define GPMI_ECCCTRL_BUFFER_MASK_MASK 0x1ff #define GPMI_ECCCTRL_BUFFER_MASK_OFFSET 0 diff --git a/arch/arm/include/asm/mach-imx/sys_proto.h b/arch/arm/include/asm/mach-imx/sys_proto.h index aa66fdc88f..1e627c8fc3 100644 --- a/arch/arm/include/asm/mach-imx/sys_proto.h +++ b/arch/arm/include/asm/mach-imx/sys_proto.h @@ -99,11 +99,6 @@ enum imx6_bmode { IMX6_BMODE_NAND_MAX = 0xf, }; -static inline u8 imx6_is_bmode_from_gpr9(void) -{ - return readl(&src_base->gpr10) & IMX6_SRC_GPR10_BMODE; -} - u32 imx6_src_get_boot_mode(void); void gpr_init(void); @@ -143,7 +138,8 @@ int mxs_wait_mask_set(struct mxs_register_32 *reg, u32 mask, u32 timeout); int mxs_wait_mask_clr(struct mxs_register_32 *reg, u32 mask, u32 timeout); unsigned long call_imx_sip(unsigned long id, unsigned long reg0, - unsigned long reg1, unsigned long reg2); + unsigned long reg1, unsigned long reg2, + unsigned long reg3); unsigned long call_imx_sip_ret2(unsigned long id, unsigned long reg0, unsigned long *reg1, unsigned long reg2, unsigned long reg3); diff --git a/arch/arm/mach-bcm283x/include/mach/timer.h b/arch/arm/mach-bcm283x/include/mach/timer.h index 014355e759..61beb1aba1 100644 --- a/arch/arm/mach-bcm283x/include/mach/timer.h +++ b/arch/arm/mach-bcm283x/include/mach/timer.h @@ -25,9 +25,6 @@ struct bcm2835_timer_regs { u32 c2; u32 c3; }; - -extern ulong get_timer_us(ulong base); - #endif #endif diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index b0b9d2c070..3f93fe5174 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -81,7 +81,8 @@ config CMD_HDMIDETECT config CMD_NANDBCB bool "i.MX6 NAND Boot Control Block(BCB) command" depends on NAND && CMD_MTDPARTS - default y if ARCH_MX6 && NAND_MXS + select BCH if MX6UL || MX6ULL + default y if (ARCH_MX6 && NAND_MXS) || (ARCH_MX7 && NAND_MXS) help Unlike normal 'nand write/erase' commands, this command update Boot Control Block(BCB) for i.MX6 platform NAND IP's. diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 9dfe883ead..6e87dc58a0 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -155,10 +155,8 @@ ifeq ($(DEPFILE_EXISTS),0) endif flash.bin: spl/u-boot-spl-ddr.bin u-boot.itb FORCE -ifeq ($(DEPFILE_EXISTS),0) $(call if_changed,mkimage) endif -endif ifeq ($(CONFIG_ARCH_IMX8), y) SPL: diff --git a/arch/arm/mach-imx/cmd_nandbcb.c b/arch/arm/mach-imx/cmd_nandbcb.c index 7811c61d22..09c4356529 100644 --- a/arch/arm/mach-imx/cmd_nandbcb.c +++ b/arch/arm/mach-imx/cmd_nandbcb.c @@ -14,8 +14,10 @@ #include <asm/io.h> #include <jffs2/jffs2.h> +#include <linux/bch.h> #include <linux/mtd/mtd.h> +#include <asm/arch/sys_proto.h> #include <asm/mach-imx/imx-nandbcb.h> #include <asm/mach-imx/imximage.cfg> #include <mxs_nand.h> @@ -25,6 +27,68 @@ #define BF_VAL(v, bf) (((v) & bf##_MASK) >> bf##_OFFSET) #define GETBIT(v, n) (((v) >> (n)) & 0x1) +#if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) +static uint8_t reverse_bit(uint8_t b) +{ + b = (b & 0xf0) >> 4 | (b & 0x0f) << 4; + b = (b & 0xcc) >> 2 | (b & 0x33) << 2; + b = (b & 0xaa) >> 1 | (b & 0x55) << 1; + + return b; +} + +static void encode_bch_ecc(void *buf, struct fcb_block *fcb, int eccbits) +{ + int i, j, m = 13; + int blocksize = 128; + int numblocks = 8; + int ecc_buf_size = (m * eccbits + 7) / 8; + struct bch_control *bch = init_bch(m, eccbits, 0); + u8 *ecc_buf = kzalloc(ecc_buf_size, GFP_KERNEL); + u8 *tmp_buf = kzalloc(blocksize * numblocks, GFP_KERNEL); + u8 *psrc, *pdst; + + /* + * The blocks here are bit aligned. If eccbits is a multiple of 8, + * we just can copy bytes. Otherwiese we must move the blocks to + * the next free bit position. + */ + WARN_ON(eccbits % 8); + + memcpy(tmp_buf, fcb, sizeof(*fcb)); + + for (i = 0; i < numblocks; i++) { + memset(ecc_buf, 0, ecc_buf_size); + psrc = tmp_buf + i * blocksize; + pdst = buf + i * (blocksize + ecc_buf_size); + + /* copy data byte aligned to destination buf */ + memcpy(pdst, psrc, blocksize); + + /* + * imx-kobs use a modified encode_bch which reverse the + * bit order of the data before calculating bch. + * Do this in the buffer and use the bch lib here. + */ + for (j = 0; j < blocksize; j++) + psrc[j] = reverse_bit(psrc[j]); + + encode_bch(bch, psrc, blocksize, ecc_buf); + + /* reverse ecc bit */ + for (j = 0; j < ecc_buf_size; j++) + ecc_buf[j] = reverse_bit(ecc_buf[j]); + + /* Here eccbuf is byte aligned and we can just copy it */ + memcpy(pdst + blocksize, ecc_buf, ecc_buf_size); + } + + kfree(ecc_buf); + kfree(tmp_buf); + free_bch(bch); +} +#else + static u8 calculate_parity_13_8(u8 d) { u8 p = 0; @@ -50,6 +114,7 @@ static void encode_hamming_13_8(void *_src, void *_ecc, size_t size) for (i = 0; i < size; i++) ecc[i] = calculate_parity_13_8(src[i]); } +#endif static u32 calc_chksum(void *buf, size_t size) { @@ -63,30 +128,41 @@ static u32 calc_chksum(void *buf, size_t size) return ~chksum; } -static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd) +static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd, + u32 fw1_start, u32 fw2_start, u32 fw_pages) { struct nand_chip *chip = mtd_to_nand(mtd); struct mxs_nand_info *nand_info = nand_get_controller_data(chip); + struct mxs_nand_layout l; + + mxs_nand_get_layout(mtd, &l); fcb->fingerprint = FCB_FINGERPRINT; fcb->version = FCB_VERSION_1; + fcb->pagesize = mtd->writesize; fcb->oob_pagesize = mtd->writesize + mtd->oobsize; fcb->sectors = mtd->erasesize / mtd->writesize; - /* Divide ECC strength by two and save the value into FCB structure. */ - fcb->ecc_level = nand_info->bch_geometry.ecc_strength >> 1; - - fcb->ecc_type = fcb->ecc_level; + fcb->meta_size = l.meta_size; + fcb->nr_blocks = l.nblocks; + fcb->ecc_nr = l.data0_size; + fcb->ecc_level = l.ecc0; + fcb->ecc_size = l.datan_size; + fcb->ecc_type = l.eccn; /* Also hardcoded in kobs-ng */ - fcb->ecc_nr = 0x00000200; - fcb->ecc_size = 0x00000200; - fcb->datasetup = 80; - fcb->datahold = 60; - fcb->addr_setup = 25; - fcb->dsample_time = 6; - fcb->meta_size = 10; + if (is_mx6()) { + fcb->datasetup = 80; + fcb->datahold = 60; + fcb->addr_setup = 25; + fcb->dsample_time = 6; + } else if (is_mx7()) { + fcb->datasetup = 10; + fcb->datahold = 7; + fcb->addr_setup = 15; + fcb->dsample_time = 6; + } /* DBBT search area starts at second page on first block */ fcb->dbbt_start = 1; @@ -98,6 +174,14 @@ static void fill_fcb(struct fcb_block *fcb, struct mtd_info *mtd) fcb->nr_blocks = mtd->writesize / fcb->ecc_nr - 1; + fcb->disbbm = 0; + fcb->disbbm_search = 0; + + fcb->fw1_start = fw1_start; /* Firmware image starts on this sector */ + fcb->fw2_start = fw2_start; /* Secondary FW Image starting Sector */ + fcb->fw1_pages = fw_pages; /* Number of sectors in firmware image */ + fcb->fw2_pages = fw_pages; /* Number of sector in secondary FW image */ + fcb->checksum = calc_chksum((void *)fcb + 4, sizeof(*fcb) - 4); } @@ -121,6 +205,114 @@ static int dbbt_fill_data(struct mtd_info *mtd, void *buf, int num_blocks) return n_bad_blocks; } +static int write_fcb_dbbt(struct mtd_info *mtd, struct fcb_block *fcb, + struct dbbt_block *dbbt, void *dbbt_data_page, + loff_t off) +{ + void *fcb_raw_page = 0; + int i, ret; + size_t dummy; + + /* + * We prepare raw page only for i.MX6, for i.MX7 we + * leverage BCH hw module instead + */ + if (is_mx6()) { + /* write fcb/dbbt */ + fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize, + GFP_KERNEL); + if (!fcb_raw_page) { + debug("failed to allocate fcb_raw_page\n"); + ret = -ENOMEM; + return ret; + } + +#if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) + /* 40 bit BCH, for i.MX6UL(L) */ + encode_bch_ecc(fcb_raw_page + 32, fcb, 40); +#else + memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block)); + encode_hamming_13_8(fcb_raw_page + 12, + fcb_raw_page + 12 + 512, 512); +#endif + /* + * Set the first and second byte of OOB data to 0xFF, + * not 0x00. These bytes are used as the Manufacturers Bad + * Block Marker (MBBM). Since the FCB is mostly written to + * the first page in a block, a scan for + * factory bad blocks will detect these blocks as bad, e.g. + * when function nand_scan_bbt() is executed to build a new + * bad block table. + */ + memset(fcb_raw_page + mtd->writesize, 0xFF, 2); + } + for (i = 0; i < 2; i++) { + if (mtd_block_isbad(mtd, off)) { + printf("Block %d is bad, skipped\n", i); + continue; + } + + /* + * User BCH ECC hardware module for i.MX7 + */ + if (is_mx7()) { + u32 off = i * mtd->erasesize; + size_t rwsize = sizeof(*fcb); + + printf("Writing %d bytes to 0x%x: ", rwsize, off); + + /* switch nand BCH to FCB compatible settings */ + mxs_nand_mode_fcb(mtd); + ret = nand_write(mtd, off, &rwsize, + (unsigned char *)fcb); + mxs_nand_mode_normal(mtd); + + printf("%s\n", ret ? "ERROR" : "OK"); + } else if (is_mx6()) { + /* raw write */ + mtd_oob_ops_t ops = { + .datbuf = (u8 *)fcb_raw_page, + .oobbuf = ((u8 *)fcb_raw_page) + + mtd->writesize, + .len = mtd->writesize, + .ooblen = mtd->oobsize, + .mode = MTD_OPS_RAW + }; + + ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops); + if (ret) + goto fcb_raw_page_err; + debug("NAND fcb write: 0x%x offset 0x%x written: %s\n", + mtd->erasesize * i, ops.len, ret ? + "ERROR" : "OK"); + } + + ret = mtd_write(mtd, mtd->erasesize * i + mtd->writesize, + mtd->writesize, &dummy, (void *)dbbt); + if (ret) + goto fcb_raw_page_err; + debug("NAND dbbt write: 0x%x offset, 0x%x bytes written: %s\n", + mtd->erasesize * i + mtd->writesize, dummy, + ret ? "ERROR" : "OK"); + + /* dbbtpages == 0 if no bad blocks */ + if (dbbt->dbbtpages > 0) { + loff_t to = (mtd->erasesize * i + mtd->writesize * 5); + + ret = mtd_write(mtd, to, mtd->writesize, &dummy, + dbbt_data_page); + if (ret) + goto fcb_raw_page_err; + } + } + +fcb_raw_page_err: + if (is_mx6()) + kfree(fcb_raw_page); + + return ret; +} + static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, size_t maxsize, const u_char *buf) { @@ -128,10 +320,11 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, struct fcb_block *fcb; struct dbbt_block *dbbt; loff_t fw1_off; - void *fwbuf, *fcb_raw_page, *dbbt_page, *dbbt_data_page; + void *fwbuf, *dbbt_page, *dbbt_data_page; + u32 fw1_start, fw1_pages; int nr_blks, nr_blks_fcb, fw1_blk; - size_t fwsize, dummy; - int i, ret; + size_t fwsize; + int ret; /* erase */ memset(&opts, 0, sizeof(opts)); @@ -194,9 +387,9 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, goto fwbuf_err; } - fcb->fw1_start = (fw1_blk * mtd->erasesize) / mtd->writesize; - fcb->fw1_pages = size / mtd->writesize + 1; - fill_fcb(fcb, mtd); + fw1_start = (fw1_blk * mtd->erasesize) / mtd->writesize; + fw1_pages = size / mtd->writesize + 1; + fill_fcb(fcb, mtd, fw1_start, 0, fw1_pages); /* fill dbbt */ dbbt_page = kzalloc(mtd->writesize, GFP_KERNEL); @@ -223,77 +416,103 @@ static int nandbcb_update(struct mtd_info *mtd, loff_t off, size_t size, else if (ret > 0) dbbt->dbbtpages = 1; - /* write fcb/dbbt */ - fcb_raw_page = kzalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL); - if (!fcb_raw_page) { - debug("failed to allocate fcb_raw_page\n"); - ret = -ENOMEM; - goto dbbt_data_page_err; + /* write fcb and dbbt to nand */ + ret = write_fcb_dbbt(mtd, fcb, dbbt, dbbt_data_page, off); + if (ret < 0) + printf("failed to write FCB/DBBT\n"); + +dbbt_data_page_err: + kfree(dbbt_data_page); +dbbt_page_err: + kfree(dbbt_page); +fcb_err: + kfree(fcb); +fwbuf_err: + kfree(fwbuf); +err: + return ret; +} + +static int do_nandbcb_bcbonly(int argc, char * const argv[]) +{ + struct fcb_block *fcb; + struct dbbt_block *dbbt; + u32 fw_len, fw1_off, fw2_off; + struct mtd_info *mtd; + void *dbbt_page, *dbbt_data_page; + int dev, ret; + + dev = nand_curr_device; + if ((dev < 0) || (dev >= CONFIG_SYS_MAX_NAND_DEVICE) || + (!get_nand_dev_by_index(dev))) { + puts("No devices available\n"); + return CMD_RET_FAILURE; } - memcpy(fcb_raw_page + 12, fcb, sizeof(struct fcb_block)); - encode_hamming_13_8(fcb_raw_page + 12, fcb_raw_page + 12 + 512, 512); - /* - * Set the first and second byte of OOB data to 0xFF, not 0x00. These - * bytes are used as the Manufacturers Bad Block Marker (MBBM). Since - * the FCB is mostly written to the first page in a block, a scan for - * factory bad blocks will detect these blocks as bad, e.g. when - * function nand_scan_bbt() is executed to build a new bad block table. - */ - memset(fcb_raw_page + mtd->writesize, 0xFF, 2); + mtd = get_nand_dev_by_index(dev); - for (i = 0; i < nr_blks_fcb; i++) { - if (mtd_block_isbad(mtd, off)) { - printf("Block %d is bad, skipped\n", i); - continue; - } + if (argc < 3) + return CMD_RET_FAILURE; - /* raw write */ - mtd_oob_ops_t ops = { - .datbuf = (u8 *)fcb_raw_page, - .oobbuf = ((u8 *)fcb_raw_page) + mtd->writesize, - .len = mtd->writesize, - .ooblen = mtd->oobsize, - .mode = MTD_OPS_RAW - }; + fw_len = simple_strtoul(argv[1], NULL, 16); + fw1_off = simple_strtoul(argv[2], NULL, 16); - ret = mtd_write_oob(mtd, mtd->erasesize * i, &ops); - if (ret) - goto fcb_raw_page_err; - debug("NAND fcb write: 0x%x offset, 0x%x bytes written: %s\n", - mtd->erasesize * i, ops.len, ret ? "ERROR" : "OK"); + if (argc > 3) + fw2_off = simple_strtoul(argv[3], NULL, 16); + else + fw2_off = fw1_off; - ret = mtd_write(mtd, mtd->erasesize * i + mtd->writesize, - mtd->writesize, &dummy, dbbt_page); - if (ret) - goto fcb_raw_page_err; - debug("NAND dbbt write: 0x%x offset, 0x%x bytes written: %s\n", - mtd->erasesize * i + mtd->writesize, dummy, - ret ? "ERROR" : "OK"); + /* fill fcb */ + fcb = kzalloc(sizeof(*fcb), GFP_KERNEL); + if (!fcb) { + debug("failed to allocate fcb\n"); + ret = -ENOMEM; + return CMD_RET_FAILURE; + } - /* dbbtpages == 0 if no bad blocks */ - if (dbbt->dbbtpages > 0) { - loff_t to = (mtd->erasesize * i + mtd->writesize * 5); + fill_fcb(fcb, mtd, fw1_off / mtd->writesize, + fw2_off / mtd->writesize, fw_len / mtd->writesize); - ret = mtd_write(mtd, to, mtd->writesize, &dummy, - dbbt_data_page); - if (ret) - goto fcb_raw_page_err; - } + /* fill dbbt */ + dbbt_page = kzalloc(mtd->writesize, GFP_KERNEL); + if (!dbbt_page) { + debug("failed to allocate dbbt_page\n"); + ret = -ENOMEM; + goto fcb_err; } -fcb_raw_page_err: - kfree(fcb_raw_page); + dbbt_data_page = kzalloc(mtd->writesize, GFP_KERNEL); + if (!dbbt_data_page) { + debug("failed to allocate dbbt_data_page\n"); + ret = -ENOMEM; + goto dbbt_page_err; + } + + dbbt = dbbt_page; + dbbt->checksum = 0; + dbbt->fingerprint = DBBT_FINGERPRINT2; + dbbt->version = DBBT_VERSION_1; + ret = dbbt_fill_data(mtd, dbbt_data_page, 0); + if (ret < 0) + goto dbbt_data_page_err; + else if (ret > 0) + dbbt->dbbtpages = 1; + + /* write fcb and dbbt to nand */ + ret = write_fcb_dbbt(mtd, fcb, dbbt, dbbt_data_page, 0); dbbt_data_page_err: kfree(dbbt_data_page); dbbt_page_err: kfree(dbbt_page); fcb_err: kfree(fcb); -fwbuf_err: - kfree(fwbuf); -err: - return ret; + + if (ret < 0) { + printf("failed to write FCB/DBBT\n"); + return CMD_RET_FAILURE; + } + + return CMD_RET_SUCCESS; } static int do_nandbcb_update(int argc, char * const argv[]) @@ -310,7 +529,7 @@ static int do_nandbcb_update(int argc, char * const argv[]) dev = nand_curr_device; if (dev < 0) { - printf("failed to get nand_curr_device, run nand device"); + printf("failed to get nand_curr_device, run nand device\n"); return CMD_RET_FAILURE; } @@ -352,6 +571,11 @@ static int do_nandbcb(cmd_tbl_t *cmdtp, int flag, int argc, goto done; } + if (strcmp(cmd, "bcbonly") == 0) { + ret = do_nandbcb_bcbonly(argc, argv); + goto done; + } + done: if (ret != -1) return ret; @@ -362,7 +586,10 @@ usage: #ifdef CONFIG_SYS_LONGHELP static char nandbcb_help_text[] = "update addr off|partition len - update 'len' bytes starting at\n" - " 'off|part' to memory address 'addr', skipping bad blocks"; + " 'off|part' to memory address 'addr', skipping bad blocks\n" + "bcbonly fw-size fw1-off [fw2-off] - write only BCB (FCB and DBBT)\n" + " where `fw-size` is fw sizes in bytes, `fw1-off` and\n" + " and `fw2-off` - firmware offsets "; #endif U_BOOT_CMD(nandbcb, 5, 1, do_nandbcb, diff --git a/arch/arm/mach-imx/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig index d17760e333..cdb78afacf 100644 --- a/arch/arm/mach-imx/imx8/Kconfig +++ b/arch/arm/mach-imx/imx8/Kconfig @@ -1,5 +1,10 @@ if ARCH_IMX8 +config AHAB_BOOT + bool "Support i.MX8 AHAB features" + help + This option enables the support for AHAB secure boot. + config IMX8 bool @@ -55,6 +60,12 @@ config TARGET_IMX8QM_MEK select BOARD_LATE_INIT select IMX8QM +config TARGET_IMX8QM_ROM7720_A1 + bool "Support i.MX8QM ROM-7720-A1" + select BOARD_LATE_INIT + select SUPPORT_SPL + select IMX8QM + config TARGET_IMX8QXP_MEK bool "Support i.MX8QXP MEK board" select BOARD_LATE_INIT @@ -64,6 +75,7 @@ endchoice source "board/freescale/imx8qm_mek/Kconfig" source "board/freescale/imx8qxp_mek/Kconfig" +source "board/advantech/imx8qm_rom7720_a1/Kconfig" source "board/toradex/apalis-imx8/Kconfig" source "board/toradex/colibri-imx8x/Kconfig" diff --git a/arch/arm/mach-imx/imx8/ahab.c b/arch/arm/mach-imx/imx8/ahab.c new file mode 100644 index 0000000000..cf3c7d762a --- /dev/null +++ b/arch/arm/mach-imx/imx8/ahab.c @@ -0,0 +1,347 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018-2019 NXP + */ + +#include <common.h> +#include <errno.h> +#include <asm/io.h> +#include <asm/arch/sci/sci.h> +#include <asm/mach-imx/sys_proto.h> +#include <asm/arch-imx/cpu.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/image.h> +#include <console.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define SEC_SECURE_RAM_BASE (0x31800000UL) +#define SEC_SECURE_RAM_END_BASE (SEC_SECURE_RAM_BASE + 0xFFFFUL) +#define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE (0x60000000UL) + +#define SECO_PT 2U + +static inline bool check_in_dram(ulong addr) +{ + int i; + bd_t *bd = gd->bd; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; ++i) { + if (bd->bi_dram[i].size) { + if (addr >= bd->bi_dram[i].start && + addr < (bd->bi_dram[i].start + bd->bi_dram[i].size)) + return true; + } + } + + return false; +} + +int authenticate_os_container(ulong addr) +{ + struct container_hdr *phdr; + int i, ret = 0; + int err; + sc_rm_mr_t mr; + sc_faddr_t start, end; + u16 length; + struct boot_img_t *img; + unsigned long s, e; + + if (addr % 4) { + puts("Error: Image's address is not 4 byte aligned\n"); + return -EINVAL; + } + + if (!check_in_dram(addr)) { + puts("Error: Image's address is invalid\n"); + return -EINVAL; + } + + phdr = (struct container_hdr *)addr; + if (phdr->tag != 0x87 && phdr->version != 0x0) { + printf("Error: Wrong container header\n"); + return -EFAULT; + } + + if (!phdr->num_images) { + printf("Error: Wrong container, no image found\n"); + return -EFAULT; + } + + length = phdr->length_lsb + (phdr->length_msb << 8); + + debug("container length %u\n", length); + memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)addr, + ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); + + err = sc_seco_authenticate(-1, SC_MISC_AUTH_CONTAINER, + SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE); + if (err) { + printf("Authenticate container hdr failed, return %d\n", + err); + ret = -EIO; + goto exit; + } + + /* Copy images to dest address */ + for (i = 0; i < phdr->num_images; i++) { + img = (struct boot_img_t *)(addr + + sizeof(struct container_hdr) + + i * sizeof(struct boot_img_t)); + + debug("img %d, dst 0x%llx, src 0x%lx, size 0x%x\n", + i, img->dst, img->offset + addr, img->size); + + memcpy((void *)img->dst, (const void *)(img->offset + addr), + img->size); + + s = img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1); + e = ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE); + + flush_dcache_range(s, e); + + /* Find the memreg and set permission for seco pt */ + err = sc_rm_find_memreg(-1, &mr, s, e); + if (err) { + printf("Not found memreg for image: %d, error %d\n", + i, err); + ret = -ENOMEM; + goto exit; + } + + err = sc_rm_get_memreg_info(-1, mr, &start, &end); + if (!err) + debug("memreg %u 0x%llx -- 0x%llx\n", mr, start, end); + + err = sc_rm_set_memreg_permissions(-1, mr, SECO_PT, + SC_RM_PERM_FULL); + if (err) { + printf("Set permission failed for img %d, error %d\n", + i, err); + ret = -EPERM; + goto exit; + } + + err = sc_seco_authenticate(-1, SC_MISC_VERIFY_IMAGE, + (1 << i)); + if (err) { + printf("Authenticate img %d failed, return %d\n", + i, err); + ret = -EIO; + } + + err = sc_rm_set_memreg_permissions(-1, mr, SECO_PT, + SC_RM_PERM_NONE); + if (err) { + printf("Remove permission failed for img %d, err %d\n", + i, err); + ret = -EPERM; + } + + if (ret) + goto exit; + } + +exit: + if (sc_seco_authenticate(-1, SC_MISC_REL_CONTAINER, 0) != SC_ERR_NONE) + printf("Error: release container failed!\n"); + + return ret; +} + +static int do_authenticate(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + ulong addr; + + if (argc < 2) + return CMD_RET_USAGE; + + addr = simple_strtoul(argv[1], NULL, 16); + + printf("Authenticate OS container at 0x%lx\n", addr); + + if (authenticate_os_container(addr)) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} + +static void display_life_cycle(u16 lc) +{ + printf("Lifecycle: 0x%04X, ", lc); + switch (lc) { + case 0x1: + printf("Pristine\n\n"); + break; + case 0x2: + printf("Fab\n\n"); + break; + case 0x8: + printf("Open\n\n"); + break; + case 0x20: + printf("NXP closed\n\n"); + break; + case 0x80: + printf("OEM closed\n\n"); + break; + case 0x100: + printf("Partial field return\n\n"); + break; + case 0x200: + printf("Full field return\n\n"); + break; + case 0x400: + printf("No return\n\n"); + break; + default: + printf("Unknown\n\n"); + break; + } +} + +#define AHAB_AUTH_CONTAINER_REQ 0x87 +#define AHAB_VERIFY_IMAGE_REQ 0x88 + +#define AHAB_NO_AUTHENTICATION_IND 0xee +#define AHAB_BAD_KEY_HASH_IND 0xfa +#define AHAB_INVALID_KEY_IND 0xf9 +#define AHAB_BAD_SIGNATURE_IND 0xf0 +#define AHAB_BAD_HASH_IND 0xf1 + +static void display_ahab_auth_event(u32 event) +{ + u8 cmd = (event >> 16) & 0xff; + u8 resp_ind = (event >> 8) & 0xff; + + switch (cmd) { + case AHAB_AUTH_CONTAINER_REQ: + printf("\tCMD = AHAB_AUTH_CONTAINER_REQ (0x%02X)\n", cmd); + printf("\tIND = "); + break; + case AHAB_VERIFY_IMAGE_REQ: + printf("\tCMD = AHAB_VERIFY_IMAGE_REQ (0x%02X)\n", cmd); + printf("\tIND = "); + break; + default: + return; + } + + switch (resp_ind) { + case AHAB_NO_AUTHENTICATION_IND: + printf("AHAB_NO_AUTHENTICATION_IND (0x%02X)\n\n", resp_ind); + break; + case AHAB_BAD_KEY_HASH_IND: + printf("AHAB_BAD_KEY_HASH_IND (0x%02X)\n\n", resp_ind); + break; + case AHAB_INVALID_KEY_IND: + printf("AHAB_INVALID_KEY_IND (0x%02X)\n\n", resp_ind); + break; + case AHAB_BAD_SIGNATURE_IND: + printf("AHAB_BAD_SIGNATURE_IND (0x%02X)\n\n", resp_ind); + break; + case AHAB_BAD_HASH_IND: + printf("AHAB_BAD_HASH_IND (0x%02X)\n\n", resp_ind); + break; + default: + printf("Unknown Indicator (0x%02X)\n\n", resp_ind); + break; + } +} + +static int do_ahab_status(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + int err; + u8 idx = 0U; + u32 event; + u16 lc; + + err = sc_seco_chip_info(-1, &lc, NULL, NULL, NULL); + if (err != SC_ERR_NONE) { + printf("Error in get lifecycle\n"); + return -EIO; + } + + display_life_cycle(lc); + + err = sc_seco_get_event(-1, idx, &event); + while (err == SC_ERR_NONE) { + printf("SECO Event[%u] = 0x%08X\n", idx, event); + display_ahab_auth_event(event); + + idx++; + err = sc_seco_get_event(-1, idx, &event); + } + + if (idx == 0) + printf("No SECO Events Found!\n\n"); + + return 0; +} + +static int confirm_close(void) +{ + puts("Warning: Please ensure your sample is in NXP closed state, " + "OEM SRK hash has been fused, \n" + " and you are able to boot a signed image successfully " + "without any SECO events reported.\n" + " If not, your sample will be unrecoverable.\n" + "\nReally perform this operation? <y/N>\n"); + + if (confirm_yesno()) + return 1; + + puts("Ahab close aborted\n"); + return 0; +} + +static int do_ahab_close(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + int err; + u16 lc; + + if (!confirm_close()) + return -EACCES; + + err = sc_seco_chip_info(-1, &lc, NULL, NULL, NULL); + if (err != SC_ERR_NONE) { + printf("Error in get lifecycle\n"); + return -EIO; + } + + if (lc != 0x20) { + puts("Current lifecycle is NOT NXP closed, can't move to OEM closed\n"); + display_life_cycle(lc); + return -EPERM; + } + + err = sc_seco_forward_lifecycle(-1, 16); + if (err != SC_ERR_NONE) { + printf("Error in forward lifecycle to OEM closed\n"); + return -EIO; + } + + printf("Change to OEM closed successfully\n"); + + return 0; +} + +U_BOOT_CMD(auth_cntr, CONFIG_SYS_MAXARGS, 1, do_authenticate, + "autenticate OS container via AHAB", + "addr\n" + "addr - OS container hex address\n" +); + +U_BOOT_CMD(ahab_status, CONFIG_SYS_MAXARGS, 1, do_ahab_status, + "display AHAB lifecycle and events from seco", + "" +); + +U_BOOT_CMD(ahab_close, CONFIG_SYS_MAXARGS, 1, do_ahab_close, + "Change AHAB lifecycle to OEM closed", + "" +); diff --git a/arch/arm/mach-imx/imx8/misc.c b/arch/arm/mach-imx/imx8/misc.c index fe73e29eee..00fe4670bb 100644 --- a/arch/arm/mach-imx/imx8/misc.c +++ b/arch/arm/mach-imx/imx8/misc.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ #include <common.h> #include <asm/arch/sci/sci.h> +#include <asm/mach-imx/sys_proto.h> int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate) { @@ -25,9 +26,14 @@ int sc_pm_setup_uart(sc_rsrc_t uart_rsrc, sc_pm_clock_rate_t clk_rate) return 0; } +#define FSL_SIP_BUILDINFO 0xC2000003 +#define FSL_SIP_BUILDINFO_GET_COMMITHASH 0x00 + void build_info(void) { + u32 seco_build = 0, seco_commit = 0; u32 sc_build = 0, sc_commit = 0; + ulong atf_commit = 0; /* Get SCFW build and commit id */ sc_misc_build_info(-1, &sc_build, &sc_commit); @@ -35,5 +41,23 @@ void build_info(void) printf("SCFW does not support build info\n"); sc_commit = 0; /* Display 0 if build info not supported */ } - printf("Build: SCFW %x\n", sc_commit); + + /* Get SECO FW build and commit id */ + sc_seco_build_info(-1, &seco_build, &seco_commit); + if (!seco_build) { + debug("SECO FW does not support build info\n"); + /* Display 0 when the build info is not supported */ + seco_commit = 0; + } + + /* Get ARM Trusted Firmware commit id */ + atf_commit = call_imx_sip(FSL_SIP_BUILDINFO, + FSL_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0); + if (atf_commit == 0xffffffff) { + debug("ATF does not support build info\n"); + atf_commit = 0x30; /* Display 0 */ + } + + printf("Build: SCFW %08x, SECO-FW %08x, ATF %s\n", + sc_commit, seco_commit, (char *)&atf_commit); } diff --git a/arch/arm/mach-imx/imx8/parse-container.c b/arch/arm/mach-imx/imx8/parse-container.c index 32f78bdddf..b57e68e412 100644 --- a/arch/arm/mach-imx/imx8/parse-container.c +++ b/arch/arm/mach-imx/imx8/parse-container.c @@ -7,6 +7,67 @@ #include <errno.h> #include <spl.h> #include <asm/arch/image.h> +#include <asm/arch/sci/sci.h> + +#define SEC_SECURE_RAM_BASE 0x31800000UL +#define SEC_SECURE_RAM_END_BASE (SEC_SECURE_RAM_BASE + 0xFFFFUL) +#define SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE 0x60000000UL + +#define SECO_PT 2U + +#ifdef CONFIG_AHAB_BOOT +static int authenticate_image(struct boot_img_t *img, int image_index) +{ + sc_faddr_t start, end; + sc_rm_mr_t mr; + int err; + int ret = 0; + + debug("img %d, dst 0x%llx, src 0x%x, size 0x%x\n", + image_index, img->dst, img->offset, img->size); + + /* Find the memreg and set permission for seco pt */ + err = sc_rm_find_memreg(-1, &mr, + img->dst & ~(CONFIG_SYS_CACHELINE_SIZE - 1), + ALIGN(img->dst + img->size, CONFIG_SYS_CACHELINE_SIZE)); + + if (err) { + printf("can't find memreg for image: %d, err %d\n", + image_index, err); + return -ENOMEM; + } + + err = sc_rm_get_memreg_info(-1, mr, &start, &end); + if (!err) + debug("memreg %u 0x%llx -- 0x%llx\n", mr, start, end); + + err = sc_rm_set_memreg_permissions(-1, mr, + SECO_PT, SC_RM_PERM_FULL); + if (err) { + printf("set permission failed for img %d, error %d\n", + image_index, err); + return -EPERM; + } + + err = sc_seco_authenticate(-1, SC_MISC_VERIFY_IMAGE, + 1 << image_index); + if (err) { + printf("authenticate img %d failed, return %d\n", + image_index, err); + ret = -EIO; + } + + err = sc_rm_set_memreg_permissions(-1, mr, + SECO_PT, SC_RM_PERM_NONE); + if (err) { + printf("remove permission failed for img %d, error %d\n", + image_index, err); + ret = -EPERM; + } + + return ret; +} +#endif static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, struct spl_load_info *info, @@ -45,6 +106,13 @@ static struct boot_img_t *read_auth_image(struct spl_image_info *spl_image, return NULL; } +#ifdef CONFIG_AHAB_BOOT + if (authenticate_image(&images[image_index], image_index)) { + printf("Failed to authenticate image %d\n", image_index); + return NULL; + } +#endif + return &images[image_index]; } @@ -54,7 +122,7 @@ static int read_auth_container(struct spl_image_info *spl_image, struct container_hdr *container = NULL; u16 length; u32 sectors; - int i, size; + int i, size, ret = 0; size = roundup(CONTAINER_HDR_ALIGNMENT, info->bl_len); sectors = size / info->bl_len; @@ -96,13 +164,27 @@ static int read_auth_container(struct spl_image_info *spl_image, return -EIO; } +#ifdef CONFIG_AHAB_BOOT + memcpy((void *)SEC_SECURE_RAM_BASE, (const void *)container, + ALIGN(length, CONFIG_SYS_CACHELINE_SIZE)); + + ret = sc_seco_authenticate(-1, SC_MISC_AUTH_CONTAINER, + SECO_LOCAL_SEC_SEC_SECURE_RAM_BASE); + if (ret) { + printf("authenticate container hdr failed, return %d\n", ret); + return ret; + } +#endif + for (i = 0; i < container->num_images; i++) { struct boot_img_t *image = read_auth_image(spl_image, info, container, i, sector); - if (!image) - return -EINVAL; + if (!image) { + ret = -EINVAL; + goto end_auth; + } if (i == 0) { spl_image->load_addr = image->dst; @@ -110,7 +192,12 @@ static int read_auth_container(struct spl_image_info *spl_image, } } - return 0; +end_auth: +#ifdef CONFIG_AHAB_BOOT + if (sc_seco_authenticate(-1, SC_MISC_REL_CONTAINER, 0)) + printf("Error: release container failed!\n"); +#endif + return ret; } int spl_load_imx_container(struct spl_image_info *spl_image, diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mq.c b/arch/arm/mach-imx/imx8m/clock_imx8mq.c index feecdb50f6..2db5bde211 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mq.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mq.c @@ -393,6 +393,15 @@ void init_usb_clk(void) } } +void init_nand_clk(void) +{ + clock_enable(CCGR_RAWNAND, 0); + clock_set_target_val(NAND_CLK_ROOT, + CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(3) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4)); + clock_enable(CCGR_RAWNAND, 1); +} + void init_uart_clk(u32 index) { /* Set uart clock root 25M OSC */ @@ -804,6 +813,13 @@ int clock_init(void) init_wdog_clk(); clock_enable(CCGR_TSENSOR, 1); + clock_enable(CCGR_OCOTP, 1); + + /* config GIC ROOT to sys_pll2_200m */ + clock_enable(CCGR_GIC, 0); + clock_set_target_val(GIC_CLK_ROOT, + CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(1)); + clock_enable(CCGR_GIC, 1); return 0; } diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index aeca82cdbf..a924af431c 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -202,14 +202,21 @@ u32 get_cpu_rev(void) } else { if (reg == CHIP_REV_1_0) { /* - * For B0 chip, the DIGPROG is not updated, still TO1.0. - * we have to check ROM version further + * For B0 chip, the DIGPROG is not updated, + * it is still TO1.0. we have to check ROM + * version or OCOTP_READ_FUSE_DATA. + * 0xff0055aa is magic number for B1. */ - rom_version = readl((void __iomem *)ROM_VERSION_A0); - if (rom_version != CHIP_REV_1_0) { - rom_version = readl((void __iomem *)ROM_VERSION_B0); - if (rom_version >= CHIP_REV_2_0) - reg = CHIP_REV_2_0; + if (readl((void __iomem *)(OCOTP_BASE_ADDR + 0x40)) == 0xff0055aa) { + reg = CHIP_REV_2_1; + } else { + rom_version = + readl((void __iomem *)ROM_VERSION_A0); + if (rom_version != CHIP_REV_1_0) { + rom_version = readl((void __iomem *)ROM_VERSION_B0); + if (rom_version == CHIP_REV_2_0) + reg = CHIP_REV_2_0; + } } } } diff --git a/arch/arm/mach-imx/imx_bootaux.c b/arch/arm/mach-imx/imx_bootaux.c index 18d7e6819c..3d9422d5a2 100644 --- a/arch/arm/mach-imx/imx_bootaux.c +++ b/arch/arm/mach-imx/imx_bootaux.c @@ -26,7 +26,7 @@ int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) /* Enable M4 */ #ifdef CONFIG_IMX8M - call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0); + call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0, 0); #else clrsetbits_le32(SRC_BASE_ADDR + SRC_M4_REG_OFFSET, SRC_M4C_NON_SCLR_RST_MASK, SRC_M4_ENABLE_MASK); @@ -38,7 +38,7 @@ int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) int arch_auxiliary_core_check_up(u32 core_id) { #ifdef CONFIG_IMX8M - return call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0); + return call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0, 0); #else unsigned int val; diff --git a/arch/arm/mach-imx/init.c b/arch/arm/mach-imx/init.c index b8d8d12372..693b724429 100644 --- a/arch/arm/mach-imx/init.c +++ b/arch/arm/mach-imx/init.c @@ -108,9 +108,9 @@ void boot_mode_apply(unsigned cfg_val) writel(cfg_val, &psrc->gpr9); reg = readl(&psrc->gpr10); if (cfg_val) - reg |= 1 << 28; + reg |= IMX6_SRC_GPR10_BMODE; else - reg &= ~(1 << 28); + reg &= ~IMX6_SRC_GPR10_BMODE; writel(reg, &psrc->gpr10); } #endif @@ -118,7 +118,7 @@ void boot_mode_apply(unsigned cfg_val) #if defined(CONFIG_MX6) u32 imx6_src_get_boot_mode(void) { - if (imx6_is_bmode_from_gpr9()) + if (readl(&src_base->gpr10) & IMX6_SRC_GPR10_BMODE) return readl(&src_base->gpr9); else return readl(&src_base->sbmr1); diff --git a/arch/arm/mach-imx/mx6/Kconfig b/arch/arm/mach-imx/mx6/Kconfig index 00e3c486bc..607210520f 100644 --- a/arch/arm/mach-imx/mx6/Kconfig +++ b/arch/arm/mach-imx/mx6/Kconfig @@ -232,6 +232,13 @@ config TARGET_MCCMON6 bool "mccmon6" select MX6QDL select SUPPORT_SPL + select DM + select DM_GPIO + select DM_ETH + select DM_SERIAL + select DM_I2C + select DM_SPI + imply CMD_DM config TARGET_MX6CUBOXI bool "Solid-run mx6 boards" @@ -589,6 +596,24 @@ config TARGET_ZC5601 select SUPPORT_SPL imply CMD_DM +config TARGET_BRPPT2 + bool "brppt2" + select BOARD_LATE_INIT + select MX6QDL + select OF_CONTROL + select SPL_OF_LIBFDT + select DM + select DM_ETH + select DM_GPIO + select DM_I2C + select DM_MMC + select SUPPORT_SPL + select SPL_DM if SPL + select SPL_OF_CONTROL if SPL + help + Support + B&R BRPPT2 platform + based on Freescale's iMX6 SoC endchoice config SYS_SOC @@ -646,5 +671,6 @@ source "board/udoo/Kconfig" source "board/udoo/neo/Kconfig" source "board/wandboard/Kconfig" source "board/warp/Kconfig" +source "board/BuR/brppt2/Kconfig" endif diff --git a/arch/arm/mach-imx/mx6/clock.c b/arch/arm/mach-imx/mx6/clock.c index 7763c79e1c..6a9e673ca2 100644 --- a/arch/arm/mach-imx/mx6/clock.c +++ b/arch/arm/mach-imx/mx6/clock.c @@ -1279,16 +1279,26 @@ unsigned int mxc_get_clock(enum mxc_clock clk) void enable_ipu_clock(void) { struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - int reg; - reg = readl(&mxc_ccm->CCGR3); - reg |= MXC_CCM_CCGR3_IPU1_IPU_MASK; - writel(reg, &mxc_ccm->CCGR3); + + setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_IPU1_IPU_MASK); if (is_mx6dqp()) { setbits_le32(&mxc_ccm->CCGR6, MXC_CCM_CCGR6_PRG_CLK0_MASK); setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_IPU2_IPU_MASK); } } + +void disable_ipu_clock(void) +{ + struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + clrbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_IPU1_IPU_MASK); + + if (is_mx6dqp()) { + clrbits_le32(&mxc_ccm->CCGR6, MXC_CCM_CCGR6_PRG_CLK0_MASK); + clrbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_IPU2_IPU_MASK); + } +} #endif #ifndef CONFIG_SPL_BUILD diff --git a/arch/arm/mach-imx/mx6/opos6ul.c b/arch/arm/mach-imx/mx6/opos6ul.c index 3ab9a3f022..0c640e2e33 100644 --- a/arch/arm/mach-imx/mx6/opos6ul.c +++ b/arch/arm/mach-imx/mx6/opos6ul.c @@ -6,11 +6,7 @@ #include <asm/arch/clock.h> #include <asm/arch/crm_regs.h> #include <asm/arch/imx-regs.h> -#include <asm/arch/iomux.h> -#include <asm/arch/mx6-pins.h> #include <asm/arch/sys_proto.h> -#include <asm/gpio.h> -#include <asm/mach-imx/iomux-v3.h> #include <asm/io.h> #include <common.h> #include <env.h> @@ -20,43 +16,6 @@ DECLARE_GLOBAL_DATA_PTR; #ifdef CONFIG_FEC_MXC #include <miiphy.h> -#define MDIO_PAD_CTRL ( \ - PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm \ -) - -#define ENET_PAD_CTRL_PU ( \ - PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm \ -) - -#define ENET_PAD_CTRL_PD ( \ - PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm \ -) - -#define ENET_CLK_PAD_CTRL ( \ - PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \ - PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST \ -) - -static iomux_v3_cfg_t const fec1_pads[] = { - MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL), - MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(MDIO_PAD_CTRL), - MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU), - MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU), - MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL_PU), - /* PHY Int */ - MX6_PAD_NAND_DQS__GPIO4_IO16 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU), - /* PHY Reset */ - MX6_PAD_NAND_DATA00__GPIO4_IO02 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL), -}; - int board_phy_config(struct phy_device *phydev) { phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x8190); @@ -67,43 +26,16 @@ int board_phy_config(struct phy_device *phydev) return 0; } -int board_eth_init(bd_t *bis) +static int setup_fec(void) { struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; - struct gpio_desc rst; - int ret; /* Use 50M anatop loopback REF_CLK1 for ENET1, * clear gpr1[13], set gpr1[17] */ clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK, IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK); - ret = enable_fec_anatop_clock(0, ENET_50MHZ); - if (ret) - return ret; - - enable_enet_clk(1); - - imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads)); - - ret = dm_gpio_lookup_name("GPIO4_2", &rst); - if (ret) { - printf("Cannot get GPIO4_2\n"); - return ret; - } - - ret = dm_gpio_request(&rst, "phy-rst"); - if (ret) { - printf("Cannot request GPIO4_2\n"); - return ret; - } - - dm_gpio_set_dir_flags(&rst, GPIOD_IS_OUT); - dm_gpio_set_value(&rst, 0); - udelay(1000); - dm_gpio_set_value(&rst, 1); - - return fecmxc_initialize(bis); + return enable_fec_anatop_clock(0, ENET_50MHZ); } #endif /* CONFIG_FEC_MXC */ @@ -112,6 +44,10 @@ int board_init(void) /* Address of boot parameters */ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; +#ifdef CONFIG_FEC_MXC + setup_fec(); +#endif + return 0; } diff --git a/arch/arm/mach-imx/sip.c b/arch/arm/mach-imx/sip.c index 968e7cf309..fca520c671 100644 --- a/arch/arm/mach-imx/sip.c +++ b/arch/arm/mach-imx/sip.c @@ -7,7 +7,8 @@ #include <asm/arch/sys_proto.h> unsigned long call_imx_sip(unsigned long id, unsigned long reg0, - unsigned long reg1, unsigned long reg2) + unsigned long reg1, unsigned long reg2, + unsigned long reg3) { struct pt_regs regs; @@ -15,6 +16,7 @@ unsigned long call_imx_sip(unsigned long id, unsigned long reg0, regs.regs[1] = reg0; regs.regs[2] = reg1; regs.regs[3] = reg2; + regs.regs[4] = reg3; smc_call(®s); diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index f025c4b301..5cc74b6f9b 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -189,6 +189,34 @@ int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name) /* called from spl_mmc to see type of boot mode for storage (RAW or FAT) */ u32 spl_boot_mode(const u32 boot_device) { +#if defined(CONFIG_MX7) || defined(CONFIG_IMX8M) || defined(CONFIG_IMX8) + switch (get_boot_device()) { + /* for MMC return either RAW or FAT mode */ + case SD1_BOOT: + case SD2_BOOT: + case SD3_BOOT: +#if defined(CONFIG_SPL_FAT_SUPPORT) + return MMCSD_MODE_FS; +#else + return MMCSD_MODE_RAW; +#endif + break; + case MMC1_BOOT: + case MMC2_BOOT: + case MMC3_BOOT: +#if defined(CONFIG_SPL_FAT_SUPPORT) + return MMCSD_MODE_FS; +#elif defined(CONFIG_SUPPORT_EMMC_BOOT) + return MMCSD_MODE_EMMCBOOT; +#else + return MMCSD_MODE_RAW; +#endif + break; + default: + puts("spl: ERROR: unsupported device\n"); + hang(); + } +#else /* * When CONFIG_SPL_FORCE_MMC_BOOT is defined the 'boot_device' is used * unconditionally to decide about device to use for booting. @@ -217,6 +245,7 @@ u32 spl_boot_mode(const u32 boot_device) puts("spl: ERROR: unsupported device\n"); hang(); } +#endif } #endif diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index 2046cb53c4..f3af88d79e 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -246,8 +246,7 @@ unsigned int sandbox_read(const void *addr, enum sandboxio_size_t size) return 0; } -void sandbox_write(const void *addr, unsigned int val, - enum sandboxio_size_t size) +void sandbox_write(void *addr, unsigned int val, enum sandboxio_size_t size) { struct sandbox_state *state = state_get_current(); diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h index 4a35c41972..ad6c29a4e2 100644 --- a/arch/sandbox/include/asm/io.h +++ b/arch/sandbox/include/asm/io.h @@ -46,8 +46,7 @@ static inline void unmap_sysmem(const void *vaddr) phys_addr_t map_to_sysmem(const void *ptr); unsigned int sandbox_read(const void *addr, enum sandboxio_size_t size); -void sandbox_write(const void *addr, unsigned int val, - enum sandboxio_size_t size); +void sandbox_write(void *addr, unsigned int val, enum sandboxio_size_t size); #define readb(addr) sandbox_read((const void *)addr, SB_SIZE_8) #define readw(addr) sandbox_read((const void *)addr, SB_SIZE_16) @@ -55,11 +54,11 @@ void sandbox_write(const void *addr, unsigned int val, #ifdef CONFIG_SANDBOX64 #define readq(addr) sandbox_read((const void *)addr, SB_SIZE_64) #endif -#define writeb(v, addr) sandbox_write((const void *)addr, v, SB_SIZE_8) -#define writew(v, addr) sandbox_write((const void *)addr, v, SB_SIZE_16) -#define writel(v, addr) sandbox_write((const void *)addr, v, SB_SIZE_32) +#define writeb(v, addr) sandbox_write((void *)addr, v, SB_SIZE_8) +#define writew(v, addr) sandbox_write((void *)addr, v, SB_SIZE_16) +#define writel(v, addr) sandbox_write((void *)addr, v, SB_SIZE_32) #ifdef CONFIG_SANDBOX64 -#define writeq(v, addr) sandbox_write((const void *)addr, v, SB_SIZE_64) +#define writeq(v, addr) sandbox_write((void *)addr, v, SB_SIZE_64) #endif /* diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index cd2b9e3155..b885e1a14f 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -213,4 +213,15 @@ int sandbox_get_pci_ep_irq_count(struct udevice *dev); */ uint sandbox_pci_read_bar(u32 barval, int type, uint size); +/** + * sandbox_set_enable_memio() - Enable readl/writel() for sandbox + * + * Normally these I/O functions do nothing with sandbox. Certain tests need them + * to work as for other architectures, so this function can be used to enable + * them. + * + * @enable: true to enable, false to disable + */ +void sandbox_set_enable_memio(bool enable); + #endif diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c index 90b546e741..31663714a0 100644 --- a/arch/x86/cpu/i386/cpu.c +++ b/arch/x86/cpu/i386/cpu.c @@ -385,6 +385,14 @@ static void setup_mtrr(void) } } +int x86_cpu_init_tpl(void) +{ + setup_cpu_features(); + setup_identity(); + + return 0; +} + int x86_cpu_init_f(void) { if (ll_boot_init()) diff --git a/arch/x86/cpu/start_from_spl.S b/arch/x86/cpu/start_from_spl.S index a73b4d7c45..22cab2dd6c 100644 --- a/arch/x86/cpu/start_from_spl.S +++ b/arch/x86/cpu/start_from_spl.S @@ -31,6 +31,7 @@ _start: call board_init_f_init_reserve + call x86_cpu_reinit_f xorl %eax, %eax call board_init_f call board_init_f_r diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index feee0f915f..21a05dab7d 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -55,6 +55,7 @@ enum { X86_SYSCON_PINCONF, /* Intel x86 pin configuration */ X86_SYSCON_PMU, /* Power Management Unit */ X86_SYSCON_SCU, /* System Controller Unit */ + X86_SYSCON_PUNIT, /* Power unit */ }; struct cpuid_result { diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index 17a4d34491..7f3ada06f6 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -76,6 +76,7 @@ struct arch_global_data { uint8_t x86_mask; uint32_t x86_device; uint64_t tsc_base; /* Initial value returned by rdtsc() */ + bool tsc_inited; /* true if tsc is ready for use */ unsigned long clock_rate; /* Clock rate of timer in Hz */ void *new_fdt; /* Relocated FDT */ uint32_t bist; /* Built-in self test value */ diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index 2466ad2ad3..3e5d56d075 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -34,6 +34,15 @@ int x86_cpu_init_f(void); */ int x86_cpu_reinit_f(void); +/** + * x86_cpu_init_tpl() - Do the minimum possible CPU init + * + * This just sets up the CPU features and figured out the identity + * + * @return 0 (indicating success, to mimic cpu_init_f()) + */ +int x86_cpu_init_tpl(void); + int cpu_init_f(void); void setup_gdt(struct global_data *id, u64 *gdt_addr); /* diff --git a/arch/x86/lib/spl.c b/arch/x86/lib/spl.c index 7623fc9ada..1677f80b25 100644 --- a/arch/x86/lib/spl.c +++ b/arch/x86/lib/spl.c @@ -5,11 +5,15 @@ #include <common.h> #include <debug_uart.h> +#include <dm.h> #include <malloc.h> #include <spl.h> +#include <syscon.h> #include <asm/cpu.h> +#include <asm/cpu_common.h> #include <asm/mrccache.h> #include <asm/mtrr.h> +#include <asm/pci.h> #include <asm/processor.h> #include <asm/spl.h> #include <asm-generic/sections.h> @@ -21,6 +25,32 @@ __weak int arch_cpu_init_dm(void) return 0; } +#ifdef CONFIG_TPL + +static int set_max_freq(void) +{ + if (cpu_get_burst_mode_state() == BURST_MODE_UNAVAILABLE) { + /* + * Burst Mode has been factory-configured as disabled and is not + * available in this physical processor package + */ + debug("Burst Mode is factory-disabled\n"); + return -ENOENT; + } + + /* Enable burst mode */ + cpu_set_burst_mode(true); + + /* Enable speed step */ + cpu_set_eist(true); + + /* Set P-State ratio */ + cpu_set_p_state_to_turbo_ratio(); + + return 0; +} +#endif + static int x86_spl_init(void) { #ifndef CONFIG_TPL @@ -31,10 +61,16 @@ static int x86_spl_init(void) * place it immediately below CONFIG_SYS_TEXT_BASE. */ char *ptr = (char *)0x110000; +#else + struct udevice *punit; #endif int ret; debug("%s starting\n", __func__); + if (IS_ENABLED(TPL)) + ret = x86_cpu_reinit_f(); + else + ret = x86_cpu_init_f(); ret = spl_init(); if (ret) { debug("%s: spl_init() failed\n", __func__); @@ -101,6 +137,14 @@ static int x86_spl_init(void) return ret; } mtrr_commit(true); +#else + ret = syscon_get_by_driver_data(X86_SYSCON_PUNIT, &punit); + if (ret) + debug("Could not find PUNIT (err=%d)\n", ret); + + ret = set_max_freq(); + if (ret) + debug("Failed to set CPU frequency (err=%d)\n", ret); #endif return 0; diff --git a/arch/x86/lib/tpl.c b/arch/x86/lib/tpl.c index d70f590541..784e3a02de 100644 --- a/arch/x86/lib/tpl.c +++ b/arch/x86/lib/tpl.c @@ -5,6 +5,7 @@ #include <common.h> #include <debug_uart.h> +#include <dm.h> #include <spl.h> #include <asm/cpu.h> #include <asm/mtrr.h> @@ -23,6 +24,11 @@ static int x86_tpl_init(void) int ret; debug("%s starting\n", __func__); + ret = x86_cpu_init_tpl(); + if (ret) { + debug("%s: x86_cpu_init_tpl() failed\n", __func__); + return ret; + } ret = spl_init(); if (ret) { debug("%s: spl_init() failed\n", __func__); @@ -39,11 +45,6 @@ static int x86_tpl_init(void) return ret; } preloader_console_init(); - ret = print_cpuinfo(); - if (ret) { - debug("%s: print_cpuinfo() failed\n", __func__); - return ret; - } return 0; } @@ -106,7 +107,7 @@ int spl_spi_load_image(void) void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) { - printf("Jumping to U-Boot SPL at %lx\n", (ulong)spl_image->entry_point); + debug("Jumping to U-Boot SPL at %lx\n", (ulong)spl_image->entry_point); jump_to_spl(spl_image->entry_point); hang(); } @@ -115,3 +116,27 @@ void spl_board_init(void) { preloader_console_init(); } + +#if !CONFIG_IS_ENABLED(PCI) +/* + * This is a fake PCI bus for TPL when it doesn't have proper PCI. It is enough + * to bind the devices on the PCI bus, some of which have early-regs properties + * providing fixed BARs. Individual drivers program these BARs themselves so + * that they can access the devices. The BARs are allocated statically in the + * device tree. + * + * Once SPL is running it enables PCI properly, but does not auto-assign BARs + * for devices, so the TPL BARs continue to be used. Once U-Boot starts it does + * the auto allocation (after relocation). + */ +static const struct udevice_id tpl_fake_pci_ids[] = { + { .compatible = "pci-x86" }, + { } +}; + +U_BOOT_DRIVER(pci_x86) = { + .name = "pci_x86", + .id = UCLASS_SIMPLE_BUS, + .of_match = tpl_fake_pci_ids, +}; +#endif diff --git a/board/BuR/brppt2/Kconfig b/board/BuR/brppt2/Kconfig new file mode 100644 index 0000000000..aa39d66fb7 --- /dev/null +++ b/board/BuR/brppt2/Kconfig @@ -0,0 +1,18 @@ +if TARGET_BRPPT2 + +config SYS_BOARD + default "brppt2" + +config SYS_VENDOR + default "BuR" + +config SYS_SOC + default "mx6" + +config SYS_CONFIG_NAME + default "brppt2" + +config SPL_DM_SPI + def_bool y + +endif diff --git a/board/BuR/brppt2/MAINTAINERS b/board/BuR/brppt2/MAINTAINERS new file mode 100644 index 0000000000..a1b5bd49bf --- /dev/null +++ b/board/BuR/brppt2/MAINTAINERS @@ -0,0 +1,6 @@ +BUR_PPT2 BOARD +M: Hannes Schmelzer <hannes.schmelzer@br-automation.com> +S: Maintained +F: board/BuR/brppt2/ +F: include/configs/brppt2.h +F: configs/brppt2_defconfig diff --git a/board/BuR/brppt2/Makefile b/board/BuR/brppt2/Makefile new file mode 100644 index 0000000000..7f3c7cd953 --- /dev/null +++ b/board/BuR/brppt2/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0+ + +# Copyright (C) 2019 +# B&R Industrial Automation GmbH - http://www.br-automation.com +# + +obj-y := ../common/common.o +obj-y += board.o diff --git a/board/BuR/brppt2/board.c b/board/BuR/brppt2/board.c new file mode 100644 index 0000000000..3284ff0936 --- /dev/null +++ b/board/BuR/brppt2/board.c @@ -0,0 +1,542 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Board functions for BuR BRPPT2 board + * + * Copyright (C) 2019 + * B&R Industrial Automation GmbH - http://www.br-automation.com/ + * + */ +#include <common.h> +#include <spl.h> +#include <dm.h> +#include <miiphy.h> +#include <asm/arch/crm_regs.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/iomux.h> +#include <asm/arch/mx6-pins.h> +#ifdef CONFIG_SPL_BUILD +# include <asm/arch/mx6-ddr.h> +#endif +#include <asm/arch/clock.h> +#include <asm/io.h> +#include <asm/gpio.h> + +#define USBHUB_RSTN IMX_GPIO_NR(1, 16) +#define BKLT_EN IMX_GPIO_NR(1, 15) +#define CAPT_INT IMX_GPIO_NR(4, 9) +#define CAPT_RESETN IMX_GPIO_NR(4, 11) +#define SW_INTN IMX_GPIO_NR(3, 26) +#define VCCDISP_EN IMX_GPIO_NR(5, 18) +#define EMMC_RSTN IMX_GPIO_NR(6, 8) +#define PMIC_IRQN IMX_GPIO_NR(5, 22) +#define TASTER IMX_GPIO_NR(5, 23) + +#define ETH0_LINK IMX_GPIO_NR(1, 27) +#define ETH1_LINK IMX_GPIO_NR(1, 28) + +#define UART_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_48ohm | \ + PAD_CTL_SRE_SLOW | PAD_CTL_HYS) + +#define I2C_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_48ohm | \ + PAD_CTL_SRE_SLOW | PAD_CTL_HYS) + +#define ECSPI_PAD_CTRL (PAD_CTL_PUS_100K_DOWN | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_48ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) +#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_48ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_60ohm | \ + PAD_CTL_SRE_SLOW | PAD_CTL_HYS) + +#define ENET_PAD_CTRL1 (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_34ohm | \ + PAD_CTL_SRE_SLOW | PAD_CTL_HYS) + +#define ENET_PAD_CTRL_PU (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_80ohm | \ + PAD_CTL_SRE_SLOW | PAD_CTL_HYS) + +#define ENET_PAD_CTRL_CLK ((PAD_CTL_PUS_100K_UP & ~PAD_CTL_PKE) | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_60ohm | \ + PAD_CTL_SRE_FAST) + +#define GPIO_PAD_CTRL_PU (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_48ohm | \ + PAD_CTL_SRE_SLOW | PAD_CTL_HYS) + +#define GPIO_PAD_CTRL_PD (PAD_CTL_PUS_100K_DOWN | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_48ohm | \ + PAD_CTL_SRE_SLOW | PAD_CTL_HYS) + +#define LCDCMOS_PAD_CTRL (PAD_CTL_PUS_100K_DOWN | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_120ohm |\ + PAD_CTL_SRE_SLOW | PAD_CTL_HYS) + +#define MUXDESC(pad, ctrl) IOMUX_PADS(pad | MUX_PAD_CTRL(ctrl)) + +#if !defined(CONFIG_SPL_BUILD) +static iomux_v3_cfg_t const eth_pads[] = { + /* + * Gigabit Ethernet + */ + /* CLKs */ + MUXDESC(PAD_GPIO_16__ENET_REF_CLK, ENET_PAD_CTRL_CLK), + MUXDESC(PAD_ENET_REF_CLK__ENET_TX_CLK, ENET_PAD_CTRL_CLK), + /* MDIO */ + MUXDESC(PAD_ENET_MDIO__ENET_MDIO, ENET_PAD_CTRL_PU), + MUXDESC(PAD_ENET_MDC__ENET_MDC, ENET_PAD_CTRL_PU), + /* RGMII */ + MUXDESC(PAD_RGMII_TXC__RGMII_TXC, ENET_PAD_CTRL1), + MUXDESC(PAD_RGMII_TD0__RGMII_TD0, ENET_PAD_CTRL), + MUXDESC(PAD_RGMII_TD1__RGMII_TD1, ENET_PAD_CTRL), + MUXDESC(PAD_RGMII_TD2__RGMII_TD2, ENET_PAD_CTRL), + MUXDESC(PAD_RGMII_TD3__RGMII_TD3, ENET_PAD_CTRL), + MUXDESC(PAD_RGMII_TX_CTL__RGMII_TX_CTL, ENET_PAD_CTRL), + MUXDESC(PAD_RGMII_RXC__RGMII_RXC, ENET_PAD_CTRL_PU), + MUXDESC(PAD_RGMII_RD0__RGMII_RD0, ENET_PAD_CTRL_PU), + MUXDESC(PAD_RGMII_RD1__RGMII_RD1, ENET_PAD_CTRL_PU), + MUXDESC(PAD_RGMII_RD2__RGMII_RD2, ENET_PAD_CTRL_PU), + MUXDESC(PAD_RGMII_RD3__RGMII_RD3, ENET_PAD_CTRL_PU), + MUXDESC(PAD_RGMII_RX_CTL__RGMII_RX_CTL, ENET_PAD_CTRL_PU), + /* ETH0_LINK */ + MUXDESC(PAD_ENET_RXD0__GPIO1_IO27, GPIO_PAD_CTRL_PD), + /* ETH1_LINK */ + MUXDESC(PAD_ENET_TX_EN__GPIO1_IO28, GPIO_PAD_CTRL_PD), +}; + +static iomux_v3_cfg_t const board_pads[] = { + /* + * I2C #3, #4 + */ + MUXDESC(PAD_GPIO_3__I2C3_SCL, I2C_PAD_CTRL), + MUXDESC(PAD_GPIO_6__I2C3_SDA, I2C_PAD_CTRL), + + /* + * UART#4 PADS + * UART_Tasten + */ + MUXDESC(PAD_CSI0_DAT12__UART4_TX_DATA, UART_PAD_CTRL), + MUXDESC(PAD_CSI0_DAT13__UART4_RX_DATA, UART_PAD_CTRL), + MUXDESC(PAD_CSI0_DAT17__UART4_CTS_B, UART_PAD_CTRL), + MUXDESC(PAD_CSI0_DAT16__UART4_RTS_B, UART_PAD_CTRL), + /* + * ESCPI#1 + * M25P32 NOR-Flash + */ + MUXDESC(PAD_EIM_D16__ECSPI1_SCLK, ECSPI_PAD_CTRL), + MUXDESC(PAD_EIM_D17__ECSPI1_MISO, ECSPI_PAD_CTRL), + MUXDESC(PAD_EIM_D18__ECSPI1_MOSI, ECSPI_PAD_CTRL), + MUXDESC(PAD_EIM_D19__GPIO3_IO19, ECSPI_PAD_CTRL), + /* + * ESCPI#2 + * resTouch SPI ADC + */ + MUXDESC(PAD_CSI0_DAT8__ECSPI2_SCLK, ECSPI_PAD_CTRL), + MUXDESC(PAD_EIM_OE__ECSPI2_MISO, ECSPI_PAD_CTRL), + MUXDESC(PAD_CSI0_DAT9__ECSPI2_MOSI, ECSPI_PAD_CTRL), + MUXDESC(PAD_EIM_D24__GPIO3_IO24, ECSPI_PAD_CTRL), + /* + * USDHC#4 + */ + MUXDESC(PAD_SD4_CLK__SD4_CLK, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_CMD__SD4_CMD, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT0__SD4_DATA0, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT1__SD4_DATA1, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT2__SD4_DATA2, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT3__SD4_DATA3, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT4__SD4_DATA4, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT5__SD4_DATA5, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT6__SD4_DATA6, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT7__SD4_DATA7, USDHC_PAD_CTRL), + /* + * USB OTG power & ID + */ + /* USB_OTG_5V_EN */ + MUXDESC(PAD_EIM_D22__GPIO3_IO22, GPIO_PAD_CTRL_PD), + MUXDESC(PAD_EIM_D31__GPIO3_IO31, GPIO_PAD_CTRL_PD), + /* USB_OTG_JUMPER */ + MUXDESC(PAD_ENET_RX_ER__USB_OTG_ID, GPIO_PAD_CTRL_PD), + /* + * PWM-Pins + */ + /* BKLT_CTL */ + MUXDESC(PAD_SD1_CMD__PWM4_OUT, GPIO_PAD_CTRL_PD), + /* SPEAKER */ + MUXDESC(PAD_SD1_DAT1__PWM3_OUT, GPIO_PAD_CTRL_PD), + /* + * GPIOs + */ + /* USB_HUB_nRESET */ + MUXDESC(PAD_SD1_DAT0__GPIO1_IO16, GPIO_PAD_CTRL_PD), + /* BKLT_EN */ + MUXDESC(PAD_SD2_DAT0__GPIO1_IO15, GPIO_PAD_CTRL_PD), + /* capTouch_INT */ + MUXDESC(PAD_KEY_ROW1__GPIO4_IO09, GPIO_PAD_CTRL_PD), + /* capTouch_nRESET */ + MUXDESC(PAD_KEY_ROW2__GPIO4_IO11, GPIO_PAD_CTRL_PD), + /* SW_nINT */ + MUXDESC(PAD_EIM_D26__GPIO3_IO26, GPIO_PAD_CTRL_PU), + /* VCC_DISP_EN */ + MUXDESC(PAD_CSI0_PIXCLK__GPIO5_IO18, GPIO_PAD_CTRL_PD), + /* eMMC_nRESET */ + MUXDESC(PAD_NANDF_ALE__GPIO6_IO08, GPIO_PAD_CTRL_PD), + /* HWID*/ + MUXDESC(PAD_NANDF_D0__GPIO2_IO00, GPIO_PAD_CTRL_PU), + MUXDESC(PAD_NANDF_D1__GPIO2_IO01, GPIO_PAD_CTRL_PU), + MUXDESC(PAD_NANDF_D2__GPIO2_IO02, GPIO_PAD_CTRL_PU), + MUXDESC(PAD_NANDF_D3__GPIO2_IO03, GPIO_PAD_CTRL_PU), + /* PMIC_nIRQ */ + MUXDESC(PAD_CSI0_DAT4__GPIO5_IO22, GPIO_PAD_CTRL_PU), + /* nTASTER */ + MUXDESC(PAD_CSI0_DAT5__GPIO5_IO23, GPIO_PAD_CTRL_PU), + /* RGB LCD Display */ + MUXDESC(PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DI0_PIN2__IPU1_DI0_PIN02, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DI0_PIN3__IPU1_DI0_PIN03, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DI0_PIN4__IPU1_DI0_PIN04, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DI0_PIN15__IPU1_DI0_PIN15, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT0__IPU1_DISP0_DATA00, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT1__IPU1_DISP0_DATA01, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT2__IPU1_DISP0_DATA02, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT3__IPU1_DISP0_DATA03, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT4__IPU1_DISP0_DATA04, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT5__IPU1_DISP0_DATA05, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT6__IPU1_DISP0_DATA06, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT7__IPU1_DISP0_DATA07, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT8__IPU1_DISP0_DATA08, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT9__IPU1_DISP0_DATA09, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT10__IPU1_DISP0_DATA10, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT11__IPU1_DISP0_DATA11, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT12__IPU1_DISP0_DATA12, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT13__IPU1_DISP0_DATA13, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT14__IPU1_DISP0_DATA14, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT15__IPU1_DISP0_DATA15, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT16__IPU1_DISP0_DATA16, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT17__IPU1_DISP0_DATA17, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT18__IPU1_DISP0_DATA18, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT19__IPU1_DISP0_DATA19, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT20__IPU1_DISP0_DATA20, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT21__IPU1_DISP0_DATA21, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT22__IPU1_DISP0_DATA22, LCDCMOS_PAD_CTRL), + MUXDESC(PAD_DISP0_DAT23__IPU1_DISP0_DATA23, LCDCMOS_PAD_CTRL), +}; + +int board_ehci_hcd_init(int port) +{ + gpio_direction_output(USBHUB_RSTN, 1); + + return 0; +} + +int board_late_init(void) +{ + ulong b_mode = 4; + + if (gpio_get_value(TASTER) == 0) + b_mode = 12; + + env_set_ulong("b_mode", b_mode); + + return 0; +} + +int board_init(void) +{ + gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100; + + if (gpio_request(BKLT_EN, "BKLT_EN")) + printf("Warning: BKLT_EN setup failed\n"); + gpio_direction_output(BKLT_EN, 0); + + if (gpio_request(USBHUB_RSTN, "USBHUB_nRST")) + printf("Warning: USBHUB_nRST setup failed\n"); + gpio_direction_output(USBHUB_RSTN, 0); + + if (gpio_request(TASTER, "TASTER")) + printf("Warning: TASTER setup failed\n"); + gpio_direction_input(TASTER); + + return 0; +} + +int board_early_init_f(void) +{ + struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR; + + SETUP_IOMUX_PADS(board_pads); + SETUP_IOMUX_PADS(eth_pads); + + /* set GPIO_16 as ENET_REF_CLK_OUT running at 25 MHz */ + setbits_le32(&iomux->gpr[1], IOMUXC_GPR1_ENET_CLK_SEL_MASK); + enable_fec_anatop_clock(0, ENET_25MHZ); + enable_enet_clk(1); + + return 0; +} + +int dram_init(void) +{ + gd->ram_size = imx_ddr_size(); + + return 0; +} +#else +/* configure MX6SOLO/DUALLITE mmdc DDR io registers */ +static struct mx6sdl_iomux_ddr_regs ddr_iomux_s = { + /* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */ + .dram_sdclk_0 = 0x00020030, + .dram_sdclk_1 = 0x00020030, + .dram_cas = 0x00020030, + .dram_ras = 0x00020030, + .dram_reset = 0x00020030, + /* SDCKE[0:1]: 100k pull-up */ + .dram_sdcke0 = 0x00003000, + .dram_sdcke1 = 0x00003000, + /* SDBA2: pull-up disabled */ + .dram_sdba2 = 0x00000000, + /* SDODT[0:1]: 100k pull-up, 40 ohm */ + .dram_sdodt0 = 0x00003030, + .dram_sdodt1 = 0x00003030, + /* SDQS[0:7]: Differential input, 40 ohm */ + .dram_sdqs0 = 0x00000030, + .dram_sdqs1 = 0x00000030, + .dram_sdqs2 = 0x00000030, + .dram_sdqs3 = 0x00000030, + .dram_sdqs4 = 0x00000030, + .dram_sdqs5 = 0x00000030, + .dram_sdqs6 = 0x00000030, + .dram_sdqs7 = 0x00000030, + /* DQM[0:7]: Differential input, 40 ohm */ + .dram_dqm0 = 0x00020030, + .dram_dqm1 = 0x00020030, + .dram_dqm2 = 0x00020030, + .dram_dqm3 = 0x00020030, + .dram_dqm4 = 0x00020030, + .dram_dqm5 = 0x00020030, + .dram_dqm6 = 0x00020030, + .dram_dqm7 = 0x00020030, +}; + +/* configure MX6SOLO/DUALLITE mmdc GRP io registers */ +static struct mx6sdl_iomux_grp_regs grp_iomux_s = { + /* DDR3 */ + .grp_ddr_type = 0x000c0000, + .grp_ddrmode_ctl = 0x00020000, + /* disable DDR pullups */ + .grp_ddrpke = 0x00000000, + /* ADDR[00:16], SDBA[0:1]: 40 ohm */ + .grp_addds = 0x00000030, + /* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */ + .grp_ctlds = 0x00000030, + /* DATA[00:63]: Differential input, 40 ohm */ + .grp_ddrmode = 0x00020000, + .grp_b0ds = 0x00000030, + .grp_b1ds = 0x00000030, + .grp_b2ds = 0x00000030, + .grp_b3ds = 0x00000030, + .grp_b4ds = 0x00000030, + .grp_b5ds = 0x00000030, + .grp_b6ds = 0x00000030, + .grp_b7ds = 0x00000030, +}; + +/* + * DDR3 desriptions - these are the memory chips we support + */ + +/* NT5CC128M16FP-DII */ +static struct mx6_ddr3_cfg cfg_nt5cc128m16fp_dii = { + .mem_speed = 1600, + .density = 2, + .width = 16, + .banks = 8, + .rowaddr = 14, + .coladdr = 10, + .pagesz = 2, + .trcd = 1375, + .trcmin = 4875, + .trasmin = 3500, +}; + +/* measured on board TSERIES_ARM/1 V_LVDS_DL64 */ +static struct mx6_mmdc_calibration cal_nt5cc128m16fp_dii_128x64_s = { + /* write leveling calibration determine, MR1-value = 0x0002 */ + .p0_mpwldectrl0 = 0x003F003E, + .p0_mpwldectrl1 = 0x003A003A, + .p1_mpwldectrl0 = 0x001B001C, + .p1_mpwldectrl1 = 0x00190031, + /* Read DQS Gating calibration */ + .p0_mpdgctrl0 = 0x02640264, + .p0_mpdgctrl1 = 0x02440250, + .p1_mpdgctrl0 = 0x02400250, + .p1_mpdgctrl1 = 0x0238023C, + /* Read Calibration: DQS delay relative to DQ read access */ + .p0_mprddlctl = 0x40464644, + .p1_mprddlctl = 0x464A4842, + /* Write Calibration: DQ/DM delay relative to DQS write access */ + .p0_mpwrdlctl = 0x38343034, + .p1_mpwrdlctl = 0x36323830, +}; + +/* measured on board TSERIES_ARM/1 V_LVDS_S32 */ +static struct mx6_mmdc_calibration cal_nt5cc128m16fp_dii_128x32_s = { + /* write leveling calibration determine, MR1-value = 0x0002 */ + .p0_mpwldectrl0 = 0x00410043, + .p0_mpwldectrl1 = 0x003A003C, + /* Read DQS Gating calibration */ + .p0_mpdgctrl0 = 0x023C0244, + .p0_mpdgctrl1 = 0x02240230, + /* Read Calibration: DQS delay relative to DQ read access */ + .p0_mprddlctl = 0x484C4A48, + /* Write Calibration: DQ/DM delay relative to DQS write access */ + .p0_mpwrdlctl = 0x3C363434, +}; + +static void spl_dram_init(void) +{ + struct gpio_regs *gpio = (struct gpio_regs *)GPIO2_BASE_ADDR; + u32 val, dram_strap = 0; + struct mx6_ddr3_cfg *mem = NULL; + struct mx6_mmdc_calibration *calib = NULL; + struct mx6_ddr_sysinfo sysinfo = { + /* width of data bus:0=16,1=32,2=64 */ + .dsize = -1, /* CPU type specific (overwritten) */ + /* config for full 4GB range so that get_mem_size() works */ + .cs_density = 32, /* 32Gb per CS */ + .ncs = 1, /* single chip select */ + .cs1_mirror = 0, + .rtt_wr = 1, /* DDR3_RTT_60_OHM, RTT_Wr = RZQ/4 */ + .rtt_nom = 1, /* DDR3_RTT_60_OHM, RTT_Nom = RZQ/4 */ + .walat = 1, /* Write additional latency */ + .ralat = 5, /* Read additional latency */ + .mif3_mode = 3, /* Command prediction working mode */ + .bi_on = 1, /* Bank interleaving enabled */ + .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ + .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ + .ddr_type = 0, /* DDR3 */ + }; + + /* + * MMDC Calibration requires the following data: + * mx6_mmdc_calibration - board-specific calibration (routing delays) + * these calibration values depend on board routing, SoC, and DDR + * mx6_ddr_sysinfo - board-specific memory architecture (width/cs/etc) + * mx6_ddr_cfg - chip specific timing/layout details + */ + + /* setup HWID3-2 to input */ + val = readl(&gpio->gpio_dir); + val &= ~(0x1 << 0 | 0x1 << 1); + writel(val, &gpio->gpio_dir); + + /* read DRAM strapping from HWID3/2 (bit 1 and bit 0) */ + dram_strap = readl(&gpio->gpio_psr) & 0x3; + + switch (dram_strap) { + /* 1 GiB, 64 bit, 4 NT5CC128M16FP chips */ + case 0: + puts("DRAM strap 00\n"); + mem = &cfg_nt5cc128m16fp_dii; + sysinfo.dsize = 2; + calib = &cal_nt5cc128m16fp_dii_128x64_s; + break; + /* 512 MiB, 32 bit, 2 NT5CC128M16FP chips */ + case 1: + puts("DRAM strap 01\n"); + mem = &cfg_nt5cc128m16fp_dii; + sysinfo.dsize = 1; + calib = &cal_nt5cc128m16fp_dii_128x32_s; + break; + default: + printf("DRAM strap 0x%x (invalid)\n", dram_strap); + break; + } + + if (!mem) { + puts("Error: Invalid Memory Configuration\n"); + hang(); + } + if (!calib) { + puts("Error: Invalid Board Calibration Configuration\n"); + hang(); + } + + mx6sdl_dram_iocfg(16 << sysinfo.dsize, + &ddr_iomux_s, + &grp_iomux_s); + + mx6_dram_cfg(&sysinfo, calib, mem); +} + +static iomux_v3_cfg_t const board_pads_spl[] = { + /* UART#1 PADS */ + MUXDESC(PAD_CSI0_DAT10__UART1_TX_DATA, UART_PAD_CTRL), + MUXDESC(PAD_CSI0_DAT11__UART1_RX_DATA, UART_PAD_CTRL), + /* ESCPI#1 PADS */ + MUXDESC(PAD_EIM_D16__ECSPI1_SCLK, ECSPI_PAD_CTRL), + MUXDESC(PAD_EIM_D17__ECSPI1_MISO, ECSPI_PAD_CTRL), + MUXDESC(PAD_EIM_D18__ECSPI1_MOSI, ECSPI_PAD_CTRL), + MUXDESC(PAD_EIM_D19__GPIO3_IO19, ECSPI_PAD_CTRL), + /* USDHC#4 PADS */ + MUXDESC(PAD_SD4_CLK__SD4_CLK, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_CMD__SD4_CMD, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT0__SD4_DATA0, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT1__SD4_DATA1, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT2__SD4_DATA2, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT3__SD4_DATA3, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT4__SD4_DATA4, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT5__SD4_DATA5, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT6__SD4_DATA6, USDHC_PAD_CTRL), + MUXDESC(PAD_SD4_DAT7__SD4_DATA7, USDHC_PAD_CTRL), + /* HWID*/ + MUXDESC(PAD_NANDF_D0__GPIO2_IO00, GPIO_PAD_CTRL_PU), + MUXDESC(PAD_NANDF_D1__GPIO2_IO01, GPIO_PAD_CTRL_PU), + MUXDESC(PAD_NANDF_D2__GPIO2_IO02, GPIO_PAD_CTRL_PU), + MUXDESC(PAD_NANDF_D3__GPIO2_IO03, GPIO_PAD_CTRL_PU), +}; + +void spl_board_init(void) +{ + preloader_console_init(); +} + +static void ccgr_init(void) +{ + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; + + /* + * We don't use DMA in SPL, but we do need it in U-Boot. U-Boot + * initializes DMA very early (before all board code), so the only + * opportunity we have to initialize APBHDMA clocks is in SPL. + * setbits_le32(&ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK); + */ + + writel(0x00C03F3F, &ccm->CCGR0); + writel(0x00F0FC03, &ccm->CCGR1); + writel(0x0FFFF000, &ccm->CCGR2); + writel(0x3FF00000, &ccm->CCGR3); + writel(0x00FFF300, &ccm->CCGR4); + writel(0x0F0030C3, &ccm->CCGR5); + writel(0x000003F0, &ccm->CCGR6); +} + +void board_init_f(ulong dummy) +{ + ccgr_init(); + arch_cpu_init(); + timer_init(); + gpr_init(); + + SETUP_IOMUX_PADS(board_pads_spl); + spl_dram_init(); +} + +void reset_cpu(ulong addr) +{ +} +#endif /* CONFIG_SPL_BUILD */ diff --git a/board/BuR/brppt2/config.mk b/board/BuR/brppt2/config.mk new file mode 100644 index 0000000000..fa973db762 --- /dev/null +++ b/board/BuR/brppt2/config.mk @@ -0,0 +1,36 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2019 Hannes Schmelzer <oe5hpm@oevsv.at> - +# B&R Industrial Automation GmbH - http://www.br-automation.com +# + +hw-platform-y :=$(shell echo $(CONFIG_DEFAULT_DEVICE_TREE) | sed -e 's/imx6dl-//') + +payload_off :=$(shell printf "%d" $(CONFIG_SYS_SPI_U_BOOT_OFFS)) + +quiet_cmd_prodbin = PRODBIN $@ $(payload_off) +cmd_prodbin = \ + dd if=/dev/zero ibs=1M count=2 2>/dev/null | tr "\000" "\377" >$@ && \ + dd conv=notrunc bs=1 if=SPL of=$@ seek=1024 2>/dev/null && \ + dd bs=1 if=u-boot-dtb.img of=$@ seek=$(payload_off) 2>/dev/null + +quiet_cmd_prodzip = SAPZIP $@ +cmd_prodzip = \ + test -d misc && rm -r misc; \ + mkdir misc && \ + cp SPL misc/ && \ + cp u-boot-dtb.img misc/ && \ + zip -9 -r $@ misc/* >/dev/null $< + +ifeq ($(hw-platform-y),brppt2) +ifneq ($(CONFIG_SPL_BUILD),y) +ALL-y += $(hw-platform-y)_prog.bin +ALL-y += $(hw-platform-y)_prod.zip +endif +endif + +$(hw-platform-y)_prog.bin: u-boot-dtb.img spl SPL + $(call if_changed,prodbin) + +$(hw-platform-y)_prod.zip: $(hw-platform-y)_prog.bin + $(call if_changed,prodzip) diff --git a/board/advantech/imx8qm_rom7720_a1/Kconfig b/board/advantech/imx8qm_rom7720_a1/Kconfig new file mode 100644 index 0000000000..cf3869ed92 --- /dev/null +++ b/board/advantech/imx8qm_rom7720_a1/Kconfig @@ -0,0 +1,14 @@ +if TARGET_IMX8QM_ROM7720_A1 + +config SYS_BOARD + default "imx8qm_rom7720_a1" + +config SYS_VENDOR + default "advantech" + +config SYS_CONFIG_NAME + default "imx8qm_rom7720" + +source "board/freescale/common/Kconfig" + +endif diff --git a/board/advantech/imx8qm_rom7720_a1/MAINTAINERS b/board/advantech/imx8qm_rom7720_a1/MAINTAINERS new file mode 100644 index 0000000000..b142ee02e6 --- /dev/null +++ b/board/advantech/imx8qm_rom7720_a1/MAINTAINERS @@ -0,0 +1,6 @@ +i.MX8QM ROM 7720 a1 BOARD +M: Oliver Graute <oliver.graute@kococonnector.com> +S: Maintained +F: board/advantech/imx8qm_rom7720_a1/ +F: include/configs/imx8qm_rom7720.h +F: configs/imx8qm_rom7720_a1_4G_defconfig diff --git a/board/advantech/imx8qm_rom7720_a1/Makefile b/board/advantech/imx8qm_rom7720_a1/Makefile new file mode 100644 index 0000000000..51c5de251c --- /dev/null +++ b/board/advantech/imx8qm_rom7720_a1/Makefile @@ -0,0 +1,11 @@ +# +# Copyright 2017 NXP +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += imx8qm_rom7720_a1.o + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +endif diff --git a/board/advantech/imx8qm_rom7720_a1/README b/board/advantech/imx8qm_rom7720_a1/README new file mode 100644 index 0000000000..bff5712589 --- /dev/null +++ b/board/advantech/imx8qm_rom7720_a1/README @@ -0,0 +1,50 @@ +U-Boot for the NXP i.MX8QM ROM 7720a1 board + +Quick Start +=========== + +- Build the ARM Trusted firmware binary +- Get scfw_tcm.bin and ahab-container.img +- Get imx-mkimage +- Build U-Boot +- Build imx-mkimage +- Flash the binary into the SD card +- Boot + +Get and Build the ARM Trusted firmware +====================================== + +$ git clone https://source.codeaurora.org/external/imx/imx-atf +$ cd imx-atf/ +$ git checkout origin/imx_4.14.78_1.0.0_ga -b imx_4.14.78_1.0.0_ga +$ make PLAT=imx8qm bl31 + +Get scfw_tcm.bin and ahab-container.img +============================== + +$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/imx-sc-firmware-1.1.bin +$ chmod +x imx-sc-firmware-1.1.bin +$ ./imx-sc-firmware-1.1.bin +$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.0.bin +$ chmod +x firmware-imx-8.0.bin +$ ./firmware-imx-8.0.bin + +Build U-Boot +============ + +$ export ATF_LOAD_ADDR=0x80000000 +$ export BL33_LOAD_ADDR=0x80020000 +$ make imx8qm_rom7720_a1_4G_defconfig +$ make u-boot.bin +$ make flash.bin + +Flash the binary into the SD card +================================= + +Burn the flash.bin binary to SD card offset 32KB: + +$ sudo dd if=flash.bin of=/dev/sd[x] bs=1k seek=32 conv=fsync + +Boot +==== +Set Boot switch SW2: 1100. diff --git a/board/advantech/imx8qm_rom7720_a1/imx8qm_rom7720_a1.c b/board/advantech/imx8qm_rom7720_a1/imx8qm_rom7720_a1.c new file mode 100644 index 0000000000..2f97d5ce96 --- /dev/null +++ b/board/advantech/imx8qm_rom7720_a1/imx8qm_rom7720_a1.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2017-2018 NXP + * Copyright (C) 2019 Oliver Graute <oliver.graute@kococonnector.com> + */ + +#include <common.h> +#include <errno.h> +#include <linux/libfdt.h> +#include <asm/io.h> +#include <asm/gpio.h> +#include <asm/arch/clock.h> +#include <asm/arch/sci/sci.h> +#include <asm/arch/imx8-pins.h> +#include <asm/arch/iomux.h> +#include <asm/arch/sys_proto.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) + +static iomux_cfg_t uart0_pads[] = { + SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL), + SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL), +}; + +static void setup_iomux_uart(void) +{ + imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads)); +} + +int board_early_init_f(void) +{ + sc_pm_clock_rate_t rate = SC_80MHZ; + int ret; + + /* Set UART0 clock root to 80 MHz */ + ret = sc_pm_setup_uart(SC_R_UART_0, rate); + if (ret) + return ret; + + setup_iomux_uart(); + + /* This is needed to because Kernel do not Power Up DC_0 */ + sc_pm_set_resource_power_mode(-1, SC_R_DC_0, SC_PM_PW_MODE_ON); + sc_pm_set_resource_power_mode(-1, SC_R_GPIO_5, SC_PM_PW_MODE_ON); + + return 0; +} + +#if IS_ENABLED(CONFIG_FEC_MXC) +#include <miiphy.h> + +int board_phy_config(struct phy_device *phydev) +{ +#ifdef CONFIG_FEC_ENABLE_MAX7322 + u8 value; + + /* This is needed to drive the pads to 1.8V instead of 1.5V */ + i2c_set_bus_num(CONFIG_MAX7322_I2C_BUS); + + if (!i2c_probe(CONFIG_MAX7322_I2C_ADDR)) { + /* Write 0x1 to enable O0 output, this device has no addr */ + /* hence addr length is 0 */ + value = 0x1; + if (dm_i2c_write(CONFIG_MAX7322_I2C_ADDR, 0, 0, &value, 1)) + printf("MAX7322 write failed\n"); + } else { + printf("MAX7322 Not found\n"); + } + mdelay(1); +#endif + + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); + + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); + phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); + + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} +#endif + +int checkboard(void) +{ + puts("Board: ROM-7720-A1 4GB\n"); + + build_info(); + print_bootinfo(); + + return 0; +} + +int board_init(void) +{ + /* Power up base board */ + sc_pm_set_resource_power_mode(-1, SC_R_BOARD_R1, SC_PM_PW_MODE_ON); + + return 0; +} + +void detail_board_ddr_info(void) +{ + puts("\nDDR "); +} + +/* + * Board specific reset that is system reset. + */ +void reset_cpu(ulong addr) +{ + /* TODO */ +} + +int board_mmc_get_env_dev(int devno) +{ + return devno; +} + +int board_late_init(void) +{ +#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG + env_set("board_name", "ROM-7720-A1"); + env_set("board_rev", "iMX8QM"); +#endif + + env_set("sec_boot", "no"); +#ifdef CONFIG_AHAB_BOOT + env_set("sec_boot", "yes"); +#endif + + return 0; +} diff --git a/board/advantech/imx8qm_rom7720_a1/imximage.cfg b/board/advantech/imx8qm_rom7720_a1/imximage.cfg new file mode 100644 index 0000000000..e324c7ca37 --- /dev/null +++ b/board/advantech/imx8qm_rom7720_a1/imximage.cfg @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2018 NXP + */ + +#define __ASSEMBLY__ + +/* Boot from SD, sector size 0x400 */ +BOOT_FROM SD 0x400 +/* SoC type IMX8QM */ +SOC_TYPE IMX8QM +/* Append seco container image */ +APPEND mx8qm-ahab-container.img +/* Create the 2nd container */ +CONTAINER +/* Add scfw image with exec attribute */ +IMAGE SCU mx8qm-val-scfw-tcm.bin +/* Add ATF image with exec attribute */ +IMAGE A35 bl31.bin 0x80000000 +/* Add U-Boot image with load attribute */ +DATA A35 u-boot-dtb.bin 0x80020000 diff --git a/board/advantech/imx8qm_rom7720_a1/spl.c b/board/advantech/imx8qm_rom7720_a1/spl.c new file mode 100644 index 0000000000..3f31a8f9c3 --- /dev/null +++ b/board/advantech/imx8qm_rom7720_a1/spl.c @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2017-2018 NXP + */ +#include <common.h> +#include <dm.h> +#include <spl.h> +#include <fsl_esdhc.h> + +#include <asm/io.h> +#include <asm/gpio.h> +#include <asm/arch/clock.h> +#include <asm/arch/sci/sci.h> +#include <asm/arch/imx8-pins.h> +#include <asm/arch/iomux.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define ESDHC_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) + +#define ESDHC_CLK_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) + +#define ENET_INPUT_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) + +#define ENET_NORMAL_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) + +#define FSPI_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) + +#define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) + +#define I2C_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) + +#define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | \ + (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) | \ + (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | \ + (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) +#ifdef CONFIG_FSL_ESDHC + +#define USDHC1_CD_GPIO IMX_GPIO_NR(5, 22) +#define USDHC2_CD_GPIO IMX_GPIO_NR(4, 12) + +static struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = { + {USDHC1_BASE_ADDR, 0, 8}, + {USDHC2_BASE_ADDR, 0, 4}, + {USDHC3_BASE_ADDR, 0, 4}, +}; + +static iomux_cfg_t emmc0[] = { + SC_P_EMMC0_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), + SC_P_EMMC0_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_EMMC0_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_EMMC0_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_EMMC0_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_EMMC0_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_EMMC0_DATA4 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_EMMC0_DATA5 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_EMMC0_DATA6 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_EMMC0_DATA7 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_EMMC0_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_EMMC0_STROBE | MUX_PAD_CTRL(ESDHC_PAD_CTRL), +}; + +static iomux_cfg_t usdhc2_sd[] = { + SC_P_USDHC2_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), + SC_P_USDHC2_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_USDHC2_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_USDHC2_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_USDHC2_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_USDHC2_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_USDHC2_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_USDHC2_WP | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), + SC_P_USDHC2_CD_B | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), +}; + +int board_mmc_init(bd_t *bis) +{ + int i, ret; + + /* + * According to the board_mmc_init() the following map is done: + * (U-Boot device node) (Physical Port) + * mmc0 USDHC1 + * mmc1 USDHC2 + * mmc2 USDHC3 + */ + for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { + switch (i) { + case 0: + ret = sc_pm_set_resource_power_mode(-1, SC_R_SDHC_0, SC_PM_PW_MODE_ON); + if (ret != SC_ERR_NONE) + return ret; + + imx8_iomux_setup_multiple_pads(emmc0, ARRAY_SIZE(emmc0)); + init_clk_usdhc(0); + usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + break; + case 1: + ret = sc_pm_set_resource_power_mode(-1, SC_R_SDHC_2, SC_PM_PW_MODE_ON); + if (ret != SC_ERR_NONE) + return ret; + ret = sc_pm_set_resource_power_mode(-1, SC_R_GPIO_4, SC_PM_PW_MODE_ON); + if (ret != SC_ERR_NONE) + return ret; + + imx8_iomux_setup_multiple_pads(usdhc2_sd, ARRAY_SIZE(usdhc2_sd)); + init_clk_usdhc(2); + usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + gpio_request(USDHC2_CD_GPIO, "sd2_cd"); + gpio_direction_input(USDHC2_CD_GPIO); + break; + default: + printf("Warning: you configured more USDHC controllers" + "(%d) than supported by the board\n", i + 1); + return 0; + } + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); + if (ret) { + printf("Warning: failed to initialize mmc dev %d\n", i); + return ret; + } + } + + return 0; +} + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + switch (cfg->esdhc_base) { + case USDHC1_BASE_ADDR: + ret = 1; + break; + case USDHC2_BASE_ADDR: + ret = !gpio_get_value(USDHC1_CD_GPIO); + break; + case USDHC3_BASE_ADDR: + ret = !gpio_get_value(USDHC2_CD_GPIO); + break; + } + + return ret; +} + +#endif /* CONFIG_FSL_ESDHC */ + +void spl_board_init(void) +{ +#if defined(CONFIG_SPL_SPI_SUPPORT) + if (sc_rm_is_resource_owned(-1, SC_R_FSPI_0)) { + if (sc_pm_set_resource_power_mode(-1, SC_R_FSPI_0, SC_PM_PW_MODE_ON)) { + puts("Warning: failed to initialize FSPI0\n"); + } + } +#endif + + puts("Normal Boot\n"); +} + +void spl_board_prepare_for_boot(void) +{ +#if defined(CONFIG_SPL_SPI_SUPPORT) + if (sc_rm_is_resource_owned(-1, SC_R_FSPI_0)) { + if (sc_pm_set_resource_power_mode(-1, SC_R_FSPI_0, SC_PM_PW_MODE_OFF)) { + puts("Warning: failed to turn off FSPI0\n"); + } + } +#endif +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* Just empty function now - can't decide what to choose */ + debug("%s: %s\n", __func__, name); + + return 0; +} +#endif + +void board_init_f(ulong dummy) +{ + /* Clear global data */ + memset((void *)gd, 0, sizeof(gd_t)); + + arch_cpu_init(); + + board_early_init_f(); + + timer_init(); + + preloader_console_init(); + + /* Clear the BSS. */ + memset(__bss_start, 0, __bss_end - __bss_start); + + board_init_r(NULL, 0); +} diff --git a/board/armadeus/opos6uldev/board.c b/board/armadeus/opos6uldev/board.c index cbf40d5c4a..ade155c5ad 100644 --- a/board/armadeus/opos6uldev/board.c +++ b/board/armadeus/opos6uldev/board.c @@ -3,53 +3,17 @@ * Copyright (C) 2018 Armadeus Systems */ -#include <asm/arch/mx6-pins.h> #include <asm/arch/sys_proto.h> #include <asm/gpio.h> -#include <asm/mach-imx/iomux-v3.h> #include <asm/io.h> #include <common.h> #ifdef CONFIG_VIDEO_MXS -#define LCD_PAD_CTRL ( \ - PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \ - PAD_CTL_PKE | PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm \ -) - -static iomux_v3_cfg_t const lcd_pads[] = { - MX6_PAD_LCD_CLK__LCDIF_CLK | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_ENABLE__LCDIF_ENABLE | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_HSYNC__LCDIF_HSYNC | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_VSYNC__LCDIF_VSYNC | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA00__LCDIF_DATA00 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA01__LCDIF_DATA01 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA02__LCDIF_DATA02 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA03__LCDIF_DATA03 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA04__LCDIF_DATA04 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA05__LCDIF_DATA05 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA06__LCDIF_DATA06 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA07__LCDIF_DATA07 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA08__LCDIF_DATA08 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA09__LCDIF_DATA09 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA10__LCDIF_DATA10 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA11__LCDIF_DATA11 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA12__LCDIF_DATA12 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA13__LCDIF_DATA13 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA14__LCDIF_DATA14 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA15__LCDIF_DATA15 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA16__LCDIF_DATA16 | MUX_PAD_CTRL(LCD_PAD_CTRL), - MX6_PAD_LCD_DATA17__LCDIF_DATA17 | MUX_PAD_CTRL(LCD_PAD_CTRL), - - MX6_PAD_NAND_ALE__GPIO4_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL) -}; - int setup_lcd(void) { struct gpio_desc backlight; int ret; - imx_iomux_v3_setup_multiple_pads(lcd_pads, ARRAY_SIZE(lcd_pads)); - /* Set Brightness to high */ ret = dm_gpio_lookup_name("GPIO4_10", &backlight); if (ret) { diff --git a/board/dhelectronics/dh_imx6/dh_imx6.c b/board/dhelectronics/dh_imx6/dh_imx6.c index 2d0f78da11..8dc4b80872 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6.c +++ b/board/dhelectronics/dh_imx6/dh_imx6.c @@ -197,7 +197,7 @@ static const struct boot_mode board_boot_modes[] = { {"sd2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)}, {"sd3", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)}, /* 8 bit bus width */ - {"emmc", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)}, + {"emmc", MAKE_CFGVAL(0x60, 0x58, 0x00, 0x00)}, {NULL, 0}, }; #endif diff --git a/board/dhelectronics/dh_imx6/dh_imx6_spl.c b/board/dhelectronics/dh_imx6/dh_imx6_spl.c index 1b7acc8df7..f2c3ac3e28 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6_spl.c +++ b/board/dhelectronics/dh_imx6/dh_imx6_spl.c @@ -476,6 +476,32 @@ static void setup_iomux_uart(void) SETUP_IOMUX_PADS(uart1_pads); } +#ifdef CONFIG_FSL_USDHC +struct fsl_esdhc_cfg usdhc_cfg[1] = { + {USDHC4_BASE_ADDR}, +}; + +int board_mmc_get_env_dev(int devno) +{ + return devno - 1; +} + +int board_mmc_getcd(struct mmc *mmc) +{ + return 1; /* eMMC/uSDHC4 is always present */ +} + +int board_mmc_init(bd_t *bis) +{ + SETUP_IOMUX_PADS(usdhc4_pads); + usdhc_cfg[0].esdhc_base = USDHC4_BASE_ADDR; + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK); + usdhc_cfg[0].max_bus_width = 8; + + return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); +} +#endif + /* USB */ static iomux_v3_cfg_t const usb_pads[] = { IOMUX_PADS(PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(NO_PAD_CTRL)), diff --git a/board/freescale/imx8mm_evk/spl.c b/board/freescale/imx8mm_evk/spl.c index 043b5f4342..2d08f9a563 100644 --- a/board/freescale/imx8mm_evk/spl.c +++ b/board/freescale/imx8mm_evk/spl.c @@ -18,6 +18,9 @@ #include <dm/uclass-internal.h> #include <dm/device-internal.h> +#include <power/pmic.h> +#include <power/bd71837.h> + DECLARE_GLOBAL_DATA_PTR; int spl_board_boot_device(enum boot_device boot_dev_spl) @@ -41,16 +44,7 @@ void spl_dram_init(void) void spl_board_init(void) { - struct udevice *dev; - int ret; - puts("Normal Boot\n"); - - ret = uclass_get_device_by_name(UCLASS_CLK, - "clock-controller@30380000", - &dev); - if (ret < 0) - printf("Failed to find clock node. Check device tree\n"); } #ifdef CONFIG_SPL_LOAD_FIT @@ -88,8 +82,45 @@ int board_early_init_f(void) return 0; } +int power_init_board(void) +{ + struct udevice *dev; + int ret; + + ret = pmic_get("pmic@4b", &dev); + if (ret == -ENODEV) { + puts("No pmic\n"); + return 0; + } + if (ret != 0) + return ret; + + /* decrease RESET key long push time from the default 10s to 10ms */ + pmic_reg_write(dev, BD718XX_PWRONCONFIG1, 0x0); + + /* unlock the PMIC regs */ + pmic_reg_write(dev, BD718XX_REGLOCK, 0x1); + + /* increase VDD_SOC to typical value 0.85v before first DRAM access */ + pmic_reg_write(dev, BD718XX_BUCK1_VOLT_RUN, 0x0f); + + /* increase VDD_DRAM to 0.975v for 3Ghz DDR */ + pmic_reg_write(dev, BD718XX_1ST_NODVS_BUCK_VOLT, 0x83); + +#ifndef CONFIG_IMX8M_LPDDR4 + /* increase NVCC_DRAM_1V2 to 1.2v for DDR4 */ + pmic_reg_write(dev, BD718XX_4TH_NODVS_BUCK_VOLT, 0x28); +#endif + + /* lock the PMIC regs */ + pmic_reg_write(dev, BD718XX_REGLOCK, 0x11); + + return 0; +} + void board_init_f(ulong dummy) { + struct udevice *dev; int ret; arch_cpu_init(); @@ -105,14 +136,24 @@ void board_init_f(ulong dummy) /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); - ret = spl_init(); + ret = spl_early_init(); if (ret) { - debug("spl_init() failed: %d\n", ret); + debug("spl_early_init() failed: %d\n", ret); + hang(); + } + + ret = uclass_get_device_by_name(UCLASS_CLK, + "clock-controller@30380000", + &dev); + if (ret < 0) { + printf("Failed to find clock node. Check device tree\n"); hang(); } enable_tzc380(); + power_init_board(); + /* DDR initialization */ spl_dram_init(); diff --git a/board/liebherr/mccmon6/Makefile b/board/liebherr/mccmon6/Makefile index ead6750ebf..3c9786c6b7 100644 --- a/board/liebherr/mccmon6/Makefile +++ b/board/liebherr/mccmon6/Makefile @@ -2,5 +2,8 @@ # # (C) Copyright 2016-2017 # Lukasz Majewski, DENX Software Engineering, lukma@denx.de - -obj-y := mccmon6.o spl.o +ifdef CONFIG_SPL_BUILD +obj-y := spl.o +else +obj-y := mccmon6.o +endif diff --git a/board/liebherr/mccmon6/mccmon6.c b/board/liebherr/mccmon6/mccmon6.c index 7d2751ab03..6a5fbbb8e6 100644 --- a/board/liebherr/mccmon6/mccmon6.c +++ b/board/liebherr/mccmon6/mccmon6.c @@ -9,54 +9,11 @@ #include <asm/arch/clock.h> #include <asm/arch/iomux.h> #include <asm/arch/imx-regs.h> -#include <asm/arch/mx6-pins.h> #include <asm/arch/sys_proto.h> #include <asm/gpio.h> -#include <asm/mach-imx/iomux-v3.h> -#include <asm/mach-imx/mxc_i2c.h> -#include <asm/mach-imx/spi.h> -#include <asm/mach-imx/boot_mode.h> -#include <asm/io.h> -#include <fsl_esdhc_imx.h> -#include <mmc.h> -#include <netdev.h> -#include <micrel.h> -#include <phy.h> -#include <input.h> -#include <i2c.h> -#include <spl.h> DECLARE_GLOBAL_DATA_PTR; -#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ - PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ - PAD_CTL_SRE_FAST | PAD_CTL_HYS) - -#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ - PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ - PAD_CTL_SRE_FAST | PAD_CTL_HYS) - -#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ - PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS) - -#define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) - -#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ - PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \ - PAD_CTL_ODE | PAD_CTL_SRE_FAST) - -#define WEIM_NOR_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ - PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) - -#define USDHC2_CD_GPIO IMX_GPIO_NR(1, 4) -#define ETH_PHY_RESET IMX_GPIO_NR(1, 27) -#define ECSPI3_CS0 IMX_GPIO_NR(4, 24) -#define ECSPI3_FLWP IMX_GPIO_NR(4, 27) -#define NOR_WP IMX_GPIO_NR(1, 1) -#define DISPLAY_EN IMX_GPIO_NR(1, 2) - int dram_init(void) { gd->ram_size = imx_ddr_size(); @@ -64,304 +21,11 @@ int dram_init(void) return 0; } -static iomux_v3_cfg_t const uart1_pads[] = { - IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), - IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), -}; - -static iomux_v3_cfg_t const usdhc2_pads[] = { - IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - /* Carrier MicroSD Card Detect */ - IOMUX_PADS(PAD_GPIO_4__GPIO1_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL)), -}; - -static iomux_v3_cfg_t const usdhc3_pads[] = { - IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), - IOMUX_PADS(PAD_SD3_RST__SD3_RESET | MUX_PAD_CTRL(USDHC_PAD_CTRL)), -}; - -static iomux_v3_cfg_t const enet_pads[] = { - IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL - | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK - | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)), - IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL - | MUX_PAD_CTRL(ENET_PAD_CTRL)), - /* KSZ9031 PHY Reset */ - IOMUX_PADS(PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL)), -}; - -static void setup_iomux_uart(void) -{ - SETUP_IOMUX_PADS(uart1_pads); -} - -static void setup_iomux_enet(void) -{ - SETUP_IOMUX_PADS(enet_pads); - - /* Reset KSZ9031 PHY */ - gpio_direction_output(ETH_PHY_RESET, 0); - mdelay(10); - gpio_set_value(ETH_PHY_RESET, 1); - udelay(100); -} - -static struct fsl_esdhc_cfg usdhc_cfg[2] = { - {USDHC3_BASE_ADDR}, - {USDHC2_BASE_ADDR}, -}; - -int board_mmc_getcd(struct mmc *mmc) -{ - struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; - int ret = 0; - - switch (cfg->esdhc_base) { - case USDHC2_BASE_ADDR: - ret = !gpio_get_value(USDHC2_CD_GPIO); - break; - case USDHC3_BASE_ADDR: - /* - * eMMC don't have card detect pin - since it is soldered to the - * PCB board - */ - ret = 1; - break; - } - return ret; -} - -int board_mmc_init(bd_t *bis) -{ - int ret; - u32 index = 0; - - /* - * MMC MAP - * (U-Boot device node) (Physical Port) - * mmc0 Soldered on board eMMC device - * mmc1 MicroSD card - */ - for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) { - switch (index) { - case 0: - SETUP_IOMUX_PADS(usdhc3_pads); - usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); - usdhc_cfg[0].max_bus_width = 8; - break; - case 1: - SETUP_IOMUX_PADS(usdhc2_pads); - usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); - usdhc_cfg[1].max_bus_width = 4; - gpio_direction_input(USDHC2_CD_GPIO); - break; - default: - printf("Warning: More USDHC controllers (%d) than supported (%d)\n", - index + 1, CONFIG_SYS_FSL_USDHC_NUM); - return -EINVAL; - } - - ret = fsl_esdhc_initialize(bis, &usdhc_cfg[index]); - if (ret) - return ret; - } - - return 0; -} - -static iomux_v3_cfg_t const eimnor_pads[] = { - IOMUX_PADS(PAD_EIM_D16__EIM_DATA16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D17__EIM_DATA17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D18__EIM_DATA18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D19__EIM_DATA19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D20__EIM_DATA20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D21__EIM_DATA21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D22__EIM_DATA22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D23__EIM_DATA23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D24__EIM_DATA24 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D25__EIM_DATA25 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D26__EIM_DATA26 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D27__EIM_DATA27 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D28__EIM_DATA28 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D29__EIM_DATA29 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D30__EIM_DATA30 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_D31__EIM_DATA31 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA0__EIM_AD00 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA1__EIM_AD01 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA2__EIM_AD02 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA3__EIM_AD03 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA4__EIM_AD04 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA5__EIM_AD05 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA6__EIM_AD06 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA7__EIM_AD07 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA8__EIM_AD08 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA9__EIM_AD09 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA10__EIM_AD10 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA11__EIM_AD11 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA12__EIM_AD12 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA13__EIM_AD13 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA14__EIM_AD14 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_DA15__EIM_AD15 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_A16__EIM_ADDR16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_A17__EIM_ADDR17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_A18__EIM_ADDR18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_A19__EIM_ADDR19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_A20__EIM_ADDR20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_A21__EIM_ADDR21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_A22__EIM_ADDR22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_A23__EIM_ADDR23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_A24__EIM_ADDR24 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_A25__EIM_ADDR25 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_OE__EIM_OE_B | MUX_PAD_CTRL(NO_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_RW__EIM_RW | MUX_PAD_CTRL(NO_PAD_CTRL)), - IOMUX_PADS(PAD_EIM_CS0__EIM_CS0_B | MUX_PAD_CTRL(NO_PAD_CTRL)), - IOMUX_PADS(PAD_GPIO_1__GPIO1_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL)), -}; - -static void eimnor_cs_setup(void) -{ - struct weim *weim_regs = (struct weim *)WEIM_BASE_ADDR; - - - /* NOR configuration */ - writel(0x00620181, &weim_regs->cs0gcr1); - writel(0x00000001, &weim_regs->cs0gcr2); - writel(0x0b020000, &weim_regs->cs0rcr1); - writel(0x0000b000, &weim_regs->cs0rcr2); - writel(0x0804a240, &weim_regs->cs0wcr1); - writel(0x00000000, &weim_regs->cs0wcr2); - - writel(0x00000120, &weim_regs->wcr); - writel(0x00000010, &weim_regs->wiar); - writel(0x00000000, &weim_regs->ear); - - set_chipselect_size(CS0_128); -} - -static void setup_eimnor(void) -{ - SETUP_IOMUX_PADS(eimnor_pads); - gpio_direction_output(NOR_WP, 1); - - enable_eim_clk(1); - eimnor_cs_setup(); -} - -/* mccmon6 board has SPI Flash is connected to SPI3 */ -int board_spi_cs_gpio(unsigned bus, unsigned cs) -{ - return (bus == 2 && cs == 0) ? ECSPI3_CS0 : -1; -} - -static iomux_v3_cfg_t const ecspi3_pads[] = { - /* SPI3 */ - IOMUX_PADS(PAD_DISP0_DAT3__GPIO4_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL)), - IOMUX_PADS(PAD_DISP0_DAT2__ECSPI3_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL)), - IOMUX_PADS(PAD_DISP0_DAT1__ECSPI3_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL)), - IOMUX_PADS(PAD_DISP0_DAT0__ECSPI3_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL)), -}; - -void setup_spi(void) -{ - SETUP_IOMUX_PADS(ecspi3_pads); - - enable_spi_clk(true, 2); - - /* set cs0 to high */ - gpio_direction_output(ECSPI3_CS0, 1); - - /* set flwp to high */ - gpio_direction_output(ECSPI3_FLWP, 1); -} - -struct i2c_pads_info mx6q_i2c1_pad_info = { - .scl = { - .i2c_mode = MX6Q_PAD_CSI0_DAT9__I2C1_SCL - | MUX_PAD_CTRL(I2C_PAD_CTRL), - .gpio_mode = MX6Q_PAD_CSI0_DAT9__GPIO5_IO27 - | MUX_PAD_CTRL(I2C_PAD_CTRL), - .gp = IMX_GPIO_NR(5, 27) - }, - .sda = { - .i2c_mode = MX6Q_PAD_CSI0_DAT8__I2C1_SDA - | MUX_PAD_CTRL(I2C_PAD_CTRL), - .gpio_mode = MX6Q_PAD_CSI0_DAT8__GPIO5_IO26 - | MUX_PAD_CTRL(I2C_PAD_CTRL), - .gp = IMX_GPIO_NR(5, 26) - } -}; - -struct i2c_pads_info mx6q_i2c2_pad_info = { - .scl = { - .i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL - | MUX_PAD_CTRL(I2C_PAD_CTRL), - .gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12 - | MUX_PAD_CTRL(I2C_PAD_CTRL), - .gp = IMX_GPIO_NR(4, 12) - }, - .sda = { - .i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA - | MUX_PAD_CTRL(I2C_PAD_CTRL), - .gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 - | MUX_PAD_CTRL(I2C_PAD_CTRL), - .gp = IMX_GPIO_NR(4, 13) - } -}; - -int board_eth_init(bd_t *bis) -{ - setup_iomux_enet(); - - return cpu_eth_init(bis); -} - -int board_early_init_f(void) -{ - setup_iomux_uart(); - - return 0; -} - int board_init(void) { /* address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100; - gpio_direction_output(DISPLAY_EN, 1); - - setup_eimnor(); - setup_spi(); - - setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c1_pad_info); - setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c2_pad_info); - return 0; } @@ -378,113 +42,3 @@ int checkboard(void) return 0; } - -int board_phy_config(struct phy_device *phydev) -{ - /* - * Default setting for GMII Clock Pad Skew Register 0x1EF: - * MMD Address 0x2h, Register 0x8h - * - * GTX_CLK Pad Skew 0xF -> 0.9 nsec skew - * RX_CLK Pad Skew 0xF -> 0.9 nsec skew - * - * Adjustment -> write 0x3FF: - * GTX_CLK Pad Skew 0x1F -> 1.8 nsec skew - * RX_CLK Pad Skew 0x1F -> 1.8 nsec skew - * - */ - ksz9031_phy_extended_write(phydev, 0x2, - MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, - MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x3FF); - - ksz9031_phy_extended_write(phydev, 0x02, - MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW, - MII_KSZ9031_MOD_DATA_NO_POST_INC, 0x00FF); - - ksz9031_phy_extended_write(phydev, 0x2, - MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW, - MII_KSZ9031_MOD_DATA_NO_POST_INC, - 0x3333); - - ksz9031_phy_extended_write(phydev, 0x2, - MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, - MII_KSZ9031_MOD_DATA_NO_POST_INC, - 0x2052); - - if (phydev->drv->config) - phydev->drv->config(phydev); - - return 0; -} - -#ifdef CONFIG_SPL_BOARD_INIT -void spl_board_init(void) -{ - setup_eimnor(); - - gpio_direction_output(DISPLAY_EN, 1); -} -#endif /* CONFIG_SPL_BOARD_INIT */ - -#ifdef CONFIG_SPL_BUILD -void board_boot_order(u32 *spl_boot_list) -{ - switch (spl_boot_device()) { - case BOOT_DEVICE_MMC2: - case BOOT_DEVICE_MMC1: - spl_boot_list[0] = BOOT_DEVICE_MMC2; - spl_boot_list[1] = BOOT_DEVICE_MMC1; - break; - - case BOOT_DEVICE_NOR: - spl_boot_list[0] = BOOT_DEVICE_NOR; - break; - } -} -#endif /* CONFIG_SPL_BUILD */ - -#ifdef CONFIG_SPL_OS_BOOT -int spl_start_uboot(void) -{ - char s[16]; - int ret; - /* - * We use BOOT_DEVICE_MMC1, but SD card is connected - * to MMC2 - * - * Correct "mapping" is delivered in board defined - * board_boot_order() function. - * - * SD card boot is regarded as a "development" one, - * hence we _always_ go through the u-boot. - * - */ - if (spl_boot_device() == BOOT_DEVICE_MMC1) - return 1; - - /* break into full u-boot on 'c' */ - if (serial_tstc() && serial_getc() == 'c') - return 1; - - env_init(); - ret = env_get_f("boot_os", s, sizeof(s)); - if ((ret != -1) && (strcmp(s, "no") == 0)) - return 1; - - /* - * Check if SWUpdate recovery needs to be started - * - * recovery_status = NULL (not set - ret == -1) -> normal operation - * - * recovery_status = progress or - * recovery_status = failed or - * recovery_status = <any value> -> start SWUpdate - * - */ - ret = env_get_f("recovery_status", s, sizeof(s)); - if (ret != -1) - return 1; - - return 0; -} -#endif /* CONFIG_SPL_OS_BOOT */ diff --git a/board/liebherr/mccmon6/spl.c b/board/liebherr/mccmon6/spl.c index f0ed78c847..fc5f5e948c 100644 --- a/board/liebherr/mccmon6/spl.c +++ b/board/liebherr/mccmon6/spl.c @@ -20,7 +20,6 @@ #include <asm/arch/sys_proto.h> #include <spl.h> -#if defined(CONFIG_SPL_BUILD) #include <asm/arch/mx6-ddr.h> /* * Driving strength: @@ -274,6 +273,25 @@ static void spl_dram_init(void) udelay(100); } +static void setup_spi(void) +{ + enable_spi_clk(true, 2); +} + +#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \ + PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +static iomux_v3_cfg_t const uart1_pads[] = { + IOMUX_PADS(PAD_CSI0_DAT10__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), + IOMUX_PADS(PAD_CSI0_DAT11__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)), +}; + +static void setup_iomux_uart(void) +{ + SETUP_IOMUX_PADS(uart1_pads); +} + void board_init_f(ulong dummy) { ccgr_init(); @@ -284,7 +302,7 @@ void board_init_f(ulong dummy) gpr_init(); /* iomux */ - board_early_init_f(); + setup_iomux_uart(); /* setup GP timer */ timer_init(); @@ -292,7 +310,264 @@ void board_init_f(ulong dummy) /* UART clocks enabled and gd valid - init serial console */ preloader_console_init(); + /* enable ECSPI clocks */ + setup_spi(); + /* DDR initialization */ spl_dram_init(); } + +void board_boot_order(u32 *spl_boot_list) +{ + switch (spl_boot_device()) { + case BOOT_DEVICE_MMC2: + case BOOT_DEVICE_MMC1: + spl_boot_list[0] = BOOT_DEVICE_MMC2; + spl_boot_list[1] = BOOT_DEVICE_MMC1; + break; + + case BOOT_DEVICE_NOR: + spl_boot_list[0] = BOOT_DEVICE_NOR; + break; + } +} + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + return 0; +} #endif + +#ifdef CONFIG_SPL_OS_BOOT +int spl_start_uboot(void) +{ + char s[16]; + int ret; + /* + * We use BOOT_DEVICE_MMC1, but SD card is connected + * to MMC2 + * + * Correct "mapping" is delivered in board defined + * board_boot_order() function. + * + * SD card boot is regarded as a "development" one, + * hence we _always_ go through the u-boot. + * + */ + if (spl_boot_device() == BOOT_DEVICE_MMC1) + return 1; + + /* break into full u-boot on 'c' */ + if (serial_tstc() && serial_getc() == 'c') + return 1; + + env_init(); + ret = env_get_f("boot_os", s, sizeof(s)); + if ((ret != -1) && (strcmp(s, "no") == 0)) + return 1; + + /* + * Check if SWUpdate recovery needs to be started + * + * recovery_status = NULL (not set - ret == -1) -> normal operation + * + * recovery_status = progress or + * recovery_status = failed or + * recovery_status = <any value> -> start SWUpdate + * + */ + ret = env_get_f("recovery_status", s, sizeof(s)); + if (ret != -1) + return 1; + + return 0; +} +#endif /* CONFIG_SPL_OS_BOOT */ + +#define WEIM_NOR_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ + PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ + PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) + +#define NOR_WP IMX_GPIO_NR(1, 1) + +static iomux_v3_cfg_t const eimnor_pads[] = { + IOMUX_PADS(PAD_EIM_D16__EIM_DATA16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D17__EIM_DATA17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D18__EIM_DATA18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D19__EIM_DATA19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D20__EIM_DATA20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D21__EIM_DATA21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D22__EIM_DATA22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D23__EIM_DATA23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D24__EIM_DATA24 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D25__EIM_DATA25 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D26__EIM_DATA26 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D27__EIM_DATA27 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D28__EIM_DATA28 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D29__EIM_DATA29 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D30__EIM_DATA30 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_D31__EIM_DATA31 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA0__EIM_AD00 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA1__EIM_AD01 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA2__EIM_AD02 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA3__EIM_AD03 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA4__EIM_AD04 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA5__EIM_AD05 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA6__EIM_AD06 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA7__EIM_AD07 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA8__EIM_AD08 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA9__EIM_AD09 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA10__EIM_AD10 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA11__EIM_AD11 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA12__EIM_AD12 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA13__EIM_AD13 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA14__EIM_AD14 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_DA15__EIM_AD15 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A16__EIM_ADDR16 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A17__EIM_ADDR17 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A18__EIM_ADDR18 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A19__EIM_ADDR19 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A20__EIM_ADDR20 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A21__EIM_ADDR21 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A22__EIM_ADDR22 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A23__EIM_ADDR23 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A24__EIM_ADDR24 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_A25__EIM_ADDR25 | MUX_PAD_CTRL(WEIM_NOR_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_OE__EIM_OE_B | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_RW__EIM_RW | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_EIM_CS0__EIM_CS0_B | MUX_PAD_CTRL(NO_PAD_CTRL)), + IOMUX_PADS(PAD_GPIO_1__GPIO1_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL)), +}; + +static void eimnor_cs_setup(void) +{ + struct weim *weim_regs = (struct weim *)WEIM_BASE_ADDR; + + /* NOR configuration */ + writel(0x00620181, &weim_regs->cs0gcr1); + writel(0x00000001, &weim_regs->cs0gcr2); + writel(0x0b020000, &weim_regs->cs0rcr1); + writel(0x0000b000, &weim_regs->cs0rcr2); + writel(0x0804a240, &weim_regs->cs0wcr1); + writel(0x00000000, &weim_regs->cs0wcr2); + + writel(0x00000120, &weim_regs->wcr); + writel(0x00000010, &weim_regs->wiar); + writel(0x00000000, &weim_regs->ear); + + set_chipselect_size(CS0_128); +} + +static void setup_eimnor(void) +{ + SETUP_IOMUX_PADS(eimnor_pads); + gpio_direction_output(NOR_WP, 1); + + enable_eim_clk(1); + eimnor_cs_setup(); +} + +#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \ + PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \ + PAD_CTL_SRE_FAST | PAD_CTL_HYS) + +#define USDHC2_CD_GPIO IMX_GPIO_NR(1, 4) + +static iomux_v3_cfg_t const usdhc2_pads[] = { + IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + /* Carrier MicroSD Card Detect */ + IOMUX_PADS(PAD_GPIO_4__GPIO1_IO04 | MUX_PAD_CTRL(NO_PAD_CTRL)), +}; + +static iomux_v3_cfg_t const usdhc3_pads[] = { + IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)), + IOMUX_PADS(PAD_SD3_RST__SD3_RESET | MUX_PAD_CTRL(USDHC_PAD_CTRL)), +}; + +static struct fsl_esdhc_cfg usdhc_cfg[2] = { + {USDHC3_BASE_ADDR}, + {USDHC2_BASE_ADDR}, +}; + +int board_mmc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; + int ret = 0; + + switch (cfg->esdhc_base) { + case USDHC2_BASE_ADDR: + ret = !gpio_get_value(USDHC2_CD_GPIO); + break; + case USDHC3_BASE_ADDR: + /* + * eMMC don't have card detect pin - since it is soldered to the + * PCB board + */ + ret = 1; + break; + } + return ret; +} + +int board_mmc_init(bd_t *bis) +{ + int ret; + u32 index = 0; + + /* + * MMC MAP + * (U-Boot device node) (Physical Port) + * mmc0 Soldered on board eMMC device + * mmc1 MicroSD card + */ + for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) { + switch (index) { + case 0: + SETUP_IOMUX_PADS(usdhc3_pads); + usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); + usdhc_cfg[0].max_bus_width = 8; + break; + case 1: + SETUP_IOMUX_PADS(usdhc2_pads); + usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); + usdhc_cfg[1].max_bus_width = 4; + gpio_direction_input(USDHC2_CD_GPIO); + break; + default: + printf("Warning: More USDHC controllers (%d) than supported (%d)\n", + index + 1, CONFIG_SYS_FSL_USDHC_NUM); + return -EINVAL; + } + + ret = fsl_esdhc_initialize(bis, &usdhc_cfg[index]); + if (ret) + return ret; + } + + return 0; +} + +#ifdef CONFIG_SPL_BOARD_INIT +#define DISPLAY_EN IMX_GPIO_NR(1, 2) +void spl_board_init(void) +{ + setup_eimnor(); + + gpio_direction_output(DISPLAY_EN, 1); +} +#endif /* CONFIG_SPL_BOARD_INIT */ diff --git a/board/synopsys/emsdp/README b/board/synopsys/emsdp/README index 034062e397..036554c4d5 100644 --- a/board/synopsys/emsdp/README +++ b/board/synopsys/emsdp/README @@ -79,5 +79,5 @@ ARC EM Software Development Platform (AKA EMSDP) 2.1. In case of proprietary MetaWare debugger run: ------------------------->8---------------------- - mdb -dll=opxdarc.so -OK -preloadexec="eval *(int*)0xf0001000=0" u-boot + mdb -digilent -OK -preloadexec="eval *(int*)0xf0001000=0" u-boot ------------------------->8---------------------- diff --git a/board/synopsys/emsdp/emsdp.c b/board/synopsys/emsdp/emsdp.c index 7a3fd5b7f2..5ba9f862e1 100644 --- a/board/synopsys/emsdp/emsdp.c +++ b/board/synopsys/emsdp/emsdp.c @@ -85,35 +85,6 @@ int board_early_init_r(void) return 0; } -int board_mmc_init(bd_t *bis) -{ - struct dwmci_host *host = NULL; - - host = malloc(sizeof(struct dwmci_host)); - if (!host) { - printf("dwmci_host malloc fail!\n"); - return 1; - } - - memset(host, 0, sizeof(struct dwmci_host)); - host->name = "Synopsys Mobile storage"; - host->ioaddr = SDIO_BASE; - host->buswidth = 4; - host->dev_index = 0; - host->bus_hz = 50000000; - - add_dwmci(host, host->bus_hz / 2, 400000); - - return 0; -} - -int board_mmc_getcd(struct mmc *mmc) -{ - struct dwmci_host *host = mmc->priv; - - return !(dwmci_readl(host, DWMCI_CDETECT) & 1); -} - #define CREG_BASE 0xF0001000 #define CREG_BOOT (void *)(CREG_BASE + 0x0FF0) #define CREG_IP_SW_RESET (void *)(CREG_BASE + 0x0FF0) diff --git a/board/synopsys/iot_devkit/iot_devkit.c b/board/synopsys/iot_devkit/iot_devkit.c index 8424e09bd3..9dbdc128f8 100644 --- a/board/synopsys/iot_devkit/iot_devkit.c +++ b/board/synopsys/iot_devkit/iot_devkit.c @@ -145,38 +145,6 @@ int mach_cpu_init(void) return set_cpu_freq(gd->cpu_clk); } -#define ARC_PERIPHERAL_BASE 0xF0000000 -#define SDIO_BASE (ARC_PERIPHERAL_BASE + 0xB000) - -int board_mmc_init(bd_t *bis) -{ - struct dwmci_host *host = NULL; - - host = malloc(sizeof(struct dwmci_host)); - if (!host) { - printf("dwmci_host malloc fail!\n"); - return -ENOMEM; - } - - memset(host, 0, sizeof(struct dwmci_host)); - host->name = "Synopsys Mobile storage"; - host->ioaddr = (void *)SDIO_BASE; - host->buswidth = 4; - host->dev_index = 0; - host->bus_hz = 50000000; - - add_dwmci(host, host->bus_hz / 2, 400000); - - return 0; -} - -int board_mmc_getcd(struct mmc *mmc) -{ - struct dwmci_host *host = mmc->priv; - - return !(dwmci_readl(host, DWMCI_CDETECT) & 1); -} - #define IOTDK_RESET_SEQ 0x55AA6699 void reset_cpu(ulong addr) diff --git a/board/toradex/colibri-imx6ull/MAINTAINERS b/board/toradex/colibri-imx6ull/MAINTAINERS index 626c1f94f9..c8199fa60a 100644 --- a/board/toradex/colibri-imx6ull/MAINTAINERS +++ b/board/toradex/colibri-imx6ull/MAINTAINERS @@ -4,6 +4,8 @@ W: http://developer.toradex.com/software/linux/linux-software W: https://www.toradex.com/community S: Maintained F: arch/arm/dts/imx6ull-colibri.dts +F: arch/arm/dts/imx6ull-colibri-u-boot.dtsi +F: arch/arm/dts/imx6ull-colibri.dtsi F: board/toradex/colibri-imx6ull/ F: configs/colibri-imx6ull_defconfig F: include/configs/colibri-imx6ull.h @@ -15,11 +15,6 @@ #define AVB_BOOTARGS "avb_bootargs" static struct AvbOps *avb_ops; -static const char * const requested_partitions[] = {"boot", - "system", - "vendor", - NULL}; - int do_avb_init(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { unsigned long mmc_dev; @@ -232,10 +227,12 @@ int do_avb_get_uuid(cmd_tbl_t *cmdtp, int flag, int do_avb_verify_part(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { + const char * const requested_partitions[] = {"boot", NULL}; AvbSlotVerifyResult slot_result; AvbSlotVerifyData *out_data; char *cmdline; char *extra_args; + char *slot_suffix = ""; bool unlocked = false; int res = CMD_RET_FAILURE; @@ -245,9 +242,12 @@ int do_avb_verify_part(cmd_tbl_t *cmdtp, int flag, return CMD_RET_FAILURE; } - if (argc != 1) + if (argc < 1 || argc > 2) return CMD_RET_USAGE; + if (argc == 2) + slot_suffix = argv[1]; + printf("## Android Verified Boot 2.0 version %s\n", avb_version_string()); @@ -260,7 +260,7 @@ int do_avb_verify_part(cmd_tbl_t *cmdtp, int flag, slot_result = avb_slot_verify(avb_ops, requested_partitions, - "", + slot_suffix, unlocked, AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, &out_data); @@ -420,7 +420,7 @@ static cmd_tbl_t cmd_avb[] = { U_BOOT_CMD_MKENT(read_part, 5, 0, do_avb_read_part, "", ""), U_BOOT_CMD_MKENT(read_part_hex, 4, 0, do_avb_read_part_hex, "", ""), U_BOOT_CMD_MKENT(write_part, 5, 0, do_avb_write_part, "", ""), - U_BOOT_CMD_MKENT(verify, 1, 0, do_avb_verify_part, "", ""), + U_BOOT_CMD_MKENT(verify, 2, 0, do_avb_verify_part, "", ""), #ifdef CONFIG_OPTEE_TA_AVB U_BOOT_CMD_MKENT(read_pvalue, 3, 0, do_avb_read_pvalue, "", ""), U_BOOT_CMD_MKENT(write_pvalue, 3, 0, do_avb_write_pvalue, "", ""), @@ -463,6 +463,7 @@ U_BOOT_CMD( "avb read_pvalue <name> <bytes> - read a persistent value <name>\n" "avb write_pvalue <name> <value> - write a persistent value <name>\n" #endif - "avb verify - run verification process using hash data\n" + "avb verify [slot_suffix] - run verification process using hash data\n" " from vbmeta structure\n" + " [slot_suffix] - _a, _b, etc (if vbmeta partition is slotted)\n" ); diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 1cb0bc1460..99a3bc57b1 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -1387,7 +1387,7 @@ static char env_help_text[] = #endif "env print [-a | name ...] - print environment\n" #if defined(CONFIG_CMD_NVEDIT_EFI) - "env print -e [name ...] - print UEFI environment\n" + "env print -e [-guid guid|-all][-n] [name ...] - print UEFI environment\n" #endif #if defined(CONFIG_CMD_RUN) "env run var [...] - run commands in an environment variable\n" @@ -1399,7 +1399,8 @@ static char env_help_text[] = #endif #endif #if defined(CONFIG_CMD_NVEDIT_EFI) - "env set -e name [arg ...] - set UEFI variable; unset if 'arg' not specified\n" + "env set -e [-nv][-bs][-rt][-a][-i addr,size][-v] name [arg ...]\n" + " - set UEFI variable; unset if '-i' or 'arg' not specified\n" #endif "env set [-f] name [arg ...]\n"; #endif @@ -1428,8 +1429,9 @@ U_BOOT_CMD_COMPLETE( "print environment variables", "[-a]\n - print [all] values of all environment variables\n" #if defined(CONFIG_CMD_NVEDIT_EFI) - "printenv -e [name ...]\n" + "printenv -e [-guid guid|-all][-n] [name ...]\n" " - print UEFI variable 'name' or all the variables\n" + " \"-n\": suppress dumping variable's value\n" #endif "printenv name ...\n" " - print value of environment variable 'name'", @@ -1459,9 +1461,16 @@ U_BOOT_CMD_COMPLETE( setenv, CONFIG_SYS_MAXARGS, 0, do_env_set, "set environment variables", #if defined(CONFIG_CMD_NVEDIT_EFI) - "-e [-nv] name [value ...]\n" + "-e [-guid guid][-nv][-bs][-rt][-a][-v]\n" + " [-i addr,size name], or [name [value ...]]\n" " - set UEFI variable 'name' to 'value' ...'\n" - " 'nv' option makes the variable non-volatile\n" + " \"-guid\": set vendor guid\n" + " \"-nv\": set non-volatile attribute\n" + " \"-bs\": set boot-service attribute\n" + " \"-rt\": set runtime attribute\n" + " \"-a\": append-write\n" + " \"-i addr,size\": use <addr,size> as variable's value\n" + " \"-v\": verbose message\n" " - delete UEFI variable 'name' if 'value' not specified\n" #endif "setenv [-f] name value ...\n" diff --git a/cmd/nvedit_efi.c b/cmd/nvedit_efi.c index ede4cd5235..8ea0da0128 100644 --- a/cmd/nvedit_efi.c +++ b/cmd/nvedit_efi.c @@ -13,6 +13,7 @@ #include <exports.h> #include <hexdump.h> #include <malloc.h> +#include <mapmem.h> #include <linux/kernel.h> /* @@ -34,15 +35,49 @@ static const struct { {EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, "AT"}, }; +static const struct { + efi_guid_t guid; + char *text; +} efi_guid_text[] = { + /* signature database */ + {EFI_GLOBAL_VARIABLE_GUID, "EFI_GLOBAL_VARIABLE_GUID"}, +}; + +/* "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" */ +static char unknown_guid[37]; + +/** + * efi_guid_to_str() - convert guid to readable name + * + * @guid: GUID + * Return: string for GUID + * + * convert guid to readable name + */ +static const char *efi_guid_to_str(const efi_guid_t *guid) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(efi_guid_text); i++) + if (!guidcmp(guid, &efi_guid_text[i].guid)) + return efi_guid_text[i].text; + + uuid_bin_to_str((unsigned char *)guid->b, unknown_guid, + UUID_STR_FORMAT_GUID); + + return unknown_guid; +} + /** * efi_dump_single_var() - show information about a UEFI variable * * @name: Name of the variable * @guid: Vendor GUID + * @verbose: if true, dump data * * Show information encoded in one UEFI variable */ -static void efi_dump_single_var(u16 *name, efi_guid_t *guid) +static void efi_dump_single_var(u16 *name, const efi_guid_t *guid, bool verbose) { u32 attributes; u8 *data; @@ -68,7 +103,7 @@ static void efi_dump_single_var(u16 *name, efi_guid_t *guid) if (ret != EFI_SUCCESS) goto out; - printf("%ls:", name); + printf("%ls:\n %s:", name, efi_guid_to_str(guid)); for (count = 0, i = 0; i < ARRAY_SIZE(efi_var_attrs); i++) if (attributes & efi_var_attrs[i].mask) { if (count) @@ -79,7 +114,9 @@ static void efi_dump_single_var(u16 *name, efi_guid_t *guid) puts(efi_var_attrs[i].text); } printf(", DataSize = 0x%zx\n", size); - print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1, data, size, true); + if (verbose) + print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1, + data, size, true); out: free(data); @@ -90,11 +127,13 @@ out: * * @argc: Number of arguments (variables) * @argv: Argument (variable name) array + * @verbose: if true, dump data * Return: CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE * * Show information encoded in named UEFI variables */ -static int efi_dump_vars(int argc, char * const argv[]) +static int efi_dump_vars(int argc, char * const argv[], + const efi_guid_t *guid, bool verbose) { u16 *var_name16, *p; efi_uintn_t buf_size, size; @@ -119,8 +158,7 @@ static int efi_dump_vars(int argc, char * const argv[]) p = var_name16; utf8_utf16_strcpy(&p, argv[0]); - efi_dump_single_var(var_name16, - (efi_guid_t *)&efi_global_variable_guid); + efi_dump_single_var(var_name16, guid, verbose); } free(var_name16); @@ -128,20 +166,56 @@ static int efi_dump_vars(int argc, char * const argv[]) return CMD_RET_SUCCESS; } +static bool match_name(int argc, char * const argv[], u16 *var_name16) +{ + char *buf, *p; + size_t buflen; + int i; + bool result = false; + + buflen = utf16_utf8_strlen(var_name16) + 1; + buf = calloc(1, buflen); + if (!buf) + return result; + + p = buf; + utf16_utf8_strcpy(&p, var_name16); + + for (i = 0; i < argc; argc--, argv++) { + if (!strcmp(buf, argv[i])) { + result = true; + goto out; + } + } + +out: + free(buf); + + return result; +} + /** - * efi_dump_vars() - show information about all the UEFI variables + * efi_dump_var_all() - show information about all the UEFI variables * + * @argc: Number of arguments (variables) + * @argv: Argument (variable name) array + * @verbose: if true, dump data * Return: CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE * * Show information encoded in all the UEFI variables */ -static int efi_dump_var_all(void) +static int efi_dump_var_all(int argc, char * const argv[], + const efi_guid_t *guid_p, bool verbose) { u16 *var_name16, *p; efi_uintn_t buf_size, size; efi_guid_t guid; efi_status_t ret; + if (argc && guid_p) + /* simplified case */ + return efi_dump_vars(argc, argv, guid_p, verbose); + buf_size = 128; var_name16 = malloc(buf_size); if (!var_name16) @@ -171,7 +245,9 @@ static int efi_dump_var_all(void) return CMD_RET_FAILURE; } - efi_dump_single_var(var_name16, &guid); + if ((!guid_p || !guidcmp(guid_p, &guid)) && + (!argc || match_name(argc, argv, var_name16))) + efi_dump_single_var(var_name16, &guid, verbose); } free(var_name16); @@ -189,12 +265,15 @@ static int efi_dump_var_all(void) * Return: CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE * * This function is for "env print -e" or "printenv -e" command: - * => env print -e [var [...]] + * => env print -e [-n] [-guid <guid> | -all] [var [...]] * If one or more variable names are specified, show information * named UEFI variables, otherwise show all the UEFI variables. */ int do_env_print_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { + efi_guid_t guid; + const efi_guid_t *guid_p; + bool default_guid, guid_any, verbose; efi_status_t ret; /* Initialize EFI drivers */ @@ -205,12 +284,47 @@ int do_env_print_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return CMD_RET_FAILURE; } - if (argc > 1) - /* show specified UEFI variables */ - return efi_dump_vars(--argc, ++argv); + default_guid = true; + guid_any = false; + verbose = true; + for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) { + if (!strcmp(argv[0], "-guid")) { + if (argc == 1) + return CMD_RET_USAGE; + + /* -a already specified */ + if (!default_guid & guid_any) + return CMD_RET_USAGE; + + argc--; + argv++; + if (uuid_str_to_bin(argv[0], guid.b, + UUID_STR_FORMAT_GUID)) + return CMD_RET_USAGE; + default_guid = false; + } else if (!strcmp(argv[0], "-all")) { + /* -guid already specified */ + if (!default_guid && !guid_any) + return CMD_RET_USAGE; + + guid_any = true; + default_guid = false; + } else if (!strcmp(argv[0], "-n")) { + verbose = false; + } else { + return CMD_RET_USAGE; + } + } + + if (guid_any) + guid_p = NULL; + else if (default_guid) + guid_p = &efi_global_variable_guid; + else + guid_p = (const efi_guid_t *)guid.b; /* enumerate and show all UEFI variables */ - return efi_dump_var_all(); + return efi_dump_var_all(argc, argv, guid_p, verbose); } /** @@ -339,18 +453,22 @@ out: * Return: CMD_RET_SUCCESS on success, or CMD_RET_RET_FAILURE * * This function is for "env set -e" or "setenv -e" command: - * => env set -e var [value ...]] + * => env set -e [-guid guid][-nv][-bs][-rt][-a][-v] + * [-i address,size] var, or + * var [value ...] * Encode values specified and set given UEFI variable. * If no value is specified, delete the variable. */ int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - char *var_name, *value = NULL; - efi_uintn_t size = 0; - u16 *var_name16 = NULL, *p; - size_t len; + char *var_name, *value, *ep; + ulong addr; + efi_uintn_t size; efi_guid_t guid; u32 attributes; + bool default_guid, verbose, value_on_memory; + u16 *var_name16 = NULL, *p; + size_t len; efi_status_t ret; if (argc == 1) @@ -364,32 +482,88 @@ int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return CMD_RET_FAILURE; } - attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS; - if (!strcmp(argv[1], "-nv")) { - attributes |= EFI_VARIABLE_NON_VOLATILE; - argc--; - argv++; - if (argc == 1) - return CMD_RET_SUCCESS; + /* + * attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | + * EFI_VARIABLE_RUNTIME_ACCESS; + */ + value = NULL; + size = 0; + attributes = 0; + guid = efi_global_variable_guid; + default_guid = true; + verbose = false; + value_on_memory = false; + for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) { + if (!strcmp(argv[0], "-guid")) { + if (argc == 1) + return CMD_RET_USAGE; + + argc--; + argv++; + if (uuid_str_to_bin(argv[0], guid.b, + UUID_STR_FORMAT_GUID)) { + printf("## Guid not specified or in XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX format\n"); + return CMD_RET_FAILURE; + } + default_guid = false; + } else if (!strcmp(argv[0], "-bs")) { + attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS; + } else if (!strcmp(argv[0], "-rt")) { + attributes |= EFI_VARIABLE_RUNTIME_ACCESS; + } else if (!strcmp(argv[0], "-nv")) { + attributes |= EFI_VARIABLE_NON_VOLATILE; + } else if (!strcmp(argv[0], "-a")) { + attributes |= EFI_VARIABLE_APPEND_WRITE; + } else if (!strcmp(argv[0], "-i")) { + /* data comes from memory */ + if (argc == 1) + return CMD_RET_USAGE; + + argc--; + argv++; + addr = simple_strtoul(argv[0], &ep, 16); + if (*ep != ',') + return CMD_RET_USAGE; + + size = simple_strtoul(++ep, NULL, 16); + if (!size) + return CMD_RET_FAILURE; + value_on_memory = true; + } else if (!strcmp(argv[0], "-v")) { + verbose = true; + } else { + return CMD_RET_USAGE; + } } + if (!argc) + return CMD_RET_USAGE; - var_name = argv[1]; - if (argc == 2) { - /* delete */ - value = NULL; - size = 0; - } else { /* set */ - argc -= 2; - argv += 2; + var_name = argv[0]; + if (default_guid) + guid = efi_global_variable_guid; + + if (verbose) { + printf("GUID: %s\n", efi_guid_to_str((const efi_guid_t *) + &guid)); + printf("Attributes: 0x%x\n", attributes); + } - for ( ; argc > 0; argc--, argv++) + /* for value */ + if (value_on_memory) + value = map_sysmem(addr, 0); + else if (argc > 1) + for (argc--, argv++; argc > 0; argc--, argv++) if (append_value(&value, &size, argv[0]) < 0) { printf("## Failed to process an argument, %s\n", argv[0]); ret = CMD_RET_FAILURE; goto out; } + + if (size && verbose) { + printf("Value:\n"); + print_hex_dump(" ", DUMP_PREFIX_OFFSET, + 16, 1, value, size, true); } len = utf8_utf16_strnlen(var_name, strlen(var_name)); @@ -402,17 +576,42 @@ int do_env_set_efi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) p = var_name16; utf8_utf16_strncpy(&p, var_name, len + 1); - guid = efi_global_variable_guid; ret = EFI_CALL(efi_set_variable(var_name16, &guid, attributes, size, value)); + unmap_sysmem(value); if (ret == EFI_SUCCESS) { ret = CMD_RET_SUCCESS; } else { - printf("## Failed to set EFI variable\n"); + const char *msg; + + switch (ret) { + case EFI_NOT_FOUND: + msg = " (not found)"; + break; + case EFI_WRITE_PROTECTED: + msg = " (read only)"; + break; + case EFI_INVALID_PARAMETER: + msg = " (invalid parameter)"; + break; + case EFI_SECURITY_VIOLATION: + msg = " (validation failed)"; + break; + case EFI_OUT_OF_RESOURCES: + msg = " (out of memory)"; + break; + default: + msg = ""; + break; + } + printf("## Failed to set EFI variable%s\n", msg); ret = CMD_RET_FAILURE; } out: - free(value); + if (value_on_memory) + unmap_sysmem(value); + else + free(value); free(var_name16); return ret; diff --git a/common/Kconfig b/common/Kconfig index 28d5e9a0cc..d9ecf79e0a 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -764,7 +764,7 @@ config SPL_LOG_CONSOLE line number are omitted. config TPL_LOG_CONSOLE - bool "Allow log output to the console in SPL" + bool "Allow log output to the console in TPL" depends on TPL_LOG default y help diff --git a/common/board_f.c b/common/board_f.c index 591f18f391..e3591cbaeb 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -588,6 +588,7 @@ static int reserve_stacks(void) static int reserve_bloblist(void) { #ifdef CONFIG_BLOBLIST + gd->start_addr_sp &= ~0xf; gd->start_addr_sp -= CONFIG_BLOBLIST_SIZE; gd->new_bloblist = map_sysmem(gd->start_addr_sp, CONFIG_BLOBLIST_SIZE); #endif @@ -695,6 +696,7 @@ static int reloc_bootstage(void) gd->bootstage, gd->new_bootstage, size); memcpy(gd->new_bootstage, gd->bootstage, size); gd->bootstage = gd->new_bootstage; + bootstage_relocate(); } #endif diff --git a/common/board_r.c b/common/board_r.c index d6fb5047a2..c1ecb06b74 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -670,7 +670,6 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_SYS_NONCACHED_MEMORY initr_noncached, #endif - bootstage_relocate, #ifdef CONFIG_OF_LIVE initr_of_live, #endif diff --git a/common/bootstage.c b/common/bootstage.c index 56ef91ad85..e8b7bbf81a 100644 --- a/common/bootstage.c +++ b/common/bootstage.c @@ -10,9 +10,10 @@ */ #include <common.h> -#include <linux/libfdt.h> #include <malloc.h> +#include <spl.h> #include <linux/compiler.h> +#include <linux/libfdt.h> DECLARE_GLOBAL_DATA_PTR; @@ -41,24 +42,34 @@ enum { }; struct bootstage_hdr { - uint32_t version; /* BOOTSTAGE_VERSION */ - uint32_t count; /* Number of records */ - uint32_t size; /* Total data size (non-zero if valid) */ - uint32_t magic; /* Unused */ + u32 version; /* BOOTSTAGE_VERSION */ + u32 count; /* Number of records */ + u32 size; /* Total data size (non-zero if valid) */ + u32 magic; /* Magic number */ + u32 next_id; /* Next ID to use for bootstage */ }; int bootstage_relocate(void) { struct bootstage_data *data = gd->bootstage; int i; + char *ptr; + + /* Figure out where to relocate the strings to */ + ptr = (char *)(data + 1); /* * Duplicate all strings. They may point to an old location in the * program .text section that can eventually get trashed. */ debug("Relocating %d records\n", data->rec_count); - for (i = 0; i < data->rec_count; i++) - data->record[i].name = strdup(data->record[i].name); + for (i = 0; i < data->rec_count; i++) { + const char *from = data->record[i].name; + + strcpy(ptr, from); + data->record[i].name = ptr; + ptr += strlen(ptr) + 1; + } return 0; } @@ -372,7 +383,6 @@ int bootstage_stash(void *base, int size) const struct bootstage_record *rec; char buf[20]; char *ptr = base, *end = ptr + size; - uint32_t count; int i; if (hdr + 1 > (struct bootstage_hdr *)end) { @@ -383,21 +393,15 @@ int bootstage_stash(void *base, int size) /* Write an arbitrary version number */ hdr->version = BOOTSTAGE_VERSION; - /* Count the number of records, and write that value first */ - for (rec = data->record, i = count = 0; i < data->rec_count; - i++, rec++) { - if (rec->id != 0) - count++; - } - hdr->count = count; + hdr->count = data->rec_count; hdr->size = 0; hdr->magic = BOOTSTAGE_MAGIC; + hdr->next_id = data->next_id; ptr += sizeof(*hdr); /* Write the records, silently stopping when we run out of space */ - for (rec = data->record, i = 0; i < data->rec_count; i++, rec++) { + for (rec = data->record, i = 0; i < data->rec_count; i++, rec++) append_data(&ptr, end, rec, sizeof(*rec)); - } /* Write the name strings */ for (rec = data->record, i = 0; i < data->rec_count; i++, rec++) { @@ -478,6 +482,8 @@ int bootstage_unstash(const void *base, int size) for (rec = data->record + data->next_id, i = 0; i < hdr->count; i++, rec++) { rec->name = ptr; + if (spl_phase() == PHASE_SPL) + rec->name = strdup(ptr); /* Assume no data corruption here */ ptr += strlen(ptr) + 1; @@ -485,6 +491,7 @@ int bootstage_unstash(const void *base, int size) /* Mark the records as read */ data->rec_count += hdr->count; + data->next_id = hdr->next_id; debug("Unstashed %d records\n", hdr->count); return 0; @@ -492,7 +499,17 @@ int bootstage_unstash(const void *base, int size) int bootstage_get_size(void) { - return sizeof(struct bootstage_data); + struct bootstage_data *data = gd->bootstage; + struct bootstage_record *rec; + int size; + int i; + + size = sizeof(struct bootstage_data); + for (rec = data->record, i = 0; i < data->rec_count; + i++, rec++) + size += strlen(rec->name) + 1; + + return size; } int bootstage_init(bool first) diff --git a/common/fdt_support.c b/common/fdt_support.c index baf7924ff6..6834399039 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -1566,7 +1566,7 @@ static int fdt_read_prop(const fdt32_t *prop, int prop_len, int cell_off, uint64_t *val, int cells) { const fdt32_t *prop32 = &prop[cell_off]; - const fdt64_t *prop64 = (const fdt64_t *)&prop[cell_off]; + const unaligned_fdt64_t *prop64 = (const fdt64_t *)&prop[cell_off]; if ((cell_off + cells) > prop_len) return -FDT_ERR_NOSPACE; diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 86d7edfee1..c661809923 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -1232,6 +1232,14 @@ config TPL if TPL +config TPL_SIZE_LIMIT + hex "Maximum size of TPL image" + depends on TPL + default 0 + help + Specifies the maximum length of the U-Boot TPL image. + If this value is zero, it is ignored. + config TPL_HANDOFF bool "Pass hand-off information from TPL to SPL and U-Boot proper" depends on HANDOFF && TPL_BLOBLIST diff --git a/common/spl/spl.c b/common/spl/spl.c index a9d3e847af..f1ad8dc9da 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -18,6 +18,7 @@ #include <version.h> #include <image.h> #include <malloc.h> +#include <mapmem.h> #include <dm/root.h> #include <linux/compiler.h> #include <fdt_support.h> @@ -396,13 +397,25 @@ static int spl_common_init(bool setup_malloc) gd->malloc_ptr = 0; } #endif - ret = bootstage_init(true); + ret = bootstage_init(u_boot_first_phase()); if (ret) { debug("%s: Failed to set up bootstage: ret=%d\n", __func__, ret); return ret; } - bootstage_mark_name(BOOTSTAGE_ID_START_SPL, "spl"); +#ifdef CONFIG_BOOTSTAGE_STASH + if (!u_boot_first_phase()) { + const void *stash = map_sysmem(CONFIG_BOOTSTAGE_STASH_ADDR, + CONFIG_BOOTSTAGE_STASH_SIZE); + + ret = bootstage_unstash(stash, CONFIG_BOOTSTAGE_STASH_SIZE); + if (ret) + debug("%s: Failed to unstash bootstage: ret=%d\n", + __func__, ret); + } +#endif /* CONFIG_BOOTSTAGE_STASH */ + bootstage_mark_name(spl_phase() == PHASE_TPL ? BOOTSTAGE_ID_START_TPL : + BOOTSTAGE_ID_START_SPL, SPL_TPL_NAME); #if CONFIG_IS_ENABLED(LOG) ret = log_init(); if (ret) { @@ -418,7 +431,8 @@ static int spl_common_init(bool setup_malloc) } } if (CONFIG_IS_ENABLED(DM)) { - bootstage_start(BOOTSTATE_ID_ACCUM_DM_SPL, "dm_spl"); + bootstage_start(BOOTSTATE_ID_ACCUM_DM_SPL, + spl_phase() == PHASE_TPL ? "dm tpl" : "dm_spl"); /* With CONFIG_SPL_OF_PLATDATA, bring in all devices */ ret = dm_init_and_scan(!CONFIG_IS_ENABLED(OF_PLATDATA)); bootstage_accum(BOOTSTATE_ID_ACCUM_DM_SPL); @@ -704,8 +718,9 @@ void board_init_r(gd_t *dummy1, ulong dummy2) debug("SPL malloc() used 0x%lx bytes (%ld KB)\n", gd->malloc_ptr, gd->malloc_ptr / 1024); #endif + bootstage_mark_name(spl_phase() == PHASE_TPL ? BOOTSTAGE_ID_END_TPL : + BOOTSTAGE_ID_END_SPL, "end " SPL_TPL_NAME); #ifdef CONFIG_BOOTSTAGE_STASH - bootstage_mark_name(BOOTSTAGE_ID_END_SPL, "end_spl"); ret = bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR, CONFIG_BOOTSTAGE_STASH_SIZE); if (ret) diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c index 7df708de9b..b1e79b9ded 100644 --- a/common/spl/spl_nor.c +++ b/common/spl/spl_nor.c @@ -51,6 +51,11 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, CONFIG_SYS_OS_BASE, (void *)header); +#if defined CONFIG_SYS_SPL_ARGS_ADDR && defined CONFIG_CMD_SPL_NOR_OFS + memcpy((void *)CONFIG_SYS_SPL_ARGS_ADDR, + (void *)CONFIG_CMD_SPL_NOR_OFS, + CONFIG_CMD_SPL_WRITE_SIZE); +#endif return ret; } #endif diff --git a/common/splash.c b/common/splash.c index 0bcedbb0ba..e7d847726d 100644 --- a/common/splash.c +++ b/common/splash.c @@ -144,8 +144,6 @@ void splash_display_banner(void) vidconsole_put_string(dev, buf); vidconsole_position_cursor(dev, 0, row); } -#else -static inline void splash_display_banner(void) { } #endif /* CONFIG_DM_VIDEO && !CONFIG_HIDE_LOGO_VERSION */ /* @@ -177,7 +175,9 @@ int splash_display(void) if (x || y) goto end; +#if defined(CONFIG_DM_VIDEO) && !defined(CONFIG_HIDE_LOGO_VERSION) splash_display_banner(); +#endif end: return ret; } diff --git a/configs/axs101_defconfig b/configs/axs101_defconfig index 0bfb532fc7..38c8ae998f 100644 --- a/configs/axs101_defconfig +++ b/configs/axs101_defconfig @@ -35,7 +35,9 @@ CONFIG_DM=y CONFIG_DM_GPIO=y CONFIG_HSDK_CREG_GPIO=y CONFIG_MMC=y +CONFIG_DM_MMC=y CONFIG_MMC_DW=y +CONFIG_MMC_DW_SNPS=y CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y diff --git a/configs/brppt2_defconfig b/configs/brppt2_defconfig new file mode 100644 index 0000000000..8f76262c5f --- /dev/null +++ b/configs/brppt2_defconfig @@ -0,0 +1,93 @@ +CONFIG_ARM=y +# CONFIG_SPL_SYS_THUMB_BUILD is not set +CONFIG_SYS_L2CACHE_OFF=y +CONFIG_ARCH_MX6=y +CONFIG_SPL_LDSCRIPT="arch/$(ARCH)/cpu/u-boot-spl.lds" +CONFIG_SYS_TEXT_BASE=0x17800000 +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x1000 +CONFIG_TARGET_BRPPT2=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI_SUPPORT=y +# CONFIG_CMD_BMODE is not set +CONFIG_DEFAULT_DEVICE_TREE="imx6dl-brppt2" +CONFIG_NR_DRAM_BANKS=1 +CONFIG_TPL_SYS_MALLOC_F_LEN=0x0 +# CONFIG_EXPERT is not set +CONFIG_OF_BOARD_SETUP=y +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg" +CONFIG_SPI_BOOT=y +CONFIG_BOOTDELAY=0 +CONFIG_USE_BOOTCOMMAND=y +CONFIG_BOOTCOMMAND="run b_default" +CONFIG_VERSION_VARIABLE=y +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_SPL_BOARD_INIT=y +# CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set +CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_HUSH_PARSER=y +CONFIG_CMD_BOOTZ=y +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_ENV_EXISTS is not set +CONFIG_CMD_MEMINFO=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_USB=y +CONFIG_CMD_DHCP=y +# CONFIG_CMD_NFS is not set +CONFIG_CMD_MII=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_TIME=y +CONFIG_CMD_EXT4=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clocks clock-names interrupt-parent interrupts dmas dma-names" +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_NET_RANDOM_ETHADDR=y +# CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_SPL_DM_SEQ_ALIAS=y +# CONFIG_OF_TRANSLATE is not set +# CONFIG_SPL_BLK is not set +CONFIG_BOOTCOUNT_LIMIT=y +CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y +CONFIG_SYS_BOOTCOUNT_ADDR=0x020CC068 +CONFIG_SYS_I2C_MXC=y +CONFIG_MMC_BROKEN_CD=y +# CONFIG_SPL_DM_MMC is not set +CONFIG_FSL_ESDHC=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x100000 +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_PHYLIB=y +CONFIG_PHY_FIXED=y +CONFIG_FEC_MXC=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +# CONFIG_REQUIRE_SERIAL_CONSOLE is not set +CONFIG_DM_SERIAL=y +CONFIG_MXC_UART=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_MXC_SPI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_STORAGE=y +CONFIG_SPL_TINY_MEMSET=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/dh_imx6_defconfig b/configs/dh_imx6_defconfig index db4753c5c7..072dcb20b5 100644 --- a/configs/dh_imx6_defconfig +++ b/configs/dh_imx6_defconfig @@ -6,6 +6,7 @@ CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_MX6_DDRCAL=y CONFIG_TARGET_DHCOMIMX6=y +CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_NR_DRAM_BANKS=1 CONFIG_SPL=y diff --git a/configs/display5_defconfig b/configs/display5_defconfig index 3227249413..91b369532d 100644 --- a/configs/display5_defconfig +++ b/configs/display5_defconfig @@ -30,6 +30,7 @@ CONFIG_SPL_DMA_SUPPORT=y CONFIG_SPL_ENV_SUPPORT=y CONFIG_SPL_SAVEENV=y CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_FORCE_MMC_BOOT=y CONFIG_SPL_OS_BOOT=y CONFIG_SPL_SPI_LOAD=y CONFIG_SYS_SPI_U_BOOT_OFFS=0x20000 diff --git a/configs/emsdp_defconfig b/configs/emsdp_defconfig index 5e55e3e2b2..09fe388e58 100644 --- a/configs/emsdp_defconfig +++ b/configs/emsdp_defconfig @@ -24,9 +24,11 @@ CONFIG_ENV_FAT_DEVICE_AND_PART="0:1" # CONFIG_NET is not set CONFIG_DM=y CONFIG_MMC=y +CONFIG_DM_MMC=y CONFIG_MMC_DW=y +CONFIG_MMC_DW_SNPS=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y -CONFIG_FS_FAT_MAX_CLUSTSIZE=4096 +CONFIG_FS_FAT_MAX_CLUSTSIZE=32768 CONFIG_USE_PRIVATE_LIBGCC=y CONFIG_PANIC_HANG=y diff --git a/configs/imx8mm_evk_defconfig b/configs/imx8mm_evk_defconfig index a934363277..4cbc62fd8f 100644 --- a/configs/imx8mm_evk_defconfig +++ b/configs/imx8mm_evk_defconfig @@ -12,6 +12,7 @@ CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y CONFIG_SPL_DRIVERS_MISC_SUPPORT=y CONFIG_SPL=y +CONFIG_SPL_TEXT_BASE=0x7E1000 CONFIG_FIT=y CONFIG_FIT_EXTERNAL_OFFSET=0x3000 CONFIG_SPL_LOAD_FIT=y @@ -20,10 +21,10 @@ CONFIG_OF_SYSTEM_SETUP=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/imx8m/imximage-8mm-lpddr4.cfg" CONFIG_DEFAULT_FDT_FILE="fsl-imx8mm-evk.dtb" CONFIG_BOARD_LATE_INIT=y -CONFIG_SPL_TEXT_BASE=0x7E1000 CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_POWER_SUPPORT=y CONFIG_HUSH_PARSER=y CONFIG_SYS_PROMPT="u-boot=> " # CONFIG_CMD_EXPORTENV is not set @@ -65,6 +66,8 @@ CONFIG_DM_ETH=y CONFIG_PINCTRL=y CONFIG_SPL_PINCTRL=y CONFIG_PINCTRL_IMX8M=y +CONFIG_DM_PMIC=y +CONFIG_SPL_DM_PMIC_BD71837=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y diff --git a/configs/imx8mq_evk_defconfig b/configs/imx8mq_evk_defconfig index f352f47ed5..523dbf895b 100644 --- a/configs/imx8mq_evk_defconfig +++ b/configs/imx8mq_evk_defconfig @@ -25,7 +25,7 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_OF_CONTROL=y -CONFIG_DEFAULT_DEVICE_TREE="fsl-imx8mq-evk" +CONFIG_DEFAULT_DEVICE_TREE="imx8mq-evk" CONFIG_ENV_IS_IN_MMC=y CONFIG_SAVED_DRAM_TIMING_BASE=0x40000000 CONFIG_DM_GPIO=y diff --git a/configs/imx8qm_rom7720_a1_4G_defconfig b/configs/imx8qm_rom7720_a1_4G_defconfig new file mode 100644 index 0000000000..bbecea8e61 --- /dev/null +++ b/configs/imx8qm_rom7720_a1_4G_defconfig @@ -0,0 +1,83 @@ +CONFIG_ARM=y +CONFIG_SPL_SYS_ICACHE_OFF=y +CONFIG_SPL_SYS_DCACHE_OFF=y +CONFIG_ARCH_IMX8=y +CONFIG_SYS_TEXT_BASE=0x80020000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_TARGET_IMX8QM_ROM7720_A1=y +CONFIG_SPL_MMC_SUPPORT=y +CONFIG_SPL_SERIAL_SUPPORT=y +CONFIG_SPL_DRIVERS_MISC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=4 +CONFIG_SPL=y +CONFIG_FIT=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_FIT_GENERATOR="arch/arm/mach-imx/mkimage_fit_atf.sh" +CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/advantech/imx8qm_rom7720_a1/imximage.cfg" +CONFIG_BOOTDELAY=3 +CONFIG_LOG=y +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_SPL_BOARD_INIT=y +CONFIG_HUSH_PARSER=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SPL_POWER_SUPPORT=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_WATCHDOG_SUPPORT=y +CONFIG_CMD_CPU=y +# CONFIG_CMD_IMPORTENV is not set +CONFIG_CMD_CLK=y +CONFIG_CMD_DM=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_FAT=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="imx8qm-rom7720-a1" +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_MMC=y +CONFIG_SPL_CLK=y +CONFIG_CLK_IMX8=y +CONFIG_CPU=y +CONFIG_DM_GPIO=y +CONFIG_MXC_GPIO=y +CONFIG_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_IMX_LPI2C=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_MISC=y +CONFIG_DM_MMC=y +CONFIG_FSL_ESDHC_IMX=y +CONFIG_PHYLIB=y +CONFIG_PHY_ADDR_ENABLE=y +CONFIG_PHY_ATHEROS=y +CONFIG_DM_ETH=y +CONFIG_PHY_GIGE=y +CONFIG_FEC_MXC_SHARE_MDIO=y +CONFIG_FEC_MXC_MDIO_BASE=0x5B040000 +CONFIG_FEC_MXC=y +CONFIG_MII=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_PINCTRL_IMX8=y +CONFIG_POWER_DOMAIN=y +CONFIG_IMX8_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_SPL_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_SPL_DM_REGULATOR_GPIO=y +CONFIG_DM_SERIAL=y +CONFIG_FSL_LPUART=y +CONFIG_SPL_TINY_MEMSET=y +# CONFIG_EFI_LOADER is not set +CONFIG_ARCH_MISC_INIT +CONFIG_NET_RANDOM_ETHADDR=y diff --git a/configs/iot_devkit_defconfig b/configs/iot_devkit_defconfig index 24bbe3fc5d..42278d4fb1 100644 --- a/configs/iot_devkit_defconfig +++ b/configs/iot_devkit_defconfig @@ -29,7 +29,9 @@ CONFIG_ENV_FAT_DEVICE_AND_PART="0:1" # CONFIG_NET is not set CONFIG_DM=y CONFIG_MMC=y +CONFIG_DM_MMC=y CONFIG_MMC_DW=y +CONFIG_MMC_DW_SNPS=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_USB=y diff --git a/configs/kp_imx6q_tpc_defconfig b/configs/kp_imx6q_tpc_defconfig index 3d93c20999..2484e91635 100644 --- a/configs/kp_imx6q_tpc_defconfig +++ b/configs/kp_imx6q_tpc_defconfig @@ -62,6 +62,8 @@ CONFIG_SPL_PINCTRL=y CONFIG_PINCTRL_IMX6=y CONFIG_DM_REGULATOR_FIXED=y CONFIG_SPL_DM_REGULATOR_FIXED=y +CONFIG_DM_RTC=y +CONFIG_RTC_DS1307=y # CONFIG_REQUIRE_SERIAL_CONSOLE is not set CONFIG_MXC_UART=y CONFIG_SYSRESET=y diff --git a/configs/mccmon6_nor_defconfig b/configs/mccmon6_nor_defconfig index a738ddba7c..e2d3b84616 100644 --- a/configs/mccmon6_nor_defconfig +++ b/configs/mccmon6_nor_defconfig @@ -10,25 +10,44 @@ CONFIG_SPL=y # CONFIG_CMD_BMODE is not set CONFIG_SPL_TEXT_BASE=0x00908000 CONFIG_DISTRO_DEFAULTS=y +CONFIG_FIT=y +CONFIG_SPL_LOAD_FIT=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/liebherr/mccmon6/mon6_imximage_nor.cfg" # CONFIG_USE_BOOTCOMMAND is not set CONFIG_BOUNCE_BUFFER=y CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_FIT_IMAGE_TINY=y CONFIG_SPL_ENV_SUPPORT=y CONFIG_SPL_NOR_SUPPORT=y +CONFIG_SPL_OS_BOOT=y +CONFIG_SYS_OS_BASE=0x8180000 +CONFIG_CMD_SPL=y +CONFIG_CMD_SPL_NOR_OFS=0x09600000 +CONFIG_CMD_SPL_WRITE_SIZE=0x20000 +CONFIG_CMD_CLK=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +# CONFIG_CMD_PINMUX is not set CONFIG_CMD_SF=y CONFIG_CMD_CACHE=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=8000000.nor" -CONFIG_MTDPARTS_DEFAULT="mtdparts=8000000.nor:32m@0x0(mccmon6-image.nor),256k@0x40000(u-boot-env.nor),1m@0x80000(u-boot.nor),8m@0x180000(kernel.nor),8m@0x980000(swupdate-kernel.nor),8m@0x1180000(swupdate-rootfs.nor),128k@0x1980000(kernel-dtb.nor),128k@0x19C0000(swupdate-kernel-dtb.nor)" +CONFIG_MTDPARTS_DEFAULT="mtdparts=8000000.nor:32m@0x0(mccmon6-image.nor),256k@0x40000(u-boot-env.nor),1m@0x80000(u-boot.nor),8m@0x180000(kernel.nor),8m@0x980000(swupdate-kernel.nor),8m@0x1180000(swupdate-rootfs.nor)" +CONFIG_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="imx6q-mccmon6" CONFIG_ENV_IS_IN_FLASH=y CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y CONFIG_DM=y CONFIG_FSL_USDHC=y +CONFIG_I2C_SET_DEFAULT_BUS_NUM=y +CONFIG_SYS_I2C_MXC=y +CONFIG_SYS_I2C_MXC_I2C1=y +CONFIG_SYS_I2C_MXC_I2C2=y +CONFIG_DM_MMC=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_MTD_DEVICE=y @@ -37,16 +56,32 @@ CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_FLASH_CFI_MTD=y CONFIG_SYS_FLASH_PROTECTION=y CONFIG_SYS_FLASH_CFI=y +CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y -CONFIG_SF_DEFAULT_BUS=2 +CONFIG_SF_DEFAULT_BUS=0 CONFIG_SF_DEFAULT_MODE=0 CONFIG_SF_DEFAULT_SPEED=25000000 CONFIG_SPI_FLASH_SPANSION=y CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y +CONFIG_FEC_MXC=y +CONFIG_RGMII=y CONFIG_MII=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_IMX6=y +CONFIG_DM_PMIC=y +# CONFIG_SPL_PMIC_CHILDREN is not set +CONFIG_DM_PMIC_PFUZE100=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_PFUZE100=y +# CONFIG_REQUIRE_SERIAL_CONSOLE is not set +# CONFIG_SPECIFY_CONSOLE_INDEX is not set +# CONFIG_SPL_SERIAL_PRESENT is not set +# CONFIG_TPL_SERIAL_PRESENT is not set +CONFIG_MXC_UART=y CONFIG_SPI=y CONFIG_MXC_SPI=y CONFIG_DM_THERMAL=y -CONFIG_OF_LIBFDT=y +CONFIG_USE_TINY_PRINTF=y +CONFIG_SPL_TINY_MEMSET=y diff --git a/configs/mccmon6_sd_defconfig b/configs/mccmon6_sd_defconfig index 377c52a41a..45aba4bb06 100644 --- a/configs/mccmon6_sd_defconfig +++ b/configs/mccmon6_sd_defconfig @@ -11,25 +11,41 @@ CONFIG_SPL=y # CONFIG_CMD_BMODE is not set CONFIG_SPL_TEXT_BASE=0x00908000 CONFIG_DISTRO_DEFAULTS=y +CONFIG_FIT=y +CONFIG_SPL_LOAD_FIT=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/liebherr/mccmon6/mon6_imximage_sd.cfg" # CONFIG_USE_BOOTCOMMAND is not set CONFIG_BOUNCE_BUFFER=y CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_ENV_SUPPORT=y CONFIG_SPL_NOR_SUPPORT=y +CONFIG_CMD_SPL=y +CONFIG_CMD_SPL_NOR_OFS=0x09600000 +CONFIG_CMD_SPL_WRITE_SIZE=0x20000 +CONFIG_CMD_CLK=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y +# CONFIG_CMD_PINMUX is not set CONFIG_CMD_SF=y CONFIG_CMD_CACHE=y +CONFIG_CMD_PMIC=y +CONFIG_CMD_REGULATOR=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_MTDPARTS=y CONFIG_MTDIDS_DEFAULT="nor0=8000000.nor" -CONFIG_MTDPARTS_DEFAULT="mtdparts=8000000.nor:32m@0x0(mccmon6-image.nor),256k@0x40000(u-boot-env.nor),1m@0x80000(u-boot.nor),8m@0x180000(kernel.nor),8m@0x980000(swupdate-kernel.nor),8m@0x1180000(swupdate-rootfs.nor),128k@0x1980000(kernel-dtb.nor),128k@0x19C0000(swupdate-kernel-dtb.nor)" +CONFIG_MTDPARTS_DEFAULT="mtdparts=8000000.nor:32m@0x0(mccmon6-image.nor),256k@0x40000(u-boot-env.nor),1m@0x80000(u-boot.nor),8m@0x180000(kernel.nor),8m@0x980000(swupdate-kernel.nor),8m@0x1180000(swupdate-rootfs.nor)" +CONFIG_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="imx6q-mccmon6" CONFIG_ENV_IS_IN_FLASH=y CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y CONFIG_DM=y CONFIG_FSL_USDHC=y +CONFIG_I2C_SET_DEFAULT_BUS_NUM=y +CONFIG_SYS_I2C_MXC=y +CONFIG_SYS_I2C_MXC_I2C1=y +CONFIG_SYS_I2C_MXC_I2C2=y +CONFIG_DM_MMC=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_MTD_DEVICE=y @@ -38,16 +54,28 @@ CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_FLASH_CFI_MTD=y CONFIG_SYS_FLASH_PROTECTION=y CONFIG_SYS_FLASH_CFI=y +CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH=y -CONFIG_SF_DEFAULT_BUS=2 CONFIG_SF_DEFAULT_MODE=0 CONFIG_SF_DEFAULT_SPEED=25000000 CONFIG_SPI_FLASH_SPANSION=y CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y +CONFIG_FEC_MXC=y +CONFIG_RGMII=y CONFIG_MII=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_IMX6=y +CONFIG_DM_PMIC=y +# CONFIG_SPL_PMIC_CHILDREN is not set +CONFIG_DM_PMIC_PFUZE100=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_PFUZE100=y +# CONFIG_REQUIRE_SERIAL_CONSOLE is not set +# CONFIG_SPL_SERIAL_PRESENT is not set +# CONFIG_TPL_SERIAL_PRESENT is not set +CONFIG_MXC_UART=y CONFIG_SPI=y CONFIG_MXC_SPI=y CONFIG_DM_THERMAL=y -CONFIG_OF_LIBFDT=y diff --git a/configs/opos6uldev_defconfig b/configs/opos6uldev_defconfig index 5eef6527cd..352d10a0d8 100644 --- a/configs/opos6uldev_defconfig +++ b/configs/opos6uldev_defconfig @@ -73,6 +73,8 @@ CONFIG_FSL_USDHC=y CONFIG_PHYLIB=y CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ8XXX=y +CONFIG_DM_ETH=y +CONFIG_DM_MDIO=y CONFIG_FEC_MXC=y CONFIG_MII=y CONFIG_PINCTRL=y @@ -93,6 +95,7 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0525 CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5 CONFIG_CI_UDC=y CONFIG_USB_GADGET_DOWNLOAD=y -CONFIG_VIDEO=y +CONFIG_DM_VIDEO=y +CONFIG_SYS_WHITE_ON_BLACK=y CONFIG_OF_LIBFDT_OVERLAY=y # CONFIG_EFI_LOADER is not set diff --git a/configs/tbs2910_defconfig b/configs/tbs2910_defconfig index 42e6f58eee..2cb57439c6 100644 --- a/configs/tbs2910_defconfig +++ b/configs/tbs2910_defconfig @@ -17,6 +17,8 @@ CONFIG_BOARD_EARLY_INIT_F=y CONFIG_HUSH_PARSER=y CONFIG_SYS_PROMPT="Matrix U-Boot> " CONFIG_CMD_BOOTZ=y +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set # CONFIG_CMD_FDT is not set CONFIG_CMD_MEMTEST=y # CONFIG_CMD_FLASH is not set @@ -78,4 +80,5 @@ CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_I2C_EDID=y CONFIG_VIDEO_IPUV3=y CONFIG_VIDEO=y +CONFIG_OF_LIBFDT_ASSUME_MASK=0xff # CONFIG_EFI_LOADER is not set diff --git a/disk/part_dos.c b/disk/part_dos.c index 8ddc13b50c..83ff40d310 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -67,28 +67,39 @@ static int test_block_type(unsigned char *buffer) { int slot; struct dos_partition *p; + int part_count = 0; if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) || (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) { return (-1); } /* no DOS Signature at all */ p = (struct dos_partition *)&buffer[DOS_PART_TBL_OFFSET]; - for (slot = 0; slot < 3; slot++) { - if (p->boot_ind != 0 && p->boot_ind != 0x80) { - if (!slot && - (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET], - "FAT", 3) == 0 || - strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET], - "FAT32", 5) == 0)) { - return DOS_PBR; /* is PBR */ - } else { - return -1; - } - } + + /* Check that the boot indicators are valid and count the partitions. */ + for (slot = 0; slot < 4; ++slot, ++p) { + if (p->boot_ind != 0 && p->boot_ind != 0x80) + break; + if (p->sys_ind) + ++part_count; } - return DOS_MBR; /* Is MBR */ -} + /* + * If the partition table is invalid or empty, + * check if this is a DOS PBR + */ + if (slot != 4 || !part_count) { + if (!strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET], + "FAT", 3) || + !strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET], + "FAT32", 5)) + return DOS_PBR; /* This is a DOS PBR and not an MBR */ + } + if (slot == 4) + return DOS_MBR; /* This is an DOS MBR */ + + /* This is neither a DOS MBR nor a DOS PBR */ + return -1; +} static int part_test_dos(struct blk_desc *dev_desc) { diff --git a/doc/android/avb2.txt b/doc/android/avb2.txt index a29cee1b6f..48e9297c75 100644 --- a/doc/android/avb2.txt +++ b/doc/android/avb2.txt @@ -95,6 +95,10 @@ e.g.: mmc read ${loadaddr} ${boot_start} ${boot_size}; \ bootm $loadaddr $loadaddr $fdtaddr; \ +If partitions you want to verify are slotted (have A/B suffixes), then current +slot suffix should be passed to 'avb verify' sub-command, e.g.: + +=> avb verify _a To switch on automatic generation of vbmeta partition in AOSP build, add these lines to device configuration mk file: diff --git a/doc/driver-model/of-plat.rst b/doc/driver-model/of-plat.rst index a38e58e4d2..557957d2a1 100644 --- a/doc/driver-model/of-plat.rst +++ b/doc/driver-model/of-plat.rst @@ -269,7 +269,7 @@ For example: }; U_BOOT_DRIVER(mmc_drv) = { - .name = "mmc", + .name = "vendor_mmc", /* matches compatible string */ .id = UCLASS_MMC, .of_match = mmc_ids, .ofdata_to_platdata = mmc_ofdata_to_platdata, diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 21a89eba5a..d10f9f0bf8 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -50,6 +50,8 @@ struct ahci_uc_priv *probe_ent = NULL; #define WAIT_MS_FLUSH 5000 #define WAIT_MS_LINKUP 200 +#define AHCI_CAP_S64A BIT(31) + __weak void __iomem *ahci_port_base(void __iomem *base, u32 port) { return base + 0x100 + (port * 0x80); @@ -503,9 +505,15 @@ static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port, } for (i = 0; i < sg_count; i++) { - ahci_sg->addr = - cpu_to_le32((unsigned long) buf + i * MAX_DATA_BYTE_COUNT); - ahci_sg->addr_hi = 0; + /* We assume virt=phys */ + phys_addr_t pa = (unsigned long)buf + i * MAX_DATA_BYTE_COUNT; + + ahci_sg->addr = cpu_to_le32(lower_32_bits(pa)); + ahci_sg->addr_hi = cpu_to_le32(upper_32_bits(pa)); + if (ahci_sg->addr_hi && !(uc_priv->cap & AHCI_CAP_S64A)) { + printf("Error: DMA address too high\n"); + return -1; + } ahci_sg->flags_size = cpu_to_le32(0x3fffff & (buf_len < MAX_DATA_BYTE_COUNT ? (buf_len - 1) diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index e8f58b3f5e..ca8978f0e1 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -580,6 +580,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name, desc = dev_get_uclass_platdata(dev); desc->if_type = if_type; desc->blksz = blksz; + desc->log2blksz = LOG2(desc->blksz); desc->lba = lba; desc->part_type = PART_TYPE_UNKNOWN; desc->bdev = dev; diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 297f0a0c7c..8f0eab2ca6 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -57,7 +57,7 @@ int ofnode_read_s32_default(ofnode node, const char *propname, s32 def) int ofnode_read_u64(ofnode node, const char *propname, u64 *outp) { - const fdt64_t *cell; + const unaligned_fdt64_t *cell; int len; assert(ofnode_valid(node)); diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c index d1d12eef38..e9e55c9d16 100644 --- a/drivers/core/regmap.c +++ b/drivers/core/regmap.c @@ -462,5 +462,5 @@ int regmap_update_bits(struct regmap *map, uint offset, uint mask, uint val) reg &= ~mask; - return regmap_write(map, offset, reg | val); + return regmap_write(map, offset, reg | (val & mask)); } diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 36f4d1c289..c520ef113a 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -6,6 +6,8 @@ * Pavel Herrmann <morpheus.ibis@gmail.com> */ +#define LOG_CATEGORY LOGC_DM + #include <common.h> #include <dm.h> #include <errno.h> @@ -303,7 +305,7 @@ int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq, int ret; *devp = NULL; - debug("%s: %d %d\n", __func__, find_req_seq, seq_or_req_seq); + log_debug("%d %d\n", find_req_seq, seq_or_req_seq); if (seq_or_req_seq == -1) return -ENODEV; ret = uclass_get(id, &uc); @@ -311,15 +313,16 @@ int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq, return ret; uclass_foreach_dev(dev, uc) { - debug(" - %d %d '%s'\n", dev->req_seq, dev->seq, dev->name); + log_debug(" - %d %d '%s'\n", + dev->req_seq, dev->seq, dev->name); if ((find_req_seq ? dev->req_seq : dev->seq) == seq_or_req_seq) { *devp = dev; - debug(" - found\n"); + log_debug(" - found\n"); return 0; } } - debug(" - not found\n"); + log_debug(" - not found\n"); return -ENODEV; } diff --git a/drivers/gpio/da8xx_gpio.c b/drivers/gpio/da8xx_gpio.c index bd79448164..0a50c68d72 100644 --- a/drivers/gpio/da8xx_gpio.c +++ b/drivers/gpio/da8xx_gpio.c @@ -342,13 +342,6 @@ int gpio_free(unsigned int gpio) } #endif -static int _gpio_direction_output(struct davinci_gpio *bank, unsigned int gpio, int value) -{ - clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); - gpio_set_value(gpio, value); - return 0; -} - static int _gpio_direction_input(struct davinci_gpio *bank, unsigned int gpio) { setbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); @@ -377,6 +370,13 @@ static int _gpio_get_dir(struct davinci_gpio *bank, unsigned int gpio) return in_le32(&bank->dir) & (1U << GPIO_BIT(gpio)); } +static int _gpio_direction_output(struct davinci_gpio *bank, unsigned int gpio, + int value) +{ + clrbits_le32(&bank->dir, 1U << GPIO_BIT(gpio)); + _gpio_set_value(bank, gpio, value); + return 0; +} #ifndef CONFIG_DM_GPIO void gpio_info(void) diff --git a/drivers/misc/imx8/fuse.c b/drivers/misc/imx8/fuse.c index 2f2fad2c17..1309215d4d 100644 --- a/drivers/misc/imx8/fuse.c +++ b/drivers/misc/imx8/fuse.c @@ -74,7 +74,7 @@ int fuse_prog(u32 bank, u32 word, u32 val) } return call_imx_sip(FSL_SIP_OTP_WRITE, (unsigned long)word, - (unsigned long)val, 0); + (unsigned long)val, 0, 0); } int fuse_override(u32 bank, u32 word, u32 val) diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index cd357ea411..8ff84aa3a8 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -25,13 +25,6 @@ DECLARE_GLOBAL_DATA_PTR; -#define SDHCI_IRQ_EN_BITS (IRQSTATEN_CC | IRQSTATEN_TC | \ - IRQSTATEN_CINT | \ - IRQSTATEN_CTOE | IRQSTATEN_CCE | IRQSTATEN_CEBE | \ - IRQSTATEN_CIE | IRQSTATEN_DTOE | IRQSTATEN_DCE | \ - IRQSTATEN_DEBE | IRQSTATEN_BRR | IRQSTATEN_BWR | \ - IRQSTATEN_DINT) - struct fsl_esdhc { uint dsaddr; /* SDMA system address register */ uint blkattr; /* Block attributes register */ @@ -82,8 +75,6 @@ struct fsl_esdhc_plat { * @mmc: mmc * Following is used when Driver Model is enabled for MMC * @dev: pointer for the device - * @non_removable: 0: removable; 1: non-removable - * @wp_enable: 1: enable checking wp; 0: no check * @cd_gpio: gpio for card detection * @wp_gpio: gpio for write protection */ @@ -92,13 +83,10 @@ struct fsl_esdhc_priv { unsigned int sdhc_clk; struct clk per_clk; unsigned int clock; - unsigned int bus_width; #if !CONFIG_IS_ENABLED(DM_MMC) struct mmc *mmc; #endif struct udevice *dev; - int non_removable; - int wp_enable; }; /* Return the XFERTYP flags for a given command and data packet */ @@ -241,12 +229,10 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, #endif if (wml_value > WML_WR_WML_MAX) wml_value = WML_WR_WML_MAX_VAL; - if (priv->wp_enable) { - if ((esdhc_read32(®s->prsstat) & - PRSSTAT_WPSPL) == 0) { - printf("\nThe SD card is locked. Can not write to a locked card.\n\n"); - return -ETIMEDOUT; - } + + if (!(esdhc_read32(®s->prsstat) & PRSSTAT_WPSPL)) { + printf("Can not write to locked SD card.\n"); + return -EINVAL; } esdhc_clrsetbits32(®s->wml, WML_WR_WML_MASK, @@ -636,236 +622,42 @@ static int esdhc_getcd_common(struct fsl_esdhc_priv *priv) if (CONFIG_ESDHC_DETECT_QUIRK) return 1; #endif - -#if CONFIG_IS_ENABLED(DM_MMC) - if (priv->non_removable) - return 1; -#endif - while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) && --timeout) udelay(1000); return timeout > 0; } -static int esdhc_reset(struct fsl_esdhc *regs) -{ - ulong start; - - /* reset the controller */ - esdhc_setbits32(®s->sysctl, SYSCTL_RSTA); - - /* hardware clears the bit when it is done */ - start = get_timer(0); - while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA)) { - if (get_timer(start) > 100) { - printf("MMC/SD: Reset never completed.\n"); - return -ETIMEDOUT; - } - } - - return 0; -} - -#if !CONFIG_IS_ENABLED(DM_MMC) -static int esdhc_getcd(struct mmc *mmc) -{ - struct fsl_esdhc_priv *priv = mmc->priv; - - return esdhc_getcd_common(priv); -} - -static int esdhc_init(struct mmc *mmc) -{ - struct fsl_esdhc_priv *priv = mmc->priv; - - return esdhc_init_common(priv, mmc); -} - -static int esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) -{ - struct fsl_esdhc_priv *priv = mmc->priv; - - return esdhc_send_cmd_common(priv, mmc, cmd, data); -} - -static int esdhc_set_ios(struct mmc *mmc) -{ - struct fsl_esdhc_priv *priv = mmc->priv; - - return esdhc_set_ios_common(priv, mmc); -} - -static const struct mmc_ops esdhc_ops = { - .getcd = esdhc_getcd, - .init = esdhc_init, - .send_cmd = esdhc_send_cmd, - .set_ios = esdhc_set_ios, -}; -#endif - -static int fsl_esdhc_init(struct fsl_esdhc_priv *priv, - struct fsl_esdhc_plat *plat) +static void fsl_esdhc_get_cfg_common(struct fsl_esdhc_priv *priv, + struct mmc_config *cfg) { - struct mmc_config *cfg; - struct fsl_esdhc *regs; - u32 caps, voltage_caps; - int ret; - - if (!priv) - return -EINVAL; - - regs = priv->esdhc_regs; - - /* First reset the eSDHC controller */ - ret = esdhc_reset(regs); - if (ret) - return ret; - - esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN | - SYSCTL_IPGEN | SYSCTL_CKEN); - - writel(SDHCI_IRQ_EN_BITS, ®s->irqstaten); - cfg = &plat->cfg; -#ifndef CONFIG_DM_MMC - memset(cfg, '\0', sizeof(*cfg)); -#endif + struct fsl_esdhc *regs = priv->esdhc_regs; + u32 caps; - voltage_caps = 0; caps = esdhc_read32(®s->hostcapblt); - #ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC135 - caps = caps & ~(ESDHC_HOSTCAPBLT_SRS | - ESDHC_HOSTCAPBLT_VS18 | ESDHC_HOSTCAPBLT_VS30); + caps &= ~(HOSTCAPBLT_SRS | HOSTCAPBLT_VS18 | HOSTCAPBLT_VS30); #endif - -/* T4240 host controller capabilities register should have VS33 bit */ #ifdef CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33 - caps = caps | ESDHC_HOSTCAPBLT_VS33; + caps |= HOSTCAPBLT_VS33; #endif - - if (caps & ESDHC_HOSTCAPBLT_VS18) - voltage_caps |= MMC_VDD_165_195; - if (caps & ESDHC_HOSTCAPBLT_VS30) - voltage_caps |= MMC_VDD_29_30 | MMC_VDD_30_31; - if (caps & ESDHC_HOSTCAPBLT_VS33) - voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34; + if (caps & HOSTCAPBLT_VS18) + cfg->voltages |= MMC_VDD_165_195; + if (caps & HOSTCAPBLT_VS30) + cfg->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31; + if (caps & HOSTCAPBLT_VS33) + cfg->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34; cfg->name = "FSL_SDHC"; -#if !CONFIG_IS_ENABLED(DM_MMC) - cfg->ops = &esdhc_ops; -#endif -#ifdef CONFIG_SYS_SD_VOLTAGE - cfg->voltages = CONFIG_SYS_SD_VOLTAGE; -#else - cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; -#endif - if ((cfg->voltages & voltage_caps) == 0) { - printf("voltage not supported by controller\n"); - return -1; - } - - if (priv->bus_width == 8) - cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; - else if (priv->bus_width == 4) - cfg->host_caps = MMC_MODE_4BIT; - - cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT; - - if (priv->bus_width > 0) { - if (priv->bus_width < 8) - cfg->host_caps &= ~MMC_MODE_8BIT; - if (priv->bus_width < 4) - cfg->host_caps &= ~MMC_MODE_4BIT; - } - if (caps & ESDHC_HOSTCAPBLT_HSS) + if (caps & HOSTCAPBLT_HSS) cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; -#ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK - if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK) - cfg->host_caps &= ~MMC_MODE_8BIT; -#endif - cfg->f_min = 400000; cfg->f_max = min(priv->sdhc_clk, (u32)200000000); - cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; - - return 0; } -#if !CONFIG_IS_ENABLED(DM_MMC) -static int fsl_esdhc_cfg_to_priv(struct fsl_esdhc_cfg *cfg, - struct fsl_esdhc_priv *priv) -{ - if (!cfg || !priv) - return -EINVAL; - - priv->esdhc_regs = (struct fsl_esdhc *)(unsigned long)(cfg->esdhc_base); - priv->bus_width = cfg->max_bus_width; - priv->sdhc_clk = cfg->sdhc_clk; - priv->wp_enable = cfg->wp_enable; - - return 0; -}; - -int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) -{ - struct fsl_esdhc_plat *plat; - struct fsl_esdhc_priv *priv; - struct mmc *mmc; - int ret; - - if (!cfg) - return -EINVAL; - - priv = calloc(sizeof(struct fsl_esdhc_priv), 1); - if (!priv) - return -ENOMEM; - plat = calloc(sizeof(struct fsl_esdhc_plat), 1); - if (!plat) { - free(priv); - return -ENOMEM; - } - - ret = fsl_esdhc_cfg_to_priv(cfg, priv); - if (ret) { - debug("%s xlate failure\n", __func__); - free(plat); - free(priv); - return ret; - } - - ret = fsl_esdhc_init(priv, plat); - if (ret) { - debug("%s init failure\n", __func__); - free(plat); - free(priv); - return ret; - } - - mmc = mmc_create(&plat->cfg, priv); - if (!mmc) - return -EIO; - - priv->mmc = mmc; - - return 0; -} - -int fsl_esdhc_mmc_init(bd_t *bis) -{ - struct fsl_esdhc_cfg *cfg; - - cfg = calloc(sizeof(struct fsl_esdhc_cfg), 1); - cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR; - cfg->sdhc_clk = gd->arch.sdhc_clk; - return fsl_esdhc_initialize(bis, cfg); -} -#endif - #ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT void mmc_adapter_card_type_ident(void) { @@ -939,7 +731,106 @@ void fdt_fixup_esdhc(void *blob, bd_t *bd) } #endif -#if CONFIG_IS_ENABLED(DM_MMC) +#if !CONFIG_IS_ENABLED(DM_MMC) +static int esdhc_getcd(struct mmc *mmc) +{ + struct fsl_esdhc_priv *priv = mmc->priv; + + return esdhc_getcd_common(priv); +} + +static int esdhc_init(struct mmc *mmc) +{ + struct fsl_esdhc_priv *priv = mmc->priv; + + return esdhc_init_common(priv, mmc); +} + +static int esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct fsl_esdhc_priv *priv = mmc->priv; + + return esdhc_send_cmd_common(priv, mmc, cmd, data); +} + +static int esdhc_set_ios(struct mmc *mmc) +{ + struct fsl_esdhc_priv *priv = mmc->priv; + + return esdhc_set_ios_common(priv, mmc); +} + +static const struct mmc_ops esdhc_ops = { + .getcd = esdhc_getcd, + .init = esdhc_init, + .send_cmd = esdhc_send_cmd, + .set_ios = esdhc_set_ios, +}; + +int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg) +{ + struct fsl_esdhc_plat *plat; + struct fsl_esdhc_priv *priv; + struct mmc_config *mmc_cfg; + struct mmc *mmc; + + if (!cfg) + return -EINVAL; + + priv = calloc(sizeof(struct fsl_esdhc_priv), 1); + if (!priv) + return -ENOMEM; + plat = calloc(sizeof(struct fsl_esdhc_plat), 1); + if (!plat) { + free(priv); + return -ENOMEM; + } + + priv->esdhc_regs = (struct fsl_esdhc *)(unsigned long)(cfg->esdhc_base); + priv->sdhc_clk = cfg->sdhc_clk; + + mmc_cfg = &plat->cfg; + + if (cfg->max_bus_width == 8) { + mmc_cfg->host_caps |= MMC_MODE_1BIT | MMC_MODE_4BIT | + MMC_MODE_8BIT; + } else if (cfg->max_bus_width == 4) { + mmc_cfg->host_caps |= MMC_MODE_1BIT | MMC_MODE_4BIT; + } else if (cfg->max_bus_width == 1) { + mmc_cfg->host_caps |= MMC_MODE_1BIT; + } else { + mmc_cfg->host_caps |= MMC_MODE_1BIT | MMC_MODE_4BIT | + MMC_MODE_8BIT; + printf("No max bus width provided. Assume 8-bit supported.\n"); + } + +#ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK + if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK) + mmc_cfg->host_caps &= ~MMC_MODE_8BIT; +#endif + mmc_cfg->ops = &esdhc_ops; + + fsl_esdhc_get_cfg_common(priv, mmc_cfg); + + mmc = mmc_create(mmc_cfg, priv); + if (!mmc) + return -EIO; + + priv->mmc = mmc; + return 0; +} + +int fsl_esdhc_mmc_init(bd_t *bis) +{ + struct fsl_esdhc_cfg *cfg; + + cfg = calloc(sizeof(struct fsl_esdhc_cfg), 1); + cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR; + cfg->sdhc_clk = gd->arch.sdhc_clk; + return fsl_esdhc_initialize(bis, cfg); +} +#else /* DM_MMC */ #ifndef CONFIG_PPC #include <asm/arch/clock.h> #endif @@ -949,7 +840,6 @@ static int fsl_esdhc_probe(struct udevice *dev) struct fsl_esdhc_plat *plat = dev_get_platdata(dev); struct fsl_esdhc_priv *priv = dev_get_priv(dev); fdt_addr_t addr; - unsigned int val; struct mmc *mmc; int ret; @@ -963,22 +853,6 @@ static int fsl_esdhc_probe(struct udevice *dev) #endif priv->dev = dev; - val = dev_read_u32_default(dev, "bus-width", -1); - if (val == 8) - priv->bus_width = 8; - else if (val == 4) - priv->bus_width = 4; - else - priv->bus_width = 1; - - if (dev_read_bool(dev, "non-removable")) { - priv->non_removable = 1; - } else { - priv->non_removable = 0; - } - - priv->wp_enable = 1; - if (IS_ENABLED(CONFIG_CLK)) { /* Assigned clock already set clock */ ret = clk_get_by_name(dev, "per", &priv->per_clk); @@ -1005,11 +879,7 @@ static int fsl_esdhc_probe(struct udevice *dev) } } - ret = fsl_esdhc_init(priv, plat); - if (ret) { - dev_err(dev, "fsl_esdhc_init failure\n"); - return ret; - } + fsl_esdhc_get_cfg_common(priv, &plat->cfg); mmc_of_parse(dev, &plat->cfg); @@ -1024,8 +894,12 @@ static int fsl_esdhc_probe(struct udevice *dev) static int fsl_esdhc_get_cd(struct udevice *dev) { + struct fsl_esdhc_plat *plat = dev_get_platdata(dev); struct fsl_esdhc_priv *priv = dev_get_priv(dev); + if (plat->cfg.host_caps & MMC_CAP_NONREMOVABLE) + return 1; + return esdhc_getcd_common(priv); } diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 43106dec75..4099386313 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -627,9 +627,6 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock) int sdhc_clk = priv->sdhc_clk; uint clk; - if (clock < mmc->cfg->f_min) - clock = mmc->cfg->f_min; - while (sdhc_clk / (16 * pre_div * ddr_pre_div) > clock && pre_div < 256) pre_div *= 2; @@ -958,6 +955,7 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) { struct fsl_esdhc *regs = priv->esdhc_regs; int ret __maybe_unused; + u32 clock; #ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK /* Select to use peripheral clock */ @@ -966,8 +964,12 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) esdhc_clock_control(priv, true); #endif /* Set the clock speed */ - if (priv->clock != mmc->clock) - set_sysctl(priv, mmc, mmc->clock); + clock = mmc->clock; + if (clock < mmc->cfg->f_min) + clock = mmc->cfg->f_min; + + if (priv->clock != clock) + set_sysctl(priv, mmc, clock); #ifdef MMC_SUPPORTS_TUNING if (mmc->clk_disable) { @@ -1645,6 +1647,9 @@ static const struct udevice_id fsl_esdhc_ids[] = { { .compatible = "fsl,imx7d-usdhc", .data = (ulong)&usdhc_imx7d_data,}, { .compatible = "fsl,imx7ulp-usdhc", }, { .compatible = "fsl,imx8qm-usdhc", .data = (ulong)&usdhc_imx8qm_data,}, + { .compatible = "fsl,imx8mm-usdhc", .data = (ulong)&usdhc_imx8qm_data,}, + { .compatible = "fsl,imx8mn-usdhc", .data = (ulong)&usdhc_imx8qm_data,}, + { .compatible = "fsl,imx8mq-usdhc", .data = (ulong)&usdhc_imx8qm_data,}, { .compatible = "fsl,esdhc", }, { /* sentinel */ } }; diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index a41b9620d0..ad7b644886 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -740,6 +740,19 @@ static int mxs_nand_ecc_write_page(struct mtd_info *mtd, d->cmd.pio_words[4] = (dma_addr_t)nand_info->data_buf; d->cmd.pio_words[5] = (dma_addr_t)nand_info->oob_buf; + if (is_mx7() && nand_info->en_randomizer) { + d->cmd.pio_words[2] |= GPMI_ECCCTRL_RANDOMIZER_ENABLE | + GPMI_ECCCTRL_RANDOMIZER_TYPE2; + /* + * Write NAND page number needed to be randomized + * to GPMI_ECCCOUNT register. + * + * The value is between 0-255. For additional details + * check 9.6.6.4 of i.MX7D Applications Processor reference + */ + d->cmd.pio_words[3] |= (page % 255) << 16; + } + mxs_dma_desc_append(channel, d); /* Flush caches */ @@ -1003,6 +1016,10 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) uint32_t tmp; int ret; + nand_info->en_randomizer = 0; + nand_info->oobsize = mtd->oobsize; + nand_info->writesize = mtd->writesize; + ret = mxs_nand_set_geometry(mtd, geo); if (ret) return ret; @@ -1020,6 +1037,7 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) tmp |= (geo->gf_len == 14 ? 1 : 0) << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET; writel(tmp, &bch_regs->hw_bch_flash0layout0); + nand_info->bch_flash0layout0 = tmp; tmp = (mtd->writesize + mtd->oobsize) << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET; @@ -1028,6 +1046,7 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd) tmp |= (geo->gf_len == 14 ? 1 : 0) << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET; writel(tmp, &bch_regs->hw_bch_flash0layout1); + nand_info->bch_flash0layout1 = tmp; /* Set *all* chip selects to use layout 0 */ writel(0, &bch_regs->hw_bch_layoutselect); @@ -1303,3 +1322,100 @@ err: free(nand_info); } #endif + +/* + * Read NAND layout for FCB block generation. + */ +void mxs_nand_get_layout(struct mtd_info *mtd, struct mxs_nand_layout *l) +{ + struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; + u32 tmp; + + tmp = readl(&bch_regs->hw_bch_flash0layout0); + l->nblocks = (tmp & BCH_FLASHLAYOUT0_NBLOCKS_MASK) >> + BCH_FLASHLAYOUT0_NBLOCKS_OFFSET; + l->meta_size = (tmp & BCH_FLASHLAYOUT0_META_SIZE_MASK) >> + BCH_FLASHLAYOUT0_META_SIZE_OFFSET; + + tmp = readl(&bch_regs->hw_bch_flash0layout1); + l->data0_size = 4 * ((tmp & BCH_FLASHLAYOUT0_DATA0_SIZE_MASK) >> + BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET); + l->ecc0 = (tmp & BCH_FLASHLAYOUT0_ECC0_MASK) >> + BCH_FLASHLAYOUT0_ECC0_OFFSET; + l->datan_size = 4 * ((tmp & BCH_FLASHLAYOUT1_DATAN_SIZE_MASK) >> + BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET); + l->eccn = (tmp & BCH_FLASHLAYOUT1_ECCN_MASK) >> + BCH_FLASHLAYOUT1_ECCN_OFFSET; +} + +/* + * Set BCH to specific layout used by ROM bootloader to read FCB. + */ +void mxs_nand_mode_fcb(struct mtd_info *mtd) +{ + u32 tmp; + struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; + struct nand_chip *nand = mtd_to_nand(mtd); + struct mxs_nand_info *nand_info = nand_get_controller_data(nand); + + nand_info->en_randomizer = 1; + + mtd->writesize = 1024; + mtd->oobsize = 1862 - 1024; + + /* 8 ecc_chunks_*/ + tmp = 7 << BCH_FLASHLAYOUT0_NBLOCKS_OFFSET; + /* 32 bytes for metadata */ + tmp |= 32 << BCH_FLASHLAYOUT0_META_SIZE_OFFSET; + /* using ECC62 level to be performed */ + tmp |= 0x1F << BCH_FLASHLAYOUT0_ECC0_OFFSET; + /* 0x20 * 4 bytes of the data0 block */ + tmp |= 0x20 << BCH_FLASHLAYOUT0_DATA0_SIZE_OFFSET; + tmp |= 0 << BCH_FLASHLAYOUT0_GF13_0_GF14_1_OFFSET; + writel(tmp, &bch_regs->hw_bch_flash0layout0); + + /* 1024 for data + 838 for OOB */ + tmp = 1862 << BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET; + /* using ECC62 level to be performed */ + tmp |= 0x1F << BCH_FLASHLAYOUT1_ECCN_OFFSET; + /* 0x20 * 4 bytes of the data0 block */ + tmp |= 0x20 << BCH_FLASHLAYOUT1_DATAN_SIZE_OFFSET; + tmp |= 0 << BCH_FLASHLAYOUT1_GF13_0_GF14_1_OFFSET; + writel(tmp, &bch_regs->hw_bch_flash0layout1); +} + +/* + * Restore BCH to normal settings. + */ +void mxs_nand_mode_normal(struct mtd_info *mtd) +{ + struct mxs_bch_regs *bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; + struct nand_chip *nand = mtd_to_nand(mtd); + struct mxs_nand_info *nand_info = nand_get_controller_data(nand); + + nand_info->en_randomizer = 0; + + mtd->writesize = nand_info->writesize; + mtd->oobsize = nand_info->oobsize; + + writel(nand_info->bch_flash0layout0, &bch_regs->hw_bch_flash0layout0); + writel(nand_info->bch_flash0layout1, &bch_regs->hw_bch_flash0layout1); +} + +uint32_t mxs_nand_mark_byte_offset(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct mxs_nand_info *nand_info = nand_get_controller_data(chip); + struct bch_geometry *geo = &nand_info->bch_geometry; + + return geo->block_mark_byte_offset; +} + +uint32_t mxs_nand_mark_bit_offset(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd_to_nand(mtd); + struct mxs_nand_info *nand_info = nand_get_controller_data(chip); + struct bch_geometry *geo = &nand_info->bch_geometry; + + return geo->block_mark_bit_offset; +} diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c index e11fbdeed3..06b0663950 100644 --- a/drivers/net/ti/am65-cpsw-nuss.c +++ b/drivers/net/ti/am65-cpsw-nuss.c @@ -234,11 +234,11 @@ static void am65_cpsw_gmii_sel_k3(struct am65_cpsw_priv *priv, break; case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_RXID: mode = AM65_GMII_SEL_MODE_RGMII; break; case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII_RXID: case PHY_INTERFACE_MODE_RGMII_TXID: mode = AM65_GMII_SEL_MODE_RGMII; rgmii_id = true; diff --git a/drivers/net/ti/cpsw.c b/drivers/net/ti/cpsw.c index 20ddb44dd8..4a990be93e 100644 --- a/drivers/net/ti/cpsw.c +++ b/drivers/net/ti/cpsw.c @@ -19,12 +19,9 @@ #include <phy.h> #include <asm/arch/cpu.h> #include <dm.h> -#include <fdt_support.h> #include "cpsw_mdio.h" -DECLARE_GLOBAL_DATA_PTR; - #define BITMASK(bits) (BIT(bits) - 1) #define NUM_DESCS (PKTBUFSRX * 2) #define PKT_MIN 60 @@ -33,6 +30,7 @@ DECLARE_GLOBAL_DATA_PTR; #define GIGABITEN BIT(7) #define FULLDUPLEXEN BIT(0) #define MIIEN BIT(15) +#define CTL_EXT_EN BIT(18) /* DMA Registers */ #define CPDMA_TXCONTROL 0x004 #define CPDMA_RXCONTROL 0x014 @@ -489,6 +487,8 @@ static int cpsw_slave_update_link(struct cpsw_slave *slave, mac_control |= FULLDUPLEXEN; if (phy->speed == 100) mac_control |= MIIEN; + if (phy->speed == 10 && phy_interface_is_rgmii(phy)) + mac_control |= CTL_EXT_EN; } if (mac_control == slave->mac_control) @@ -836,6 +836,7 @@ static int cpsw_phy_init(struct cpsw_priv *priv, struct cpsw_slave *slave) { struct phy_device *phydev; u32 supported = PHY_GBIT_FEATURES; + int ret; phydev = phy_connect(priv->bus, slave->data->phy_addr, @@ -846,11 +847,18 @@ static int cpsw_phy_init(struct cpsw_priv *priv, struct cpsw_slave *slave) return -1; phydev->supported &= supported; + if (slave->data->max_speed) { + ret = phy_set_supported(phydev, slave->data->max_speed); + if (ret) + return ret; + dev_dbg(priv->dev, "Port %u speed forced to %uMbit\n", + slave->slave_num + 1, slave->data->max_speed); + } phydev->advertising = phydev->supported; #ifdef CONFIG_DM_ETH - if (slave->data->phy_of_handle) - phydev->node = offset_to_ofnode(slave->data->phy_of_handle); + if (ofnode_valid(slave->data->phy_of_handle)) + phydev->node = slave->data->phy_of_handle; #endif priv->phydev = phydev; @@ -1038,12 +1046,6 @@ static const struct eth_ops cpsw_eth_ops = { .stop = cpsw_eth_stop, }; -static inline fdt_addr_t cpsw_get_addr_by_node(const void *fdt, int node) -{ - return fdtdec_get_addr_size_auto_noparent(fdt, node, "reg", 0, NULL, - false); -} - static void cpsw_gmii_sel_am3352(struct cpsw_priv *priv, phy_interface_t phy_mode) { @@ -1061,10 +1063,10 @@ static void cpsw_gmii_sel_am3352(struct cpsw_priv *priv, break; case PHY_INTERFACE_MODE_RGMII: + case PHY_INTERFACE_MODE_RGMII_RXID: mode = AM33XX_GMII_SEL_MODE_RGMII; break; case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII_RXID: case PHY_INTERFACE_MODE_RGMII_TXID: mode = AM33XX_GMII_SEL_MODE_RGMII; rgmii_id = true; @@ -1176,23 +1178,53 @@ static int cpsw_eth_probe(struct udevice *dev) } #if CONFIG_IS_ENABLED(OF_CONTROL) +static void cpsw_eth_of_parse_slave(struct cpsw_platform_data *data, + int slave_index, ofnode subnode) +{ + struct ofnode_phandle_args out_args; + struct cpsw_slave_data *slave_data; + const char *phy_mode; + u32 phy_id[2]; + int ret; + + slave_data = &data->slave_data[slave_index]; + + phy_mode = ofnode_read_string(subnode, "phy-mode"); + if (phy_mode) + slave_data->phy_if = phy_get_interface_by_name(phy_mode); + + ret = ofnode_parse_phandle_with_args(subnode, "phy-handle", + NULL, 0, 0, &out_args); + if (!ret) { + slave_data->phy_of_handle = out_args.node; + + ret = ofnode_read_s32(slave_data->phy_of_handle, "reg", + &slave_data->phy_addr); + if (ret) + printf("error: phy addr not found in dt\n"); + } else { + ret = ofnode_read_u32_array(subnode, "phy_id", phy_id, 2); + if (ret) + printf("error: phy_id read failed\n"); + } + + slave_data->max_speed = ofnode_read_s32_default(subnode, + "max-speed", 0); +} + static int cpsw_eth_ofdata_to_platdata(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct cpsw_platform_data *data; struct gpio_desc *mode_gpios; - const char *phy_mode; - const void *fdt = gd->fdt_blob; - int node = dev_of_offset(dev); - int subnode; int slave_index = 0; - int active_slave; int num_mode_gpios; + ofnode subnode; int ret; data = calloc(1, sizeof(struct cpsw_platform_data)); pdata->priv_pdata = data; - pdata->iobase = devfdt_get_addr(dev); + pdata->iobase = dev_read_addr(dev); data->version = CPSW_CTRL_VERSION_2; data->bd_ram_ofs = CPSW_BD_OFFSET; data->ale_reg_ofs = CPSW_ALE_OFFSET; @@ -1203,36 +1235,37 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev) pdata->phy_interface = -1; data->cpsw_base = pdata->iobase; - data->channels = fdtdec_get_int(fdt, node, "cpdma_channels", -1); - if (data->channels <= 0) { + + ret = dev_read_s32(dev, "cpdma_channels", &data->channels); + if (ret) { printf("error: cpdma_channels not found in dt\n"); - return -ENOENT; + return ret; } - data->slaves = fdtdec_get_int(fdt, node, "slaves", -1); - if (data->slaves <= 0) { + ret = dev_read_s32(dev, "slaves", &data->slaves); + if (ret) { printf("error: slaves not found in dt\n"); - return -ENOENT; + return ret; } data->slave_data = malloc(sizeof(struct cpsw_slave_data) * data->slaves); - data->ale_entries = fdtdec_get_int(fdt, node, "ale_entries", -1); - if (data->ale_entries <= 0) { + ret = dev_read_s32(dev, "ale_entries", &data->ale_entries); + if (ret) { printf("error: ale_entries not found in dt\n"); - return -ENOENT; + return ret; } - data->bd_ram_ofs = fdtdec_get_int(fdt, node, "bd_ram_size", -1); - if (data->bd_ram_ofs <= 0) { + ret = dev_read_u32(dev, "bd_ram_size", &data->bd_ram_ofs); + if (ret) { printf("error: bd_ram_size not found in dt\n"); - return -ENOENT; + return ret; } - data->mac_control = fdtdec_get_int(fdt, node, "mac_control", -1); - if (data->mac_control <= 0) { + ret = dev_read_u32(dev, "mac_control", &data->mac_control); + if (ret) { printf("error: ale_entries not found in dt\n"); - return -ENOENT; + return ret; } num_mode_gpios = gpio_get_list_count(dev, "mode-gpios"); @@ -1244,67 +1277,41 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev) free(mode_gpios); } - active_slave = fdtdec_get_int(fdt, node, "active_slave", 0); - data->active_slave = active_slave; + data->active_slave = dev_read_u32_default(dev, "active_slave", 0); - fdt_for_each_subnode(subnode, fdt, node) { - int len; + ofnode_for_each_subnode(subnode, dev_ofnode(dev)) { const char *name; - name = fdt_get_name(fdt, subnode, &len); + name = ofnode_get_name(subnode); if (!strncmp(name, "mdio", 4)) { - u32 mdio_base; - - mdio_base = cpsw_get_addr_by_node(fdt, subnode); - if (mdio_base == FDT_ADDR_T_NONE) { + data->mdio_base = ofnode_get_addr(subnode); + if (data->mdio_base == FDT_ADDR_T_NONE) { pr_err("Not able to get MDIO address space\n"); return -ENOENT; } - data->mdio_base = mdio_base; } if (!strncmp(name, "slave", 5)) { - u32 phy_id[2]; - if (slave_index >= data->slaves) continue; - phy_mode = fdt_getprop(fdt, subnode, "phy-mode", NULL); - if (phy_mode) - data->slave_data[slave_index].phy_if = - phy_get_interface_by_name(phy_mode); - - data->slave_data[slave_index].phy_of_handle = - fdtdec_lookup_phandle(fdt, subnode, - "phy-handle"); - - if (data->slave_data[slave_index].phy_of_handle >= 0) { - data->slave_data[slave_index].phy_addr = - fdtdec_get_int(gd->fdt_blob, - data->slave_data[slave_index].phy_of_handle, - "reg", -1); - } else { - fdtdec_get_int_array(fdt, subnode, "phy_id", - phy_id, 2); - data->slave_data[slave_index].phy_addr = - phy_id[1]; - } + + cpsw_eth_of_parse_slave(data, slave_index, subnode); slave_index++; } if (!strncmp(name, "cpsw-phy-sel", 12)) { - data->gmii_sel = cpsw_get_addr_by_node(fdt, subnode); + data->gmii_sel = ofnode_get_addr(subnode); if (data->gmii_sel == FDT_ADDR_T_NONE) { pr_err("Not able to get gmii_sel reg address\n"); return -ENOENT; } - if (fdt_get_property(fdt, subnode, "rmii-clock-ext", - NULL)) + if (ofnode_read_bool(subnode, "rmii-clock-ext")) data->rmii_clock_external = true; - data->phy_sel_compat = fdt_getprop(fdt, subnode, - "compatible", NULL); + data->phy_sel_compat = ofnode_read_string(subnode, + "compatible"); if (!data->phy_sel_compat) { pr_err("Not able to get gmii_sel compatible\n"); return -ENOENT; @@ -1320,15 +1327,16 @@ static int cpsw_eth_ofdata_to_platdata(struct udevice *dev) data->slave_data[1].sliver_reg_ofs = CPSW_SLIVER1_OFFSET; } - ret = ti_cm_get_macid_addr(dev, active_slave, data); + ret = ti_cm_get_macid_addr(dev, data->active_slave, data); if (ret < 0) { pr_err("cpsw read efuse mac failed\n"); return ret; } - pdata->phy_interface = data->slave_data[active_slave].phy_if; + pdata->phy_interface = data->slave_data[data->active_slave].phy_if; if (pdata->phy_interface == -1) { - debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode); + debug("%s: Invalid PHY interface '%s'\n", __func__, + phy_string_for_interface(pdata->phy_interface)); return -EINVAL; } diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index ee6b581d9e..f915817aaa 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -123,6 +123,9 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, } *prp2 = (ulong)dev->prp_pool; + flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool + + dev->prp_entry_num * sizeof(u64)); + return 0; } @@ -580,14 +583,19 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) static int nvme_get_info_from_identify(struct nvme_dev *dev) { - ALLOC_CACHE_ALIGN_BUFFER(char, buf, sizeof(struct nvme_id_ctrl)); - struct nvme_id_ctrl *ctrl = (struct nvme_id_ctrl *)buf; + struct nvme_id_ctrl *ctrl; int ret; int shift = NVME_CAP_MPSMIN(dev->cap) + 12; + ctrl = memalign(dev->page_size, sizeof(struct nvme_id_ctrl)); + if (!ctrl) + return -ENOMEM; + ret = nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl); - if (ret) + if (ret) { + free(ctrl); return -EIO; + } dev->nn = le32_to_cpu(ctrl->nn); dev->vwc = ctrl->vwc; @@ -618,6 +626,7 @@ static int nvme_get_info_from_identify(struct nvme_dev *dev) dev->max_transfer_shift = 20; } + free(ctrl); return 0; } @@ -658,16 +667,21 @@ static int nvme_blk_probe(struct udevice *udev) struct blk_desc *desc = dev_get_uclass_platdata(udev); struct nvme_ns *ns = dev_get_priv(udev); u8 flbas; - ALLOC_CACHE_ALIGN_BUFFER(char, buf, sizeof(struct nvme_id_ns)); - struct nvme_id_ns *id = (struct nvme_id_ns *)buf; struct pci_child_platdata *pplat; + struct nvme_id_ns *id; + + id = memalign(ndev->page_size, sizeof(struct nvme_id_ns)); + if (!id) + return -ENOMEM; memset(ns, 0, sizeof(*ns)); ns->dev = ndev; /* extract the namespace id from the block device name */ ns->ns_id = trailing_strtol(udev->name) + 1; - if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id)) + if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id)) { + free(id); return -EIO; + } memcpy(&ns->eui64, &id->eui64, sizeof(id->eui64)); flbas = id->flbas & NVME_NS_FLBAS_LBA_MASK; @@ -686,6 +700,7 @@ static int nvme_blk_probe(struct udevice *udev) memcpy(desc->product, ndev->serial, sizeof(ndev->serial)); memcpy(desc->revision, ndev->firmware_rev, sizeof(ndev->firmware_rev)); + free(id); return 0; } @@ -705,9 +720,8 @@ static ulong nvme_blk_rw(struct udevice *udev, lbaint_t blknr, u16 lbas = 1 << (dev->max_transfer_shift - ns->lba_shift); u64 total_lbas = blkcnt; - if (!read) - flush_dcache_range((unsigned long)buffer, - (unsigned long)buffer + total_len); + flush_dcache_range((unsigned long)buffer, + (unsigned long)buffer + total_len); c.rw.opcode = read ? nvme_cmd_read : nvme_cmd_write; c.rw.flags = 0; diff --git a/drivers/phy/phy-uclass.c b/drivers/phy/phy-uclass.c index a0ac30aa71..e201a90c8c 100644 --- a/drivers/phy/phy-uclass.c +++ b/drivers/phy/phy-uclass.c @@ -108,35 +108,55 @@ int generic_phy_get_by_name(struct udevice *dev, const char *phy_name, int generic_phy_init(struct phy *phy) { - struct phy_ops const *ops = phy_dev_ops(phy->dev); + struct phy_ops const *ops; + + if (!phy) + return 0; + ops = phy_dev_ops(phy->dev); return ops->init ? ops->init(phy) : 0; } int generic_phy_reset(struct phy *phy) { - struct phy_ops const *ops = phy_dev_ops(phy->dev); + struct phy_ops const *ops; + + if (!phy) + return 0; + ops = phy_dev_ops(phy->dev); return ops->reset ? ops->reset(phy) : 0; } int generic_phy_exit(struct phy *phy) { - struct phy_ops const *ops = phy_dev_ops(phy->dev); + struct phy_ops const *ops; + + if (!phy) + return 0; + ops = phy_dev_ops(phy->dev); return ops->exit ? ops->exit(phy) : 0; } int generic_phy_power_on(struct phy *phy) { - struct phy_ops const *ops = phy_dev_ops(phy->dev); + struct phy_ops const *ops; + + if (!phy) + return 0; + ops = phy_dev_ops(phy->dev); return ops->power_on ? ops->power_on(phy) : 0; } int generic_phy_power_off(struct phy *phy) { - struct phy_ops const *ops = phy_dev_ops(phy->dev); + struct phy_ops const *ops; + + if (!phy) + return 0; + ops = phy_dev_ops(phy->dev); return ops->power_off ? ops->power_off(phy) : 0; } diff --git a/drivers/power/domain/imx8m-power-domain.c b/drivers/power/domain/imx8m-power-domain.c index 164fb3d31d..40ece9ee3f 100644 --- a/drivers/power/domain/imx8m-power-domain.c +++ b/drivers/power/domain/imx8m-power-domain.c @@ -37,7 +37,8 @@ static int imx8m_power_domain_on(struct power_domain *power_domain) if (pdata->has_pd) power_domain_on(&pdata->pd); - call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, pdata->resource_id, 1); + call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, + pdata->resource_id, 1, 0); return 0; } @@ -51,7 +52,8 @@ static int imx8m_power_domain_off(struct power_domain *power_domain) if (pdata->resource_id < 0) return -EINVAL; - call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, pdata->resource_id, 0); + call_imx_sip(IMX_SIP_GPC, IMX_SIP_GPC_PM_DOMAIN, + pdata->resource_id, 0, 0); if (pdata->has_pd) power_domain_off(&pdata->pd); diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 586772fdec..4718dc700c 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -55,6 +55,14 @@ config DM_PMIC_BD71837 This config enables implementation of driver-model pmic uclass features for PMIC BD71837. The driver implements read/write operations. +config SPL_DM_PMIC_BD71837 + bool "Enable Driver Model for PMIC BD71837 in SPL stage" + depends on DM_PMIC + help + This config enables implementation of driver-model pmic uclass + features for PMIC BD71837. The driver implements read/write + operations. + config DM_PMIC_FAN53555 bool "Enable support for OnSemi FAN53555" depends on DM_PMIC && DM_REGULATOR && DM_I2C diff --git a/drivers/power/pmic/bd71837.c b/drivers/power/pmic/bd71837.c index e292d42a8c..2e04298273 100644 --- a/drivers/power/pmic/bd71837.c +++ b/drivers/power/pmic/bd71837.c @@ -3,8 +3,6 @@ * Copyright 2018 NXP */ -#define DEBUG - #include <common.h> #include <errno.h> #include <dm.h> diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index cff00820e4..75ccd65799 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -91,6 +91,13 @@ config RESET_ROCKCHIP though is that some reset signals, like I2C or MISC reset multiple devices. +config RESET_HSDK + bool "Synopsys HSDK Reset Driver" + depends on DM_RESET && TARGET_HSDK + default y + help + This enables the reset controller driver for HSDK board. + config RESET_MESON bool "Reset controller driver for Amlogic Meson SoCs" depends on DM_RESET && ARCH_MESON diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 8102d8db29..0a044d5d8c 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_STM32_RESET) += stm32-reset.o obj-$(CONFIG_TEGRA_CAR_RESET) += tegra-car-reset.o obj-$(CONFIG_TEGRA186_RESET) += tegra186-reset.o obj-$(CONFIG_RESET_TI_SCI) += reset-ti-sci.o +obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o obj-$(CONFIG_AST2500_RESET) += ast2500-reset.o diff --git a/drivers/reset/reset-hsdk.c b/drivers/reset/reset-hsdk.c new file mode 100644 index 0000000000..213d6c87be --- /dev/null +++ b/drivers/reset/reset-hsdk.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * HSDK SoC Reset Controller driver + * + * Copyright (C) 2019 Synopsys, Inc. All rights reserved. + * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> + */ + +#include <asm/io.h> +#include <common.h> +#include <dm.h> +#include <linux/iopoll.h> +#include <reset-uclass.h> + +struct hsdk_rst { + void __iomem *regs_ctl; + void __iomem *regs_rst; +}; + +static const u32 rst_map[] = { + BIT(16), /* APB_RST */ + BIT(17), /* AXI_RST */ + BIT(18), /* ETH_RST */ + BIT(19), /* USB_RST */ + BIT(20), /* SDIO_RST */ + BIT(21), /* HDMI_RST */ + BIT(22), /* GFX_RST */ + BIT(25), /* DMAC_RST */ + BIT(31), /* EBI_RST */ +}; + +#define HSDK_MAX_RESETS ARRAY_SIZE(rst_map) + +#define CGU_SYS_RST_CTRL 0x0 +#define CGU_IP_SW_RESET 0x0 +#define CGU_IP_SW_RESET_DELAY_SHIFT 16 +#define CGU_IP_SW_RESET_DELAY_MASK GENMASK(31, CGU_IP_SW_RESET_DELAY_SHIFT) +#define CGU_IP_SW_RESET_DELAY 0 +#define CGU_IP_SW_RESET_RESET BIT(0) +#define SW_RESET_TIMEOUT 10000 + +static void hsdk_reset_config(struct hsdk_rst *rst, unsigned long id) +{ + writel(rst_map[id], rst->regs_ctl + CGU_SYS_RST_CTRL); +} + +static int hsdk_reset_do(struct hsdk_rst *rst) +{ + u32 reg; + + reg = readl(rst->regs_rst + CGU_IP_SW_RESET); + reg &= ~CGU_IP_SW_RESET_DELAY_MASK; + reg |= CGU_IP_SW_RESET_DELAY << CGU_IP_SW_RESET_DELAY_SHIFT; + reg |= CGU_IP_SW_RESET_RESET; + writel(reg, rst->regs_rst + CGU_IP_SW_RESET); + + /* wait till reset bit is back to 0 */ + return readl_poll_timeout(rst->regs_rst + CGU_IP_SW_RESET, reg, + !(reg & CGU_IP_SW_RESET_RESET), SW_RESET_TIMEOUT); +} + +static int hsdk_reset_reset(struct reset_ctl *rst_ctl) +{ + struct udevice *dev = rst_ctl->dev; + struct hsdk_rst *rst = dev_get_priv(dev); + + if (rst_ctl->id >= HSDK_MAX_RESETS) + return -EINVAL; + + debug("%s(reset_ctl=%p) (dev=%p, id=%lu)\n", __func__, rst_ctl, + rst_ctl->dev, rst_ctl->id); + + hsdk_reset_config(rst, rst_ctl->id); + return hsdk_reset_do(rst); +} + +static int hsdk_reset_noop(struct reset_ctl *rst_ctl) +{ + return 0; +} + +static const struct reset_ops hsdk_reset_ops = { + .request = hsdk_reset_noop, + .free = hsdk_reset_noop, + .rst_assert = hsdk_reset_noop, + .rst_deassert = hsdk_reset_reset, +}; + +static const struct udevice_id hsdk_reset_dt_match[] = { + { .compatible = "snps,hsdk-reset" }, + { }, +}; + +static int hsdk_reset_probe(struct udevice *dev) +{ + struct hsdk_rst *rst = dev_get_priv(dev); + + rst->regs_ctl = dev_remap_addr_index(dev, 0); + if (!rst->regs_ctl) + return -EINVAL; + + rst->regs_rst = dev_remap_addr_index(dev, 1); + if (!rst->regs_rst) + return -EINVAL; + + return 0; +} + +U_BOOT_DRIVER(hsdk_reset) = { + .name = "hsdk-reset", + .id = UCLASS_RESET, + .of_match = hsdk_reset_dt_match, + .ops = &hsdk_reset_ops, + .probe = hsdk_reset_probe, + .priv_auto_alloc_size = sizeof(struct hsdk_rst), +}; diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c index 16473ec7a0..6b610ff823 100644 --- a/drivers/spi/sandbox_spi.c +++ b/drivers/spi/sandbox_spi.c @@ -122,11 +122,22 @@ static int sandbox_cs_info(struct udevice *bus, uint cs, return 0; } +static int sandbox_spi_get_mmap(struct udevice *dev, ulong *map_basep, + uint *map_sizep, uint *offsetp) +{ + *map_basep = 0x1000; + *map_sizep = 0x2000; + *offsetp = 0x100; + + return 0; +} + static const struct dm_spi_ops sandbox_spi_ops = { .xfer = sandbox_spi_xfer, .set_speed = sandbox_spi_set_speed, .set_mode = sandbox_spi_set_mode, .cs_info = sandbox_cs_info, + .get_mmap = sandbox_spi_get_mmap, }; static const struct udevice_id sandbox_spi_ids[] = { diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 947516073e..665611f7e2 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -92,6 +92,20 @@ int dm_spi_xfer(struct udevice *dev, unsigned int bitlen, return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags); } +int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep, + uint *offsetp) +{ + struct udevice *bus = dev->parent; + struct dm_spi_ops *ops = spi_get_ops(bus); + + if (bus->uclass->uc_drv->id != UCLASS_SPI) + return -EOPNOTSUPP; + if (!ops->get_mmap) + return -ENOSYS; + + return ops->get_mmap(dev, map_basep, map_sizep, offsetp); +} + int spi_claim_bus(struct spi_slave *slave) { return log_ret(dm_spi_claim_bus(slave->dev)); diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c index 919caba8a1..637c8ff25a 100644 --- a/drivers/timer/tsc_timer.c +++ b/drivers/timer/tsc_timer.c @@ -394,7 +394,7 @@ static int tsc_timer_get_count(struct udevice *dev, u64 *count) static void tsc_timer_ensure_setup(bool early) { - if (gd->arch.tsc_base) + if (gd->arch.tsc_inited) return; gd->arch.tsc_base = rdtsc(); @@ -425,6 +425,7 @@ static void tsc_timer_ensure_setup(bool early) done: gd->arch.clock_rate = fast_calibrate * 1000000; } + gd->arch.tsc_inited = true; } static int tsc_timer_probe(struct udevice *dev) @@ -461,6 +462,8 @@ unsigned long notrace timer_early_get_rate(void) u64 notrace timer_early_get_count(void) { + tsc_timer_ensure_setup(true); + return rdtsc() - gd->arch.tsc_base; } diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 6922a130c6..c52981053e 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -367,6 +367,7 @@ static int mxs_video_probe(struct udevice *dev) mmu_set_region_dcache_behaviour(fb_start, fb_end - fb_start, DCACHE_WRITEBACK); video_set_flush_dcache(dev, true); + gd->fb_base = plat->base; return ret; } diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c index 08764ee6f2..202e5ab1d3 100644 --- a/drivers/virtio/virtio_pci_legacy.c +++ b/drivers/virtio/virtio_pci_legacy.c @@ -277,7 +277,7 @@ static int virtio_pci_notify(struct udevice *udev, struct virtqueue *vq) static int virtio_pci_bind(struct udevice *udev) { - static int num_devs; + static unsigned int num_devs; char name[20]; /* Create a unique device name for PCI type devices */ diff --git a/drivers/watchdog/imx_watchdog.c b/drivers/watchdog/imx_watchdog.c index 53a3e9f5c7..c030360c21 100644 --- a/drivers/watchdog/imx_watchdog.c +++ b/drivers/watchdog/imx_watchdog.c @@ -15,15 +15,23 @@ #endif #include <fsl_wdog.h> -static void imx_watchdog_expire_now(struct watchdog_regs *wdog) +static void imx_watchdog_expire_now(struct watchdog_regs *wdog, bool ext_reset) { - clrsetbits_le16(&wdog->wcr, WCR_WT_MSK, WCR_WDE); + u16 wcr = WCR_WDE; + + if (ext_reset) + wcr |= WCR_SRS; /* do not assert internal reset */ + else + wcr |= WCR_WDA; /* do not assert external reset */ + + /* Write 3 times to ensure it works, due to IMX6Q errata ERR004346 */ + writew(wcr, &wdog->wcr); + writew(wcr, &wdog->wcr); + writew(wcr, &wdog->wcr); - writew(0x5555, &wdog->wsr); - writew(0xaaaa, &wdog->wsr); /* load minimum 1/2 second timeout */ while (1) { /* - * spin for .5 seconds before reset + * spin before reset */ } } @@ -34,7 +42,7 @@ void __attribute__((weak)) reset_cpu(ulong addr) { struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR; - imx_watchdog_expire_now(wdog); + imx_watchdog_expire_now(wdog, true); } #endif @@ -47,9 +55,10 @@ static void imx_watchdog_reset(struct watchdog_regs *wdog) #endif /* CONFIG_WATCHDOG_RESET_DISABLE*/ } -static void imx_watchdog_init(struct watchdog_regs *wdog) +static void imx_watchdog_init(struct watchdog_regs *wdog, bool ext_reset) { u16 timeout; + u16 wcr; /* * The timer watchdog can be set between @@ -61,11 +70,14 @@ static void imx_watchdog_init(struct watchdog_regs *wdog) #endif timeout = (CONFIG_WATCHDOG_TIMEOUT_MSECS / 500) - 1; #ifdef CONFIG_FSL_LSCH2 - writew((WCR_WDA | WCR_SRS | WCR_WDE) << 8 | timeout, &wdog->wcr); + wcr = (WCR_WDA | WCR_SRS | WCR_WDE) << 8 | timeout; #else - writew(WCR_WDZST | WCR_WDBG | WCR_WDE | WCR_WDT | WCR_SRS | - WCR_WDA | SET_WCR_WT(timeout), &wdog->wcr); + wcr = WCR_WDZST | WCR_WDBG | WCR_WDE | WCR_SRS | + WCR_WDA | SET_WCR_WT(timeout); + if (ext_reset) + wcr |= WCR_WDT; #endif /* CONFIG_FSL_LSCH2*/ + writew(wcr, &wdog->wcr); imx_watchdog_reset(wdog); } @@ -81,11 +93,12 @@ void hw_watchdog_init(void) { struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR; - imx_watchdog_init(wdog); + imx_watchdog_init(wdog, true); } #else struct imx_wdt_priv { void __iomem *base; + bool ext_reset; }; static int imx_wdt_reset(struct udevice *dev) @@ -101,7 +114,7 @@ static int imx_wdt_expire_now(struct udevice *dev, ulong flags) { struct imx_wdt_priv *priv = dev_get_priv(dev); - imx_watchdog_expire_now(priv->base); + imx_watchdog_expire_now(priv->base, priv->ext_reset); hang(); return 0; @@ -111,7 +124,7 @@ static int imx_wdt_start(struct udevice *dev, u64 timeout, ulong flags) { struct imx_wdt_priv *priv = dev_get_priv(dev); - imx_watchdog_init(priv->base); + imx_watchdog_init(priv->base, priv->ext_reset); return 0; } @@ -124,6 +137,8 @@ static int imx_wdt_probe(struct udevice *dev) if (!priv->base) return -ENOENT; + priv->ext_reset = dev_read_bool(dev, "fsl,ext-reset-output"); + return 0; } diff --git a/dts/Kconfig b/dts/Kconfig index c9ab66cccc..2bd959a7dc 100644 --- a/dts/Kconfig +++ b/dts/Kconfig @@ -44,7 +44,7 @@ config SPL_OF_CONTROL depends on SPL && OF_CONTROL help Some boards use device tree in U-Boot but only have 4KB of SRAM - which is not enough to support device tree. Enable this option to + which is not enough to support device tree. Disable this option to allow such boards to be supported by U-Boot SPL. config TPL_OF_CONTROL @@ -131,7 +131,7 @@ config OF_LIST separated by <space>. choice - prompt "SPL OF LIST compression" + prompt "OF LIST compression" depends on MULTI_DTB_FIT default MULTI_DTB_FIT_NO_COMPRESSION diff --git a/include/bootstage.h b/include/bootstage.h index 5e7e242b83..d105ae0181 100644 --- a/include/bootstage.h +++ b/include/bootstage.h @@ -170,6 +170,8 @@ enum bootstage_id { * rough boot timing information. */ BOOTSTAGE_ID_AWAKE, + BOOTSTAGE_ID_START_TPL, + BOOTSTAGE_ID_END_TPL, BOOTSTAGE_ID_START_SPL, BOOTSTAGE_ID_END_SPL, BOOTSTAGE_ID_START_UBOOT_F, diff --git a/include/cbfs.h b/include/cbfs.h index 6d4c4d4b06..f3bc8ca24a 100644 --- a/include/cbfs.h +++ b/include/cbfs.h @@ -72,13 +72,13 @@ struct cbfs_fileheader { struct cbfs_cachenode { struct cbfs_cachenode *next; - u32 type; void *data; - u32 data_length; char *name; + u32 type; + u32 data_length; u32 name_length; u32 attributes_offset; -} __packed; +}; extern enum cbfs_result file_cbfs_result; diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index 3570a32dff..fc0935fa21 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -189,6 +189,7 @@ "fi\0" \ \ "nvme_boot=" \ + BOOTENV_RUN_PCI_ENUM \ BOOTENV_RUN_NVME_INIT \ BOOTENV_SHARED_BLKDEV_BODY(nvme) #define BOOTENV_DEV_NVME BOOTENV_DEV_BLKDEV diff --git a/include/configs/brppt2.h b/include/configs/brppt2.h new file mode 100644 index 0000000000..d369315090 --- /dev/null +++ b/include/configs/brppt2.h @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Config file for BuR BRPP2_IMX6 board + * + * Copyright (C) 2018 + * B&R Industrial Automation GmbH - http://www.br-automation.com/ + */ +#ifndef __CONFIG_BRPP2_IMX6_H +#define __CONFIG_BRPP2_IMX6_H + +#include <configs/bur_cfg_common.h> +#include <asm/arch/imx-regs.h> + +/* -- i.mx6 specifica -- */ +#ifndef CONFIG_SYS_L2CACHE_OFF +#define CONFIG_SYS_L2_PL310 +#define CONFIG_SYS_PL310_BASE L2_PL310_BASE +#endif /* !CONFIG_SYS_L2CACHE_OFF */ + +#define CONFIG_BOARD_POSTCLK_INIT +#define CONFIG_MXC_GPT_HCLK + +#define CONFIG_LOADADDR 0x10700000 +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR + +/* MMC */ +#define CONFIG_FSL_USDHC + +/* Boot */ +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_INITRD_TAG +#define CONFIG_MACH_TYPE 0xFFFFFFFF + +/* misc */ +#define CONFIG_SYS_MALLOC_LEN (10 * 1024 * 1024) + +/* Environment */ +#define CONFIG_ENV_OVERWRITE +#define CONFIG_ENV_SECT_SIZE 0x10000 +#define CONFIG_ENV_SIZE 0x10000 +#define CONFIG_ENV_OFFSET 0x20000 + +#define CONFIG_EXTRA_ENV_SETTINGS \ +BUR_COMMON_ENV \ +"autoload=0\0" \ +"cfgaddr=0x106F0000\0" \ +"scraddr=0x10700000\0" \ +"loadaddr=0x10800000\0" \ +"dtbaddr=0x12000000\0" \ +"ramaddr=0x12100000\0" \ +"cfgscr=mw ${loadaddr} 0 128\0" \ +"cfgscrl=fdt addr ${dtbaddr} &&"\ +" sf probe; sf read ${cfgaddr} 0x40000 0x10000 && source ${cfgaddr}\0" \ +"console=ttymxc0,115200n8 consoleblank=0 quiet\0" \ +"t50args#0=setenv bootargs b_mode=${b_mode} console=${console} " \ + " root=/dev/mmcblk0p2 rootfstype=ext4 rootwait panic=2 \0" \ +"b_t50lgcy#0=" \ + "load ${loaddev}:2 ${loadaddr} /boot/zImage && " \ + "load ${loaddev}:2 ${dtbaddr} /boot/imx6dl-brppt50.dtb; " \ + "run t50args#0; run cfgscrl; bootz ${loadaddr} - ${dtbaddr}\0" \ +"t50args#1=setenv bootargs console=${console} b_mode=${b_mode}" \ + " rootwait panic=2\0" \ +"b_t50lgcy#1=" \ + "load ${loaddev}:1 ${loadaddr} zImage && " \ + "load ${loaddev}:1 ${dtbaddr} imx6dl-brppt50.dtb && " \ + "load ${loaddev}:1 ${ramaddr} rootfsPPT50.uboot && " \ + "run t50args#1; run cfgscrl; bootz ${loadaddr} ${ramaddr} ${dtbaddr}\0"\ +"b_mmc0=load ${loaddev}:1 ${scraddr} bootscr.img && source ${scraddr}\0" \ +"b_mmc1=load ${loaddev}:1 ${scraddr} /boot/bootscr.img && source ${scraddr}\0" \ +"b_usb0=usb start && load usb 0 ${scraddr} bootscr.img && source ${scraddr}\0" \ +"b_net=tftp ${scraddr} netscript.img && source ${scraddr}\0" \ +"b_tgts_std=mmc0 mmc1 t50lgcy#0 t50lgcy#1 usb0 net\0" \ +"b_tgts_rcy=t50lgcy#1 usb0 net\0" \ +"b_tgts_pme=net usb0 mmc0 mmc1\0" \ +"b_mode=4\0" \ +"b_break=0\0" \ +"b_deftgts=if test ${b_mode} = 12; then setenv b_tgts ${b_tgts_pme};" \ +" elif test ${b_mode} = 0; then setenv b_tgts ${b_tgts_rcy};" \ +" else setenv b_tgts ${b_tgts_std}; fi\0" \ +"b_default=run b_deftgts; for target in ${b_tgts};"\ +" do echo \"### booting ${target} ###\"; run b_${target};" \ +" if test ${b_break} = 1; then; exit; fi; done\0" \ +"loaddev=mmc 0\0" \ +"altbootcmd=setenv b_mode 0; run b_default;\0" \ +"bootlimit=1\0" \ +"net2nor=sf probe && dhcp &&" \ +" tftp ${loadaddr} SPL && sf erase 0 +${filesize} &&" \ +" sf write ${loadaddr} 400 ${filesize} &&" \ +" tftp ${loadaddr} u-boot-dtb.img && sf erase 0x100000 +${filesize} &&" \ +" sf write ${loadaddr} 0x100000 ${filesize}\0" + +/* RAM */ +#define PHYS_SDRAM_1 MMDC0_ARB_BASE_ADDR +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 +#define CONFIG_SYS_MEMTEST_START 0x10000000 +#define CONFIG_SYS_MEMTEST_END 0x10010000 +#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR +#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE +#define CONFIG_SYS_INIT_SP_OFFSET \ + (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_ADDR \ + (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET) + +/* Ethernet */ +#define CONFIG_MII +#define CONFIG_FEC_XCV_TYPE RGMII +#define CONFIG_FEC_FIXED_SPEED _1000BASET +#define CONFIG_ARP_TIMEOUT 1500UL + +/* USB Configs */ +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET +#define CONFIG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW) + +/* SPL */ +#ifdef CONFIG_SPL +#include "imx6_spl.h" + +#endif /* CONFIG_SPL */ +#endif /* __CONFIG_BRPP2_IMX6_H */ diff --git a/include/configs/imx8mq_evk.h b/include/configs/imx8mq_evk.h index d4d8d20850..84fae34777 100644 --- a/include/configs/imx8mq_evk.h +++ b/include/configs/imx8mq_evk.h @@ -107,7 +107,7 @@ "fdt_addr=0x43000000\0" \ "fdt_high=0xffffffffffffffff\0" \ "boot_fdt=try\0" \ - "fdt_file=fsl-imx8mq-evk.dtb\0" \ + "fdt_file=imx8mq-evk.dtb\0" \ "initrd_addr=0x43800000\0" \ "initrd_high=0xffffffffffffffff\0" \ "mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \ diff --git a/include/configs/imx8qm_mek.h b/include/configs/imx8qm_mek.h index 2b8f85ded1..37ef595e4e 100644 --- a/include/configs/imx8qm_mek.h +++ b/include/configs/imx8qm_mek.h @@ -54,8 +54,15 @@ #define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +#ifdef CONFIG_AHAB_BOOT +#define AHAB_ENV "sec_boot=yes\0" +#else +#define AHAB_ENV "sec_boot=no\0" +#endif + /* Initial environment variables */ #define CONFIG_EXTRA_ENV_SETTINGS \ + AHAB_ENV \ "script=boot.scr\0" \ "image=Image\0" \ "panel=NULL\0" \ @@ -76,16 +83,27 @@ "source\0" \ "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \ "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \ + "boot_os=booti ${loadaddr} - ${fdt_addr};\0" \ + "loadcntr=fatload mmc ${mmcdev}:${mmcpart} ${cntr_addr} ${cntr_file}\0" \ + "auth_os=auth_cntr ${cntr_addr}\0" \ "mmcboot=echo Booting from mmc ...; " \ "run mmcargs; " \ - "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ - "if run loadfdt; then " \ - "booti ${loadaddr} - ${fdt_addr}; " \ + "if test ${sec_boot} = yes; then " \ + "if run auth_os; then " \ + "run boot_os; " \ "else " \ - "echo WARN: Cannot load the DT; " \ + "echo ERR: failed to authenticate; " \ "fi; " \ "else " \ - "echo wait for boot; " \ + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ + "if run loadfdt; then " \ + "run boot_os; " \ + "else " \ + "echo WARN: Cannot load the DT; " \ + "fi; " \ + "else " \ + "echo wait for boot; " \ + "fi;" \ "fi;\0" \ "netargs=setenv bootargs console=${console} " \ "root=/dev/nfs " \ @@ -97,15 +115,24 @@ "else " \ "setenv get_cmd tftp; " \ "fi; " \ - "${get_cmd} ${loadaddr} ${image}; " \ - "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ - "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \ - "booti ${loadaddr} - ${fdt_addr}; " \ + "if test ${sec_boot} = yes; then " \ + "${get_cmd} ${cntr_addr} ${cntr_file}; " \ + "if run auth_os; then " \ + "run boot_os; " \ "else " \ - "echo WARN: Cannot load the DT; " \ + "echo ERR: failed to authenticate; " \ "fi; " \ "else " \ - "booti; " \ + "${get_cmd} ${loadaddr} ${image}; " \ + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ + "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \ + "booti ${loadaddr} - ${fdt_addr}; " \ + "else " \ + "echo WARN: Cannot load the DT; " \ + "fi; " \ + "else " \ + "booti; " \ + "fi;" \ "fi;\0" #define CONFIG_BOOTCOMMAND \ @@ -113,10 +140,17 @@ "if run loadbootscript; then " \ "run bootscript; " \ "else " \ - "if run loadimage; then " \ - "run mmcboot; " \ - "else run netboot; " \ - "fi; " \ + "if test ${sec_boot} = yes; then " \ + "if run loadcntr; then " \ + "run mmcboot; " \ + "else run netboot; " \ + "fi; " \ + "else " \ + "if run loadimage; then " \ + "run mmcboot; " \ + "else run netboot; " \ + "fi; " \ + "fi; " \ "fi; " \ "else booti ${loadaddr} - ${fdt_addr}; fi" diff --git a/include/configs/imx8qm_rom7720.h b/include/configs/imx8qm_rom7720.h new file mode 100644 index 0000000000..fb31dc4627 --- /dev/null +++ b/include/configs/imx8qm_rom7720.h @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2017-2018 NXP + */ + +#ifndef __IMX8QM_ROM7720_H +#define __IMX8QM_ROM7720_H + +#include <linux/sizes.h> +#include <asm/arch/imx-regs.h> +#define CONFIG_REMAKE_ELF + +#define CONFIG_SPL_MAX_SIZE (124 * 1024) +#define CONFIG_SPL_BSS_START_ADDR 0x00128000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x1000 /* 4 KB */ + +#undef CONFIG_BOOTM_NETBSD + +#define CONFIG_FSL_USDHC +#define CONFIG_SYS_FSL_ESDHC_ADDR 0 +#define CONFIG_SUPPORT_EMMC_BOOT /* eMMC specific */ + +#define CONFIG_ENV_OVERWRITE + +#define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +/* FUSE command */ +#define CONFIG_CMD_FUSE + +/* Boot M4 */ +#define M4_BOOT_ENV \ + "m4_0_image=m4_0.bin\0" \ + "m4_1_image=m4_1.bin\0" \ + "loadm4image_0=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${m4_0_image}\0" \ + "loadm4image_1=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${m4_1_image}\0" \ + "m4boot_0=run loadm4image_0; dcache flush; bootaux ${loadaddr} 0\0" \ + "m4boot_1=run loadm4image_1; dcache flush; bootaux ${loadaddr} 1\0" \ + +#ifdef CONFIG_NAND_BOOT +#define MFG_NAND_PARTITION "mtdparts=gpmi-nand:128m(boot),32m(kernel),16m(dtb),8m(misc),-(rootfs) " +#else +#define MFG_NAND_PARTITION "" +#endif + +#define CONFIG_MFG_ENV_SETTINGS \ + "mfgtool_args=setenv bootargs console=${console},${baudrate} " \ + "rdinit=/linuxrc " \ + "g_mass_storage.stall=0 g_mass_storage.removable=1 " \ + "g_mass_storage.idVendor=0x066F g_mass_storage.idProduct=0x37FF "\ + "g_mass_storage.iSerialNumber=\"\" "\ + MFG_NAND_PARTITION \ + "clk_ignore_unused "\ + "\0" \ + "initrd_addr=0x83800000\0" \ + "initrd_high=0xffffffffffffffff\0" \ + "bootcmd_mfg=run mfgtool_args;booti ${loadaddr} ${initrd_addr} ${fdt_addr};\0" \ + +/* Initial environment variables */ +#define CONFIG_EXTRA_ENV_SETTINGS \ + CONFIG_MFG_ENV_SETTINGS \ + M4_BOOT_ENV \ + "script=boot.scr\0" \ + "image=Image\0" \ + "panel=NULL\0" \ + "console=ttyLP0\0" \ + "fdt_addr=0x83000000\0" \ + "fdt_high=0xffffffffffffffff\0" \ + "boot_fdt=try\0" \ + "fdt_file=imx8qm-rom7720-a1.dtb\0" \ + "initrd_addr=0x83800000\0" \ + "initrd_high=0xffffffffffffffff\0" \ + "mmcdev="__stringify(CONFIG_SYS_MMC_ENV_DEV)"\0" \ + "mmcpart=" __stringify(CONFIG_SYS_MMC_IMG_LOAD_PART) "\0" \ + "mmcroot=" CONFIG_MMCROOT " rootwait rw\0" \ + "mmcautodetect=yes\0" \ + "mmcargs=setenv bootargs console=${console},${baudrate} root=${mmcroot} earlycon\0 " \ + "loadbootscript=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \ + "bootscript=echo Running bootscript from mmc ...; " \ + "source\0" \ + "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \ + "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \ + "mmcboot=echo Booting from mmc ...; " \ + "run mmcargs; " \ + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ + "if run loadfdt; then " \ + "booti ${loadaddr} - ${fdt_addr}; " \ + "else " \ + "echo WARN: Cannot load the DT; " \ + "fi; " \ + "else " \ + "echo wait for boot; " \ + "fi;\0" \ + "netargs=setenv bootargs console=${console},${baudrate} " \ + "root=/dev/nfs " \ + "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp rw earlycon\0" \ + "netboot=echo Booting from net ...; " \ + "run netargs; " \ + "if test ${ip_dyn} = yes; then " \ + "setenv get_cmd dhcp; " \ + "else " \ + "setenv get_cmd tftp; " \ + "fi; " \ + "${get_cmd} ${loadaddr} ${image}; " \ + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ + "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \ + "booti ${loadaddr} - ${fdt_addr}; " \ + "else " \ + "echo WARN: Cannot load the DT; " \ + "fi; " \ + "else " \ + "booti; " \ + "fi;\0" + +#define CONFIG_BOOTCOMMAND \ + "mmc dev ${mmcdev}; if mmc rescan; then " \ + "if run loadbootscript; then " \ + "run bootscript; " \ + "else " \ + "if run loadimage; then " \ + "run mmcboot; " \ + "else run netboot; " \ + "fi; " \ + "fi; " \ + "else booti ${loadaddr} - ${fdt_addr}; fi" + +/* Link Definitions */ +#define CONFIG_LOADADDR 0x80280000 + +#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR + +#define CONFIG_SYS_INIT_SP_ADDR 0x80200000 + +/* Default environment is in SD */ +#define CONFIG_ENV_SIZE 0x2000 + +#ifdef CONFIG_QSPI_BOOT +#define CONFIG_ENV_OFFSET (4 * 1024 * 1024) +#define CONFIG_ENV_SECT_SIZE (128 * 1024) +#define CONFIG_ENV_SPI_BUS CONFIG_SF_DEFAULT_BUS +#define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS +#define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE +#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED +#else +#define CONFIG_ENV_OFFSET (64 * SZ_64K) +#define CONFIG_SYS_MMC_ENV_PART 0 /* user area */ +#endif + +#define CONFIG_SYS_MMC_IMG_LOAD_PART 1 + +/* On LPDDR4 board, USDHC1 is for eMMC, USDHC2 is for SD on CPU board, + * USDHC3 is for SD on base board On DDR4 board, USDHC1 is mux for NAND, + * USDHC2 is for SD, USDHC3 is for SD on base board + */ +#define CONFIG_SYS_MMC_ENV_DEV 2 /* USDHC3 */ +#define CONFIG_MMCROOT "/dev/mmcblk2p2" /* USDHC3 */ +#define CONFIG_SYS_FSL_USDHC_NUM 3 + +/* Size of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN ((CONFIG_ENV_SIZE + (32 * 1024)) * 1024) + +#define CONFIG_SYS_SDRAM_BASE 0x80000000 +#define PHYS_SDRAM_1 0x80000000 +#define PHYS_SDRAM_2 0x880000000 +#define PHYS_SDRAM_1_SIZE 0x80000000 /* 2 GB */ +/* LPDDR4 board total DDR is 6GB, DDR4 board total DDR is 4 GB */ +#define PHYS_SDRAM_2_SIZE 0x80000000 /* 2 GB */ + +#define CONFIG_SYS_MEMTEST_START 0xA0000000 +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + (PHYS_SDRAM_1_SIZE >> 2)) + +/* Serial */ +#define CONFIG_BAUDRATE 115200 + +/* Generic Timer Definitions */ +#define COUNTER_FREQUENCY 8000000 /* 8MHz */ + +/* Networking */ +#define CONFIG_FEC_XCV_TYPE RGMII +#define FEC_QUIRK_ENET_MAC + +#endif /* __IMX8QM_ROM7720_H */ diff --git a/include/configs/imx8qxp_mek.h b/include/configs/imx8qxp_mek.h index 872805cae6..59f88bd203 100644 --- a/include/configs/imx8qxp_mek.h +++ b/include/configs/imx8qxp_mek.h @@ -53,8 +53,15 @@ #define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG +#ifdef CONFIG_AHAB_BOOT +#define AHAB_ENV "sec_boot=yes\0" +#else +#define AHAB_ENV "sec_boot=no\0" +#endif + /* Initial environment variables */ #define CONFIG_EXTRA_ENV_SETTINGS \ + AHAB_ENV \ "script=boot.scr\0" \ "image=Image\0" \ "panel=NULL\0" \ @@ -75,16 +82,27 @@ "source\0" \ "loadimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${image}\0" \ "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \ + "loadcntr=fatload mmc ${mmcdev}:${mmcpart} ${cntr_addr} ${cntr_file}\0" \ + "auth_os=auth_cntr ${cntr_addr}\0" \ + "boot_os=booti ${loadaddr} - ${fdt_addr};\0" \ "mmcboot=echo Booting from mmc ...; " \ "run mmcargs; " \ - "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ - "if run loadfdt; then " \ - "booti ${loadaddr} - ${fdt_addr}; " \ + "if test ${sec_boot} = yes; then " \ + "if run auth_os; then " \ + "run boot_os; " \ "else " \ - "echo WARN: Cannot load the DT; " \ + "echo ERR: failed to authenticate; " \ "fi; " \ "else " \ - "echo wait for boot; " \ + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ + "if run loadfdt; then " \ + "run boot_os; " \ + "else " \ + "echo WARN: Cannot load the DT; " \ + "fi; " \ + "else " \ + "echo wait for boot; " \ + "fi;" \ "fi;\0" \ "netargs=setenv bootargs console=${console} " \ "root=/dev/nfs " \ @@ -96,15 +114,24 @@ "else " \ "setenv get_cmd tftp; " \ "fi; " \ - "${get_cmd} ${loadaddr} ${image}; " \ - "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ - "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \ - "booti ${loadaddr} - ${fdt_addr}; " \ + "if test ${sec_boot} = yes; then " \ + "${get_cmd} ${cntr_addr} ${cntr_file}; " \ + "if run auth_os; then " \ + "run boot_os; " \ "else " \ - "echo WARN: Cannot load the DT; " \ + "echo ERR: failed to authenticate; " \ "fi; " \ "else " \ - "booti; " \ + "${get_cmd} ${loadaddr} ${image}; " \ + "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \ + "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \ + "run boot_os; " \ + "else " \ + "echo WARN: Cannot load the DT; " \ + "fi; " \ + "else " \ + "booti; " \ + "fi;" \ "fi;\0" #define CONFIG_BOOTCOMMAND \ @@ -112,10 +139,17 @@ "if run loadbootscript; then " \ "run bootscript; " \ "else " \ - "if run loadimage; then " \ - "run mmcboot; " \ - "else run netboot; " \ - "fi; " \ + "if test ${sec_boot} = yes; then " \ + "if run loadcntr; then " \ + "run mmcboot; " \ + "else run netboot; " \ + "fi; " \ + "else " \ + "if run loadimage; then " \ + "run mmcboot; " \ + "else run netboot; " \ + "fi; " \ + "fi; " \ "fi; " \ "else booti ${loadaddr} - ${fdt_addr}; fi" diff --git a/include/configs/mccmon6.h b/include/configs/mccmon6.h index 667dac7340..c685de6551 100644 --- a/include/configs/mccmon6.h +++ b/include/configs/mccmon6.h @@ -14,10 +14,6 @@ #define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_UBOOT_BASE (CONFIG_SYS_FLASH_BASE + 0x80000) -#define CONFIG_SPL_OS_BOOT -#define CONFIG_SYS_OS_BASE (CONFIG_SYS_FLASH_BASE + 0x180000) -#define CONFIG_SYS_FDT_BASE (CONFIG_SYS_FLASH_BASE + 0x1980000) -#define CONFIG_SYS_FDT_SIZE (48 * SZ_1K) #define CONFIG_SYS_SPL_ARGS_ADDR 0x18000000 /* @@ -28,28 +24,17 @@ #define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR (0x800) #define CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS (0x80) #define CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR (0x1000) -#define CONFIG_SPL_FS_LOAD_KERNEL_NAME "uImage" -#define CONFIG_SPL_FS_LOAD_ARGS_NAME "imx6q-mccmon.dtb" +#define CONFIG_SPL_FS_LOAD_KERNEL_NAME "fitImage" /* Size of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (10 * SZ_1M) -#define CONFIG_BOARD_EARLY_INIT_F #define CONFIG_BOARD_LATE_INIT - -#define CONFIG_MXC_UART #define CONFIG_MXC_UART_BASE UART1_BASE #define CONFIG_SYS_MEMTEST_START 0x10000000 #define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 500 * SZ_1M) -/* I2C Configs */ -#define CONFIG_SYS_I2C -#define CONFIG_SYS_I2C_MXC -#define CONFIG_SYS_I2C_MXC_I2C1 /* enable I2C bus 1 */ -#define CONFIG_SYS_I2C_MXC_I2C2 /* enable I2C bus 2 */ -#define CONFIG_SYS_I2C_SPEED 100000 - /* MMC Configuration */ #define CONFIG_SYS_FSL_USDHC_NUM 2 #define CONFIG_SYS_FSL_ESDHC_ADDR 0 @@ -66,22 +51,18 @@ #define CONFIG_SYS_FLASH_BANKS_SIZES { (32 * SZ_1M) } /* Ethernet Configuration */ -#define CONFIG_FEC_MXC #define IMX_FEC_BASE ENET_BASE_ADDR -#define CONFIG_FEC_XCV_TYPE RGMII -#define CONFIG_ETHPRIME "FEC" #define CONFIG_FEC_MXC_PHYADDR 1 #define CONFIG_EXTRA_ENV_SETTINGS \ "console=ttymxc0,115200 quiet\0" \ - "fdtfile=imx6q-mccmon6.dtb\0" \ "fdt_high=0xffffffff\0" \ "initrd_high=0xffffffff\0" \ "boot_os=yes\0" \ + "kernelsize=0x300000\0" \ "disable_giga=yes\0" \ "download_kernel=" \ - "tftpboot ${kernel_addr} ${kernel_file};" \ - "tftpboot ${fdt_addr} ${fdtfile};\0" \ + "tftpboot ${loadaddr} ${kernel_file};\0" \ "get_boot_medium=" \ "setenv boot_medium nor;" \ "setexpr.l _src_sbmr1 *0x020d8004;" \ @@ -89,10 +70,7 @@ "if test ${_b_medium} = 40; then " \ "setenv boot_medium sdcard;" \ "fi\0" \ - "kernel_file=uImage\0" \ - "load_kernel=" \ - "load mmc ${bootdev}:${bootpart} ${kernel_addr} uImage;" \ - "load mmc ${bootdev}:${bootpart} ${fdt_addr} ${fdtfile};\0" \ + "kernel_file=fitImage\0" \ "boot_sd=" \ "echo '#######################';" \ "echo '# Factory SDcard Boot #';" \ @@ -103,12 +81,11 @@ "run factory_flash_img;\0" \ "boot_nor=" \ "setenv kernelnor 0x08180000;" \ - "setenv dtbnor 0x09980000;" \ "setenv bootargs console=${console} " \ CONFIG_MTDPARTS_DEFAULT " " \ "root=/dev/mmcblk1 rootfstype=ext4 rw rootwait noinitrd;" \ - "cp.l ${dtbnor} ${dtbloadaddr} 0x8000;" \ - "bootm ${kernelnor} - ${dtbloadaddr};\0" \ + "cp.l ${kernelnor} ${loadaddr} ${kernelsize};" \ + "bootm ${loadaddr};reset;\0" \ "boot_recovery=" \ "echo '#######################';" \ "echo '# RECOVERY SWU Boot #';" \ @@ -116,14 +93,13 @@ "setenv rootfsloadaddr 0x13000000;" \ "setenv swukernelnor 0x08980000;" \ "setenv swurootfsnor 0x09180000;" \ - "setenv swudtbnor 0x099A0000;" \ "setenv bootargs console=${console} " \ CONFIG_MTDPARTS_DEFAULT " " \ "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}" \ ":${hostname}::off root=/dev/ram rw;" \ "cp.l ${swurootfsnor} ${rootfsloadaddr} 0x200000;" \ - "cp.l ${swudtbnor} ${dtbloadaddr} 0x8000;" \ - "bootm ${swukernelnor} ${rootfsloadaddr} ${dtbloadaddr};\0" \ + "cp.l ${swukernelnor} ${loadaddr} ${kernelsize};" \ + "bootm ${loadaddr} ${rootfsloadaddr};reset;\0" \ "boot_tftp=" \ "echo '#######################';" \ "echo '# TFTP Boot #';" \ @@ -131,7 +107,7 @@ "if run download_kernel; then " \ "setenv bootargs console=${console} " \ "root=/dev/mmcblk0p2 rootwait;" \ - "bootm ${kernel_addr} - ${fdt_addr};" \ + "bootm $loadaddr};reset;" \ "fi\0" \ "bootcmd=" \ "if test -n ${recovery_status}; then " \ @@ -151,13 +127,10 @@ "fi;" \ "fi\0" \ "mtdparts=" CONFIG_MTDPARTS_DEFAULT "\0" \ - "fdt_addr=0x18000000\0" \ "bootdev=1\0" \ "bootpart=1\0" \ - "kernel_addr=" __stringify(CONFIG_LOADADDR) "\0" \ "netdev=eth0\0" \ "load_addr=0x11000000\0" \ - "dtbloadaddr=0x12000000\0" \ "uboot_file=u-boot.img\0" \ "SPL_file=SPL\0" \ "load_uboot=tftp ${load_addr} ${uboot_file}\0" \ @@ -184,6 +157,7 @@ "device ${mmcdev};" \ "run factory_nor_img;" \ "run factory_eMMC_img;" \ + "run factory_SPL_falcon_setup;" \ "fi\0" \ "factory_eMMC_img="\ "echo 'Update mccmon6 eMMC image'; " \ @@ -205,6 +179,16 @@ "erase ${nor_bank_start} +${nor_img_size};" \ "setexpr nor_img_size ${nor_img_size} / 4; " \ "cp.l ${nor_img_addr} ${nor_bank_start} ${nor_img_size}\0" \ + "factory_SPL_falcon_setup="\ + "echo 'Write Falcon boot data'; " \ + "setenv kernelnor 0x08180000;" \ + "cp.l ${kernelnor} ${loadaddr} ${kernelsize};" \ + "spl export fdt ${loadaddr};" \ + "setenv nor_img_addr ${fdtargsaddr};" \ + "setenv nor_img_size 0x20000;" \ + "setenv nor_bank_start " \ + __stringify(CONFIG_CMD_SPL_NOR_OFS)";" \ + "run nor_update\0" \ "tftp_nor_uboot="\ "echo 'Update mccmon6 NOR U-BOOT via TFTP'; " \ "setenv nor_img_file u-boot.img; " \ @@ -213,22 +197,14 @@ "if tftpboot ${nor_img_addr} ${nor_img_file}; then " \ "run nor_update;" \ "fi\0" \ - "tftp_nor_uImg="\ - "echo 'Update mccmon6 NOR uImage via TFTP'; " \ - "setenv nor_img_file uImage; " \ + "tftp_nor_fitImg="\ + "echo 'Update mccmon6 NOR fitImage via TFTP'; " \ + "setenv nor_img_file fitImage; " \ "setenv nor_img_size 0x500000; " \ "setenv nor_bank_start 0x08180000; " \ "if tftpboot ${nor_img_addr} ${nor_img_file}; then " \ "run nor_update;" \ "fi\0" \ - "tftp_nor_dtb="\ - "echo 'Update mccmon6 NOR DTB via TFTP'; " \ - "setenv nor_img_file imx6q-mccmon6.dtb; " \ - "setenv nor_img_size 0x20000; " \ - "setenv nor_bank_start 0x09980000; " \ - "if tftpboot ${nor_img_addr} ${nor_img_file}; then " \ - "run nor_update;" \ - "fi\0" \ "tftp_nor_img="\ "echo 'Update mccmon6 NOR image via TFTP'; " \ "if tftpboot ${nor_img_addr} ${nor_img_file}; then " \ diff --git a/include/configs/opos6uldev.h b/include/configs/opos6uldev.h index 309b4717c4..f80e34729a 100644 --- a/include/configs/opos6uldev.h +++ b/include/configs/opos6uldev.h @@ -41,17 +41,9 @@ #define CONFIG_USB_MAX_CONTROLLER_COUNT 2 #endif -/* Ethernet */ -#ifdef CONFIG_FEC_MXC -#define IMX_FEC_BASE ENET_BASE_ADDR -#define CONFIG_FEC_MXC_PHYADDR 0x1 -#define CONFIG_FEC_XCV_TYPE RMII -#define CONFIG_ETHPRIME "FEC" -#endif - /* LCD */ #ifndef CONFIG_SPL_BUILD -#ifdef CONFIG_VIDEO +#ifdef CONFIG_DM_VIDEO #define CONFIG_VIDEO_LOGO #define CONFIG_SPLASH_SCREEN #define CONFIG_SPLASH_SCREEN_ALIGN @@ -59,6 +51,8 @@ #define CONFIG_VIDEO_BMP_RLE8 #define CONFIG_VIDEO_BMP_LOGO #define CONFIG_BMP_16BPP +#define CONFIG_BMP_24BPP +#define CONFIG_BMP_32BPP #define CONFIG_VIDEO_MXS #define MXS_LCDIF_BASE MX6UL_LCDIF1_BASE_ADDR #endif @@ -95,6 +89,8 @@ "mmcroot=/dev/mmcblk0p2 ro\0" \ "mmcrootfstype=ext4 rootwait\0" \ "kernelimg=" __stringify(CONFIG_BOARD_NAME) "-linux.bin\0" \ + "splashpos=0,0\0" \ + "splashimage=" __stringify(CONFIG_LOADADDR) "\0" \ "videomode=video=ctfb:x:800,y:480,depth:18,pclk:33033,le:96,ri:96,up:20,lo:21,hs:64,vs:4,sync:0,vmode:0\0" \ "check_env=if test -n ${flash_env_version}; " \ "then env default env_version; " \ diff --git a/include/cpsw.h b/include/cpsw.h index 96ff254f98..786f8b385b 100644 --- a/include/cpsw.h +++ b/include/cpsw.h @@ -16,6 +16,8 @@ #ifndef _CPSW_H_ #define _CPSW_H_ +#include <dm/ofnode.h> + /* reg offset */ #define CPSW_HOST_PORT_OFFSET 0x108 #define CPSW_SLAVE0_OFFSET 0x208 @@ -38,7 +40,8 @@ struct cpsw_slave_data { u32 sliver_reg_ofs; int phy_addr; int phy_if; - int phy_of_handle; + ofnode phy_of_handle; + int max_speed; }; enum { diff --git a/include/dt-bindings/clock/imx8mq-clock.h b/include/dt-bindings/clock/imx8mq-clock.h index 11dcafcfde..65463673d2 100644 --- a/include/dt-bindings/clock/imx8mq-clock.h +++ b/include/dt-bindings/clock/imx8mq-clock.h @@ -1,10 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright 2016 Freescale Semiconductor, Inc. * Copyright 2017 NXP - * - * 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. */ #ifndef __DT_BINDINGS_CLOCK_IMX8MQ_H @@ -148,465 +145,263 @@ /* BUS TYPE */ /* MAIN AXI */ -#define IMX8MQ_CLK_MAIN_AXI_SRC 103 -#define IMX8MQ_CLK_MAIN_AXI_CG 104 -#define IMX8MQ_CLK_MAIN_AXI_PRE_DIV 105 -#define IMX8MQ_CLK_MAIN_AXI_DIV 106 +#define IMX8MQ_CLK_MAIN_AXI 103 /* ENET AXI */ -#define IMX8MQ_CLK_ENET_AXI_SRC 107 -#define IMX8MQ_CLK_ENET_AXI_CG 108 -#define IMX8MQ_CLK_ENET_AXI_PRE_DIV 109 -#define IMX8MQ_CLK_ENET_AXI_DIV 110 +#define IMX8MQ_CLK_ENET_AXI 104 /* NAND_USDHC_BUS */ -#define IMX8MQ_CLK_NAND_USDHC_BUS_SRC 111 -#define IMX8MQ_CLK_NAND_USDHC_BUS_CG 112 -#define IMX8MQ_CLK_NAND_USDHC_BUS_PRE_DIV 113 -#define IMX8MQ_CLK_NAND_USDHC_BUS_DIV 114 +#define IMX8MQ_CLK_NAND_USDHC_BUS 105 /* VPU BUS */ -#define IMX8MQ_CLK_VPU_BUS_SRC 115 -#define IMX8MQ_CLK_VPU_BUS_CG 116 -#define IMX8MQ_CLK_VPU_BUS_PRE_DIV 117 -#define IMX8MQ_CLK_VPU_BUS_DIV 118 +#define IMX8MQ_CLK_VPU_BUS 106 /* DISP_AXI */ -#define IMX8MQ_CLK_DISP_AXI_SRC 119 -#define IMX8MQ_CLK_DISP_AXI_CG 120 -#define IMX8MQ_CLK_DISP_AXI_PRE_DIV 121 -#define IMX8MQ_CLK_DISP_AXI_DIV 122 +#define IMX8MQ_CLK_DISP_AXI 107 /* DISP APB */ -#define IMX8MQ_CLK_DISP_APB_SRC 123 -#define IMX8MQ_CLK_DISP_APB_CG 124 -#define IMX8MQ_CLK_DISP_APB_PRE_DIV 125 -#define IMX8MQ_CLK_DISP_APB_DIV 126 +#define IMX8MQ_CLK_DISP_APB 108 /* DISP RTRM */ -#define IMX8MQ_CLK_DISP_RTRM_SRC 127 -#define IMX8MQ_CLK_DISP_RTRM_CG 128 -#define IMX8MQ_CLK_DISP_RTRM_PRE_DIV 129 -#define IMX8MQ_CLK_DISP_RTRM_DIV 130 +#define IMX8MQ_CLK_DISP_RTRM 109 /* USB_BUS */ -#define IMX8MQ_CLK_USB_BUS_SRC 131 -#define IMX8MQ_CLK_USB_BUS_CG 132 -#define IMX8MQ_CLK_USB_BUS_PRE_DIV 133 -#define IMX8MQ_CLK_USB_BUS_DIV 134 +#define IMX8MQ_CLK_USB_BUS 110 /* GPU_AXI */ -#define IMX8MQ_CLK_GPU_AXI_SRC 135 -#define IMX8MQ_CLK_GPU_AXI_CG 136 -#define IMX8MQ_CLK_GPU_AXI_PRE_DIV 137 -#define IMX8MQ_CLK_GPU_AXI_DIV 138 +#define IMX8MQ_CLK_GPU_AXI 111 /* GPU_AHB */ -#define IMX8MQ_CLK_GPU_AHB_SRC 139 -#define IMX8MQ_CLK_GPU_AHB_CG 140 -#define IMX8MQ_CLK_GPU_AHB_PRE_DIV 141 -#define IMX8MQ_CLK_GPU_AHB_DIV 142 +#define IMX8MQ_CLK_GPU_AHB 112 /* NOC */ -#define IMX8MQ_CLK_NOC_SRC 143 -#define IMX8MQ_CLK_NOC_CG 144 -#define IMX8MQ_CLK_NOC_PRE_DIV 145 -#define IMX8MQ_CLK_NOC_DIV 146 +#define IMX8MQ_CLK_NOC 113 /* NOC_APB */ -#define IMX8MQ_CLK_NOC_APB_SRC 147 -#define IMX8MQ_CLK_NOC_APB_CG 148 -#define IMX8MQ_CLK_NOC_APB_PRE_DIV 149 -#define IMX8MQ_CLK_NOC_APB_DIV 150 +#define IMX8MQ_CLK_NOC_APB 115 /* AHB */ -#define IMX8MQ_CLK_AHB_SRC 151 -#define IMX8MQ_CLK_AHB_CG 152 -#define IMX8MQ_CLK_AHB_PRE_DIV 153 -#define IMX8MQ_CLK_AHB_DIV 154 +#define IMX8MQ_CLK_AHB 116 /* AUDIO AHB */ -#define IMX8MQ_CLK_AUDIO_AHB_SRC 155 -#define IMX8MQ_CLK_AUDIO_AHB_CG 156 -#define IMX8MQ_CLK_AUDIO_AHB_PRE_DIV 157 -#define IMX8MQ_CLK_AUDIO_AHB_DIV 158 +#define IMX8MQ_CLK_AUDIO_AHB 117 /* DRAM_ALT */ -#define IMX8MQ_CLK_DRAM_ALT_SRC 159 -#define IMX8MQ_CLK_DRAM_ALT_CG 160 -#define IMX8MQ_CLK_DRAM_ALT_PRE_DIV 161 -#define IMX8MQ_CLK_DRAM_ALT_DIV 162 +#define IMX8MQ_CLK_DRAM_ALT 118 /* DRAM APB */ -#define IMX8MQ_CLK_DRAM_APB_SRC 163 -#define IMX8MQ_CLK_DRAM_APB_CG 164 -#define IMX8MQ_CLK_DRAM_APB_PRE_DIV 165 -#define IMX8MQ_CLK_DRAM_APB_DIV 166 +#define IMX8MQ_CLK_DRAM_APB 119 /* VPU_G1 */ -#define IMX8MQ_CLK_VPU_G1_SRC 167 -#define IMX8MQ_CLK_VPU_G1_CG 168 -#define IMX8MQ_CLK_VPU_G1_PRE_DIV 169 -#define IMX8MQ_CLK_VPU_G1_DIV 170 +#define IMX8MQ_CLK_VPU_G1 120 /* VPU_G2 */ -#define IMX8MQ_CLK_VPU_G2_SRC 171 -#define IMX8MQ_CLK_VPU_G2_CG 172 -#define IMX8MQ_CLK_VPU_G2_PRE_DIV 173 -#define IMX8MQ_CLK_VPU_G2_DIV 174 +#define IMX8MQ_CLK_VPU_G2 121 /* DISP_DTRC */ -#define IMX8MQ_CLK_DISP_DTRC_SRC 175 -#define IMX8MQ_CLK_DISP_DTRC_CG 176 -#define IMX8MQ_CLK_DISP_DTRC_PRE_DIV 177 -#define IMX8MQ_CLK_DISP_DTRC_DIV 178 +#define IMX8MQ_CLK_DISP_DTRC 122 /* DISP_DC8000 */ -#define IMX8MQ_CLK_DISP_DC8000_SRC 179 -#define IMX8MQ_CLK_DISP_DC8000_CG 180 -#define IMX8MQ_CLK_DISP_DC8000_PRE_DIV 181 -#define IMX8MQ_CLK_DISP_DC8000_DIV 182 +#define IMX8MQ_CLK_DISP_DC8000 123 /* PCIE_CTRL */ -#define IMX8MQ_CLK_PCIE1_CTRL_SRC 183 -#define IMX8MQ_CLK_PCIE1_CTRL_CG 184 -#define IMX8MQ_CLK_PCIE1_CTRL_PRE_DIV 185 -#define IMX8MQ_CLK_PCIE1_CTRL_DIV 186 +#define IMX8MQ_CLK_PCIE1_CTRL 124 /* PCIE_PHY */ -#define IMX8MQ_CLK_PCIE1_PHY_SRC 187 -#define IMX8MQ_CLK_PCIE1_PHY_CG 188 -#define IMX8MQ_CLK_PCIE1_PHY_PRE_DIV 189 -#define IMX8MQ_CLK_PCIE1_PHY_DIV 190 +#define IMX8MQ_CLK_PCIE1_PHY 125 /* PCIE_AUX */ -#define IMX8MQ_CLK_PCIE1_AUX_SRC 191 -#define IMX8MQ_CLK_PCIE1_AUX_CG 192 -#define IMX8MQ_CLK_PCIE1_AUX_PRE_DIV 193 -#define IMX8MQ_CLK_PCIE1_AUX_DIV 194 +#define IMX8MQ_CLK_PCIE1_AUX 126 /* DC_PIXEL */ -#define IMX8MQ_CLK_DC_PIXEL_SRC 195 -#define IMX8MQ_CLK_DC_PIXEL_CG 196 -#define IMX8MQ_CLK_DC_PIXEL_PRE_DIV 197 -#define IMX8MQ_CLK_DC_PIXEL_DIV 198 +#define IMX8MQ_CLK_DC_PIXEL 127 /* LCDIF_PIXEL */ -#define IMX8MQ_CLK_LCDIF_PIXEL_SRC 199 -#define IMX8MQ_CLK_LCDIF_PIXEL_CG 200 -#define IMX8MQ_CLK_LCDIF_PIXEL_PRE_DIV 201 -#define IMX8MQ_CLK_LCDIF_PIXEL_DIV 202 +#define IMX8MQ_CLK_LCDIF_PIXEL 128 /* SAI1~6 */ -#define IMX8MQ_CLK_SAI1_SRC 203 -#define IMX8MQ_CLK_SAI1_CG 204 -#define IMX8MQ_CLK_SAI1_PRE_DIV 205 -#define IMX8MQ_CLK_SAI1_DIV 206 - -#define IMX8MQ_CLK_SAI2_SRC 207 -#define IMX8MQ_CLK_SAI2_CG 208 -#define IMX8MQ_CLK_SAI2_PRE_DIV 209 -#define IMX8MQ_CLK_SAI2_DIV 210 - -#define IMX8MQ_CLK_SAI3_SRC 211 -#define IMX8MQ_CLK_SAI3_CG 212 -#define IMX8MQ_CLK_SAI3_PRE_DIV 213 -#define IMX8MQ_CLK_SAI3_DIV 214 - -#define IMX8MQ_CLK_SAI4_SRC 215 -#define IMX8MQ_CLK_SAI4_CG 216 -#define IMX8MQ_CLK_SAI4_PRE_DIV 217 -#define IMX8MQ_CLK_SAI4_DIV 218 - -#define IMX8MQ_CLK_SAI5_SRC 219 -#define IMX8MQ_CLK_SAI5_CG 220 -#define IMX8MQ_CLK_SAI5_PRE_DIV 221 -#define IMX8MQ_CLK_SAI5_DIV 222 - -#define IMX8MQ_CLK_SAI6_SRC 223 -#define IMX8MQ_CLK_SAI6_CG 224 -#define IMX8MQ_CLK_SAI6_PRE_DIV 225 -#define IMX8MQ_CLK_SAI6_DIV 226 +#define IMX8MQ_CLK_SAI1 129 + +#define IMX8MQ_CLK_SAI2 130 + +#define IMX8MQ_CLK_SAI3 131 + +#define IMX8MQ_CLK_SAI4 132 + +#define IMX8MQ_CLK_SAI5 133 + +#define IMX8MQ_CLK_SAI6 134 /* SPDIF1 */ -#define IMX8MQ_CLK_SPDIF1_SRC 227 -#define IMX8MQ_CLK_SPDIF1_CG 228 -#define IMX8MQ_CLK_SPDIF1_PRE_DIV 229 -#define IMX8MQ_CLK_SPDIF1_DIV 230 +#define IMX8MQ_CLK_SPDIF1 135 /* SPDIF2 */ -#define IMX8MQ_CLK_SPDIF2_SRC 231 -#define IMX8MQ_CLK_SPDIF2_CG 232 -#define IMX8MQ_CLK_SPDIF2_PRE_DIV 233 -#define IMX8MQ_CLK_SPDIF2_DIV 234 +#define IMX8MQ_CLK_SPDIF2 136 /* ENET_REF */ -#define IMX8MQ_CLK_ENET_REF_SRC 235 -#define IMX8MQ_CLK_ENET_REF_CG 236 -#define IMX8MQ_CLK_ENET_REF_PRE_DIV 237 -#define IMX8MQ_CLK_ENET_REF_DIV 238 +#define IMX8MQ_CLK_ENET_REF 137 /* ENET_TIMER */ -#define IMX8MQ_CLK_ENET_TIMER_SRC 239 -#define IMX8MQ_CLK_ENET_TIMER_CG 240 -#define IMX8MQ_CLK_ENET_TIMER_PRE_DIV 241 -#define IMX8MQ_CLK_ENET_TIMER_DIV 242 +#define IMX8MQ_CLK_ENET_TIMER 138 /* ENET_PHY */ -#define IMX8MQ_CLK_ENET_PHY_REF_SRC 243 -#define IMX8MQ_CLK_ENET_PHY_REF_CG 244 -#define IMX8MQ_CLK_ENET_PHY_REF_PRE_DIV 245 -#define IMX8MQ_CLK_ENET_PHY_REF_DIV 246 +#define IMX8MQ_CLK_ENET_PHY_REF 139 /* NAND */ -#define IMX8MQ_CLK_NAND_SRC 247 -#define IMX8MQ_CLK_NAND_CG 248 -#define IMX8MQ_CLK_NAND_PRE_DIV 249 -#define IMX8MQ_CLK_NAND_DIV 250 +#define IMX8MQ_CLK_NAND 140 /* QSPI */ -#define IMX8MQ_CLK_QSPI_SRC 251 -#define IMX8MQ_CLK_QSPI_CG 252 -#define IMX8MQ_CLK_QSPI_PRE_DIV 253 -#define IMX8MQ_CLK_QSPI_DIV 254 +#define IMX8MQ_CLK_QSPI 141 /* USDHC1 */ -#define IMX8MQ_CLK_USDHC1_SRC 255 -#define IMX8MQ_CLK_USDHC1_CG 256 -#define IMX8MQ_CLK_USDHC1_PRE_DIV 257 -#define IMX8MQ_CLK_USDHC1_DIV 258 +#define IMX8MQ_CLK_USDHC1 142 /* USDHC2 */ -#define IMX8MQ_CLK_USDHC2_SRC 259 -#define IMX8MQ_CLK_USDHC2_CG 260 -#define IMX8MQ_CLK_USDHC2_PRE_DIV 261 -#define IMX8MQ_CLK_USDHC2_DIV 262 +#define IMX8MQ_CLK_USDHC2 143 /* I2C1 */ -#define IMX8MQ_CLK_I2C1_SRC 263 -#define IMX8MQ_CLK_I2C1_CG 264 -#define IMX8MQ_CLK_I2C1_PRE_DIV 265 -#define IMX8MQ_CLK_I2C1_DIV 266 +#define IMX8MQ_CLK_I2C1 144 /* I2C2 */ -#define IMX8MQ_CLK_I2C2_SRC 267 -#define IMX8MQ_CLK_I2C2_CG 268 -#define IMX8MQ_CLK_I2C2_PRE_DIV 269 -#define IMX8MQ_CLK_I2C2_DIV 270 +#define IMX8MQ_CLK_I2C2 145 /* I2C3 */ -#define IMX8MQ_CLK_I2C3_SRC 271 -#define IMX8MQ_CLK_I2C3_CG 272 -#define IMX8MQ_CLK_I2C3_PRE_DIV 273 -#define IMX8MQ_CLK_I2C3_DIV 274 +#define IMX8MQ_CLK_I2C3 146 /* I2C4 */ -#define IMX8MQ_CLK_I2C4_SRC 275 -#define IMX8MQ_CLK_I2C4_CG 276 -#define IMX8MQ_CLK_I2C4_PRE_DIV 277 -#define IMX8MQ_CLK_I2C4_DIV 278 +#define IMX8MQ_CLK_I2C4 147 /* UART1 */ -#define IMX8MQ_CLK_UART1_SRC 279 -#define IMX8MQ_CLK_UART1_CG 280 -#define IMX8MQ_CLK_UART1_PRE_DIV 281 -#define IMX8MQ_CLK_UART1_DIV 282 +#define IMX8MQ_CLK_UART1 148 /* UART2 */ -#define IMX8MQ_CLK_UART2_SRC 283 -#define IMX8MQ_CLK_UART2_CG 284 -#define IMX8MQ_CLK_UART2_PRE_DIV 285 -#define IMX8MQ_CLK_UART2_DIV 286 +#define IMX8MQ_CLK_UART2 149 /* UART3 */ -#define IMX8MQ_CLK_UART3_SRC 287 -#define IMX8MQ_CLK_UART3_CG 288 -#define IMX8MQ_CLK_UART3_PRE_DIV 289 -#define IMX8MQ_CLK_UART3_DIV 290 +#define IMX8MQ_CLK_UART3 150 /* UART4 */ -#define IMX8MQ_CLK_UART4_SRC 291 -#define IMX8MQ_CLK_UART4_CG 292 -#define IMX8MQ_CLK_UART4_PRE_DIV 293 -#define IMX8MQ_CLK_UART4_DIV 294 +#define IMX8MQ_CLK_UART4 151 /* USB_CORE_REF */ -#define IMX8MQ_CLK_USB_CORE_REF_SRC 295 -#define IMX8MQ_CLK_USB_CORE_REF_CG 296 -#define IMX8MQ_CLK_USB_CORE_REF_PRE_DIV 297 -#define IMX8MQ_CLK_USB_CORE_REF_DIV 298 +#define IMX8MQ_CLK_USB_CORE_REF 152 /* USB_PHY_REF */ -#define IMX8MQ_CLK_USB_PHY_REF_SRC 299 -#define IMX8MQ_CLK_USB_PHY_REF_CG 300 -#define IMX8MQ_CLK_USB_PHY_REF_PRE_DIV 301 -#define IMX8MQ_CLK_USB_PHY_REF_DIV 302 +#define IMX8MQ_CLK_USB_PHY_REF 153 /* ECSPI1 */ -#define IMX8MQ_CLK_ECSPI1_SRC 303 -#define IMX8MQ_CLK_ECSPI1_CG 304 -#define IMX8MQ_CLK_ECSPI1_PRE_DIV 305 -#define IMX8MQ_CLK_ECSPI1_DIV 306 +#define IMX8MQ_CLK_ECSPI1 154 /* ECSPI2 */ -#define IMX8MQ_CLK_ECSPI2_SRC 307 -#define IMX8MQ_CLK_ECSPI2_CG 308 -#define IMX8MQ_CLK_ECSPI2_PRE_DIV 309 -#define IMX8MQ_CLK_ECSPI2_DIV 310 +#define IMX8MQ_CLK_ECSPI2 155 /* PWM1 */ -#define IMX8MQ_CLK_PWM1_SRC 311 -#define IMX8MQ_CLK_PWM1_CG 312 -#define IMX8MQ_CLK_PWM1_PRE_DIV 313 -#define IMX8MQ_CLK_PWM1_DIV 314 +#define IMX8MQ_CLK_PWM1 156 /* PWM2 */ -#define IMX8MQ_CLK_PWM2_SRC 315 -#define IMX8MQ_CLK_PWM2_CG 316 -#define IMX8MQ_CLK_PWM2_PRE_DIV 317 -#define IMX8MQ_CLK_PWM2_DIV 318 +#define IMX8MQ_CLK_PWM2 157 /* PWM3 */ -#define IMX8MQ_CLK_PWM3_SRC 319 -#define IMX8MQ_CLK_PWM3_CG 320 -#define IMX8MQ_CLK_PWM3_PRE_DIV 321 -#define IMX8MQ_CLK_PWM3_DIV 322 +#define IMX8MQ_CLK_PWM3 158 /* PWM4 */ -#define IMX8MQ_CLK_PWM4_SRC 323 -#define IMX8MQ_CLK_PWM4_CG 324 -#define IMX8MQ_CLK_PWM4_PRE_DIV 325 -#define IMX8MQ_CLK_PWM4_DIV 326 +#define IMX8MQ_CLK_PWM4 159 /* GPT1 */ -#define IMX8MQ_CLK_GPT1_SRC 327 -#define IMX8MQ_CLK_GPT1_CG 328 -#define IMX8MQ_CLK_GPT1_PRE_DIV 329 -#define IMX8MQ_CLK_GPT1_DIV 330 +#define IMX8MQ_CLK_GPT1 160 /* WDOG */ -#define IMX8MQ_CLK_WDOG_SRC 331 -#define IMX8MQ_CLK_WDOG_CG 332 -#define IMX8MQ_CLK_WDOG_PRE_DIV 333 -#define IMX8MQ_CLK_WDOG_DIV 334 +#define IMX8MQ_CLK_WDOG 161 /* WRCLK */ -#define IMX8MQ_CLK_WRCLK_SRC 335 -#define IMX8MQ_CLK_WRCLK_CG 336 -#define IMX8MQ_CLK_WRCLK_PRE_DIV 337 -#define IMX8MQ_CLK_WRCLK_DIV 338 +#define IMX8MQ_CLK_WRCLK 162 /* DSI_CORE */ -#define IMX8MQ_CLK_DSI_CORE_SRC 339 -#define IMX8MQ_CLK_DSI_CORE_CG 340 -#define IMX8MQ_CLK_DSI_CORE_PRE_DIV 341 -#define IMX8MQ_CLK_DSI_CORE_DIV 342 +#define IMX8MQ_CLK_DSI_CORE 163 /* DSI_PHY */ -#define IMX8MQ_CLK_DSI_PHY_REF_SRC 343 -#define IMX8MQ_CLK_DSI_PHY_REF_CG 344 -#define IMX8MQ_CLK_DSI_PHY_REF_PRE_DIV 345 -#define IMX8MQ_CLK_DSI_PHY_REF_DIV 346 +#define IMX8MQ_CLK_DSI_PHY_REF 164 /* DSI_DBI */ -#define IMX8MQ_CLK_DSI_DBI_SRC 347 -#define IMX8MQ_CLK_DSI_DBI_CG 348 -#define IMX8MQ_CLK_DSI_DBI_PRE_DIV 349 -#define IMX8MQ_CLK_DSI_DBI_DIV 350 +#define IMX8MQ_CLK_DSI_DBI 165 /*DSI_ESC */ -#define IMX8MQ_CLK_DSI_ESC_SRC 351 -#define IMX8MQ_CLK_DSI_ESC_CG 352 -#define IMX8MQ_CLK_DSI_ESC_PRE_DIV 353 -#define IMX8MQ_CLK_DSI_ESC_DIV 354 +#define IMX8MQ_CLK_DSI_ESC 166 /* CSI1_CORE */ -#define IMX8MQ_CLK_CSI1_CORE_SRC 355 -#define IMX8MQ_CLK_CSI1_CORE_CG 356 -#define IMX8MQ_CLK_CSI1_CORE_PRE_DIV 357 -#define IMX8MQ_CLK_CSI1_CORE_DIV 358 +#define IMX8MQ_CLK_CSI1_CORE 167 /* CSI1_PHY */ -#define IMX8MQ_CLK_CSI1_PHY_REF_SRC 359 -#define IMX8MQ_CLK_CSI1_PHY_REF_CG 360 -#define IMX8MQ_CLK_CSI1_PHY_REF_PRE_DIV 361 -#define IMX8MQ_CLK_CSI1_PHY_REF_DIV 362 +#define IMX8MQ_CLK_CSI1_PHY_REF 168 /* CSI_ESC */ -#define IMX8MQ_CLK_CSI1_ESC_SRC 363 -#define IMX8MQ_CLK_CSI1_ESC_CG 364 -#define IMX8MQ_CLK_CSI1_ESC_PRE_DIV 365 -#define IMX8MQ_CLK_CSI1_ESC_DIV 366 +#define IMX8MQ_CLK_CSI1_ESC 169 /* CSI2_CORE */ -#define IMX8MQ_CLK_CSI2_CORE_SRC 367 -#define IMX8MQ_CLK_CSI2_CORE_CG 368 -#define IMX8MQ_CLK_CSI2_CORE_PRE_DIV 369 -#define IMX8MQ_CLK_CSI2_CORE_DIV 370 +#define IMX8MQ_CLK_CSI2_CORE 170 /* CSI2_PHY */ -#define IMX8MQ_CLK_CSI2_PHY_REF_SRC 371 -#define IMX8MQ_CLK_CSI2_PHY_REF_CG 372 -#define IMX8MQ_CLK_CSI2_PHY_REF_PRE_DIV 373 -#define IMX8MQ_CLK_CSI2_PHY_REF_DIV 374 +#define IMX8MQ_CLK_CSI2_PHY_REF 171 /* CSI2_ESC */ -#define IMX8MQ_CLK_CSI2_ESC_SRC 375 -#define IMX8MQ_CLK_CSI2_ESC_CG 376 -#define IMX8MQ_CLK_CSI2_ESC_PRE_DIV 377 -#define IMX8MQ_CLK_CSI2_ESC_DIV 378 +#define IMX8MQ_CLK_CSI2_ESC 172 /* PCIE2_CTRL */ -#define IMX8MQ_CLK_PCIE2_CTRL_SRC 379 -#define IMX8MQ_CLK_PCIE2_CTRL_CG 380 -#define IMX8MQ_CLK_PCIE2_CTRL_PRE_DIV 381 -#define IMX8MQ_CLK_PCIE2_CTRL_DIV 382 +#define IMX8MQ_CLK_PCIE2_CTRL 173 /* PCIE2_PHY */ -#define IMX8MQ_CLK_PCIE2_PHY_SRC 383 -#define IMX8MQ_CLK_PCIE2_PHY_CG 384 -#define IMX8MQ_CLK_PCIE2_PHY_PRE_DIV 385 -#define IMX8MQ_CLK_PCIE2_PHY_DIV 386 +#define IMX8MQ_CLK_PCIE2_PHY 174 /* PCIE2_AUX */ -#define IMX8MQ_CLK_PCIE2_AUX_SRC 387 -#define IMX8MQ_CLK_PCIE2_AUX_CG 388 -#define IMX8MQ_CLK_PCIE2_AUX_PRE_DIV 389 -#define IMX8MQ_CLK_PCIE2_AUX_DIV 390 +#define IMX8MQ_CLK_PCIE2_AUX 175 /* ECSPI3 */ -#define IMX8MQ_CLK_ECSPI3_SRC 391 -#define IMX8MQ_CLK_ECSPI3_CG 392 -#define IMX8MQ_CLK_ECSPI3_PRE_DIV 393 -#define IMX8MQ_CLK_ECSPI3_DIV 394 +#define IMX8MQ_CLK_ECSPI3 176 /* CCGR clocks */ -#define IMX8MQ_CLK_A53_ROOT 395 -#define IMX8MQ_CLK_DRAM_ROOT 396 -#define IMX8MQ_CLK_ECSPI1_ROOT 397 -#define IMX8MQ_CLK_ECSPI2_ROOT 398 -#define IMX8MQ_CLK_ECSPI3_ROOT 399 -#define IMX8MQ_CLK_ENET1_ROOT 400 -#define IMX8MQ_CLK_GPT1_ROOT 401 -#define IMX8MQ_CLK_I2C1_ROOT 402 -#define IMX8MQ_CLK_I2C2_ROOT 403 -#define IMX8MQ_CLK_I2C3_ROOT 404 -#define IMX8MQ_CLK_I2C4_ROOT 405 -#define IMX8MQ_CLK_M4_ROOT 406 -#define IMX8MQ_CLK_PCIE1_ROOT 407 -#define IMX8MQ_CLK_PCIE2_ROOT 408 -#define IMX8MQ_CLK_PWM1_ROOT 409 -#define IMX8MQ_CLK_PWM2_ROOT 410 -#define IMX8MQ_CLK_PWM3_ROOT 411 -#define IMX8MQ_CLK_PWM4_ROOT 412 -#define IMX8MQ_CLK_QSPI_ROOT 413 -#define IMX8MQ_CLK_SAI1_ROOT 414 -#define IMX8MQ_CLK_SAI2_ROOT 415 -#define IMX8MQ_CLK_SAI3_ROOT 416 -#define IMX8MQ_CLK_SAI4_ROOT 417 -#define IMX8MQ_CLK_SAI5_ROOT 418 -#define IMX8MQ_CLK_SAI6_ROOT 419 -#define IMX8MQ_CLK_UART1_ROOT 420 -#define IMX8MQ_CLK_UART2_ROOT 421 -#define IMX8MQ_CLK_UART3_ROOT 422 -#define IMX8MQ_CLK_UART4_ROOT 423 -#define IMX8MQ_CLK_USB1_CTRL_ROOT 424 -#define IMX8MQ_CLK_USB2_CTRL_ROOT 425 -#define IMX8MQ_CLK_USB1_PHY_ROOT 426 -#define IMX8MQ_CLK_USB2_PHY_ROOT 427 -#define IMX8MQ_CLK_USDHC1_ROOT 428 -#define IMX8MQ_CLK_USDHC2_ROOT 429 -#define IMX8MQ_CLK_WDOG1_ROOT 430 -#define IMX8MQ_CLK_WDOG2_ROOT 431 -#define IMX8MQ_CLK_WDOG3_ROOT 432 -#define IMX8MQ_CLK_GPU_ROOT 433 -#define IMX8MQ_CLK_HEVC_ROOT 434 -#define IMX8MQ_CLK_AVC_ROOT 435 -#define IMX8MQ_CLK_VP9_ROOT 436 -#define IMX8MQ_CLK_HEVC_INTER_ROOT 437 -#define IMX8MQ_CLK_DISP_ROOT 438 -#define IMX8MQ_CLK_HDMI_ROOT 439 -#define IMX8MQ_CLK_HDMI_PHY_ROOT 440 -#define IMX8MQ_CLK_VPU_DEC_ROOT 441 -#define IMX8MQ_CLK_CSI1_ROOT 442 -#define IMX8MQ_CLK_CSI2_ROOT 443 -#define IMX8MQ_CLK_RAWNAND_ROOT 444 -#define IMX8MQ_CLK_SDMA1_ROOT 445 -#define IMX8MQ_CLK_SDMA2_ROOT 446 -#define IMX8MQ_CLK_VPU_G1_ROOT 447 -#define IMX8MQ_CLK_VPU_G2_ROOT 448 +#define IMX8MQ_CLK_A53_ROOT 177 +#define IMX8MQ_CLK_DRAM_ROOT 178 +#define IMX8MQ_CLK_ECSPI1_ROOT 179 +#define IMX8MQ_CLK_ECSPI2_ROOT 180 +#define IMX8MQ_CLK_ECSPI3_ROOT 181 +#define IMX8MQ_CLK_ENET1_ROOT 182 +#define IMX8MQ_CLK_GPT1_ROOT 183 +#define IMX8MQ_CLK_I2C1_ROOT 184 +#define IMX8MQ_CLK_I2C2_ROOT 185 +#define IMX8MQ_CLK_I2C3_ROOT 186 +#define IMX8MQ_CLK_I2C4_ROOT 187 +#define IMX8MQ_CLK_M4_ROOT 188 +#define IMX8MQ_CLK_PCIE1_ROOT 189 +#define IMX8MQ_CLK_PCIE2_ROOT 190 +#define IMX8MQ_CLK_PWM1_ROOT 191 +#define IMX8MQ_CLK_PWM2_ROOT 192 +#define IMX8MQ_CLK_PWM3_ROOT 193 +#define IMX8MQ_CLK_PWM4_ROOT 194 +#define IMX8MQ_CLK_QSPI_ROOT 195 +#define IMX8MQ_CLK_SAI1_ROOT 196 +#define IMX8MQ_CLK_SAI2_ROOT 197 +#define IMX8MQ_CLK_SAI3_ROOT 198 +#define IMX8MQ_CLK_SAI4_ROOT 199 +#define IMX8MQ_CLK_SAI5_ROOT 200 +#define IMX8MQ_CLK_SAI6_ROOT 201 +#define IMX8MQ_CLK_UART1_ROOT 202 +#define IMX8MQ_CLK_UART2_ROOT 203 +#define IMX8MQ_CLK_UART3_ROOT 204 +#define IMX8MQ_CLK_UART4_ROOT 205 +#define IMX8MQ_CLK_USB1_CTRL_ROOT 206 +#define IMX8MQ_CLK_USB2_CTRL_ROOT 207 +#define IMX8MQ_CLK_USB1_PHY_ROOT 208 +#define IMX8MQ_CLK_USB2_PHY_ROOT 209 +#define IMX8MQ_CLK_USDHC1_ROOT 210 +#define IMX8MQ_CLK_USDHC2_ROOT 211 +#define IMX8MQ_CLK_WDOG1_ROOT 212 +#define IMX8MQ_CLK_WDOG2_ROOT 213 +#define IMX8MQ_CLK_WDOG3_ROOT 214 +#define IMX8MQ_CLK_GPU_ROOT 215 +#define IMX8MQ_CLK_HEVC_ROOT 216 +#define IMX8MQ_CLK_AVC_ROOT 217 +#define IMX8MQ_CLK_VP9_ROOT 218 +#define IMX8MQ_CLK_HEVC_INTER_ROOT 219 +#define IMX8MQ_CLK_DISP_ROOT 220 +#define IMX8MQ_CLK_HDMI_ROOT 221 +#define IMX8MQ_CLK_HDMI_PHY_ROOT 222 +#define IMX8MQ_CLK_VPU_DEC_ROOT 223 +#define IMX8MQ_CLK_CSI1_ROOT 224 +#define IMX8MQ_CLK_CSI2_ROOT 225 +#define IMX8MQ_CLK_RAWNAND_ROOT 226 +#define IMX8MQ_CLK_SDMA1_ROOT 227 +#define IMX8MQ_CLK_SDMA2_ROOT 228 +#define IMX8MQ_CLK_VPU_G1_ROOT 229 +#define IMX8MQ_CLK_VPU_G2_ROOT 230 /* SCCG PLL GATE */ -#define IMX8MQ_SYS1_PLL_OUT 449 -#define IMX8MQ_SYS2_PLL_OUT 450 -#define IMX8MQ_SYS3_PLL_OUT 451 -#define IMX8MQ_DRAM_PLL_OUT 452 - -#define IMX8MQ_GPT_3M_CLK 453 - -#define IMX8MQ_CLK_IPG_ROOT 454 -#define IMX8MQ_CLK_IPG_AUDIO_ROOT 455 -#define IMX8MQ_CLK_SAI1_IPG 456 -#define IMX8MQ_CLK_SAI2_IPG 457 -#define IMX8MQ_CLK_SAI3_IPG 458 -#define IMX8MQ_CLK_SAI4_IPG 459 -#define IMX8MQ_CLK_SAI5_IPG 460 -#define IMX8MQ_CLK_SAI6_IPG 461 +#define IMX8MQ_SYS1_PLL_OUT 231 +#define IMX8MQ_SYS2_PLL_OUT 232 +#define IMX8MQ_SYS3_PLL_OUT 233 +#define IMX8MQ_DRAM_PLL_OUT 234 + +#define IMX8MQ_GPT_3M_CLK 235 + +#define IMX8MQ_CLK_IPG_ROOT 236 +#define IMX8MQ_CLK_IPG_AUDIO_ROOT 237 +#define IMX8MQ_CLK_SAI1_IPG 238 +#define IMX8MQ_CLK_SAI2_IPG 239 +#define IMX8MQ_CLK_SAI3_IPG 240 +#define IMX8MQ_CLK_SAI4_IPG 241 +#define IMX8MQ_CLK_SAI5_IPG 242 +#define IMX8MQ_CLK_SAI6_IPG 243 /* DSI AHB/IPG clocks */ /* rxesc clock */ -#define IMX8MQ_CLK_DSI_AHB_SRC 462 -#define IMX8MQ_CLK_DSI_AHB_CG 463 -#define IMX8MQ_CLK_DSI_AHB_PRE_DIV 464 -#define IMX8MQ_CLK_DSI_AHB_DIV 465 +#define IMX8MQ_CLK_DSI_AHB 244 /* txesc clock */ -#define IMX8MQ_CLK_DSI_IPG_DIV 466 - -/* VIDEO2 PLL */ -#define IMX8MQ_VIDEO2_PLL1_REF_SEL 467 -#define IMX8MQ_VIDEO2_PLL1_REF_DIV 468 -#define IMX8MQ_VIDEO2_PLL1 469 -#define IMX8MQ_VIDEO2_PLL1_OUT 470 -#define IMX8MQ_VIDEO2_PLL1_OUT_DIV 471 -#define IMX8MQ_VIDEO2_PLL2 472 -#define IMX8MQ_VIDEO2_PLL2_DIV 473 -#define IMX8MQ_VIDEO2_PLL2_OUT 474 -#define IMX8MQ_CLK_TMU_ROOT 475 - -#define IMX8MQ_CLK_END 476 +#define IMX8MQ_CLK_DSI_IPG_DIV 245 + +#define IMX8MQ_CLK_TMU_ROOT 246 + +/* Display root clocks */ +#define IMX8MQ_CLK_DISP_AXI_ROOT 247 +#define IMX8MQ_CLK_DISP_APB_ROOT 248 +#define IMX8MQ_CLK_DISP_RTRM_ROOT 249 + +#define IMX8MQ_CLK_OCOTP_ROOT 250 + +#define IMX8MQ_CLK_DRAM_ALT_ROOT 251 +#define IMX8MQ_CLK_DRAM_CORE 252 + +#define IMX8MQ_CLK_MU_ROOT 253 +#define IMX8MQ_VIDEO2_PLL_OUT 254 + +#define IMX8MQ_CLK_CLKO2 255 + +#define IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK 256 + +#define IMX8MQ_CLK_CLKO1 257 +#define IMX8MQ_CLK_ARM 258 + +#define IMX8MQ_CLK_GPIO1_ROOT 259 +#define IMX8MQ_CLK_GPIO2_ROOT 260 +#define IMX8MQ_CLK_GPIO3_ROOT 261 +#define IMX8MQ_CLK_GPIO4_ROOT 262 +#define IMX8MQ_CLK_GPIO5_ROOT 263 + +#define IMX8MQ_CLK_SNVS_ROOT 264 +#define IMX8MQ_CLK_GIC 265 + +#define IMX8MQ_CLK_END 266 #endif /* __DT_BINDINGS_CLOCK_IMX8MQ_H */ diff --git a/include/dt-bindings/reset/snps,hsdk-reset.h b/include/dt-bindings/reset/snps,hsdk-reset.h new file mode 100644 index 0000000000..e1a643e4bc --- /dev/null +++ b/include/dt-bindings/reset/snps,hsdk-reset.h @@ -0,0 +1,17 @@ +/** + * This header provides index for the HSDK reset controller. + */ +#ifndef _DT_BINDINGS_RESET_CONTROLLER_SNPS_HSDK +#define _DT_BINDINGS_RESET_CONTROLLER_SNPS_HSDK + +#define HSDK_APB_RESET 0 +#define HSDK_AXI_RESET 1 +#define HSDK_ETH_RESET 2 +#define HSDK_USB_RESET 3 +#define HSDK_SDIO_RESET 4 +#define HSDK_HDMI_RESET 5 +#define HSDK_GFX_RESET 6 +#define HSDK_DMAC_RESET 7 +#define HSDK_EBI_RESET 8 + +#endif /*_DT_BINDINGS_RESET_CONTROLLER_SNPS_HSDK*/ diff --git a/include/dt-bindings/usb/pd.h b/include/dt-bindings/usb/pd.h new file mode 100644 index 0000000000..985f2bbd4d --- /dev/null +++ b/include/dt-bindings/usb/pd.h @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __DT_POWER_DELIVERY_H +#define __DT_POWER_DELIVERY_H + +/* Power delivery Power Data Object definitions */ +#define PDO_TYPE_FIXED 0 +#define PDO_TYPE_BATT 1 +#define PDO_TYPE_VAR 2 +#define PDO_TYPE_APDO 3 + +#define PDO_TYPE_SHIFT 30 +#define PDO_TYPE_MASK 0x3 + +#define PDO_TYPE(t) ((t) << PDO_TYPE_SHIFT) + +#define PDO_VOLT_MASK 0x3ff +#define PDO_CURR_MASK 0x3ff +#define PDO_PWR_MASK 0x3ff + +#define PDO_FIXED_DUAL_ROLE (1 << 29) /* Power role swap supported */ +#define PDO_FIXED_SUSPEND (1 << 28) /* USB Suspend supported (Source) */ +#define PDO_FIXED_HIGHER_CAP (1 << 28) /* Requires more than vSafe5V (Sink) */ +#define PDO_FIXED_EXTPOWER (1 << 27) /* Externally powered */ +#define PDO_FIXED_USB_COMM (1 << 26) /* USB communications capable */ +#define PDO_FIXED_DATA_SWAP (1 << 25) /* Data role swap supported */ +#define PDO_FIXED_VOLT_SHIFT 10 /* 50mV units */ +#define PDO_FIXED_CURR_SHIFT 0 /* 10mA units */ + +#define PDO_FIXED_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_FIXED_VOLT_SHIFT) +#define PDO_FIXED_CURR(ma) ((((ma) / 10) & PDO_CURR_MASK) << PDO_FIXED_CURR_SHIFT) + +#define PDO_FIXED(mv, ma, flags) \ + (PDO_TYPE(PDO_TYPE_FIXED) | (flags) | \ + PDO_FIXED_VOLT(mv) | PDO_FIXED_CURR(ma)) + +#define VSAFE5V 5000 /* mv units */ + +#define PDO_BATT_MAX_VOLT_SHIFT 20 /* 50mV units */ +#define PDO_BATT_MIN_VOLT_SHIFT 10 /* 50mV units */ +#define PDO_BATT_MAX_PWR_SHIFT 0 /* 250mW units */ + +#define PDO_BATT_MIN_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_BATT_MIN_VOLT_SHIFT) +#define PDO_BATT_MAX_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_BATT_MAX_VOLT_SHIFT) +#define PDO_BATT_MAX_POWER(mw) ((((mw) / 250) & PDO_PWR_MASK) << PDO_BATT_MAX_PWR_SHIFT) + +#define PDO_BATT(min_mv, max_mv, max_mw) \ + (PDO_TYPE(PDO_TYPE_BATT) | PDO_BATT_MIN_VOLT(min_mv) | \ + PDO_BATT_MAX_VOLT(max_mv) | PDO_BATT_MAX_POWER(max_mw)) + +#define PDO_VAR_MAX_VOLT_SHIFT 20 /* 50mV units */ +#define PDO_VAR_MIN_VOLT_SHIFT 10 /* 50mV units */ +#define PDO_VAR_MAX_CURR_SHIFT 0 /* 10mA units */ + +#define PDO_VAR_MIN_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_VAR_MIN_VOLT_SHIFT) +#define PDO_VAR_MAX_VOLT(mv) ((((mv) / 50) & PDO_VOLT_MASK) << PDO_VAR_MAX_VOLT_SHIFT) +#define PDO_VAR_MAX_CURR(ma) ((((ma) / 10) & PDO_CURR_MASK) << PDO_VAR_MAX_CURR_SHIFT) + +#define PDO_VAR(min_mv, max_mv, max_ma) \ + (PDO_TYPE(PDO_TYPE_VAR) | PDO_VAR_MIN_VOLT(min_mv) | \ + PDO_VAR_MAX_VOLT(max_mv) | PDO_VAR_MAX_CURR(max_ma)) + +#define APDO_TYPE_PPS 0 + +#define PDO_APDO_TYPE_SHIFT 28 /* Only valid value currently is 0x0 - PPS */ +#define PDO_APDO_TYPE_MASK 0x3 + +#define PDO_APDO_TYPE(t) ((t) << PDO_APDO_TYPE_SHIFT) + +#define PDO_PPS_APDO_MAX_VOLT_SHIFT 17 /* 100mV units */ +#define PDO_PPS_APDO_MIN_VOLT_SHIFT 8 /* 100mV units */ +#define PDO_PPS_APDO_MAX_CURR_SHIFT 0 /* 50mA units */ + +#define PDO_PPS_APDO_VOLT_MASK 0xff +#define PDO_PPS_APDO_CURR_MASK 0x7f + +#define PDO_PPS_APDO_MIN_VOLT(mv) \ + ((((mv) / 100) & PDO_PPS_APDO_VOLT_MASK) << PDO_PPS_APDO_MIN_VOLT_SHIFT) +#define PDO_PPS_APDO_MAX_VOLT(mv) \ + ((((mv) / 100) & PDO_PPS_APDO_VOLT_MASK) << PDO_PPS_APDO_MAX_VOLT_SHIFT) +#define PDO_PPS_APDO_MAX_CURR(ma) \ + ((((ma) / 50) & PDO_PPS_APDO_CURR_MASK) << PDO_PPS_APDO_MAX_CURR_SHIFT) + +#define PDO_PPS_APDO(min_mv, max_mv, max_ma) \ + (PDO_TYPE(PDO_TYPE_APDO) | PDO_APDO_TYPE(APDO_TYPE_PPS) | \ + PDO_PPS_APDO_MIN_VOLT(min_mv) | PDO_PPS_APDO_MAX_VOLT(max_mv) | \ + PDO_PPS_APDO_MAX_CURR(max_ma)) + + #endif /* __DT_POWER_DELIVERY_H */ diff --git a/include/errno.h b/include/errno.h index ccb7869e17..3af539b9e9 100644 --- a/include/errno.h +++ b/include/errno.h @@ -12,12 +12,21 @@ extern int errno; #define __set_errno(val) do { errno = val; } while (0) +/** + * errno_str() - get description for error number + * + * @errno: error number (negative in case of error) + * Return: string describing the error. If CONFIG_ERRNO_STR is not + * defined an empty string is returned. + */ #ifdef CONFIG_ERRNO_STR const char *errno_str(int errno); #else +static const char error_message[] = ""; + static inline const char *errno_str(int errno) { - return 0; + return error_message; } #endif #endif /* _ERRNO_H */ diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h index 33dcbee53b..8e8cd2cc1a 100644 --- a/include/fsl_esdhc.h +++ b/include/fsl_esdhc.h @@ -156,18 +156,18 @@ #define BLKATTR_SIZE(x) (x & 0x1fff) #define MAX_BLK_CNT 0x7fff /* so malloc will have enough room with 32M */ -#define ESDHC_HOSTCAPBLT_VS18 0x04000000 -#define ESDHC_HOSTCAPBLT_VS30 0x02000000 -#define ESDHC_HOSTCAPBLT_VS33 0x01000000 -#define ESDHC_HOSTCAPBLT_SRS 0x00800000 -#define ESDHC_HOSTCAPBLT_DMAS 0x00400000 -#define ESDHC_HOSTCAPBLT_HSS 0x00200000 +/* Host controller capabilities register */ +#define HOSTCAPBLT_VS18 0x04000000 +#define HOSTCAPBLT_VS30 0x02000000 +#define HOSTCAPBLT_VS33 0x01000000 +#define HOSTCAPBLT_SRS 0x00800000 +#define HOSTCAPBLT_DMAS 0x00400000 +#define HOSTCAPBLT_HSS 0x00200000 struct fsl_esdhc_cfg { phys_addr_t esdhc_base; u32 sdhc_clk; u8 max_bus_width; - int wp_enable; int vs18_enable; /* Use 1.8V if set to 1 */ struct mmc_config cfg; }; diff --git a/include/generic-phy.h b/include/generic-phy.h index 947c582f68..95caf58341 100644 --- a/include/generic-phy.h +++ b/include/generic-phy.h @@ -270,7 +270,7 @@ static inline int generic_phy_get_by_name(struct udevice *user, const char *phy_ */ static inline bool generic_phy_valid(struct phy *phy) { - return phy->dev != NULL; + return phy && phy->dev; } #endif /*__GENERIC_PHY_H */ diff --git a/include/linux/kernel.h b/include/linux/kernel.h index a85c15d8dc..5c7e5f635b 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -37,6 +37,8 @@ #define UINT32_MAX U32_MAX #define UINT64_MAX U64_MAX +#define INT32_MAX S32_MAX + #define STACK_MAGIC 0xdeadbeef #define REPEAT_BYTE(x) ((~0ul / 0xff) * (x)) diff --git a/include/linux/libfdt_env.h b/include/linux/libfdt_env.h index e2bf79c7ee..148b908e2e 100644 --- a/include/linux/libfdt_env.h +++ b/include/linux/libfdt_env.h @@ -10,12 +10,14 @@ #define LIBFDT_ENV_H #include <linux/string.h> +#include <linux/kernel.h> #include <asm/byteorder.h> typedef __be16 fdt16_t; typedef __be32 fdt32_t; typedef __be64 fdt64_t; +typedef __be64 unaligned_fdt64_t __aligned(4); #define fdt32_to_cpu(x) be32_to_cpu(x) #define cpu_to_fdt32(x) cpu_to_be32(x) diff --git a/include/mxs_nand.h b/include/mxs_nand.h index 4bd65cded9..ada20483d0 100644 --- a/include/mxs_nand.h +++ b/include/mxs_nand.h @@ -66,8 +66,30 @@ struct mxs_nand_info { /* DMA descriptors */ struct mxs_dma_desc **desc; uint32_t desc_index; + + /* Hardware BCH interface and randomizer */ + u32 en_randomizer; + u32 writesize; + u32 oobsize; + u32 bch_flash0layout0; + u32 bch_flash0layout1; +}; + +struct mxs_nand_layout { + u32 nblocks; + u32 meta_size; + u32 data0_size; + u32 ecc0; + u32 datan_size; + u32 eccn; }; int mxs_nand_init_ctrl(struct mxs_nand_info *nand_info); int mxs_nand_init_spl(struct nand_chip *nand); int mxs_nand_setup_ecc(struct mtd_info *mtd); + +void mxs_nand_mode_fcb(struct mtd_info *mtd); +void mxs_nand_mode_normal(struct mtd_info *mtd); +u32 mxs_nand_mark_byte_offset(struct mtd_info *mtd); +u32 mxs_nand_mark_bit_offset(struct mtd_info *mtd); +void mxs_nand_get_layout(struct mtd_info *mtd, struct mxs_nand_layout *l); diff --git a/include/regmap.h b/include/regmap.h index 0854200a9c..9ada1af5ef 100644 --- a/include/regmap.h +++ b/include/regmap.h @@ -295,7 +295,8 @@ int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset, * @map: The map returned by regmap_init_mem*() * @offset: Offset of the memory * @mask: Mask to apply to the read value - * @val: Value to apply to the value to write + * @val: Value to OR with the read value after masking. Note that any + * bits set in @val which are not set in @mask are ignored * Return: 0 if OK, -ve on error */ int regmap_update_bits(struct regmap *map, uint offset, uint mask, uint val); diff --git a/include/spi.h b/include/spi.h index 3f79168df3..6fbb4336ce 100644 --- a/include/spi.h +++ b/include/spi.h @@ -462,6 +462,19 @@ struct dm_spi_ops { * is invalid, other -ve value on error */ int (*cs_info)(struct udevice *bus, uint cs, struct spi_cs_info *info); + + /** + * get_mmap() - Get memory-mapped SPI + * + * @dev: The SPI flash slave device + * @map_basep: Returns base memory address for mapped SPI + * @map_sizep: Returns size of mapped SPI + * @offsetp: Returns start offset of SPI flash where the map works + * correctly (offsets before this are not visible) + * @return 0 if OK, -EFAULT if memory mapping is not available + */ + int (*get_mmap)(struct udevice *dev, ulong *map_basep, + uint *map_sizep, uint *offsetp); }; struct dm_spi_emul_ops { @@ -650,6 +663,20 @@ void dm_spi_release_bus(struct udevice *dev); int dm_spi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din, unsigned long flags); +/** + * spi_get_mmap() - Get memory-mapped SPI + * + * @dev: SPI slave device to check + * @map_basep: Returns base memory address for mapped SPI + * @map_sizep: Returns size of mapped SPI + * @offsetp: Returns start offset of SPI flash where the map works + * correctly (offsets before this are not visible) + * @return 0 if OK, -ENOSYS if no operation, -EFAULT if memory mapping is not + * available + */ +int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep, + uint *offsetp); + /* Access the operations for a SPI device */ #define spi_get_ops(dev) ((struct dm_spi_ops *)(dev)->driver->ops) #define spi_emul_get_ops(dev) ((struct dm_spi_emul_ops *)(dev)->driver->ops) diff --git a/include/spl.h b/include/spl.h index b5387ef273..08ffddac29 100644 --- a/include/spl.h +++ b/include/spl.h @@ -332,14 +332,14 @@ struct spl_image_loader { */ #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT #define SPL_LOAD_IMAGE_METHOD(_name, _priority, _boot_device, _method) \ - SPL_LOAD_IMAGE(_method ## _priority ## _boot_device) = { \ + SPL_LOAD_IMAGE(_boot_device ## _priority ## _method) = { \ .name = _name, \ .boot_device = _boot_device, \ .load_image = _method, \ } #else #define SPL_LOAD_IMAGE_METHOD(_name, _priority, _boot_device, _method) \ - SPL_LOAD_IMAGE(_method ## _priority ## _boot_device) = { \ + SPL_LOAD_IMAGE(_boot_device ## _priority ## _method) = { \ .boot_device = _boot_device, \ .load_image = _method, \ } diff --git a/include/test/ut.h b/include/test/ut.h index 19bcb8c374..fbfde10719 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -61,7 +61,8 @@ void ut_failf(struct unit_test_state *uts, const char *fname, int line, if (val1 != val2) { \ ut_failf(uts, __FILE__, __LINE__, __func__, \ #expr1 " == " #expr2, \ - "Expected %d, got %d", val1, val2); \ + "Expected %#x (%d), got %#x (%d)", val1, val1, \ + val2, val2); \ return CMD_RET_FAILURE; \ } \ } diff --git a/include/time.h b/include/time.h index 1e9b369be7..a1149522ed 100644 --- a/include/time.h +++ b/include/time.h @@ -13,6 +13,7 @@ unsigned long get_timer(unsigned long base); * Granularity may be larger than 1us if hardware does not support this. */ unsigned long timer_get_us(void); +uint64_t get_timer_us(uint64_t base); /* * timer_test_add_offset() diff --git a/lib/Kconfig b/lib/Kconfig index 135f0b372b..b8a8509d72 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -464,6 +464,17 @@ config OF_LIBFDT particular compatible nodes. The library operates on a flattened version of the device tree. +config OF_LIBFDT_ASSUME_MASK + hex "Mask of conditions to assume for libfdt" + depends on OF_LIBFDT || FIT + default 0 + help + Use this to change the assumptions made by libfdt about the + device tree it is working with. A value of 0 means that no assumptions + are made, and libfdt is able to deal with malicious data. A value of + 0xff means all assumptions are made and any invalid data may cause + unsafe execution. See FDT_ASSUME_PERFECT, etc. in libfdt_internal.h + config OF_LIBFDT_OVERLAY bool "Enable the FDT library overlay support" depends on OF_LIBFDT @@ -481,6 +492,17 @@ config SPL_OF_LIBFDT particular compatible nodes. The library operates on a flattened version of the device tree. +config SPL_OF_LIBFDT_ASSUME_MASK + hex "Mask of conditions to assume for libfdt" + depends on SPL_OF_LIBFDT || FIT + default 0xff + help + Use this to change the assumptions made by libfdt in SPL about the + device tree it is working with. A value of 0 means that no assumptions + are made, and libfdt is able to deal with malicious data. A value of + 0xff means all assumptions are made and any invalid data may cause + unsafe execution. See FDT_ASSUME_PERFECT, etc. in libfdt_internal.h + config TPL_OF_LIBFDT bool "Enable the FDT library for TPL" default y if TPL_OF_CONTROL @@ -491,6 +513,17 @@ config TPL_OF_LIBFDT particular compatible nodes. The library operates on a flattened version of the device tree. +config TPL_OF_LIBFDT_ASSUME_MASK + hex "Mask of conditions to assume for libfdt" + depends on TPL_OF_LIBFDT || FIT + default 0xff + help + Use this to change the assumptions made by libfdt in TPL about the + device tree it is working with. A value of 0 means that no assumptions + are made, and libfdt is able to deal with malicious data. A value of + 0xff means all assumptions are made and any invalid data may cause + unsafe execution. See FDT_ASSUME_PERFECT, etc. in libfdt_internal.h + config FDT_FIXUP_PARTITIONS bool "overwrite MTD partitions in DTS through defined in 'mtdparts'" depends on OF_LIBFDT diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index d0daf7bdeb..46f35bc60b 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -5,14 +5,12 @@ * Copyright (c) 2017 Rob Clark */ -#include <env.h> -#include <malloc.h> -#include <charset.h> +#include <common.h> #include <efi_loader.h> -#include <hexdump.h> #include <env_internal.h> +#include <hexdump.h> +#include <malloc.h> #include <search.h> -#include <uuid.h> #define READ_ONLY BIT(31) diff --git a/lib/errno_str.c b/lib/errno_str.c index 0ba950e970..2e5f4a887d 100644 --- a/lib/errno_str.c +++ b/lib/errno_str.c @@ -13,7 +13,7 @@ static const char * const errno_message[] = { ERRNO_MSG(0, "Success"), ERRNO_MSG(EPERM, "Operation not permitted"), - ERRNO_MSG(ENOEN, "No such file or directory"), + ERRNO_MSG(ENOENT, "No such file or directory"), ERRNO_MSG(ESRCH, "No such process"), ERRNO_MSG(EINTR, "Interrupted system call"), ERRNO_MSG(EIO, "I/O error"), @@ -26,7 +26,7 @@ static const char * const errno_message[] = { ERRNO_MSG(ENOMEM, "Out of memory"), ERRNO_MSG(EACCES, "Permission denied"), ERRNO_MSG(EFAULT, "Bad address"), - ERRNO_MSG(ENOTBL, "Block device required"), + ERRNO_MSG(ENOTBLK, "Block device required"), ERRNO_MSG(EBUSY, "Device or resource busy"), ERRNO_MSG(EEXIST, "File exists"), ERRNO_MSG(EXDEV, "Cross-device link"), @@ -136,6 +136,8 @@ static const char * const errno_message[] = { ERRNO_MSG(EDQUOT, "Quota exceeded"), ERRNO_MSG(ENOMEDIUM, "No medium found"), ERRNO_MSG(EMEDIUMTYPE, "Wrong medium type"), + /* Message for unsupported error numbers */ + ERRNO_MSG(0, "Unknown error"), }; const char *errno_str(int errno) @@ -143,5 +145,9 @@ const char *errno_str(int errno) if (errno >= 0) return errno_message[0]; - return errno_message[abs(errno)]; + errno = -errno; + if (errno >= ARRAY_SIZE(errno_message)) + errno = ARRAY_SIZE(errno_message) - 1; + + return errno_message[errno]; } diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 17736ce665..125d9dbf26 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -242,7 +242,7 @@ int fdtdec_get_pci_bar32(struct udevice *dev, struct fdt_pci_addr *addr, uint64_t fdtdec_get_uint64(const void *blob, int node, const char *prop_name, uint64_t default_val) { - const uint64_t *cell64; + const unaligned_fdt64_t *cell64; int length; cell64 = fdt_getprop(blob, node, prop_name, &length); diff --git a/lib/libavb/avb_cmdline.c b/lib/libavb/avb_cmdline.c index d246699272..684c512bb9 100644 --- a/lib/libavb/avb_cmdline.c +++ b/lib/libavb/avb_cmdline.c @@ -39,6 +39,14 @@ char* avb_sub_cmdline(AvbOps* ops, char part_name[AVB_PART_NAME_MAX_SIZE]; char guid_buf[37]; + /* Don't attempt to query the partition guid unless its search string is + * present in the command line. Note: the original cmdline is used here, + * not the replaced one. See b/116010959. + */ + if (avb_strstr(cmdline, replace_str[n]) == NULL) { + continue; + } + if (!avb_str_concat(part_name, sizeof part_name, part_name_str[n], @@ -70,7 +78,15 @@ char* avb_sub_cmdline(AvbOps* ops, } } - avb_assert(ret != NULL); + /* It's possible there is no _PARTUUID for replacement above. + * Duplicate cmdline to ret for additional substitutions below. + */ + if (ret == NULL) { + ret = avb_strdup(cmdline); + if (ret == NULL) { + goto fail; + } + } /* Replace any additional substitutions. */ if (additional_substitutions != NULL) { @@ -198,21 +214,27 @@ static int cmdline_append_hex(AvbSlotVerifyData* slot_data, AvbSlotVerifyResult avb_append_options( AvbOps* ops, + AvbSlotVerifyFlags flags, AvbSlotVerifyData* slot_data, AvbVBMetaImageHeader* toplevel_vbmeta, AvbAlgorithmType algorithm_type, - AvbHashtreeErrorMode hashtree_error_mode) { + AvbHashtreeErrorMode hashtree_error_mode, + AvbHashtreeErrorMode resolved_hashtree_error_mode) { AvbSlotVerifyResult ret; const char* verity_mode; bool is_device_unlocked; AvbIOResult io_ret; - /* Add androidboot.vbmeta.device option. */ - if (!cmdline_append_option(slot_data, - "androidboot.vbmeta.device", - "PARTUUID=$(ANDROID_VBMETA_PARTUUID)")) { - ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; - goto out; + /* Add androidboot.vbmeta.device option... except if not using a vbmeta + * partition since it doesn't make sense in that case. + */ + if (!(flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION)) { + if (!cmdline_append_option(slot_data, + "androidboot.vbmeta.device", + "PARTUUID=$(ANDROID_VBMETA_PARTUUID)")) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto out; + } } /* Add androidboot.vbmeta.avb_version option. */ @@ -304,7 +326,7 @@ AvbSlotVerifyResult avb_append_options( const char* dm_verity_mode; char* new_ret; - switch (hashtree_error_mode) { + switch (resolved_hashtree_error_mode) { case AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE: if (!cmdline_append_option( slot_data, "androidboot.vbmeta.invalidate_on_error", "yes")) { @@ -331,6 +353,12 @@ AvbSlotVerifyResult avb_append_options( verity_mode = "logging"; dm_verity_mode = "ignore_corruption"; break; + case AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO: + // Should never get here because MANAGED_RESTART_AND_EIO is + // remapped by avb_manage_hashtree_error_mode(). + avb_assert_not_reached(); + ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT; + goto out; default: ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT; goto out; @@ -349,6 +377,13 @@ AvbSlotVerifyResult avb_append_options( ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; goto out; } + if (hashtree_error_mode == AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO) { + if (!cmdline_append_option( + slot_data, "androidboot.veritymode.managed", "yes")) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto out; + } + } ret = AVB_SLOT_VERIFY_RESULT_OK; diff --git a/lib/libavb/avb_cmdline.h b/lib/libavb/avb_cmdline.h index 9af3a99994..96539d84bd 100644 --- a/lib/libavb/avb_cmdline.h +++ b/lib/libavb/avb_cmdline.h @@ -43,10 +43,12 @@ char* avb_sub_cmdline(AvbOps* ops, AvbSlotVerifyResult avb_append_options( AvbOps* ops, + AvbSlotVerifyFlags flags, AvbSlotVerifyData* slot_data, AvbVBMetaImageHeader* toplevel_vbmeta, AvbAlgorithmType algorithm_type, - AvbHashtreeErrorMode hashtree_error_mode); + AvbHashtreeErrorMode hashtree_error_mode, + AvbHashtreeErrorMode resolved_hashtree_error_mode); /* Allocates and initializes a new command line substitution list. Free with * |avb_free_cmdline_subst_list|. diff --git a/lib/libavb/avb_descriptor.c b/lib/libavb/avb_descriptor.c index fb0b305f2c..9f03b9777a 100644 --- a/lib/libavb/avb_descriptor.c +++ b/lib/libavb/avb_descriptor.c @@ -72,7 +72,11 @@ bool avb_descriptor_foreach(const uint8_t* image_data, const AvbDescriptor* dh = (const AvbDescriptor*)p; avb_assert_aligned(dh); uint64_t nb_following = avb_be64toh(dh->num_bytes_following); - uint64_t nb_total = sizeof(AvbDescriptor) + nb_following; + uint64_t nb_total = 0; + if (!avb_safe_add(&nb_total, sizeof(AvbDescriptor), nb_following)) { + avb_error("Invalid descriptor length.\n"); + goto out; + } if ((nb_total & 7) != 0) { avb_error("Invalid descriptor length.\n"); @@ -88,7 +92,10 @@ bool avb_descriptor_foreach(const uint8_t* image_data, goto out; } - p += nb_total; + if (!avb_safe_add_to((uint64_t*)(&p), nb_total)) { + avb_error("Invalid descriptor length.\n"); + goto out; + } } ret = true; diff --git a/lib/libavb/avb_ops.h b/lib/libavb/avb_ops.h index 8bbdc7c31b..6a5c589da8 100644 --- a/lib/libavb/avb_ops.h +++ b/lib/libavb/avb_ops.h @@ -18,6 +18,7 @@ extern "C" { /* Well-known names of named persistent values. */ #define AVB_NPV_PERSISTENT_DIGEST_PREFIX "avb.persistent_digest." +#define AVB_NPV_MANAGED_VERITY_MODE "avb.managed_verity_mode" /* Return codes used for I/O operations. * @@ -171,6 +172,10 @@ struct AvbOps { * * If AVB_IO_RESULT_OK is returned then |out_is_trusted| is set - * true if trusted or false if untrusted. + * + * NOTE: If AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION is passed to + * avb_slot_verify() then this operation is never used. Instead, the + * validate_public_key_for_partition() operation is used */ AvbIOResult (*validate_vbmeta_public_key)(AvbOps* ops, const uint8_t* public_key_data, @@ -231,6 +236,9 @@ struct AvbOps { * (NUL-terminated UTF-8 string). Returns the value in * |out_size_num_bytes|. * + * If the partition doesn't exist the AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION + * error code should be returned. + * * Returns AVB_IO_RESULT_OK on success, otherwise an error code. */ AvbIOResult (*get_size_of_partition)(AvbOps* ops, @@ -253,9 +261,10 @@ struct AvbOps { * AVB_IO_RESULT_ERROR_NO_SUCH_VALUE. If |buffer_size| is smaller than the * size of the stored value, returns AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE. * - * This operation is currently only used to support persistent digests. If a - * device does not use persistent digests this function pointer can be set to - * NULL. + * This operation is currently only used to support persistent digests or the + * AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO hashtree error mode. If a + * device does not use one of these features this function pointer can be set + * to NULL. */ AvbIOResult (*read_persistent_value)(AvbOps* ops, const char* name, @@ -275,14 +284,34 @@ struct AvbOps { * AVB_IO_RESULT_ERROR_NO_SUCH_VALUE. If the |value_size| is not supported, * returns AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE. * - * This operation is currently only used to support persistent digests. If a - * device does not use persistent digests this function pointer can be set to - * NULL. + * This operation is currently only used to support persistent digests or the + * AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO hashtree error mode. If a + * device does not use one of these features this function pointer can be set + * to NULL. */ AvbIOResult (*write_persistent_value)(AvbOps* ops, const char* name, size_t value_size, const uint8_t* value); + + /* Like validate_vbmeta_public_key() but for when the flag + * AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION is being used. The name of the + * partition to get the public key for is passed in |partition_name|. + * + * Also returns the rollback index location to use for the partition, in + * |out_rollback_index_location|. + * + * Returns AVB_IO_RESULT_OK on success, otherwise an error code. + */ + AvbIOResult (*validate_public_key_for_partition)( + AvbOps* ops, + const char* partition, + const uint8_t* public_key_data, + size_t public_key_length, + const uint8_t* public_key_metadata, + size_t public_key_metadata_length, + bool* out_is_trusted, + uint32_t* out_rollback_index_location); }; #ifdef __cplusplus diff --git a/lib/libavb/avb_sha.h b/lib/libavb/avb_sha.h index 365aaadc2f..f5d02e09f2 100644 --- a/lib/libavb/avb_sha.h +++ b/lib/libavb/avb_sha.h @@ -31,8 +31,8 @@ extern "C" { /* Data structure used for SHA-256. */ typedef struct { uint32_t h[8]; - uint32_t tot_len; - uint32_t len; + uint64_t tot_len; + size_t len; uint8_t block[2 * AVB_SHA256_BLOCK_SIZE]; uint8_t buf[AVB_SHA256_DIGEST_SIZE]; /* Used for storing the final digest. */ } AvbSHA256Ctx; @@ -40,8 +40,8 @@ typedef struct { /* Data structure used for SHA-512. */ typedef struct { uint64_t h[8]; - uint32_t tot_len; - uint32_t len; + uint64_t tot_len; + size_t len; uint8_t block[2 * AVB_SHA512_BLOCK_SIZE]; uint8_t buf[AVB_SHA512_DIGEST_SIZE]; /* Used for storing the final digest. */ } AvbSHA512Ctx; @@ -50,7 +50,7 @@ typedef struct { void avb_sha256_init(AvbSHA256Ctx* ctx); /* Updates the SHA-256 context with |len| bytes from |data|. */ -void avb_sha256_update(AvbSHA256Ctx* ctx, const uint8_t* data, uint32_t len); +void avb_sha256_update(AvbSHA256Ctx* ctx, const uint8_t* data, size_t len); /* Returns the SHA-256 digest. */ uint8_t* avb_sha256_final(AvbSHA256Ctx* ctx) AVB_ATTR_WARN_UNUSED_RESULT; @@ -59,7 +59,7 @@ uint8_t* avb_sha256_final(AvbSHA256Ctx* ctx) AVB_ATTR_WARN_UNUSED_RESULT; void avb_sha512_init(AvbSHA512Ctx* ctx); /* Updates the SHA-512 context with |len| bytes from |data|. */ -void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, uint32_t len); +void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, size_t len); /* Returns the SHA-512 digest. */ uint8_t* avb_sha512_final(AvbSHA512Ctx* ctx) AVB_ATTR_WARN_UNUSED_RESULT; diff --git a/lib/libavb/avb_sha256.c b/lib/libavb/avb_sha256.c index d24c7015f6..86ecca57b7 100644 --- a/lib/libavb/avb_sha256.c +++ b/lib/libavb/avb_sha256.c @@ -29,6 +29,18 @@ *((str) + 0) = (uint8_t)((x) >> 24); \ } +#define UNPACK64(x, str) \ + { \ + *((str) + 7) = (uint8_t)x; \ + *((str) + 6) = (uint8_t)((uint64_t)x >> 8); \ + *((str) + 5) = (uint8_t)((uint64_t)x >> 16); \ + *((str) + 4) = (uint8_t)((uint64_t)x >> 24); \ + *((str) + 3) = (uint8_t)((uint64_t)x >> 32); \ + *((str) + 2) = (uint8_t)((uint64_t)x >> 40); \ + *((str) + 1) = (uint8_t)((uint64_t)x >> 48); \ + *((str) + 0) = (uint8_t)((uint64_t)x >> 56); \ + } + #define PACK32(str, x) \ { \ *(x) = ((uint32_t) * ((str) + 3)) | ((uint32_t) * ((str) + 2) << 8) | \ @@ -96,18 +108,18 @@ void avb_sha256_init(AvbSHA256Ctx* ctx) { static void SHA256_transform(AvbSHA256Ctx* ctx, const uint8_t* message, - unsigned int block_nb) { + size_t block_nb) { uint32_t w[64]; uint32_t wv[8]; uint32_t t1, t2; const unsigned char* sub_block; - int i; + size_t i; #ifndef UNROLL_LOOPS - int j; + size_t j; #endif - for (i = 0; i < (int)block_nb; i++) { + for (i = 0; i < block_nb; i++) { sub_block = message + (i << 6); #ifndef UNROLL_LOOPS @@ -293,9 +305,9 @@ static void SHA256_transform(AvbSHA256Ctx* ctx, } } -void avb_sha256_update(AvbSHA256Ctx* ctx, const uint8_t* data, uint32_t len) { - unsigned int block_nb; - unsigned int new_len, rem_len, tmp_len; +void avb_sha256_update(AvbSHA256Ctx* ctx, const uint8_t* data, size_t len) { + size_t block_nb; + size_t new_len, rem_len, tmp_len; const uint8_t* shifted_data; tmp_len = AVB_SHA256_BLOCK_SIZE - ctx->len; @@ -325,11 +337,11 @@ void avb_sha256_update(AvbSHA256Ctx* ctx, const uint8_t* data, uint32_t len) { } uint8_t* avb_sha256_final(AvbSHA256Ctx* ctx) { - unsigned int block_nb; - unsigned int pm_len; - unsigned int len_b; + size_t block_nb; + size_t pm_len; + uint64_t len_b; #ifndef UNROLL_LOOPS - int i; + size_t i; #endif block_nb = @@ -340,7 +352,7 @@ uint8_t* avb_sha256_final(AvbSHA256Ctx* ctx) { avb_memset(ctx->block + ctx->len, 0, pm_len - ctx->len); ctx->block[ctx->len] = 0x80; - UNPACK32(len_b, ctx->block + pm_len - 4); + UNPACK64(len_b, ctx->block + pm_len - 8); SHA256_transform(ctx, ctx->block, block_nb); diff --git a/lib/libavb/avb_sha512.c b/lib/libavb/avb_sha512.c index a5e7297aa7..b19054fc74 100644 --- a/lib/libavb/avb_sha512.c +++ b/lib/libavb/avb_sha512.c @@ -127,14 +127,14 @@ void avb_sha512_init(AvbSHA512Ctx* ctx) { static void SHA512_transform(AvbSHA512Ctx* ctx, const uint8_t* message, - unsigned int block_nb) { + size_t block_nb) { uint64_t w[80]; uint64_t wv[8]; uint64_t t1, t2; const uint8_t* sub_block; - int i, j; + size_t i, j; - for (i = 0; i < (int)block_nb; i++) { + for (i = 0; i < block_nb; i++) { sub_block = message + (i << 7); #ifdef UNROLL_LOOPS_SHA512 @@ -291,9 +291,9 @@ static void SHA512_transform(AvbSHA512Ctx* ctx, } } -void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, uint32_t len) { - unsigned int block_nb; - unsigned int new_len, rem_len, tmp_len; +void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, size_t len) { + size_t block_nb; + size_t new_len, rem_len, tmp_len; const uint8_t* shifted_data; tmp_len = AVB_SHA512_BLOCK_SIZE - ctx->len; @@ -323,12 +323,12 @@ void avb_sha512_update(AvbSHA512Ctx* ctx, const uint8_t* data, uint32_t len) { } uint8_t* avb_sha512_final(AvbSHA512Ctx* ctx) { - unsigned int block_nb; - unsigned int pm_len; - unsigned int len_b; + size_t block_nb; + size_t pm_len; + uint64_t len_b; #ifndef UNROLL_LOOPS_SHA512 - int i; + size_t i; #endif block_nb = @@ -339,7 +339,7 @@ uint8_t* avb_sha512_final(AvbSHA512Ctx* ctx) { avb_memset(ctx->block + ctx->len, 0, pm_len - ctx->len); ctx->block[ctx->len] = 0x80; - UNPACK32(len_b, ctx->block + pm_len - 4); + UNPACK64(len_b, ctx->block + pm_len - 8); SHA512_transform(ctx, ctx->block, block_nb); diff --git a/lib/libavb/avb_slot_verify.c b/lib/libavb/avb_slot_verify.c index a941850d93..c0defdf9c9 100644 --- a/lib/libavb/avb_slot_verify.c +++ b/lib/libavb/avb_slot_verify.c @@ -24,6 +24,14 @@ /* Maximum size of a vbmeta image - 64 KiB. */ #define VBMETA_MAX_SIZE (64 * 1024) +static AvbSlotVerifyResult initialize_persistent_digest( + AvbOps* ops, + const char* part_name, + const char* persistent_value_name, + size_t digest_size, + const uint8_t* initial_digest, + uint8_t* out_digest); + /* Helper function to see if we should continue with verification in * allow_verification_error=true mode if something goes wrong. See the * comments for the avb_slot_verify() function for more information. @@ -114,9 +122,26 @@ static AvbSlotVerifyResult load_full_partition(AvbOps* ops, return AVB_SLOT_VERIFY_RESULT_OK; } +/* Reads a persistent digest stored as a named persistent value corresponding to + * the given |part_name|. The value is returned in |out_digest| which must point + * to |expected_digest_size| bytes. If there is no digest stored for |part_name| + * it can be initialized by providing a non-NULL |initial_digest| of length + * |expected_digest_size|. This automatic initialization will only occur if the + * device is currently locked. The |initial_digest| may be NULL. + * + * Returns AVB_SLOT_VERIFY_RESULT_OK on success, otherwise returns an + * AVB_SLOT_VERIFY_RESULT_ERROR_* error code. + * + * If the value does not exist, is not supported, or is not populated, and + * |initial_digest| is NULL, returns + * AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA. If |expected_digest_size| does + * not match the stored digest size, also returns + * AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA. + */ static AvbSlotVerifyResult read_persistent_digest(AvbOps* ops, const char* part_name, size_t expected_digest_size, + const uint8_t* initial_digest, uint8_t* out_digest) { char* persistent_value_name = NULL; AvbIOResult io_ret = AVB_IO_RESULT_OK; @@ -131,30 +156,106 @@ static AvbSlotVerifyResult read_persistent_digest(AvbOps* ops, if (persistent_value_name == NULL) { return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; } + io_ret = ops->read_persistent_value(ops, persistent_value_name, expected_digest_size, out_digest, &stored_digest_size); + + // If no such named persistent value exists and an initial digest value was + // given, initialize the named persistent value with the given digest. If + // initialized successfully, this will recurse into this function but with a + // NULL initial_digest. + if (io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_VALUE && initial_digest) { + AvbSlotVerifyResult ret = + initialize_persistent_digest(ops, + part_name, + persistent_value_name, + expected_digest_size, + initial_digest, + out_digest); + avb_free(persistent_value_name); + return ret; + } avb_free(persistent_value_name); + if (io_ret == AVB_IO_RESULT_ERROR_OOM) { return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; } else if (io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_VALUE) { + // Treat a missing persistent value as a verification error, which is + // ignoreable, rather than a metadata error which is not. avb_errorv(part_name, ": Persistent digest does not exist.\n", NULL); - return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; + return AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION; } else if (io_ret == AVB_IO_RESULT_ERROR_INVALID_VALUE_SIZE || - io_ret == AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE || - expected_digest_size != stored_digest_size) { + io_ret == AVB_IO_RESULT_ERROR_INSUFFICIENT_SPACE) { avb_errorv( part_name, ": Persistent digest is not of expected size.\n", NULL); return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; } else if (io_ret != AVB_IO_RESULT_OK) { avb_errorv(part_name, ": Error reading persistent digest.\n", NULL); return AVB_SLOT_VERIFY_RESULT_ERROR_IO; + } else if (expected_digest_size != stored_digest_size) { + avb_errorv( + part_name, ": Persistent digest is not of expected size.\n", NULL); + return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; } return AVB_SLOT_VERIFY_RESULT_OK; } +static AvbSlotVerifyResult initialize_persistent_digest( + AvbOps* ops, + const char* part_name, + const char* persistent_value_name, + size_t digest_size, + const uint8_t* initial_digest, + uint8_t* out_digest) { + AvbSlotVerifyResult ret; + AvbIOResult io_ret = AVB_IO_RESULT_OK; + bool is_device_unlocked = true; + + io_ret = ops->read_is_device_unlocked(ops, &is_device_unlocked); + if (io_ret == AVB_IO_RESULT_ERROR_OOM) { + return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + } else if (io_ret != AVB_IO_RESULT_OK) { + avb_error("Error getting device lock state.\n"); + return AVB_SLOT_VERIFY_RESULT_ERROR_IO; + } + + if (is_device_unlocked) { + avb_debugv(part_name, + ": Digest does not exist, device unlocked so not initializing " + "digest.\n", + NULL); + return AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION; + } + + // Device locked; initialize digest with given initial value. + avb_debugv(part_name, + ": Digest does not exist, initializing persistent digest.\n", + NULL); + io_ret = ops->write_persistent_value( + ops, persistent_value_name, digest_size, initial_digest); + if (io_ret == AVB_IO_RESULT_ERROR_OOM) { + return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + } else if (io_ret != AVB_IO_RESULT_OK) { + avb_errorv(part_name, ": Error initializing persistent digest.\n", NULL); + return AVB_SLOT_VERIFY_RESULT_ERROR_IO; + } + + // To ensure that the digest value was written successfully - and avoid a + // scenario where the digest is simply 'initialized' on every verify - recurse + // into read_persistent_digest to read back the written value. The NULL + // initial_digest ensures that this will not recurse again. + ret = read_persistent_digest(ops, part_name, digest_size, NULL, out_digest); + if (ret != AVB_SLOT_VERIFY_RESULT_OK) { + avb_errorv(part_name, + ": Reading back initialized persistent digest failed!\n", + NULL); + } + return ret; +} + static AvbSlotVerifyResult load_and_verify_hash_partition( AvbOps* ops, const char* const* requested_partitions, @@ -248,24 +349,16 @@ static AvbSlotVerifyResult load_and_verify_hash_partition( */ image_size = hash_desc.image_size; if (allow_verification_error) { - if (ops->get_size_of_partition == NULL) { - avb_errorv(part_name, - ": The get_size_of_partition() operation is " - "not implemented so we may not load the entire partition. " - "Please implement.", - NULL); - } else { - io_ret = ops->get_size_of_partition(ops, part_name, &image_size); - if (io_ret == AVB_IO_RESULT_ERROR_OOM) { - ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; - goto out; - } else if (io_ret != AVB_IO_RESULT_OK) { - avb_errorv(part_name, ": Error determining partition size.\n", NULL); - ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; - goto out; - } - avb_debugv(part_name, ": Loading entire partition.\n", NULL); + io_ret = ops->get_size_of_partition(ops, part_name, &image_size); + if (io_ret == AVB_IO_RESULT_ERROR_OOM) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto out; + } else if (io_ret != AVB_IO_RESULT_OK) { + avb_errorv(part_name, ": Error determining partition size.\n", NULL); + ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; + goto out; } + avb_debugv(part_name, ": Loading entire partition.\n", NULL); } ret = load_full_partition( @@ -273,19 +366,27 @@ static AvbSlotVerifyResult load_and_verify_hash_partition( if (ret != AVB_SLOT_VERIFY_RESULT_OK) { goto out; } - + // Although only one of the type might be used, we have to defined the + // structure here so that they would live outside the 'if/else' scope to be + // used later. + AvbSHA256Ctx sha256_ctx; + AvbSHA512Ctx sha512_ctx; + size_t image_size_to_hash = hash_desc.image_size; + // If we allow verification error and the whole partition is smaller than + // image size in hash descriptor, we just hash the whole partition. + if (image_size_to_hash > image_size) { + image_size_to_hash = image_size; + } if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha256") == 0) { - AvbSHA256Ctx sha256_ctx; avb_sha256_init(&sha256_ctx); avb_sha256_update(&sha256_ctx, desc_salt, hash_desc.salt_len); - avb_sha256_update(&sha256_ctx, image_buf, hash_desc.image_size); + avb_sha256_update(&sha256_ctx, image_buf, image_size_to_hash); digest = avb_sha256_final(&sha256_ctx); digest_len = AVB_SHA256_DIGEST_SIZE; } else if (avb_strcmp((const char*)hash_desc.hash_algorithm, "sha512") == 0) { - AvbSHA512Ctx sha512_ctx; avb_sha512_init(&sha512_ctx); avb_sha512_update(&sha512_ctx, desc_salt, hash_desc.salt_len); - avb_sha512_update(&sha512_ctx, image_buf, hash_desc.image_size); + avb_sha512_update(&sha512_ctx, image_buf, image_size_to_hash); digest = avb_sha512_final(&sha512_ctx); digest_len = AVB_SHA512_DIGEST_SIZE; } else { @@ -295,18 +396,21 @@ static AvbSlotVerifyResult load_and_verify_hash_partition( } if (hash_desc.digest_len == 0) { - // Expect a match to a persistent digest. + /* Expect a match to a persistent digest. */ avb_debugv(part_name, ": No digest, using persistent digest.\n", NULL); expected_digest_len = digest_len; expected_digest = expected_digest_buf; avb_assert(expected_digest_len <= sizeof(expected_digest_buf)); - ret = - read_persistent_digest(ops, part_name, digest_len, expected_digest_buf); + /* Pass |digest| as the |initial_digest| so devices not yet initialized get + * initialized to the current partition digest. + */ + ret = read_persistent_digest( + ops, part_name, digest_len, digest, expected_digest_buf); if (ret != AVB_SLOT_VERIFY_RESULT_OK) { goto out; } } else { - // Expect a match to the digest in the descriptor. + /* Expect a match to the digest in the descriptor. */ expected_digest_len = hash_desc.digest_len; expected_digest = desc_digest; } @@ -365,12 +469,6 @@ static AvbSlotVerifyResult load_requested_partitions( bool image_preloaded = false; size_t n; - if (ops->get_size_of_partition == NULL) { - avb_error("get_size_of_partition() not implemented.\n"); - ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT; - goto out; - } - for (n = 0; requested_partitions[n] != NULL; n++) { char part_name[AVB_PART_NAME_MAX_SIZE]; AvbIOResult io_ret; @@ -441,6 +539,7 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( AvbOps* ops, const char* const* requested_partitions, const char* ab_suffix, + AvbSlotVerifyFlags flags, bool allow_verification_error, AvbVBMetaImageFlags toplevel_vbmeta_flags, int rollback_index_location, @@ -467,7 +566,7 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( size_t num_descriptors; size_t n; bool is_main_vbmeta; - bool is_vbmeta_partition; + bool look_for_vbmeta_footer; AvbVBMetaData* vbmeta_image_data = NULL; ret = AVB_SLOT_VERIFY_RESULT_OK; @@ -478,8 +577,20 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( * rollback_index_location to determine whether we're the main * vbmeta struct. */ - is_main_vbmeta = (rollback_index_location == 0); - is_vbmeta_partition = (avb_strcmp(partition_name, "vbmeta") == 0); + is_main_vbmeta = false; + if (rollback_index_location == 0) { + if ((flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION) == 0) { + is_main_vbmeta = true; + } + } + + /* Don't use footers for vbmeta partitions ('vbmeta' or + * 'vbmeta_<partition_name>'). + */ + look_for_vbmeta_footer = true; + if (avb_strncmp(partition_name, "vbmeta", avb_strlen("vbmeta")) == 0) { + look_for_vbmeta_footer = false; + } if (!avb_validate_utf8((const uint8_t*)partition_name, partition_name_len)) { avb_error("Partition name is not valid UTF-8.\n"); @@ -487,7 +598,7 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( goto out; } - /* Construct full partition name. */ + /* Construct full partition name e.g. system_a. */ if (!avb_str_concat(full_partition_name, sizeof full_partition_name, partition_name, @@ -499,19 +610,15 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( goto out; } - avb_debugv("Loading vbmeta struct from partition '", - full_partition_name, - "'.\n", - NULL); - - /* If we're loading from the main vbmeta partition, the vbmeta - * struct is in the beginning. Otherwise we have to locate it via a - * footer. + /* If we're loading from the main vbmeta partition, the vbmeta struct is in + * the beginning. Otherwise we may have to locate it via a footer... if no + * footer is found, we look in the beginning to support e.g. vbmeta_<org> + * partitions holding data for e.g. super partitions (b/80195851 for + * rationale). */ - if (is_vbmeta_partition) { - vbmeta_offset = 0; - vbmeta_size = VBMETA_MAX_SIZE; - } else { + vbmeta_offset = 0; + vbmeta_size = VBMETA_MAX_SIZE; + if (look_for_vbmeta_footer) { uint8_t footer_buf[AVB_FOOTER_SIZE]; size_t footer_num_read; AvbFooter footer; @@ -534,21 +641,17 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( if (!avb_footer_validate_and_byteswap((const AvbFooter*)footer_buf, &footer)) { - avb_errorv(full_partition_name, ": Error validating footer.\n", NULL); - ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; - goto out; - } - - /* Basic footer sanity check since the data is untrusted. */ - if (footer.vbmeta_size > VBMETA_MAX_SIZE) { - avb_errorv( - full_partition_name, ": Invalid vbmeta size in footer.\n", NULL); - ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; - goto out; + avb_debugv(full_partition_name, ": No footer detected.\n", NULL); + } else { + /* Basic footer sanity check since the data is untrusted. */ + if (footer.vbmeta_size > VBMETA_MAX_SIZE) { + avb_errorv( + full_partition_name, ": Invalid vbmeta size in footer.\n", NULL); + } else { + vbmeta_offset = footer.vbmeta_offset; + vbmeta_size = footer.vbmeta_size; + } } - - vbmeta_offset = footer.vbmeta_offset; - vbmeta_size = footer.vbmeta_size; } vbmeta_buf = avb_malloc(vbmeta_size); @@ -557,6 +660,18 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( goto out; } + if (vbmeta_offset != 0) { + avb_debugv("Loading vbmeta struct in footer from partition '", + full_partition_name, + "'.\n", + NULL); + } else { + avb_debugv("Loading vbmeta struct from partition '", + full_partition_name, + "'.\n", + NULL); + } + io_ret = ops->read_from_partition(ops, full_partition_name, vbmeta_offset, @@ -571,13 +686,14 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( * go try to get it from the boot partition instead. */ if (is_main_vbmeta && io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION && - is_vbmeta_partition) { + !look_for_vbmeta_footer) { avb_debugv(full_partition_name, ": No such partition. Trying 'boot' instead.\n", NULL); ret = load_and_verify_vbmeta(ops, requested_partitions, ab_suffix, + flags, allow_verification_error, 0 /* toplevel_vbmeta_flags */, 0 /* rollback_index_location */, @@ -655,6 +771,8 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( } } + uint32_t rollback_index_location_to_use = rollback_index_location; + /* Check if key used to make signature matches what is expected. */ if (pk_data != NULL) { if (expected_public_key != NULL) { @@ -682,9 +800,27 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( pk_metadata_len = vbmeta_header.public_key_metadata_size; } - avb_assert(is_main_vbmeta); - io_ret = ops->validate_vbmeta_public_key( - ops, pk_data, pk_len, pk_metadata, pk_metadata_len, &key_is_trusted); + // If we're not using a vbmeta partition, need to use another AvbOps... + if (flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION) { + io_ret = ops->validate_public_key_for_partition( + ops, + full_partition_name, + pk_data, + pk_len, + pk_metadata, + pk_metadata_len, + &key_is_trusted, + &rollback_index_location_to_use); + } else { + avb_assert(is_main_vbmeta); + io_ret = ops->validate_vbmeta_public_key(ops, + pk_data, + pk_len, + pk_metadata, + pk_metadata_len, + &key_is_trusted); + } + if (io_ret == AVB_IO_RESULT_ERROR_OOM) { ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; goto out; @@ -709,7 +845,7 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( /* Check rollback index. */ io_ret = ops->read_rollback_index( - ops, rollback_index_location, &stored_rollback_index); + ops, rollback_index_location_to_use, &stored_rollback_index); if (io_ret == AVB_IO_RESULT_ERROR_OOM) { ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; goto out; @@ -735,7 +871,9 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( if (is_main_vbmeta) { avb_assert(slot_data->num_vbmeta_images == 0); } else { - avb_assert(slot_data->num_vbmeta_images > 0); + if (!(flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION)) { + avb_assert(slot_data->num_vbmeta_images > 0); + } } if (slot_data->num_vbmeta_images == MAX_NUMBER_OF_VBMETA_IMAGES) { avb_errorv(full_partition_name, ": Too many vbmeta images.\n", NULL); @@ -859,6 +997,7 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( load_and_verify_vbmeta(ops, requested_partitions, ab_suffix, + flags, allow_verification_error, toplevel_vbmeta_flags, chain_desc.rollback_index_location, @@ -1019,7 +1158,11 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( goto out; } - ret = read_persistent_digest(ops, part_name, digest_len, digest_buf); + ret = read_persistent_digest(ops, + part_name, + digest_len, + NULL /* initial_digest */, + digest_buf); if (ret != AVB_SLOT_VERIFY_RESULT_OK) { goto out; } @@ -1043,7 +1186,8 @@ static AvbSlotVerifyResult load_and_verify_vbmeta( } } - if (rollback_index_location >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS) { + if (rollback_index_location < 0 || + rollback_index_location >= AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS) { avb_errorv( full_partition_name, ": Invalid rollback_index_location.\n", NULL); ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; @@ -1072,13 +1216,137 @@ out: return ret; } +static AvbIOResult avb_manage_hashtree_error_mode( + AvbOps* ops, + AvbSlotVerifyFlags flags, + AvbSlotVerifyData* data, + AvbHashtreeErrorMode* out_hashtree_error_mode) { + AvbHashtreeErrorMode ret = AVB_HASHTREE_ERROR_MODE_RESTART; + AvbIOResult io_ret = AVB_IO_RESULT_OK; + uint8_t vbmeta_digest_sha256[AVB_SHA256_DIGEST_SIZE]; + uint8_t stored_vbmeta_digest_sha256[AVB_SHA256_DIGEST_SIZE]; + size_t num_bytes_read; + + avb_assert(out_hashtree_error_mode != NULL); + avb_assert(ops->read_persistent_value != NULL); + avb_assert(ops->write_persistent_value != NULL); + + // If we're rebooting because of dm-verity corruption, make a note of + // the vbmeta hash so we can stay in 'eio' mode until things change. + if (flags & AVB_SLOT_VERIFY_FLAGS_RESTART_CAUSED_BY_HASHTREE_CORRUPTION) { + avb_debug( + "Rebooting because of dm-verity corruption - " + "recording OS instance and using 'eio' mode.\n"); + avb_slot_verify_data_calculate_vbmeta_digest( + data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest_sha256); + io_ret = ops->write_persistent_value(ops, + AVB_NPV_MANAGED_VERITY_MODE, + AVB_SHA256_DIGEST_SIZE, + vbmeta_digest_sha256); + if (io_ret != AVB_IO_RESULT_OK) { + avb_error("Error writing to " AVB_NPV_MANAGED_VERITY_MODE ".\n"); + goto out; + } + ret = AVB_HASHTREE_ERROR_MODE_EIO; + io_ret = AVB_IO_RESULT_OK; + goto out; + } + + // See if we're in 'eio' mode. + io_ret = ops->read_persistent_value(ops, + AVB_NPV_MANAGED_VERITY_MODE, + AVB_SHA256_DIGEST_SIZE, + stored_vbmeta_digest_sha256, + &num_bytes_read); + if (io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_VALUE || + (io_ret == AVB_IO_RESULT_OK && num_bytes_read == 0)) { + // This is the usual case ('eio' mode not set). + avb_debug("No dm-verity corruption - using in 'restart' mode.\n"); + ret = AVB_HASHTREE_ERROR_MODE_RESTART; + io_ret = AVB_IO_RESULT_OK; + goto out; + } else if (io_ret != AVB_IO_RESULT_OK) { + avb_error("Error reading from " AVB_NPV_MANAGED_VERITY_MODE ".\n"); + goto out; + } + if (num_bytes_read != AVB_SHA256_DIGEST_SIZE) { + avb_error( + "Unexpected number of bytes read from " AVB_NPV_MANAGED_VERITY_MODE + ".\n"); + io_ret = AVB_IO_RESULT_ERROR_IO; + goto out; + } + + // OK, so we're currently in 'eio' mode and the vbmeta digest of the OS + // that caused this is in |stored_vbmeta_digest_sha256| ... now see if + // the OS we're dealing with now is the same. + avb_slot_verify_data_calculate_vbmeta_digest( + data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest_sha256); + if (avb_memcmp(vbmeta_digest_sha256, + stored_vbmeta_digest_sha256, + AVB_SHA256_DIGEST_SIZE) == 0) { + // It's the same so we're still in 'eio' mode. + avb_debug("Same OS instance detected - staying in 'eio' mode.\n"); + ret = AVB_HASHTREE_ERROR_MODE_EIO; + io_ret = AVB_IO_RESULT_OK; + } else { + // It did change! + avb_debug( + "New OS instance detected - changing from 'eio' to 'restart' mode.\n"); + io_ret = + ops->write_persistent_value(ops, + AVB_NPV_MANAGED_VERITY_MODE, + 0, // This clears the persistent property. + vbmeta_digest_sha256); + if (io_ret != AVB_IO_RESULT_OK) { + avb_error("Error clearing " AVB_NPV_MANAGED_VERITY_MODE ".\n"); + goto out; + } + ret = AVB_HASHTREE_ERROR_MODE_RESTART; + io_ret = AVB_IO_RESULT_OK; + } + +out: + *out_hashtree_error_mode = ret; + return io_ret; +} + +static bool has_system_partition(AvbOps* ops, const char* ab_suffix) { + char part_name[AVB_PART_NAME_MAX_SIZE]; + char* system_part_name = "system"; + char guid_buf[37]; + AvbIOResult io_ret; + + if (!avb_str_concat(part_name, + sizeof part_name, + system_part_name, + avb_strlen(system_part_name), + ab_suffix, + avb_strlen(ab_suffix))) { + avb_error("System partition name and suffix does not fit.\n"); + return false; + } + + io_ret = ops->get_unique_guid_for_partition( + ops, part_name, guid_buf, sizeof guid_buf); + if (io_ret == AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION) { + avb_debug("No system partition.\n"); + return false; + } else if (io_ret != AVB_IO_RESULT_OK) { + avb_error("Error getting unique GUID for system partition.\n"); + return false; + } + + return true; +} + AvbSlotVerifyResult avb_slot_verify(AvbOps* ops, const char* const* requested_partitions, const char* ab_suffix, AvbSlotVerifyFlags flags, AvbHashtreeErrorMode hashtree_error_mode, AvbSlotVerifyData** out_data) { - AvbSlotVerifyResult ret; + AvbSlotVerifyResult ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT; AvbSlotVerifyData* slot_data = NULL; AvbAlgorithmType algorithm_type = AVB_ALGORITHM_TYPE_NONE; bool using_boot_for_vbmeta = false; @@ -1087,14 +1355,10 @@ AvbSlotVerifyResult avb_slot_verify(AvbOps* ops, (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR); AvbCmdlineSubstList* additional_cmdline_subst = NULL; - /* Fail early if we're missing the AvbOps needed for slot verification. - * - * For now, handle get_size_of_partition() not being implemented. In - * a later release we may change that. - */ + /* Fail early if we're missing the AvbOps needed for slot verification. */ avb_assert(ops->read_is_device_unlocked != NULL); avb_assert(ops->read_from_partition != NULL); - avb_assert(ops->validate_vbmeta_public_key != NULL); + avb_assert(ops->get_size_of_partition != NULL); avb_assert(ops->read_rollback_index != NULL); avb_assert(ops->get_unique_guid_for_partition != NULL); @@ -1112,6 +1376,36 @@ AvbSlotVerifyResult avb_slot_verify(AvbOps* ops, goto fail; } + /* Make sure passed-in AvbOps support persistent values if + * asking for libavb to manage verity state. + */ + if (hashtree_error_mode == AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO) { + if (ops->read_persistent_value == NULL || + ops->write_persistent_value == NULL) { + avb_error( + "Persistent values required for " + "AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO " + "but are not implemented in given AvbOps.\n"); + ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT; + goto fail; + } + } + + /* Make sure passed-in AvbOps support verifying public keys and getting + * rollback index location if not using a vbmeta partition. + */ + if (flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION) { + if (ops->validate_public_key_for_partition == NULL) { + avb_error( + "AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION was passed but the " + "validate_public_key_for_partition() operation isn't implemented.\n"); + ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT; + goto fail; + } + } else { + avb_assert(ops->validate_vbmeta_public_key != NULL); + } + slot_data = avb_calloc(sizeof(AvbSlotVerifyData)); if (slot_data == NULL) { ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; @@ -1136,99 +1430,163 @@ AvbSlotVerifyResult avb_slot_verify(AvbOps* ops, goto fail; } - ret = load_and_verify_vbmeta(ops, - requested_partitions, - ab_suffix, - allow_verification_error, - 0 /* toplevel_vbmeta_flags */, - 0 /* rollback_index_location */, - "vbmeta", - avb_strlen("vbmeta"), - NULL /* expected_public_key */, - 0 /* expected_public_key_length */, - slot_data, - &algorithm_type, - additional_cmdline_subst); - if (!allow_verification_error && ret != AVB_SLOT_VERIFY_RESULT_OK) { + if (flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION) { + if (requested_partitions == NULL || requested_partitions[0] == NULL) { + avb_fatal( + "Requested partitions cannot be empty when using " + "AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION"); + ret = AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT; + goto fail; + } + + /* No vbmeta partition, go through each of the requested partitions... */ + for (size_t n = 0; requested_partitions[n] != NULL; n++) { + ret = load_and_verify_vbmeta(ops, + requested_partitions, + ab_suffix, + flags, + allow_verification_error, + 0 /* toplevel_vbmeta_flags */, + 0 /* rollback_index_location */, + requested_partitions[n], + avb_strlen(requested_partitions[n]), + NULL /* expected_public_key */, + 0 /* expected_public_key_length */, + slot_data, + &algorithm_type, + additional_cmdline_subst); + if (!allow_verification_error && ret != AVB_SLOT_VERIFY_RESULT_OK) { + goto fail; + } + } + + } else { + /* Usual path, load "vbmeta"... */ + ret = load_and_verify_vbmeta(ops, + requested_partitions, + ab_suffix, + flags, + allow_verification_error, + 0 /* toplevel_vbmeta_flags */, + 0 /* rollback_index_location */, + "vbmeta", + avb_strlen("vbmeta"), + NULL /* expected_public_key */, + 0 /* expected_public_key_length */, + slot_data, + &algorithm_type, + additional_cmdline_subst); + if (!allow_verification_error && ret != AVB_SLOT_VERIFY_RESULT_OK) { + goto fail; + } + } + + if (!result_should_continue(ret)) { goto fail; } /* If things check out, mangle the kernel command-line as needed. */ - if (result_should_continue(ret)) { + if (!(flags & AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION)) { if (avb_strcmp(slot_data->vbmeta_images[0].partition_name, "vbmeta") != 0) { avb_assert( avb_strcmp(slot_data->vbmeta_images[0].partition_name, "boot") == 0); using_boot_for_vbmeta = true; } + } - /* Byteswap top-level vbmeta header since we'll need it below. */ - avb_vbmeta_image_header_to_host_byte_order( - (const AvbVBMetaImageHeader*)slot_data->vbmeta_images[0].vbmeta_data, - &toplevel_vbmeta); + /* Byteswap top-level vbmeta header since we'll need it below. */ + avb_vbmeta_image_header_to_host_byte_order( + (const AvbVBMetaImageHeader*)slot_data->vbmeta_images[0].vbmeta_data, + &toplevel_vbmeta); - /* Fill in |ab_suffix| field. */ - slot_data->ab_suffix = avb_strdup(ab_suffix); - if (slot_data->ab_suffix == NULL) { - ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; - goto fail; - } + /* Fill in |ab_suffix| field. */ + slot_data->ab_suffix = avb_strdup(ab_suffix); + if (slot_data->ab_suffix == NULL) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto fail; + } - /* If verification is disabled, we are done ... we specifically - * don't want to add any androidboot.* options since verification - * is disabled. + /* If verification is disabled, we are done ... we specifically + * don't want to add any androidboot.* options since verification + * is disabled. + */ + if (toplevel_vbmeta.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) { + /* Since verification is disabled we didn't process any + * descriptors and thus there's no cmdline... so set root= such + * that the system partition is mounted. */ - if (toplevel_vbmeta.flags & AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED) { - /* Since verification is disabled we didn't process any - * descriptors and thus there's no cmdline... so set root= such - * that the system partition is mounted. - */ - avb_assert(slot_data->cmdline == NULL); + avb_assert(slot_data->cmdline == NULL); + // Devices with dynamic partitions won't have system partition. + // Instead, it has a large super partition to accommodate *.img files. + // See b/119551429 for details. + if (has_system_partition(ops, ab_suffix)) { slot_data->cmdline = avb_strdup("root=PARTUUID=$(ANDROID_SYSTEM_PARTUUID)"); - if (slot_data->cmdline == NULL) { - ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; - goto fail; - } } else { - /* Add options - any failure in avb_append_options() is either an - * I/O or OOM error. - */ - AvbSlotVerifyResult sub_ret = avb_append_options(ops, - slot_data, - &toplevel_vbmeta, - algorithm_type, - hashtree_error_mode); - if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) { - ret = sub_ret; - goto fail; - } + // The |cmdline| field should be a NUL-terminated string. + slot_data->cmdline = avb_strdup(""); } - - /* Substitute $(ANDROID_SYSTEM_PARTUUID) and friends. */ - if (slot_data->cmdline != NULL) { - char* new_cmdline; - new_cmdline = avb_sub_cmdline(ops, - slot_data->cmdline, - ab_suffix, - using_boot_for_vbmeta, - additional_cmdline_subst); - if (new_cmdline != slot_data->cmdline) { - if (new_cmdline == NULL) { + if (slot_data->cmdline == NULL) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto fail; + } + } else { + /* If requested, manage dm-verity mode... */ + AvbHashtreeErrorMode resolved_hashtree_error_mode = hashtree_error_mode; + if (hashtree_error_mode == + AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO) { + AvbIOResult io_ret; + io_ret = avb_manage_hashtree_error_mode( + ops, flags, slot_data, &resolved_hashtree_error_mode); + if (io_ret != AVB_IO_RESULT_OK) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; + if (io_ret == AVB_IO_RESULT_ERROR_OOM) { ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; - goto fail; } - avb_free(slot_data->cmdline); - slot_data->cmdline = new_cmdline; + goto fail; } } + slot_data->resolved_hashtree_error_mode = resolved_hashtree_error_mode; - if (out_data != NULL) { - *out_data = slot_data; - } else { - avb_slot_verify_data_free(slot_data); + /* Add options... */ + AvbSlotVerifyResult sub_ret; + sub_ret = avb_append_options(ops, + flags, + slot_data, + &toplevel_vbmeta, + algorithm_type, + hashtree_error_mode, + resolved_hashtree_error_mode); + if (sub_ret != AVB_SLOT_VERIFY_RESULT_OK) { + ret = sub_ret; + goto fail; + } + } + + /* Substitute $(ANDROID_SYSTEM_PARTUUID) and friends. */ + if (slot_data->cmdline != NULL && avb_strlen(slot_data->cmdline) != 0) { + char* new_cmdline; + new_cmdline = avb_sub_cmdline(ops, + slot_data->cmdline, + ab_suffix, + using_boot_for_vbmeta, + additional_cmdline_subst); + if (new_cmdline != slot_data->cmdline) { + if (new_cmdline == NULL) { + ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; + goto fail; + } + avb_free(slot_data->cmdline); + slot_data->cmdline = new_cmdline; } } + if (out_data != NULL) { + *out_data = slot_data; + } else { + avb_slot_verify_data_free(slot_data); + } + avb_free_cmdline_subst_list(additional_cmdline_subst); additional_cmdline_subst = NULL; diff --git a/lib/libavb/avb_slot_verify.h b/lib/libavb/avb_slot_verify.h index 73fd70d4ce..8d0fa53693 100644 --- a/lib/libavb/avb_slot_verify.h +++ b/lib/libavb/avb_slot_verify.h @@ -51,12 +51,25 @@ typedef enum { * be used ONLY for diagnostics and debugging. It cannot be used * unless AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR is also * used. + * + * AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO means that either + * AVB_HASHTREE_ERROR_MODE_RESTART or AVB_HASHTREE_ERROR_MODE_EIO is used + * depending on state. This mode implements a state machine whereby + * AVB_HASHTREE_ERROR_MODE_RESTART is used by default and when + * AVB_SLOT_VERIFY_FLAGS_RESTART_CAUSED_BY_HASHTREE_CORRUPTION is passed the + * mode transitions to AVB_HASHTREE_ERROR_MODE_EIO. When a new OS has been + * detected the device transitions back to the AVB_HASHTREE_ERROR_MODE_RESTART + * mode. To do this persistent storage is needed - specifically this means that + * the passed in AvbOps will need to have the read_persistent_value() and + * write_persistent_value() operations implemented. The name of the persistent + * value used is "avb.managed_verity_mode" and 32 bytes of storage is needed. */ typedef enum { AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE, AVB_HASHTREE_ERROR_MODE_RESTART, AVB_HASHTREE_ERROR_MODE_EIO, - AVB_HASHTREE_ERROR_MODE_LOGGING + AVB_HASHTREE_ERROR_MODE_LOGGING, + AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO } AvbHashtreeErrorMode; /* Flags that influence how avb_slot_verify() works. @@ -80,10 +93,26 @@ typedef enum { * contents loaded from |requested_partition| will be the contents of * the entire partition instead of just the size specified in the hash * descriptor. + * + * The AVB_SLOT_VERIFY_FLAGS_RESTART_CAUSED_BY_HASHTREE_CORRUPTION flag + * should be set if using AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO + * and the reason the boot loader is running is because the device + * was restarted by the dm-verity driver. + * + * If the AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION flag is set then + * data won't be loaded from the "vbmeta" partition and the + * |validate_vbmeta_public_key| operation is never called. Instead, the + * vbmeta structs in |requested_partitions| are loaded and processed and the + * |validate_public_key_for_partition| operation is called for each of these + * vbmeta structs. This flag is useful when booting into recovery on a device + * not using A/B - see section "Booting into recovery" in README.md for + * more information. */ typedef enum { AVB_SLOT_VERIFY_FLAGS_NONE = 0, - AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR = (1 << 0) + AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR = (1 << 0), + AVB_SLOT_VERIFY_FLAGS_RESTART_CAUSED_BY_HASHTREE_CORRUPTION = (1 << 1), + AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION = (1 << 2), } AvbSlotVerifyFlags; /* Get a textual representation of |result|. */ @@ -188,6 +217,10 @@ typedef struct { * set to AVB_HASHTREE_ERROR_MODE_EIO, and 'logging' if it's set to * AVB_HASHTREE_ERROR_MODE_LOGGING. * + * androidboot.veritymode.managed: This is set to 'yes' only + * if hashtree validation isn't disabled and the passed-in hashtree + * error mode is AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO. + * * androidboot.vbmeta.invalidate_on_error: This is set to 'yes' only * if hashtree validation isn't disabled and the passed-in hashtree * error mode is AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE. @@ -203,7 +236,9 @@ typedef struct { * PARTUUID=$(ANDROID_VBMETA_PARTUUID) before substitution so it * will end up pointing to the vbmeta partition for the verified * slot. If there is no vbmeta partition it will point to the boot - * partition of the verified slot. + * partition of the verified slot. If the flag + * AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION is used, this is not + * set. * * androidboot.vbmeta.avb_version: This is set to the decimal value * of AVB_VERSION_MAJOR followed by a dot followed by the decimal @@ -228,6 +263,15 @@ typedef struct { * appropriate system partition is substituted in. Note that none of * the androidboot.* options mentioned above will be set. * + * The |resolved_hashtree_error_mode| is the the value of the passed + * avb_slot_verify()'s |hashtree_error_mode| parameter except that it never has + * the value AVB_HASHTREE_ERROR_MODE_MANAGED_RESTART_AND_EIO. If this value was + * passed in, then the restart/eio state machine is used resulting in + * |resolved_hashtree_error_mode| being set to either + * AVB_HASHTREE_ERROR_MODE_RESTART or AVB_HASHTREE_ERROR_MODE_EIO. If set to + * AVB_HASHTREE_ERROR_MODE_EIO the boot loader should present a RED warning + * screen for the user to click through before continuing to boot. + * * This struct may grow in the future without it being considered an * ABI break. */ @@ -239,6 +283,7 @@ typedef struct { size_t num_loaded_partitions; char* cmdline; uint64_t rollback_indexes[AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS]; + AvbHashtreeErrorMode resolved_hashtree_error_mode; } AvbSlotVerifyData; /* Calculates a digest of all vbmeta images in |data| using @@ -282,12 +327,8 @@ void avb_slot_verify_data_free(AvbSlotVerifyData* data); * ignore verification errors which is something needed in the * UNLOCKED state. See the AvbSlotVerifyFlags enumeration for details. * - * The |hashtree_error_mode| parameter should be set to the desired - * error handling mode when hashtree validation fails inside the - * HLOS. This value isn't used by libavb per se - it is forwarded to - * the HLOS through the androidboot.veritymode and - * androidboot.vbmeta.invalidate_on_error cmdline parameters. See the - * AvbHashtreeErrorMode enumeration for details. + * The |hashtree_error_mode| parameter should be set to the desired error + * handling mode. See the AvbHashtreeErrorMode enumeration for details. * * Also note that |out_data| is never set if * AVB_SLOT_VERIFY_RESULT_ERROR_OOM, AVB_SLOT_VERIFY_RESULT_ERROR_IO, diff --git a/lib/libavb/avb_sysdeps.h b/lib/libavb/avb_sysdeps.h index f032de4a2e..f52428cc62 100644 --- a/lib/libavb/avb_sysdeps.h +++ b/lib/libavb/avb_sysdeps.h @@ -53,6 +53,14 @@ int avb_memcmp(const void* src1, */ int avb_strcmp(const char* s1, const char* s2); +/* Compare |n| bytes in two strings. + * + * Return an integer less than, equal to, or greater than zero if the + * first |n| bytes of |s1| is found, respectively, to be less than, + * to match, or be greater than the first |n| bytes of |s2|. + */ +int avb_strncmp(const char* s1, const char* s2, size_t n); + /* Copy |n| bytes from |src| to |dest|. */ void* avb_memcpy(void* dest, const void* src, size_t n); diff --git a/lib/libavb/avb_sysdeps_posix.c b/lib/libavb/avb_sysdeps_posix.c index e9addc1c87..4ccf41e428 100644 --- a/lib/libavb/avb_sysdeps_posix.c +++ b/lib/libavb/avb_sysdeps_posix.c @@ -24,14 +24,12 @@ int avb_strcmp(const char* s1, const char* s2) { return strcmp(s1, s2); } -size_t avb_strlen(const char* str) { - return strlen(str); +int avb_strncmp(const char* s1, const char* s2, size_t n) { + return strncmp(s1, s2, n); } -uint32_t avb_div_by_10(uint64_t* dividend) { - uint32_t rem = (uint32_t)(*dividend % 10); - *dividend /= 10; - return rem; +size_t avb_strlen(const char* str) { + return strlen(str); } void avb_abort(void) { @@ -60,3 +58,9 @@ void* avb_malloc_(size_t size) { void avb_free(void* ptr) { free(ptr); } + +uint32_t avb_div_by_10(uint64_t* dividend) { + uint32_t rem = (uint32_t)(*dividend % 10); + *dividend /= 10; + return rem; +} diff --git a/lib/libavb/avb_vbmeta_image.c b/lib/libavb/avb_vbmeta_image.c index a7e2322b9e..384f5ac19e 100644 --- a/lib/libavb/avb_vbmeta_image.c +++ b/lib/libavb/avb_vbmeta_image.c @@ -35,17 +35,18 @@ AvbVBMetaVerifyResult avb_vbmeta_image_verify( *out_public_key_length = 0; } + /* Before we byteswap or compare Magic, ensure length is long enough. */ + if (length < sizeof(AvbVBMetaImageHeader)) { + avb_error("Length is smaller than header.\n"); + goto out; + } + /* Ensure magic is correct. */ if (avb_safe_memcmp(data, AVB_MAGIC, AVB_MAGIC_LEN) != 0) { avb_error("Magic is incorrect.\n"); goto out; } - /* Before we byteswap, ensure length is long enough. */ - if (length < sizeof(AvbVBMetaImageHeader)) { - avb_error("Length is smaller than header.\n"); - goto out; - } avb_vbmeta_image_header_to_host_byte_order((const AvbVBMetaImageHeader*)data, &h); diff --git a/lib/libfdt/Makefile b/lib/libfdt/Makefile index ef5b6e29d4..5d3ae4e2f1 100644 --- a/lib/libfdt/Makefile +++ b/lib/libfdt/Makefile @@ -22,4 +22,5 @@ obj-y += fdt_ro.o # U-Boot own file obj-y += fdt_region.o -ccflags-y := -I$(srctree)/scripts/dtc/libfdt +ccflags-y := -I$(srctree)/scripts/dtc/libfdt \ + -DFDT_ASSUME_MASK=$(CONFIG_$(SPL_TPL_)OF_LIBFDT_ASSUME_MASK) diff --git a/lib/libfdt/fdt_ro.c b/lib/libfdt/fdt_ro.c index 693de9aa5a..560041b603 100644 --- a/lib/libfdt/fdt_ro.c +++ b/lib/libfdt/fdt_ro.c @@ -14,12 +14,13 @@ #include "libfdt_internal.h" -static int _fdt_nodename_eq(const void *fdt, int offset, +static int fdt_nodename_eq_(const void *fdt, int offset, const char *s, int len) { - const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1); + int olen; + const char *p = fdt_get_name(fdt, offset, &olen); - if (!p) + if (!p || (fdt_chk_extra() && olen < len)) /* short match */ return 0; @@ -34,46 +35,85 @@ static int _fdt_nodename_eq(const void *fdt, int offset, return 0; } -const char *fdt_string(const void *fdt, int stroffset) -{ - return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; -} - -static int _fdt_string_eq(const void *fdt, int stroffset, - const char *s, int len) +const char *fdt_get_string(const void *fdt, int stroffset, int *lenp) { - const char *p = fdt_string(fdt, stroffset); + int32_t totalsize; + uint32_t absoffset; + size_t len; + int err; + const char *s, *n; - return (strnlen(p, len + 1) == len) && (memcmp(p, s, len) == 0); -} + if (!fdt_chk_extra()) { + s = (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; -uint32_t fdt_get_max_phandle(const void *fdt) -{ - uint32_t max_phandle = 0; - int offset; + if (lenp) + *lenp = strlen(s); + return s; + } + totalsize = fdt_ro_probe_(fdt); + err = totalsize; + if (totalsize < 0) + goto fail; + + err = -FDT_ERR_BADOFFSET; + absoffset = stroffset + fdt_off_dt_strings(fdt); + if (absoffset >= totalsize) + goto fail; + len = totalsize - absoffset; + + if (fdt_magic(fdt) == FDT_MAGIC) { + if (stroffset < 0) + goto fail; + if (!fdt_chk_version() || fdt_version(fdt) >= 17) { + if (stroffset >= fdt_size_dt_strings(fdt)) + goto fail; + if ((fdt_size_dt_strings(fdt) - stroffset) < len) + len = fdt_size_dt_strings(fdt) - stroffset; + } + } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { + if ((stroffset >= 0) + || (stroffset < -fdt_size_dt_strings(fdt))) + goto fail; + if ((-stroffset) < len) + len = -stroffset; + } else { + err = -FDT_ERR_INTERNAL; + goto fail; + } - for (offset = fdt_next_node(fdt, -1, NULL);; - offset = fdt_next_node(fdt, offset, NULL)) { - uint32_t phandle; + s = (const char *)fdt + absoffset; + n = memchr(s, '\0', len); + if (!n) { + /* missing terminating NULL */ + err = -FDT_ERR_TRUNCATED; + goto fail; + } - if (offset == -FDT_ERR_NOTFOUND) - return max_phandle; + if (lenp) + *lenp = n - s; + return s; - if (offset < 0) - return (uint32_t)-1; +fail: + if (lenp) + *lenp = err; + return NULL; +} - phandle = fdt_get_phandle(fdt, offset); - if (phandle == (uint32_t)-1) - continue; +const char *fdt_string(const void *fdt, int stroffset) +{ + return fdt_get_string(fdt, stroffset, NULL); +} - if (phandle > max_phandle) - max_phandle = phandle; - } +static int fdt_string_eq_(const void *fdt, int stroffset, + const char *s, int len) +{ + int slen; + const char *p = fdt_get_string(fdt, stroffset, &slen); - return 0; + return p && (slen == len) && (memcmp(p, s, len) == 0); } -int fdt_generate_phandle(const void *fdt, uint32_t *phandle) +int fdt_find_max_phandle(const void *fdt, uint32_t *phandle) { uint32_t max = 0; int offset = -1; @@ -95,6 +135,21 @@ int fdt_generate_phandle(const void *fdt, uint32_t *phandle) max = value; } + if (phandle) + *phandle = max; + + return 0; +} + +int fdt_generate_phandle(const void *fdt, uint32_t *phandle) +{ + uint32_t max; + int err; + + err = fdt_find_max_phandle(fdt, &max); + if (err < 0) + return err; + if (max == FDT_MAX_PHANDLE) return -FDT_ERR_NOPHANDLES; @@ -104,24 +159,48 @@ int fdt_generate_phandle(const void *fdt, uint32_t *phandle) return 0; } +static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n) +{ + int offset = n * sizeof(struct fdt_reserve_entry); + int absoffset = fdt_off_mem_rsvmap(fdt) + offset; + + if (fdt_chk_extra()) { + if (absoffset < fdt_off_mem_rsvmap(fdt)) + return NULL; + if (absoffset > fdt_totalsize(fdt) - + sizeof(struct fdt_reserve_entry)) + return NULL; + } + return fdt_mem_rsv_(fdt, n); +} + int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) { - FDT_CHECK_HEADER(fdt); - *address = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->address); - *size = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->size); + const struct fdt_reserve_entry *re; + + FDT_RO_PROBE(fdt); + re = fdt_mem_rsv(fdt, n); + if (fdt_chk_extra() && !re) + return -FDT_ERR_BADOFFSET; + + *address = fdt64_ld(&re->address); + *size = fdt64_ld(&re->size); return 0; } int fdt_num_mem_rsv(const void *fdt) { - int i = 0; + int i; + const struct fdt_reserve_entry *re; - while (fdt64_to_cpu(fdt_mem_rsv_(fdt, i)->size) != 0) - i++; - return i; + for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) { + if (fdt64_ld(&re->size) == 0) + return i; + } + return -FDT_ERR_TRUNCATED; } -static int _nextprop(const void *fdt, int offset) +static int nextprop_(const void *fdt, int offset) { uint32_t tag; int nextoffset; @@ -150,13 +229,13 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset, { int depth; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); for (depth = 0; (offset >= 0) && (depth >= 0); offset = fdt_next_node(fdt, offset, &depth)) if ((depth == 1) - && _fdt_nodename_eq(fdt, offset, name, namelen)) + && fdt_nodename_eq_(fdt, offset, name, namelen)) return offset; if (depth < 0) @@ -170,36 +249,17 @@ int fdt_subnode_offset(const void *fdt, int parentoffset, return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name)); } -/* - * Find the next of path separator, note we need to search for both '/' and ':' - * and then take the first one so that we do the right thing for e.g. - * "foo/bar:option" and "bar:option/otheroption", both of which happen, so - * first searching for either ':' or '/' does not work. - */ -static const char *fdt_path_next_separator(const char *path, int len) -{ - const void *sep1 = memchr(path, '/', len); - const void *sep2 = memchr(path, ':', len); - - if (sep1 && sep2) - return (sep1 < sep2) ? sep1 : sep2; - else if (sep1) - return sep1; - else - return sep2; -} - int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) { const char *end = path + namelen; const char *p = path; int offset = 0; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* see if we have an alias */ if (*path != '/') { - const char *q = fdt_path_next_separator(path, namelen); + const char *q = memchr(path, '/', end - p); if (!q) q = end; @@ -212,17 +272,16 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) p = q; } - while (*p && (p < end)) { + while (p < end) { const char *q; - while (*p == '/') + while (*p == '/') { p++; - - if (*p == '\0' || *p == ':') - return offset; - - q = fdt_path_next_separator(p, end - p); - if (!q) + if (p == end) + return offset; + } + q = memchr(p, '/', end - p); + if (! q) q = end; offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p); @@ -243,16 +302,35 @@ int fdt_path_offset(const void *fdt, const char *path) const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) { const struct fdt_node_header *nh = fdt_offset_ptr_(fdt, nodeoffset); + const char *nameptr; int err; - if (((err = fdt_check_header(fdt)) != 0) - || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0)) + if (fdt_chk_extra() && + (((err = fdt_ro_probe_(fdt)) < 0) + || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0))) + goto fail; + + nameptr = nh->name; + + if (fdt_chk_version() && fdt_version(fdt) < 0x10) { + /* + * For old FDT versions, match the naming conventions of V16: + * give only the leaf name (after all /). The actual tree + * contents are loosely checked. + */ + const char *leaf; + leaf = strrchr(nameptr, '/'); + if (leaf == NULL) { + err = -FDT_ERR_BADSTRUCTURE; goto fail; + } + nameptr = leaf+1; + } if (len) - *len = strlen(nh->name); + *len = strlen(nameptr); - return nh->name; + return nameptr; fail: if (len) @@ -267,7 +345,7 @@ int fdt_first_property_offset(const void *fdt, int nodeoffset) if ((offset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) return offset; - return _nextprop(fdt, offset); + return nextprop_(fdt, offset); } int fdt_next_property_offset(const void *fdt, int offset) @@ -275,17 +353,17 @@ int fdt_next_property_offset(const void *fdt, int offset) if ((offset = fdt_check_prop_offset_(fdt, offset)) < 0) return offset; - return _nextprop(fdt, offset); + return nextprop_(fdt, offset); } -const struct fdt_property *fdt_get_property_by_offset(const void *fdt, - int offset, - int *lenp) +static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt, + int offset, + int *lenp) { int err; const struct fdt_property *prop; - if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) { + if (fdt_chk_basic() && (err = fdt_check_prop_offset_(fdt, offset)) < 0) { if (lenp) *lenp = err; return NULL; @@ -294,28 +372,50 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, prop = fdt_offset_ptr_(fdt, offset); if (lenp) - *lenp = fdt32_to_cpu(prop->len); + *lenp = fdt32_ld(&prop->len); return prop; } -const struct fdt_property *fdt_get_property_namelen(const void *fdt, - int offset, - const char *name, - int namelen, int *lenp) +const struct fdt_property *fdt_get_property_by_offset(const void *fdt, + int offset, + int *lenp) +{ + /* Prior to version 16, properties may need realignment + * and this API does not work. fdt_getprop_*() will, however. */ + + if (fdt_chk_version() && fdt_version(fdt) < 0x10) { + if (lenp) + *lenp = -FDT_ERR_BADVERSION; + return NULL; + } + + return fdt_get_property_by_offset_(fdt, offset, lenp); +} + +static const struct fdt_property *fdt_get_property_namelen_(const void *fdt, + int offset, + const char *name, + int namelen, + int *lenp, + int *poffset) { for (offset = fdt_first_property_offset(fdt, offset); (offset >= 0); (offset = fdt_next_property_offset(fdt, offset))) { const struct fdt_property *prop; - if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) { + prop = fdt_get_property_by_offset_(fdt, offset, lenp); + if (fdt_chk_extra() && !prop) { offset = -FDT_ERR_INTERNAL; break; } - if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff), - name, namelen)) + if (fdt_string_eq_(fdt, fdt32_ld(&prop->nameoff), + name, namelen)) { + if (poffset) + *poffset = offset; return prop; + } } if (lenp) @@ -323,6 +423,25 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, return NULL; } + +const struct fdt_property *fdt_get_property_namelen(const void *fdt, + int offset, + const char *name, + int namelen, int *lenp) +{ + /* Prior to version 16, properties may need realignment + * and this API does not work. fdt_getprop_*() will, however. */ + if (fdt_chk_version() && fdt_version(fdt) < 0x10) { + if (lenp) + *lenp = -FDT_ERR_BADVERSION; + return NULL; + } + + return fdt_get_property_namelen_(fdt, offset, name, namelen, lenp, + NULL); +} + + const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset, const char *name, int *lenp) @@ -334,12 +453,18 @@ const struct fdt_property *fdt_get_property(const void *fdt, const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, const char *name, int namelen, int *lenp) { + int poffset; const struct fdt_property *prop; - prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp); + prop = fdt_get_property_namelen_(fdt, nodeoffset, name, namelen, lenp, + &poffset); if (!prop) return NULL; + /* Handle realignment */ + if (fdt_chk_version() && fdt_version(fdt) < 0x10 && + (poffset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8) + return prop->data + 4; return prop->data; } @@ -348,11 +473,31 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, { const struct fdt_property *prop; - prop = fdt_get_property_by_offset(fdt, offset, lenp); + prop = fdt_get_property_by_offset_(fdt, offset, lenp); if (!prop) return NULL; - if (namep) - *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + if (namep) { + const char *name; + int namelen; + + if (fdt_chk_extra()) { + name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff), + &namelen); + if (!name) { + if (lenp) + *lenp = namelen; + return NULL; + } + *namep = name; + } else { + *namep = fdt_string(fdt, fdt32_ld(&prop->nameoff)); + } + } + + /* Handle realignment */ + if (fdt_chk_version() && fdt_version(fdt) < 0x10 && + (offset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8) + return prop->data + 4; return prop->data; } @@ -376,7 +521,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) return 0; } - return fdt32_to_cpu(*php); + return fdt32_ld(php); } const char *fdt_get_alias_namelen(const void *fdt, @@ -402,7 +547,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) int offset, depth, namelen; const char *name; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); if (buflen < 2) return -FDT_ERR_NOSPACE; @@ -454,7 +599,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, int offset, depth; int supernodeoffset = -FDT_ERR_INTERNAL; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); if (supernodedepth < 0) return -FDT_ERR_NOTFOUND; @@ -476,10 +621,12 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, } } - if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) - return -FDT_ERR_BADOFFSET; - else if (offset == -FDT_ERR_BADOFFSET) - return -FDT_ERR_BADSTRUCTURE; + if (fdt_chk_extra()) { + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) + return -FDT_ERR_BADOFFSET; + else if (offset == -FDT_ERR_BADOFFSET) + return -FDT_ERR_BADSTRUCTURE; + } return offset; /* error from fdt_next_node() */ } @@ -491,7 +638,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset) err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth); if (err) - return (err < 0) ? err : -FDT_ERR_INTERNAL; + return (!fdt_chk_extra() || err < 0) ? err : -FDT_ERR_INTERNAL; return nodedepth; } @@ -513,7 +660,7 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, const void *val; int len; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_getprop(), then if that didn't @@ -539,7 +686,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) if ((phandle == 0) || (phandle == -1)) return -FDT_ERR_BADPHANDLE; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* FIXME: The algorithm here is pretty horrible: we * potentially scan each property of a node in @@ -692,7 +839,7 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, { int offset, err; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_node_check_compatible(), then if @@ -711,3 +858,68 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, return offset; /* error from fdt_next_node() */ } + +#if !defined(CHECK_LEVEL) || CHECK_LEVEL > 0 +int fdt_check_full(const void *fdt, size_t bufsize) +{ + int err; + int num_memrsv; + int offset, nextoffset = 0; + uint32_t tag; + unsigned depth = 0; + const void *prop; + const char *propname; + + if (bufsize < FDT_V1_SIZE) + return -FDT_ERR_TRUNCATED; + err = fdt_check_header(fdt); + if (err != 0) + return err; + if (bufsize < fdt_totalsize(fdt)) + return -FDT_ERR_TRUNCATED; + + num_memrsv = fdt_num_mem_rsv(fdt); + if (num_memrsv < 0) + return num_memrsv; + + while (1) { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + + if (nextoffset < 0) + return nextoffset; + + switch (tag) { + case FDT_NOP: + break; + + case FDT_END: + if (depth != 0) + return -FDT_ERR_BADSTRUCTURE; + return 0; + + case FDT_BEGIN_NODE: + depth++; + if (depth > INT_MAX) + return -FDT_ERR_BADSTRUCTURE; + break; + + case FDT_END_NODE: + if (depth == 0) + return -FDT_ERR_BADSTRUCTURE; + depth--; + break; + + case FDT_PROP: + prop = fdt_getprop_by_offset(fdt, offset, &propname, + &err); + if (!prop) + return err; + break; + + default: + return -FDT_ERR_INTERNAL; + } + } +} +#endif diff --git a/lib/linux_compat.c b/lib/linux_compat.c index 6373b4451e..81ea8fb126 100644 --- a/lib/linux_compat.c +++ b/lib/linux_compat.c @@ -20,7 +20,7 @@ void *kmalloc(size_t size, int flags) void *p; p = malloc_cache_aligned(size); - if (flags & __GFP_ZERO) + if (p && flags & __GFP_ZERO) memset(p, 0, size); return p; diff --git a/lib/time.c b/lib/time.c index f5751ab162..f30fc05804 100644 --- a/lib/time.c +++ b/lib/time.c @@ -134,6 +134,20 @@ ulong __weak get_timer(ulong base) return tick_to_time(get_ticks()) - base; } +static uint64_t notrace tick_to_time_us(uint64_t tick) +{ + ulong div = get_tbclk() / 1000; + + tick *= CONFIG_SYS_HZ; + do_div(tick, div); + return tick; +} + +uint64_t __weak get_timer_us(uint64_t base) +{ + return tick_to_time_us(get_ticks()) - base; +} + unsigned long __weak notrace timer_get_us(void) { return tick_to_time(get_ticks() * 1000); diff --git a/lib/tiny-printf.c b/lib/tiny-printf.c index ebef92fc9f..1138c7012a 100644 --- a/lib/tiny-printf.c +++ b/lib/tiny-printf.c @@ -157,7 +157,8 @@ static void ip4_addr_string(struct printf_info *info, u8 *addr) * decimal). */ -static void pointer(struct printf_info *info, const char *fmt, void *ptr) +static void __maybe_unused pointer(struct printf_info *info, const char *fmt, + void *ptr) { #ifdef DEBUG unsigned long num = (uintptr_t)ptr; @@ -266,6 +267,21 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va) div_out(info, &num, div); } break; + case 'p': +#ifdef DEBUG + pointer(info, fmt, va_arg(va, void *)); + /* + * Skip this because it pulls in _ctype which is + * 256 bytes, and we don't generally implement + * pointer anyway + */ + while (isalnum(fmt[0])) + fmt++; + break; +#else + islong = true; + /* no break */ +#endif case 'x': if (islong) { num = va_arg(va, unsigned long); @@ -287,11 +303,6 @@ static int _vprintf(struct printf_info *info, const char *fmt, va_list va) case 's': p = va_arg(va, char*); break; - case 'p': - pointer(info, fmt, va_arg(va, void *)); - while (isalnum(fmt[0])) - fmt++; - break; case '%': out(info, '%'); default: @@ -366,6 +377,22 @@ int sprintf(char *buf, const char *fmt, ...) return ret; } +#if CONFIG_IS_ENABLED(LOG) +/* Note that size is ignored */ +int vsnprintf(char *buf, size_t size, const char *fmt, va_list va) +{ + struct printf_info info; + int ret; + + info.outstr = buf; + info.putc = putc_outstr; + ret = _vprintf(&info, fmt, va); + *info.outstr = '\0'; + + return ret; +} +#endif + /* Note that size is ignored */ int snprintf(char *buf, size_t size, const char *fmt, ...) { @@ -382,3 +409,9 @@ int snprintf(char *buf, size_t size, const char *fmt, ...) return ret; } + +void print_grouped_ull(unsigned long long int_val, int digits) +{ + /* Don't try to print the upper 32-bits */ + printf("%ld ", (ulong)int_val); +} diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 373094e59e..6fcc66afb0 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1,9 +1,11 @@ #!/usr/bin/env perl +# SPDX-License-Identifier: GPL-2.0 +# # (c) 2001, Dave Jones. (the file handling bit) # (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the ugly bit) # (c) 2007,2008, Andy Whitcroft <apw@uk.ibm.com> (new conditions, test suite) # (c) 2008-2010 Andy Whitcroft <apw@canonical.com> -# Licensed under the terms of the GNU GPL License version 2 +# (c) 2010-2018 Joe Perches <joe@perches.com> use strict; use warnings; @@ -11,6 +13,7 @@ use POSIX; use File::Basename; use Cwd 'abs_path'; use Term::ANSIColor qw(:constants); +use Encode qw(decode encode); my $P = $0; my $D = dirname(abs_path($P)); @@ -58,7 +61,9 @@ my $codespellfile = "/usr/share/codespell/dictionary.txt"; my $conststructsfile = "$D/const_structs.checkpatch"; my $typedefsfile = ""; my $color = "auto"; -my $allow_c99_comments = 1; +my $allow_c99_comments = 1; # Can be overridden by --ignore C99_COMMENT_TOLERANCE +# git output parsing needs US English output, so first set backtick child process LANGUAGE +my $git_command ='export LANGUAGE=en_US.UTF-8; git'; sub help { my ($exitcode) = @_; @@ -238,11 +243,11 @@ $check_orig = $check; my $exit = 0; +my $perl_version_ok = 1; if ($^V && $^V lt $minimum_perl_version) { + $perl_version_ok = 0; printf "$P: requires at least perl version %vd\n", $minimum_perl_version; - if (!$ignore_perl_version) { - exit(1); - } + exit(1) if (!$ignore_perl_version); } #if no filenames are given, push '-' to read patch from stdin @@ -344,9 +349,10 @@ our $Sparse = qr{ __force| __iomem| __must_check| - __init_refok| __kprobes| __ref| + __refconst| + __refdata| __rcu| __private }x; @@ -376,6 +382,7 @@ our $Attribute = qr{ __noclone| __deprecated| __read_mostly| + __ro_after_init| __kprobes| $InitAttribute| ____cacheline_aligned| @@ -461,8 +468,19 @@ our $logFunctions = qr{(?x: seq_vprintf|seq_printf|seq_puts )}; +our $allocFunctions = qr{(?x: + (?:(?:devm_)? + (?:kv|k|v)[czm]alloc(?:_node|_array)? | + kstrdup(?:_const)? | + kmemdup(?:_nul)?) | + (?:\w+)?alloc_skb(?:ip_align)? | + # dev_alloc_skb/netdev_alloc_skb, et al + dma_alloc_coherent +)}; + our $signature_tags = qr{(?xi: Signed-off-by:| + Co-developed-by:| Acked-by:| Tested-by:| Reviewed-by:| @@ -568,6 +586,27 @@ foreach my $entry (@mode_permission_funcs) { } $mode_perms_search = "(?:${mode_perms_search})"; +our %deprecated_apis = ( + "synchronize_rcu_bh" => "synchronize_rcu", + "synchronize_rcu_bh_expedited" => "synchronize_rcu_expedited", + "call_rcu_bh" => "call_rcu", + "rcu_barrier_bh" => "rcu_barrier", + "synchronize_sched" => "synchronize_rcu", + "synchronize_sched_expedited" => "synchronize_rcu_expedited", + "call_rcu_sched" => "call_rcu", + "rcu_barrier_sched" => "rcu_barrier", + "get_state_synchronize_sched" => "get_state_synchronize_rcu", + "cond_synchronize_sched" => "cond_synchronize_rcu", +); + +#Create a search pattern for all these strings to speed up a loop below +our $deprecated_apis_search = ""; +foreach my $entry (keys %deprecated_apis) { + $deprecated_apis_search .= '|' if ($deprecated_apis_search ne ""); + $deprecated_apis_search .= $entry; +} +$deprecated_apis_search = "(?:${deprecated_apis_search})"; + our $mode_perms_world_writable = qr{ S_IWUGO | S_IWOTH | @@ -845,6 +884,17 @@ sub is_maintained_obsolete { return $status =~ /obsolete/i; } +sub is_SPDX_License_valid { + my ($license) = @_; + + return 1 if (!$tree || which("python") eq "" || !(-e "$root/scripts/spdxcheck.py") || !(-e "$root/.git")); + + my $root_path = abs_path($root); + my $status = `cd "$root_path"; echo "$license" | python scripts/spdxcheck.py -`; + return 0 if ($status ne ""); + return 1; +} + my $camelcase_seeded = 0; sub seed_camelcase_includes { return if ($camelcase_seeded); @@ -856,7 +906,7 @@ sub seed_camelcase_includes { $camelcase_seeded = 1; if (-e ".git") { - my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`; + my $git_last_include_commit = `${git_command} log --no-merges --pretty=format:"%h%n" -1 -- include`; chomp $git_last_include_commit; $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit"; } else { @@ -884,7 +934,7 @@ sub seed_camelcase_includes { } if (-e ".git") { - $files = `git ls-files "include/*.h"`; + $files = `${git_command} ls-files "include/*.h"`; @include_files = split('\n', $files); } @@ -908,13 +958,13 @@ sub git_commit_info { return ($id, $desc) if ((which("git") eq "") || !(-e ".git")); - my $output = `git log --no-color --format='%H %s' -1 $commit 2>&1`; + my $output = `${git_command} log --no-color --format='%H %s' -1 $commit 2>&1`; $output =~ s/^\s*//gm; my @lines = split("\n", $output); return ($id, $desc) if ($#lines < 0); - if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous\./) { + if ($lines[0] =~ /^error: short SHA1 $commit is ambiguous/) { # Maybe one day convert this block of bash into something that returns # all matching commit ids, but it's very slow... # @@ -958,7 +1008,7 @@ if ($git) { } else { $git_range = "-1 $commit_expr"; } - my $lines = `git log --no-color --no-merges --pretty=format:'%H %s' $git_range`; + my $lines = `${git_command} log --no-color --no-merges --pretty=format:'%H %s' $git_range`; foreach my $line (split(/\n/, $lines)) { $line =~ /^([0-9a-fA-F]{40,40}) (.*)$/; next if (!defined($1) || !defined($2)); @@ -973,6 +1023,7 @@ if ($git) { } my $vname; +$allow_c99_comments = !defined $ignore_type{"C99_COMMENT_TOLERANCE"}; for my $filename (@ARGV) { my $FILE; if ($git) { @@ -1024,11 +1075,11 @@ if (!$quiet) { hash_show_words(\%use_type, "Used"); hash_show_words(\%ignore_type, "Ignored"); - if ($^V lt 5.10.0) { + if (!$perl_version_ok) { print << "EOM" NOTE: perl $^V is not modern enough to detect all possible issues. - An upgrade to at least perl v5.10.0 is suggested. + An upgrade to at least perl $minimum_perl_version is suggested. EOM } if ($exit) { @@ -2233,10 +2284,14 @@ sub process { our $clean = 1; my $signoff = 0; + my $author = ''; + my $authorsignoff = 0; my $is_patch = 0; + my $is_binding_patch = -1; my $in_header_lines = $file ? 0 : 1; my $in_commit_log = 0; #Scanning lines before patch my $has_commit_log = 0; #Encountered lines before patch + my $commit_log_lines = 0; #Number of commit log lines my $commit_log_possible_stack_dump = 0; my $commit_log_long_line = 0; my $commit_log_has_diff = 0; @@ -2375,6 +2430,14 @@ sub process { my $rawline = $rawlines[$linenr - 1]; +# check if it's a mode change, rename or start of a patch + if (!$in_commit_log && + ($line =~ /^ mode change [0-7]+ => [0-7]+ \S+\s*$/ || + ($line =~ /^rename (?:from|to) \S+\s*$/ || + $line =~ /^diff --git a\/[\w\/\.\_\-]+ b\/\S+\s*$/))) { + $is_patch = 1; + } + #extract the line range in the file after the patch is applied if (!$in_commit_log && $line =~ /^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@(.*)/) { @@ -2475,6 +2538,19 @@ sub process { $check = $check_orig; } $checklicenseline = 1; + + if ($realfile !~ /^MAINTAINERS/) { + my $last_binding_patch = $is_binding_patch; + + $is_binding_patch = () = $realfile =~ m@^(?:Documentation/devicetree/|include/dt-bindings/)@; + + if (($last_binding_patch != -1) && + ($last_binding_patch ^ $is_binding_patch)) { + WARN("DT_SPLIT_BINDING_PATCH", + "DT binding docs and includes should be a separate patch. See: Documentation/devicetree/bindings/submitting-patches.txt\n"); + } + } + next; } @@ -2486,6 +2562,18 @@ sub process { $cnt_lines++ if ($realcnt != 0); +# Verify the existence of a commit log if appropriate +# 2 is used because a $signature is counted in $commit_log_lines + if ($in_commit_log) { + if ($line !~ /^\s*$/) { + $commit_log_lines++; #could be a $signature + } + } elsif ($has_commit_log && $commit_log_lines < 2) { + WARN("COMMIT_MESSAGE", + "Missing commit description - Add an appropriate one\n"); + $commit_log_lines = 2; #warn only once + } + # Check if the commit log has what seems like a diff which can confuse patch if ($in_commit_log && !$commit_log_has_diff && (($line =~ m@^\s+diff\b.*a/[\w/]+@ && @@ -2507,10 +2595,24 @@ sub process { } } +# Check the patch for a From: + if (decode("MIME-Header", $line) =~ /^From:\s*(.*)/) { + $author = $1; + $author = encode("utf8", $author) if ($line =~ /=\?utf-8\?/i); + $author =~ s/"//g; + } + # Check the patch for a signoff: if ($line =~ /^\s*signed-off-by:/i) { $signoff++; $in_commit_log = 0; + if ($author ne '') { + my $l = $line; + $l =~ s/"//g; + if ($l =~ /^\s*signed-off-by:\s*\Q$author\E/i) { + $authorsignoff = 1; + } + } } # Check if MAINTAINERS is being updated. If so, there's probably no need to @@ -2587,6 +2689,24 @@ sub process { } else { $signatures{$sig_nospace} = 1; } + +# Check Co-developed-by: immediately followed by Signed-off-by: with same name and email + if ($sign_off =~ /^co-developed-by:$/i) { + if ($email eq $author) { + WARN("BAD_SIGN_OFF", + "Co-developed-by: should not be used to attribute nominal patch author '$author'\n" . "$here\n" . $rawline); + } + if (!defined $lines[$linenr]) { + WARN("BAD_SIGN_OFF", + "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline); + } elsif ($rawlines[$linenr] !~ /^\s*signed-off-by:\s*(.*)/i) { + WARN("BAD_SIGN_OFF", + "Co-developed-by: must be immediately followed by Signed-off-by:\n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); + } elsif ($1 ne $email) { + WARN("BAD_SIGN_OFF", + "Co-developed-by and Signed-off-by: name/email do not match \n" . "$here\n" . $rawline . "\n" .$rawlines[$linenr]); + } + } } # Check email subject for common tools that don't need to be mentioned @@ -2596,12 +2716,6 @@ sub process { "A patch subject line should describe the change not the tool that found it\n" . $herecurr); } -# Check for old stable address - if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) { - ERROR("STABLE_ADDRESS", - "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr); - } - # Check for unwanted Gerrit info if ($in_commit_log && $line =~ /^\s*change-id:/i) { ERROR("GERRIT_CHANGE_ID", @@ -2613,8 +2727,10 @@ sub process { ($line =~ /^\s*(?:WARNING:|BUG:)/ || $line =~ /^\s*\[\s*\d+\.\d{6,6}\s*\]/ || # timestamp - $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/)) { - # stack dump address + $line =~ /^\s*\[\<[0-9a-fA-F]{8,}\>\]/) || + $line =~ /^(?:\s+\w+:\s+[0-9a-fA-F]+){3,3}/ || + $line =~ /^\s*\#\d+\s*\[[0-9a-fA-F]+\]\s*\w+ at [0-9a-fA-F]+/) { + # stack dump address styles $commit_log_possible_stack_dump = 1; } @@ -2786,6 +2902,17 @@ sub process { } } +# check for invalid commit id + if ($in_commit_log && $line =~ /(^fixes:|\bcommit)\s+([0-9a-f]{6,40})\b/i) { + my $id; + my $description; + ($id, $description) = git_commit_info($2, undef, undef); + if (!defined($id)) { + WARN("UNKNOWN_COMMIT_ID", + "Unknown commit id '$2', maybe rebased or not pulled?\n" . $herecurr); + } + } + # ignore non-hunk lines and lines being removed next if (!$hunk_line || $line =~ /^-/); @@ -2915,7 +3042,7 @@ sub process { my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g; my $dt_path = $root . "/Documentation/devicetree/bindings/"; - my $vp_file = $dt_path . "vendor-prefixes.txt"; + my $vp_file = $dt_path . "vendor-prefixes.yaml"; foreach my $compat (@compats) { my $compat2 = $compat; @@ -2930,7 +3057,7 @@ sub process { next if $compat !~ /^([a-zA-Z0-9\-]+)\,/; my $vendor = $1; - `grep -Eq "^$vendor\\b" $vp_file`; + `grep -Eq "\\"\\^\Q$vendor\E,\\.\\*\\":" $vp_file`; if ( $? >> 8 ) { WARN("UNDOCUMENTED_DT_STRING", "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr); @@ -2954,10 +3081,24 @@ sub process { $comment = '..'; } +# check SPDX comment style for .[chsS] files + if ($realfile =~ /\.[chsS]$/ && + $rawline =~ /SPDX-License-Identifier:/ && + $rawline !~ m@^\+\s*\Q$comment\E\s*@) { + WARN("SPDX_LICENSE_TAG", + "Improper SPDX comment style for '$realfile', please use '$comment' instead\n" . $herecurr); + } + if ($comment !~ /^$/ && - $rawline !~ /^\+\Q$comment\E SPDX-License-Identifier: /) { + $rawline !~ m@^\+\Q$comment\E SPDX-License-Identifier: @) { WARN("SPDX_LICENSE_TAG", "Missing or malformed SPDX-License-Identifier tag in line $checklicenseline\n" . $herecurr); + } elsif ($rawline =~ /(SPDX-License-Identifier: .*)/) { + my $spdx_license = $1; + if (!is_SPDX_License_valid($spdx_license)) { + WARN("SPDX_LICENSE_TAG", + "'$spdx_license' is not supported in LICENSES/...\n" . $herecurr); + } } } } @@ -2965,6 +3106,14 @@ sub process { # check we are in a valid source file if not then ignore this hunk next if ($realfile !~ /\.(h|c|s|S|sh|dtsi|dts)$/); +# check for using SPDX-License-Identifier on the wrong line number + if ($realline != $checklicenseline && + $rawline =~ /\bSPDX-License-Identifier:/ && + substr($line, @-, @+ - @-) eq "$;" x (@+ - @-)) { + WARN("SPDX_LICENSE_TAG", + "Misplaced SPDX-License-Identifier tag - use line $checklicenseline instead\n" . $herecurr); + } + # line length limit (with some exclusions) # # There are a few types of lines that may extend beyond $max_line_length: @@ -3062,6 +3211,12 @@ sub process { } } +# check for assignments on the start of a line + if ($sline =~ /^\+\s+($Assignment)[^=]/) { + CHK("ASSIGNMENT_CONTINUATIONS", + "Assignment operator '$1' should be on the previous line\n" . $hereprev); + } + # check for && or || at the start of a line if ($rawline =~ /^\+\s*(&&|\|\|)/) { CHK("LOGICAL_CONTINUATIONS", @@ -3069,7 +3224,7 @@ sub process { } # check indentation starts on a tab stop - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $sline =~ /^\+\t+( +)(?:$c90_Keywords\b|\{\s*$|\}\s*(?:else\b|while\b|\s*$)|$Declare\s*$Ident\s*[;=])/) { my $indent = length($1); if ($indent % 8) { @@ -3082,7 +3237,7 @@ sub process { } # check multi-line statement indentation matches previous line - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|(?:\*\s*)*$Lval\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) { $prevline =~ /^\+(\t*)(.*)$/; my $oldindent = $1; @@ -3239,7 +3394,7 @@ sub process { # known declaration macros $sline =~ /^\+\s+$declaration_macros/ || # start of struct or union or enum - $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ || + $sline =~ /^\+\s+(?:static\s+)?(?:const\s+)?(?:union|struct|enum|typedef)\b/ || # start or end of block or continuation of declaration $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ || # bitfield continuation @@ -3771,19 +3926,48 @@ sub process { "type '$tmp' should be specified in [[un]signed] [short|int|long|long long] order\n" . $herecurr); } +# check for unnecessary <signed> int declarations of short/long/long long + while ($sline =~ m{\b($TypeMisordered(\s*\*)*|$C90_int_types)\b}g) { + my $type = trim($1); + next if ($type !~ /\bint\b/); + next if ($type !~ /\b(?:short|long\s+long|long)\b/); + my $new_type = $type; + $new_type =~ s/\b\s*int\s*\b/ /; + $new_type =~ s/\b\s*(?:un)?signed\b\s*/ /; + $new_type =~ s/^const\s+//; + $new_type = "unsigned $new_type" if ($type =~ /\bunsigned\b/); + $new_type = "const $new_type" if ($type =~ /^const\b/); + $new_type =~ s/\s+/ /g; + $new_type = trim($new_type); + if (WARN("UNNECESSARY_INT", + "Prefer '$new_type' over '$type' as the int is unnecessary\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b\Q$type\E\b/$new_type/; + } + } + # check for static const char * arrays. if ($line =~ /\bstatic\s+const\s+char\s*\*\s*(\w+)\s*\[\s*\]\s*=\s*/) { WARN("STATIC_CONST_CHAR_ARRAY", "static const char * array should probably be static const char * const\n" . $herecurr); - } + } + +# check for initialized const char arrays that should be static const + if ($line =~ /^\+\s*const\s+(char|unsigned\s+char|_*u8|(?:[us]_)?int8_t)\s+\w+\s*\[\s*(?:\w+\s*)?\]\s*=\s*"/) { + if (WARN("STATIC_CONST_CHAR_ARRAY", + "const array should probably be static const\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/(^.\s*)const\b/${1}static const/; + } + } # check for static char foo[] = "bar" declarations. if ($line =~ /\bstatic\s+char\s+(\w+)\s*\[\s*\]\s*=\s*"/) { WARN("STATIC_CONST_CHAR_ARRAY", "static char array declaration should probably be static const char\n" . $herecurr); - } + } # check for const <foo> const where <foo> is not a pointer or array type if ($sline =~ /\bconst\s+($BasicType)\s+const\b/) { @@ -3957,7 +4141,7 @@ sub process { # function brace can't be on same line, except for #defines of do while, # or if closed on same line - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $sline =~ /$Type\s*$Ident\s*$balanced_parens\s*\{/ && $sline !~ /\#\s*define\b.*do\s*\{/ && $sline !~ /}/) { @@ -4083,7 +4267,7 @@ sub process { my ($where, $prefix) = ($-[1], $1); if ($prefix !~ /$Type\s+$/ && ($where != 0 || $prefix !~ /^.\s+$/) && - $prefix !~ /[{,]\s+$/) { + $prefix !~ /[{,:]\s+$/) { if (ERROR("BRACKET_SPACE", "space prohibited before open square bracket '['\n" . $herecurr) && $fix) { @@ -4473,11 +4657,11 @@ sub process { #need space before brace following if, while, etc if (($line =~ /\(.*\)\{/ && $line !~ /\($Type\)\{/) || - $line =~ /do\{/) { + $line =~ /\b(?:else|do)\{/) { if (ERROR("SPACING", "space required before the open brace '{'\n" . $herecurr) && $fix) { - $fixed[$fixlinenr] =~ s/^(\+.*(?:do|\)))\{/$1 {/; + $fixed[$fixlinenr] =~ s/^(\+.*(?:do|else|\)))\{/$1 {/; } } @@ -4491,7 +4675,7 @@ sub process { # closing brace should have a space following it when it has anything # on the line - if ($line =~ /}(?!(?:,|;|\)))\S/) { + if ($line =~ /}(?!(?:,|;|\)|\}))\S/) { if (ERROR("SPACING", "space required after that close brace '}'\n" . $herecurr) && $fix) { @@ -4568,7 +4752,7 @@ sub process { # check for unnecessary parentheses around comparisons in if uses # when !drivers/staging or command-line uses --strict if (($realfile !~ m@^(?:drivers/staging/)@ || $check_orig) && - $^V && $^V ge 5.10.0 && defined($stat) && + $perl_version_ok && defined($stat) && $stat =~ /(^.\s*if\s*($balanced_parens))/) { my $if_stat = $1; my $test = substr($2, 1, -1); @@ -4605,7 +4789,7 @@ sub process { # return is not a function if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) { my $spacing = $1; - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) { my $value = $1; $value = deparenthesize($value); @@ -4632,7 +4816,7 @@ sub process { } # if statements using unnecessary parentheses - ie: if ((foo == bar)) - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $line =~ /\bif\s*((?:\(\s*){2,})/) { my $openparens = $1; my $count = $openparens =~ tr@\(@\(@; @@ -4649,7 +4833,7 @@ sub process { # avoid cases like "foo + BAR < baz" # only fix matches surrounded by parentheses to avoid incorrect # conversions like "FOO < baz() + 5" being "misfixed" to "baz() > FOO + 5" - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $line =~ /^\+(.*)\b($Constant|[A-Z_][A-Z0-9_]*)\s*($Compare)\s*($LvalOrFunc)/) { my $lead = $1; my $const = $2; @@ -4841,17 +5025,6 @@ sub process { while ($line =~ m{($Constant|$Lval)}g) { my $var = $1; -#gcc binary extension - if ($var =~ /^$Binary$/) { - if (WARN("GCC_BINARY_CONSTANT", - "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) && - $fix) { - my $hexval = sprintf("0x%x", oct($var)); - $fixed[$fixlinenr] =~ - s/\b$var\b/$hexval/; - } - } - #CamelCase if ($var !~ /^$Constant$/ && $var =~ /[A-Z][a-z]|[a-z][A-Z]/ && @@ -4939,6 +5112,7 @@ sub process { if (defined $define_args && $define_args ne "") { $define_args = substr($define_args, 1, length($define_args) - 2); $define_args =~ s/\s*//g; + $define_args =~ s/\\\+?//g; @def_args = split(",", $define_args); } @@ -5032,10 +5206,10 @@ sub process { next if ($arg =~ /\.\.\./); next if ($arg =~ /^type$/i); my $tmp_stmt = $define_stmt; - $tmp_stmt =~ s/\b(typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; + $tmp_stmt =~ s/\b(sizeof|typeof|__typeof__|__builtin\w+|typecheck\s*\(\s*$Type\s*,|\#+)\s*\(*\s*$arg\s*\)*\b//g; $tmp_stmt =~ s/\#+\s*$arg\b//g; $tmp_stmt =~ s/\b$arg\s*\#\#//g; - my $use_cnt = $tmp_stmt =~ s/\b$arg\b//g; + my $use_cnt = () = $tmp_stmt =~ /\b$arg\b/g; if ($use_cnt > 1) { CHK("MACRO_ARG_REUSE", "Macro argument reuse '$arg' - possible side-effects?\n" . "$herectx"); @@ -5074,7 +5248,7 @@ sub process { # do {} while (0) macro tests: # single-statement macros do not need to be enclosed in do while (0) loop, # macro should not end with a semicolon - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $realfile !~ m@/vmlinux.lds.h$@ && $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) { my $ln = $linenr; @@ -5115,16 +5289,6 @@ sub process { } } -# make sure symbols are always wrapped with VMLINUX_SYMBOL() ... -# all assignments may have only one of the following with an assignment: -# . -# ALIGN(...) -# VMLINUX_SYMBOL(...) - if ($realfile eq 'vmlinux.lds.h' && $line =~ /(?:(?:^|\s)$Ident\s*=|=\s*$Ident(?:\s|$))/) { - WARN("MISSING_VMLINUX_SYMBOL", - "vmlinux.lds.h needs VMLINUX_SYMBOL() around C-visible symbols\n" . $herecurr); - } - # check for redundant bracing round if etc if ($line =~ /(^.*)\bif\b/ && $1 !~ /else\s*$/) { my ($level, $endln, @chunks) = @@ -5330,15 +5494,28 @@ sub process { } # concatenated string without spaces between elements - if ($line =~ /$String[A-Z_]/ || $line =~ /[A-Za-z0-9_]$String/) { - CHK("CONCATENATED_STRING", - "Concatenated strings should use spaces between elements\n" . $herecurr); + if ($line =~ /$String[A-Za-z0-9_]/ || $line =~ /[A-Za-z0-9_]$String/) { + if (CHK("CONCATENATED_STRING", + "Concatenated strings should use spaces between elements\n" . $herecurr) && + $fix) { + while ($line =~ /($String)/g) { + my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); + $fixed[$fixlinenr] =~ s/\Q$extracted_string\E([A-Za-z0-9_])/$extracted_string $1/; + $fixed[$fixlinenr] =~ s/([A-Za-z0-9_])\Q$extracted_string\E/$1 $extracted_string/; + } + } } # uncoalesced string fragments if ($line =~ /$String\s*"/) { - WARN("STRING_FRAGMENTS", - "Consecutive strings are generally better as a single string\n" . $herecurr); + if (WARN("STRING_FRAGMENTS", + "Consecutive strings are generally better as a single string\n" . $herecurr) && + $fix) { + while ($line =~ /($String)(?=\s*")/g) { + my $extracted_string = substr($rawline, $-[0], $+[0] - $-[0]); + $fixed[$fixlinenr] =~ s/\Q$extracted_string\E\s*"/substr($extracted_string, 0, -1)/e; + } + } } # check for non-standard and hex prefixed decimal printf formats @@ -5374,9 +5551,14 @@ sub process { # warn about #if 0 if ($line =~ /^.\s*\#\s*if\s+0\b/) { - CHK("REDUNDANT_CODE", - "if this code is redundant consider removing it\n" . - $herecurr); + WARN("IF_0", + "Consider removing the code enclosed by this #if 0 and its #endif\n" . $herecurr); + } + +# warn about #if 1 + if ($line =~ /^.\s*\#\s*if\s+1\b/) { + WARN("IF_1", + "Consider removing the #if 1 and its #endif\n" . $herecurr); } # check for needless "if (<foo>) fn(<foo>)" uses @@ -5423,7 +5605,8 @@ sub process { my ($s, $c) = ctx_statement_block($linenr - 3, $realcnt, 0); # print("line: <$line>\nprevline: <$prevline>\ns: <$s>\nc: <$c>\n\n\n"); - if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*(?:devm_)?(?:[kv][czm]alloc(?:_node|_array)?\b|kstrdup|kmemdup|(?:dev_)?alloc_skb)/) { + if ($s =~ /(?:^|\n)[ \+]\s*(?:$Type\s*)?\Q$testval\E\s*=\s*(?:\([^\)]*\)\s*)?\s*$allocFunctions\s*\(/ && + $s !~ /\b__GFP_NOWARN\b/ ) { WARN("OOM_MESSAGE", "Possible unnecessary 'out of memory' message\n" . $hereprev); } @@ -5447,7 +5630,7 @@ sub process { } # check for mask then right shift without a parentheses - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $line =~ /$LvalOrFunc\s*\&\s*($LvalOrFunc)\s*>>/ && $4 !~ /^\&/) { # $LvalOrFunc may be &foo, ignore if so WARN("MASK_THEN_SHIFT", @@ -5455,7 +5638,7 @@ sub process { } # check for pointer comparisons to NULL - if ($^V && $^V ge 5.10.0) { + if ($perl_version_ok) { while ($line =~ /\b$LvalOrFunc\s*(==|\!=)\s*NULL\b/g) { my $val = $1; my $equal = "!"; @@ -5544,7 +5727,7 @@ sub process { # ignore udelay's < 10, however if (! ($delay < 10) ) { CHK("USLEEP_RANGE", - "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr); + "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.rst\n" . $herecurr); } if ($delay > 2000) { WARN("LONG_UDELAY", @@ -5556,7 +5739,7 @@ sub process { if ($line =~ /\bmsleep\s*\((\d+)\);/) { if ($1 < 20) { WARN("MSLEEP", - "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr); + "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.rst\n" . $herecurr); } } @@ -5698,13 +5881,6 @@ sub process { "__packed is preferred over __attribute__((packed))\n" . $herecurr); } -# Check for new packed members, warn to use care - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b(__attribute__\s*\(\s*\(.*\bpacked|__packed)\b/) { - WARN("NEW_PACKED", - "Adding new packed members is to be done with care\n" . $herecurr); - } - # Check for __attribute__ aligned, prefer __aligned if ($realfile !~ m@\binclude/uapi/@ && $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { @@ -5712,6 +5888,18 @@ sub process { "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); } +# Check for __attribute__ section, prefer __section + if ($realfile !~ m@\binclude/uapi/@ && + $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) { + my $old = substr($rawline, $-[1], $+[1] - $-[1]); + my $new = substr($old, 1, -1); + if (WARN("PREFER_SECTION", + "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; + } + } + # Check for __attribute__ format(printf, prefer __printf if ($realfile !~ m@\binclude/uapi/@ && $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { @@ -5734,7 +5922,7 @@ sub process { } # Check for __attribute__ weak, or __weak declarations (may have link issues) - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ && ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ || $line =~ /\b__weak\b/)) { @@ -5816,25 +6004,25 @@ sub process { } # check for vsprintf extension %p<foo> misuses - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s && $1 !~ /^_*volatile_*$/) { - my $specifier; - my $extension; - my $bad_specifier = ""; my $stat_real; my $lc = $stat =~ tr@\n@@; $lc = $lc + $linenr; for (my $count = $linenr; $count <= $lc; $count++) { + my $specifier; + my $extension; + my $bad_specifier = ""; my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); $fmt =~ s/%%//g; while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) { $specifier = $1; $extension = $2; - if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOx]/) { + if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOxt]/) { $bad_specifier = $specifier; last; } @@ -5863,7 +6051,7 @@ sub process { } # Check for misused memsets - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { @@ -5881,7 +6069,7 @@ sub process { } # Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar) -# if ($^V && $^V ge 5.10.0 && +# if ($perl_version_ok && # defined $stat && # $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { # if (WARN("PREFER_ETHER_ADDR_COPY", @@ -5892,7 +6080,7 @@ sub process { # } # Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar) -# if ($^V && $^V ge 5.10.0 && +# if ($perl_version_ok && # defined $stat && # $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { # WARN("PREFER_ETHER_ADDR_EQUAL", @@ -5901,7 +6089,7 @@ sub process { # check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr # check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr -# if ($^V && $^V ge 5.10.0 && +# if ($perl_version_ok && # defined $stat && # $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) { # @@ -5923,7 +6111,7 @@ sub process { # } # typecasts on min/max could be min_t/max_t - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) { if (defined $2 || defined $7) { @@ -5947,23 +6135,23 @@ sub process { } # check usleep_range arguments - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) { my $min = $1; my $max = $7; if ($min eq $max) { WARN("USLEEP_RANGE", - "usleep_range should not use min == max args; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); + "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); } elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ && $min > $max) { WARN("USLEEP_RANGE", - "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.txt\n" . "$here\n$stat\n"); + "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n"); } } # check for naked sscanf - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $line =~ /\bsscanf\b/ && ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ && @@ -5977,7 +6165,7 @@ sub process { } # check for simple sscanf that should be kstrto<foo> - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $line =~ /\bsscanf\b/) { my $lc = $stat =~ tr@\n@@; @@ -6049,7 +6237,7 @@ sub process { } # check for function definitions - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) { $context_function = $1; @@ -6081,22 +6269,22 @@ sub process { } } -# check for pointless casting of kmalloc return - if ($line =~ /\*\s*\)\s*[kv][czm]alloc(_node){0,1}\b/) { +# check for pointless casting of alloc functions + if ($line =~ /\*\s*\)\s*$allocFunctions\b/) { WARN("UNNECESSARY_CASTS", "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr); } # alloc style # p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...) - if ($^V && $^V ge 5.10.0 && - $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { + if ($perl_version_ok && + $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) { CHK("ALLOC_SIZEOF_STRUCT", "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr); } # check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) { my $oldfunc = $3; @@ -6125,8 +6313,9 @@ sub process { } # check for krealloc arg reuse - if ($^V && $^V ge 5.10.0 && - $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) { + if ($perl_version_ok && + $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ && + $1 eq $3) { WARN("KREALLOC_ARG_REUSE", "Reusing the krealloc arg is almost always a bug\n" . $herecurr); } @@ -6194,7 +6383,7 @@ sub process { } # check for switch/default statements without a break; - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) { my $cnt = statement_rawlines($stat); @@ -6270,6 +6459,20 @@ sub process { "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr); } +# check for spin_is_locked(), suggest lockdep instead + if ($line =~ /\bspin_is_locked\(/) { + WARN("USE_LOCKDEP", + "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr); + } + +# check for deprecated apis + if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) { + my $deprecated_api = $1; + my $new_api = $deprecated_apis{$deprecated_api}; + WARN("DEPRECATED_API", + "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr); + } + # check for various structs that are normally const (ops, kgdb, device_tree) # and avoid what seem like struct definitions 'struct foo {' if ($line !~ /\bconst\b/ && @@ -6298,12 +6501,18 @@ sub process { } # likely/unlikely comparisons similar to "(likely(foo) > 0)" - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) { WARN("LIKELY_MISUSE", "Using $1 should generally have parentheses around the comparison\n" . $herecurr); } +# nested likely/unlikely calls + if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) { + WARN("LIKELY_MISUSE", + "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr); + } + # whine mightly about in_atomic if ($line =~ /\bin_atomic\s*\(/) { if ($realfile =~ m@^drivers/@) { @@ -6341,7 +6550,7 @@ sub process { # check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> # and whether or not function naming is typical and if # DEVICE_ATTR permissions uses are unusual too - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) { my $var = $1; @@ -6401,7 +6610,7 @@ sub process { # specific definition of not visible in sysfs. # o Ignore proc_create*(...) uses with a decimal 0 permission as that means # use the default permissions - if ($^V && $^V ge 5.10.0 && + if ($perl_version_ok && defined $stat && $line =~ /$mode_perms_search/) { foreach my $entry (@mode_permission_funcs) { @@ -6463,6 +6672,12 @@ sub process { "unknown module license " . $extracted_string . "\n" . $herecurr); } } + +# check for sysctl duplicate constants + if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) { + WARN("DUPLICATED_SYSCTL_CONST", + "duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr); + } } # If we have no input at all, then there is nothing to report on @@ -6487,9 +6702,14 @@ sub process { ERROR("NOT_UNIFIED_DIFF", "Does not appear to be a unified-diff format patch\n"); } - if ($is_patch && $has_commit_log && $chk_signoff && $signoff == 0) { - ERROR("MISSING_SIGN_OFF", - "Missing Signed-off-by: line(s)\n"); + if ($is_patch && $has_commit_log && $chk_signoff) { + if ($signoff == 0) { + ERROR("MISSING_SIGN_OFF", + "Missing Signed-off-by: line(s)\n"); + } elsif (!$authorsignoff) { + WARN("NO_AUTHOR_SIGN_OFF", + "Missing Signed-off-by: line by nominal patch author '$author'\n"); + } } print report_dump(); diff --git a/scripts/dtc/libfdt/Makefile.libfdt b/scripts/dtc/libfdt/Makefile.libfdt index 098b3f36e6..e54639738c 100644 --- a/scripts/dtc/libfdt/Makefile.libfdt +++ b/scripts/dtc/libfdt/Makefile.libfdt @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) # Makefile.libfdt # # This is not a complete Makefile of itself. Instead, it is designed to @@ -9,3 +10,9 @@ LIBFDT_VERSION = version.lds LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c fdt_empty_tree.c \ fdt_addresses.c fdt_overlay.c LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o) +LIBFDT_LIB = libfdt-$(DTC_VERSION).$(SHAREDLIB_EXT) + +libfdt_clean: + @$(VECHO) CLEAN "(libfdt)" + rm -f $(STD_CLEANFILES:%=$(LIBFDT_dir)/%) + rm -f $(LIBFDT_dir)/$(LIBFDT_soname) diff --git a/scripts/dtc/libfdt/fdt.c b/scripts/dtc/libfdt/fdt.c index 7855a17877..8e4cce3b9b 100644 --- a/scripts/dtc/libfdt/fdt.c +++ b/scripts/dtc/libfdt/fdt.c @@ -1,52 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -55,14 +10,24 @@ #include "libfdt_internal.h" -int fdt_check_header(const void *fdt) +/* + * Minimal sanity check for a read-only tree. fdt_ro_probe_() checks + * that the given buffer contains what appears to be a flattened + * device tree with sane information in its header. + */ +int32_t fdt_ro_probe_(const void *fdt) { + uint32_t totalsize = fdt_totalsize(fdt); + if (fdt_magic(fdt) == FDT_MAGIC) { /* Complete tree */ - if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) - return -FDT_ERR_BADVERSION; - if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) - return -FDT_ERR_BADVERSION; + if (fdt_chk_version()) { + if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) + return -FDT_ERR_BADVERSION; + if (fdt_last_comp_version(fdt) > + FDT_LAST_SUPPORTED_VERSION) + return -FDT_ERR_BADVERSION; + } } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { /* Unfinished sequential-write blob */ if (fdt_size_dt_struct(fdt) == 0) @@ -71,6 +36,96 @@ int fdt_check_header(const void *fdt) return -FDT_ERR_BADMAGIC; } + if (totalsize < INT32_MAX) + return totalsize; + else + return -FDT_ERR_TRUNCATED; +} + +static int check_off_(uint32_t hdrsize, uint32_t totalsize, uint32_t off) +{ + return (off >= hdrsize) && (off <= totalsize); +} + +static int check_block_(uint32_t hdrsize, uint32_t totalsize, + uint32_t base, uint32_t size) +{ + if (!check_off_(hdrsize, totalsize, base)) + return 0; /* block start out of bounds */ + if ((base + size) < base) + return 0; /* overflow */ + if (!check_off_(hdrsize, totalsize, base + size)) + return 0; /* block end out of bounds */ + return 1; +} + +size_t fdt_header_size_(uint32_t version) +{ + if (version <= 1) + return FDT_V1_SIZE; + else if (version <= 2) + return FDT_V2_SIZE; + else if (version <= 3) + return FDT_V3_SIZE; + else if (version <= 16) + return FDT_V16_SIZE; + else + return FDT_V17_SIZE; +} + +size_t fdt_header_size(const void *fdt) +{ + return fdt_chk_version() ? fdt_header_size_(fdt_version(fdt)) : + FDT_V17_SIZE; +} + +int fdt_check_header(const void *fdt) +{ + size_t hdrsize; + + if (fdt_magic(fdt) != FDT_MAGIC) + return -FDT_ERR_BADMAGIC; + if (fdt_chk_version()) { + if ((fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) + || (fdt_last_comp_version(fdt) > + FDT_LAST_SUPPORTED_VERSION)) + return -FDT_ERR_BADVERSION; + if (fdt_version(fdt) < fdt_last_comp_version(fdt)) + return -FDT_ERR_BADVERSION; + } + hdrsize = fdt_header_size(fdt); + if (fdt_chk_basic()) { + + if ((fdt_totalsize(fdt) < hdrsize) + || (fdt_totalsize(fdt) > INT_MAX)) + return -FDT_ERR_TRUNCATED; + + /* Bounds check memrsv block */ + if (!check_off_(hdrsize, fdt_totalsize(fdt), + fdt_off_mem_rsvmap(fdt))) + return -FDT_ERR_TRUNCATED; + } + + if (fdt_chk_extra()) { + /* Bounds check structure block */ + if (fdt_chk_version() && fdt_version(fdt) < 17) { + if (!check_off_(hdrsize, fdt_totalsize(fdt), + fdt_off_dt_struct(fdt))) + return -FDT_ERR_TRUNCATED; + } else { + if (!check_block_(hdrsize, fdt_totalsize(fdt), + fdt_off_dt_struct(fdt), + fdt_size_dt_struct(fdt))) + return -FDT_ERR_TRUNCATED; + } + + /* Bounds check strings block */ + if (!check_block_(hdrsize, fdt_totalsize(fdt), + fdt_off_dt_strings(fdt), + fdt_size_dt_strings(fdt))) + return -FDT_ERR_TRUNCATED; + } + return 0; } @@ -78,12 +133,13 @@ const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len) { unsigned absoffset = offset + fdt_off_dt_struct(fdt); - if ((absoffset < offset) - || ((absoffset + len) < absoffset) - || (absoffset + len) > fdt_totalsize(fdt)) - return NULL; + if (fdt_chk_basic()) + if ((absoffset < offset) + || ((absoffset + len) < absoffset) + || (absoffset + len) > fdt_totalsize(fdt)) + return NULL; - if (fdt_version(fdt) >= 0x11) + if (!fdt_chk_version() || fdt_version(fdt) >= 0x11) if (((offset + len) < offset) || ((offset + len) > fdt_size_dt_struct(fdt))) return NULL; @@ -100,7 +156,7 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) *nextoffset = -FDT_ERR_TRUNCATED; tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE); - if (!tagp) + if (fdt_chk_basic() && !tagp) return FDT_END; /* premature end */ tag = fdt32_to_cpu(*tagp); offset += FDT_TAGSIZE; @@ -112,18 +168,19 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) do { p = fdt_offset_ptr(fdt, offset++, 1); } while (p && (*p != '\0')); - if (!p) + if (fdt_chk_basic() && !p) return FDT_END; /* premature end */ break; case FDT_PROP: lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp)); - if (!lenp) + if (fdt_chk_basic() && !lenp) return FDT_END; /* premature end */ /* skip-name offset, length and value */ offset += sizeof(struct fdt_property) - FDT_TAGSIZE + fdt32_to_cpu(*lenp); - if (fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 && + if (fdt_chk_version() && + fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 && ((offset - fdt32_to_cpu(*lenp)) % 8) != 0) offset += 4; break; @@ -137,7 +194,8 @@ uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset) return FDT_END; } - if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset)) + if (fdt_chk_basic() && + !fdt_offset_ptr(fdt, startoffset, offset - startoffset)) return FDT_END; /* premature end */ *nextoffset = FDT_TAGALIGN(offset); @@ -244,7 +302,7 @@ const char *fdt_find_string_(const char *strtab, int tabsize, const char *s) int fdt_move(const void *fdt, void *buf, int bufsize) { - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); if (fdt_totalsize(fdt) > bufsize) return -FDT_ERR_NOSPACE; diff --git a/scripts/dtc/libfdt/fdt.h b/scripts/dtc/libfdt/fdt.h index 74961f9026..f2e68807f2 100644 --- a/scripts/dtc/libfdt/fdt.h +++ b/scripts/dtc/libfdt/fdt.h @@ -1,55 +1,10 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ #ifndef FDT_H #define FDT_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * Copyright 2012 Kim Phillips, Freescale Semiconductor. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef __ASSEMBLY__ diff --git a/scripts/dtc/libfdt/fdt_addresses.c b/scripts/dtc/libfdt/fdt_addresses.c index 788c143113..9a82cd0ba2 100644 --- a/scripts/dtc/libfdt/fdt_addresses.c +++ b/scripts/dtc/libfdt/fdt_addresses.c @@ -1,53 +1,8 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au> * Copyright (C) 2018 embedded brains GmbH - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -97,3 +52,50 @@ int fdt_size_cells(const void *fdt, int nodeoffset) return 1; return val; } + +/* This function assumes that [address|size]_cells is 1 or 2 */ +int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset, + const char *name, uint64_t addr, uint64_t size) +{ + int addr_cells, size_cells, ret; + uint8_t data[sizeof(fdt64_t) * 2], *prop; + + ret = fdt_address_cells(fdt, parent); + if (ret < 0) + return ret; + addr_cells = ret; + + ret = fdt_size_cells(fdt, parent); + if (ret < 0) + return ret; + size_cells = ret; + + /* check validity of address */ + prop = data; + if (addr_cells == 1) { + if ((addr > UINT32_MAX) || ((UINT32_MAX + 1 - addr) < size)) + return -FDT_ERR_BADVALUE; + + fdt32_st(prop, (uint32_t)addr); + } else if (addr_cells == 2) { + fdt64_st(prop, addr); + } else { + return -FDT_ERR_BADNCELLS; + } + + /* check validity of size */ + prop += addr_cells * sizeof(fdt32_t); + if (size_cells == 1) { + if (size > UINT32_MAX) + return -FDT_ERR_BADVALUE; + + fdt32_st(prop, (uint32_t)size); + } else if (size_cells == 2) { + fdt64_st(prop, size); + } else { + return -FDT_ERR_BADNCELLS; + } + + return fdt_appendprop(fdt, nodeoffset, name, data, + (addr_cells + size_cells) * sizeof(fdt32_t)); +} diff --git a/scripts/dtc/libfdt/fdt_empty_tree.c b/scripts/dtc/libfdt/fdt_empty_tree.c index f2ae9b77c2..49d54d44b8 100644 --- a/scripts/dtc/libfdt/fdt_empty_tree.c +++ b/scripts/dtc/libfdt/fdt_empty_tree.c @@ -1,52 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2012 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" diff --git a/scripts/dtc/libfdt/fdt_overlay.c b/scripts/dtc/libfdt/fdt_overlay.c index bf75388ec9..be71873366 100644 --- a/scripts/dtc/libfdt/fdt_overlay.c +++ b/scripts/dtc/libfdt/fdt_overlay.c @@ -1,53 +1,8 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2016 Free Electrons * Copyright (C) 2016 NextThing Co. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -93,11 +48,11 @@ static uint32_t overlay_get_target_phandle(const void *fdto, int fragment) * @pathp: pointer which receives the path of the target (or NULL) * * overlay_get_target() retrieves the target offset in the base - * device tree of a fragment, no matter how the actual targetting is + * device tree of a fragment, no matter how the actual targeting is * done (through a phandle or a path) * * returns: - * the targetted node offset in the base device tree + * the targeted node offset in the base device tree * Negative error code on error */ static int overlay_get_target(const void *fdt, const void *fdto, @@ -697,7 +652,7 @@ static int get_path_len(const void *fdt, int nodeoffset) int len = 0, namelen; const char *name; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); for (;;) { name = fdt_get_name(fdt, nodeoffset, &namelen); @@ -778,26 +733,36 @@ static int overlay_symbol_update(void *fdt, void *fdto) /* keep end marker to avoid strlen() */ e = path + path_len; - /* format: /<fragment-name>/__overlay__/<relative-subnode-path> */ - if (*path != '/') return -FDT_ERR_BADVALUE; /* get fragment name first */ s = strchr(path + 1, '/'); - if (!s) - return -FDT_ERR_BADOVERLAY; + if (!s) { + /* Symbol refers to something that won't end + * up in the target tree */ + continue; + } frag_name = path + 1; frag_name_len = s - path - 1; /* verify format; safe since "s" lies in \0 terminated prop */ len = sizeof("/__overlay__/") - 1; - if ((e - s) < len || memcmp(s, "/__overlay__/", len)) - return -FDT_ERR_BADOVERLAY; - - rel_path = s + len; - rel_path_len = e - rel_path; + if ((e - s) > len && (memcmp(s, "/__overlay__/", len) == 0)) { + /* /<fragment-name>/__overlay__/<relative-subnode-path> */ + rel_path = s + len; + rel_path_len = e - rel_path; + } else if ((e - s) == len + && (memcmp(s, "/__overlay__", len - 1) == 0)) { + /* /<fragment-name>/__overlay__ */ + rel_path = ""; + rel_path_len = 0; + } else { + /* Symbol refers to something that won't end + * up in the target tree */ + continue; + } /* find the fragment index in which the symbol lies */ ret = fdt_subnode_offset_namelen(fdto, 0, frag_name, @@ -863,11 +828,15 @@ static int overlay_symbol_update(void *fdt, void *fdto) int fdt_overlay_apply(void *fdt, void *fdto) { - uint32_t delta = fdt_get_max_phandle(fdt); + uint32_t delta; int ret; - FDT_CHECK_HEADER(fdt); - FDT_CHECK_HEADER(fdto); + FDT_RO_PROBE(fdt); + FDT_RO_PROBE(fdto); + + ret = fdt_find_max_phandle(fdt, &delta); + if (ret) + goto err; ret = overlay_adjust_local_phandles(fdto, delta); if (ret) diff --git a/scripts/dtc/libfdt/fdt_ro.c b/scripts/dtc/libfdt/fdt_ro.c index dc499884e4..e398815485 100644 --- a/scripts/dtc/libfdt/fdt_ro.c +++ b/scripts/dtc/libfdt/fdt_ro.c @@ -1,52 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -61,7 +16,7 @@ static int fdt_nodename_eq_(const void *fdt, int offset, int olen; const char *p = fdt_get_name(fdt, offset, &olen); - if (!p || olen < len) + if (!p || (fdt_chk_extra() && olen < len)) /* short match */ return 0; @@ -76,46 +31,85 @@ static int fdt_nodename_eq_(const void *fdt, int offset, return 0; } -const char *fdt_string(const void *fdt, int stroffset) -{ - return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; -} - -static int fdt_string_eq_(const void *fdt, int stroffset, - const char *s, int len) +const char *fdt_get_string(const void *fdt, int stroffset, int *lenp) { - const char *p = fdt_string(fdt, stroffset); + int32_t totalsize; + uint32_t absoffset; + size_t len; + int err; + const char *s, *n; - return (strlen(p) == len) && (memcmp(p, s, len) == 0); -} + if (!fdt_chk_extra()) { + s = (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset; -uint32_t fdt_get_max_phandle(const void *fdt) -{ - uint32_t max_phandle = 0; - int offset; + if (lenp) + *lenp = strlen(s); + return s; + } + totalsize = fdt_ro_probe_(fdt); + err = totalsize; + if (totalsize < 0) + goto fail; + + err = -FDT_ERR_BADOFFSET; + absoffset = stroffset + fdt_off_dt_strings(fdt); + if (absoffset >= totalsize) + goto fail; + len = totalsize - absoffset; + + if (fdt_magic(fdt) == FDT_MAGIC) { + if (stroffset < 0) + goto fail; + if (!fdt_chk_version() || fdt_version(fdt) >= 17) { + if (stroffset >= fdt_size_dt_strings(fdt)) + goto fail; + if ((fdt_size_dt_strings(fdt) - stroffset) < len) + len = fdt_size_dt_strings(fdt) - stroffset; + } + } else if (fdt_magic(fdt) == FDT_SW_MAGIC) { + if ((stroffset >= 0) + || (stroffset < -fdt_size_dt_strings(fdt))) + goto fail; + if ((-stroffset) < len) + len = -stroffset; + } else { + err = -FDT_ERR_INTERNAL; + goto fail; + } - for (offset = fdt_next_node(fdt, -1, NULL);; - offset = fdt_next_node(fdt, offset, NULL)) { - uint32_t phandle; + s = (const char *)fdt + absoffset; + n = memchr(s, '\0', len); + if (!n) { + /* missing terminating NULL */ + err = -FDT_ERR_TRUNCATED; + goto fail; + } - if (offset == -FDT_ERR_NOTFOUND) - return max_phandle; + if (lenp) + *lenp = n - s; + return s; - if (offset < 0) - return (uint32_t)-1; +fail: + if (lenp) + *lenp = err; + return NULL; +} - phandle = fdt_get_phandle(fdt, offset); - if (phandle == (uint32_t)-1) - continue; +const char *fdt_string(const void *fdt, int stroffset) +{ + return fdt_get_string(fdt, stroffset, NULL); +} - if (phandle > max_phandle) - max_phandle = phandle; - } +static int fdt_string_eq_(const void *fdt, int stroffset, + const char *s, int len) +{ + int slen; + const char *p = fdt_get_string(fdt, stroffset, &slen); - return 0; + return p && (slen == len) && (memcmp(p, s, len) == 0); } -int fdt_generate_phandle(const void *fdt, uint32_t *phandle) +int fdt_find_max_phandle(const void *fdt, uint32_t *phandle) { uint32_t max = 0; int offset = -1; @@ -137,6 +131,21 @@ int fdt_generate_phandle(const void *fdt, uint32_t *phandle) max = value; } + if (phandle) + *phandle = max; + + return 0; +} + +int fdt_generate_phandle(const void *fdt, uint32_t *phandle) +{ + uint32_t max; + int err; + + err = fdt_find_max_phandle(fdt, &max); + if (err < 0) + return err; + if (max == FDT_MAX_PHANDLE) return -FDT_ERR_NOPHANDLES; @@ -146,21 +155,45 @@ int fdt_generate_phandle(const void *fdt, uint32_t *phandle) return 0; } +static const struct fdt_reserve_entry *fdt_mem_rsv(const void *fdt, int n) +{ + int offset = n * sizeof(struct fdt_reserve_entry); + int absoffset = fdt_off_mem_rsvmap(fdt) + offset; + + if (fdt_chk_extra()) { + if (absoffset < fdt_off_mem_rsvmap(fdt)) + return NULL; + if (absoffset > fdt_totalsize(fdt) - + sizeof(struct fdt_reserve_entry)) + return NULL; + } + return fdt_mem_rsv_(fdt, n); +} + int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size) { - FDT_CHECK_HEADER(fdt); - *address = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->address); - *size = fdt64_to_cpu(fdt_mem_rsv_(fdt, n)->size); + const struct fdt_reserve_entry *re; + + FDT_RO_PROBE(fdt); + re = fdt_mem_rsv(fdt, n); + if (fdt_chk_extra() && !re) + return -FDT_ERR_BADOFFSET; + + *address = fdt64_ld(&re->address); + *size = fdt64_ld(&re->size); return 0; } int fdt_num_mem_rsv(const void *fdt) { - int i = 0; + int i; + const struct fdt_reserve_entry *re; - while (fdt64_to_cpu(fdt_mem_rsv_(fdt, i)->size) != 0) - i++; - return i; + for (i = 0; (re = fdt_mem_rsv(fdt, i)) != NULL; i++) { + if (fdt64_ld(&re->size) == 0) + return i; + } + return -FDT_ERR_TRUNCATED; } static int nextprop_(const void *fdt, int offset) @@ -192,7 +225,7 @@ int fdt_subnode_offset_namelen(const void *fdt, int offset, { int depth; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); for (depth = 0; (offset >= 0) && (depth >= 0); @@ -218,7 +251,7 @@ int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen) const char *p = path; int offset = 0; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* see if we have an alias */ if (*path != '/') { @@ -268,13 +301,14 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) const char *nameptr; int err; - if (((err = fdt_check_header(fdt)) != 0) - || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0)) - goto fail; + if (fdt_chk_extra() && + (((err = fdt_ro_probe_(fdt)) < 0) + || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0))) + goto fail; nameptr = nh->name; - if (fdt_version(fdt) < 0x10) { + if (fdt_chk_version() && fdt_version(fdt) < 0x10) { /* * For old FDT versions, match the naming conventions of V16: * give only the leaf name (after all /). The actual tree @@ -325,7 +359,7 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt, int err; const struct fdt_property *prop; - if ((err = fdt_check_prop_offset_(fdt, offset)) < 0) { + if (fdt_chk_basic() && (err = fdt_check_prop_offset_(fdt, offset)) < 0) { if (lenp) *lenp = err; return NULL; @@ -334,7 +368,7 @@ static const struct fdt_property *fdt_get_property_by_offset_(const void *fdt, prop = fdt_offset_ptr_(fdt, offset); if (lenp) - *lenp = fdt32_to_cpu(prop->len); + *lenp = fdt32_ld(&prop->len); return prop; } @@ -346,7 +380,7 @@ const struct fdt_property *fdt_get_property_by_offset(const void *fdt, /* Prior to version 16, properties may need realignment * and this API does not work. fdt_getprop_*() will, however. */ - if (fdt_version(fdt) < 0x10) { + if (fdt_chk_version() && fdt_version(fdt) < 0x10) { if (lenp) *lenp = -FDT_ERR_BADVERSION; return NULL; @@ -367,11 +401,12 @@ static const struct fdt_property *fdt_get_property_namelen_(const void *fdt, (offset = fdt_next_property_offset(fdt, offset))) { const struct fdt_property *prop; - if (!(prop = fdt_get_property_by_offset_(fdt, offset, lenp))) { + prop = fdt_get_property_by_offset_(fdt, offset, lenp); + if (fdt_chk_extra() && !prop) { offset = -FDT_ERR_INTERNAL; break; } - if (fdt_string_eq_(fdt, fdt32_to_cpu(prop->nameoff), + if (fdt_string_eq_(fdt, fdt32_ld(&prop->nameoff), name, namelen)) { if (poffset) *poffset = offset; @@ -392,7 +427,7 @@ const struct fdt_property *fdt_get_property_namelen(const void *fdt, { /* Prior to version 16, properties may need realignment * and this API does not work. fdt_getprop_*() will, however. */ - if (fdt_version(fdt) < 0x10) { + if (fdt_chk_version() && fdt_version(fdt) < 0x10) { if (lenp) *lenp = -FDT_ERR_BADVERSION; return NULL; @@ -423,8 +458,8 @@ const void *fdt_getprop_namelen(const void *fdt, int nodeoffset, return NULL; /* Handle realignment */ - if (fdt_version(fdt) < 0x10 && (poffset + sizeof(*prop)) % 8 && - fdt32_to_cpu(prop->len) >= 8) + if (fdt_chk_version() && fdt_version(fdt) < 0x10 && + (poffset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8) return prop->data + 4; return prop->data; } @@ -437,12 +472,27 @@ const void *fdt_getprop_by_offset(const void *fdt, int offset, prop = fdt_get_property_by_offset_(fdt, offset, lenp); if (!prop) return NULL; - if (namep) - *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff)); + if (namep) { + const char *name; + int namelen; + + if (fdt_chk_extra()) { + name = fdt_get_string(fdt, fdt32_ld(&prop->nameoff), + &namelen); + if (!name) { + if (lenp) + *lenp = namelen; + return NULL; + } + *namep = name; + } else { + *namep = fdt_string(fdt, fdt32_ld(&prop->nameoff)); + } + } /* Handle realignment */ - if (fdt_version(fdt) < 0x10 && (offset + sizeof(*prop)) % 8 && - fdt32_to_cpu(prop->len) >= 8) + if (fdt_chk_version() && fdt_version(fdt) < 0x10 && + (offset + sizeof(*prop)) % 8 && fdt32_ld(&prop->len) >= 8) return prop->data + 4; return prop->data; } @@ -467,7 +517,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset) return 0; } - return fdt32_to_cpu(*php); + return fdt32_ld(php); } const char *fdt_get_alias_namelen(const void *fdt, @@ -493,7 +543,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) int offset, depth, namelen; const char *name; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); if (buflen < 2) return -FDT_ERR_NOSPACE; @@ -545,7 +595,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, int offset, depth; int supernodeoffset = -FDT_ERR_INTERNAL; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); if (supernodedepth < 0) return -FDT_ERR_NOTFOUND; @@ -567,10 +617,12 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, } } - if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) - return -FDT_ERR_BADOFFSET; - else if (offset == -FDT_ERR_BADOFFSET) - return -FDT_ERR_BADSTRUCTURE; + if (fdt_chk_extra()) { + if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) + return -FDT_ERR_BADOFFSET; + else if (offset == -FDT_ERR_BADOFFSET) + return -FDT_ERR_BADSTRUCTURE; + } return offset; /* error from fdt_next_node() */ } @@ -582,7 +634,7 @@ int fdt_node_depth(const void *fdt, int nodeoffset) err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth); if (err) - return (err < 0) ? err : -FDT_ERR_INTERNAL; + return (!fdt_chk_extra() || err < 0) ? err : -FDT_ERR_INTERNAL; return nodedepth; } @@ -604,7 +656,7 @@ int fdt_node_offset_by_prop_value(const void *fdt, int startoffset, const void *val; int len; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_getprop(), then if that didn't @@ -630,7 +682,7 @@ int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle) if ((phandle == 0) || (phandle == -1)) return -FDT_ERR_BADPHANDLE; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* FIXME: The algorithm here is pretty horrible: we * potentially scan each property of a node in @@ -783,7 +835,7 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, { int offset, err; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); /* FIXME: The algorithm here is pretty horrible: we scan each * property of a node in fdt_node_check_compatible(), then if @@ -802,3 +854,68 @@ int fdt_node_offset_by_compatible(const void *fdt, int startoffset, return offset; /* error from fdt_next_node() */ } + +#if !defined(FDT_ASSUME_MASK) || FDT_ASSUME_MASK != 0xff +int fdt_check_full(const void *fdt, size_t bufsize) +{ + int err; + int num_memrsv; + int offset, nextoffset = 0; + uint32_t tag; + unsigned depth = 0; + const void *prop; + const char *propname; + + if (bufsize < FDT_V1_SIZE) + return -FDT_ERR_TRUNCATED; + err = fdt_check_header(fdt); + if (err != 0) + return err; + if (bufsize < fdt_totalsize(fdt)) + return -FDT_ERR_TRUNCATED; + + num_memrsv = fdt_num_mem_rsv(fdt); + if (num_memrsv < 0) + return num_memrsv; + + while (1) { + offset = nextoffset; + tag = fdt_next_tag(fdt, offset, &nextoffset); + + if (nextoffset < 0) + return nextoffset; + + switch (tag) { + case FDT_NOP: + break; + + case FDT_END: + if (depth != 0) + return -FDT_ERR_BADSTRUCTURE; + return 0; + + case FDT_BEGIN_NODE: + depth++; + if (depth > INT_MAX) + return -FDT_ERR_BADSTRUCTURE; + break; + + case FDT_END_NODE: + if (depth == 0) + return -FDT_ERR_BADSTRUCTURE; + depth--; + break; + + case FDT_PROP: + prop = fdt_getprop_by_offset(fdt, offset, &propname, + &err); + if (!prop) + return err; + break; + + default: + return -FDT_ERR_INTERNAL; + } + } +} +#endif diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c index 9b829051e4..08e2981a44 100644 --- a/scripts/dtc/libfdt/fdt_rw.c +++ b/scripts/dtc/libfdt/fdt_rw.c @@ -1,52 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -58,6 +13,8 @@ static int fdt_blocks_misordered_(const void *fdt, int mem_rsv_size, int struct_size) { + if (!fdt_chk_basic()) + return false; return (fdt_off_mem_rsvmap(fdt) < FDT_ALIGN(sizeof(struct fdt_header), 8)) || (fdt_off_dt_struct(fdt) < (fdt_off_mem_rsvmap(fdt) + mem_rsv_size)) @@ -67,25 +24,27 @@ static int fdt_blocks_misordered_(const void *fdt, (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt))); } -static int fdt_rw_check_header_(void *fdt) +static int fdt_rw_probe_(void *fdt) { - FDT_CHECK_HEADER(fdt); + if (!fdt_chk_basic()) + return 0; + FDT_RO_PROBE(fdt); - if (fdt_version(fdt) < 17) + if (fdt_chk_version() && fdt_version(fdt) < 17) return -FDT_ERR_BADVERSION; if (fdt_blocks_misordered_(fdt, sizeof(struct fdt_reserve_entry), fdt_size_dt_struct(fdt))) return -FDT_ERR_BADLAYOUT; - if (fdt_version(fdt) > 17) + if (fdt_chk_version() && fdt_version(fdt) > 17) fdt_set_version(fdt, 17); return 0; } -#define FDT_RW_CHECK_HEADER(fdt) \ +#define FDT_RW_PROBE(fdt) \ { \ int err_; \ - if ((err_ = fdt_rw_check_header_(fdt)) != 0) \ + if (fdt_chk_extra() && (err_ = fdt_rw_probe_(fdt)) != 0) \ return err_; \ } @@ -136,6 +95,14 @@ static int fdt_splice_struct_(void *fdt, void *p, return 0; } +/* Must only be used to roll back in case of error */ +static void fdt_del_last_string_(void *fdt, const char *s) +{ + int newlen = strlen(s) + 1; + + fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) - newlen); +} + static int fdt_splice_string_(void *fdt, int newlen) { void *p = (char *)fdt @@ -149,7 +116,16 @@ static int fdt_splice_string_(void *fdt, int newlen) return 0; } -static int fdt_find_add_string_(void *fdt, const char *s) +/** + * fdt_find_add_string_() - Find or allocate a string + * + * @fdt: pointer to the device tree to check/adjust + * @s: string to find/add + * @allocated: Set to 0 if the string was found, 1 if not found and so + * allocated. Ignored if !fdt_chk_basic() + * @return offset of string in the string table (whether found or added) + */ +static int fdt_find_add_string_(void *fdt, const char *s, int *allocated) { char *strtab = (char *)fdt + fdt_off_dt_strings(fdt); const char *p; @@ -157,6 +133,9 @@ static int fdt_find_add_string_(void *fdt, const char *s) int len = strlen(s) + 1; int err; + if (fdt_chk_basic()) + *allocated = 0; + p = fdt_find_string_(strtab, fdt_size_dt_strings(fdt), s); if (p) /* found it */ @@ -167,6 +146,9 @@ static int fdt_find_add_string_(void *fdt, const char *s) if (err) return err; + if (fdt_chk_basic()) + *allocated = 1; + memcpy(new, s, len); return (new - strtab); } @@ -176,7 +158,7 @@ int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size) struct fdt_reserve_entry *re; int err; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); re = fdt_mem_rsv_w_(fdt, fdt_num_mem_rsv(fdt)); err = fdt_splice_mem_rsv_(fdt, re, 0, 1); @@ -192,7 +174,7 @@ int fdt_del_mem_rsv(void *fdt, int n) { struct fdt_reserve_entry *re = fdt_mem_rsv_w_(fdt, n); - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); if (n >= fdt_num_mem_rsv(fdt)) return -FDT_ERR_NOTFOUND; @@ -225,11 +207,12 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name, int nextoffset; int namestroff; int err; + int allocated; if ((nextoffset = fdt_check_node_offset_(fdt, nodeoffset)) < 0) return nextoffset; - namestroff = fdt_find_add_string_(fdt, name); + namestroff = fdt_find_add_string_(fdt, name, &allocated); if (namestroff < 0) return namestroff; @@ -237,8 +220,12 @@ static int fdt_add_property_(void *fdt, int nodeoffset, const char *name, proplen = sizeof(**prop) + FDT_TAGALIGN(len); err = fdt_splice_struct_(fdt, *prop, 0, proplen); - if (err) + if (err) { + /* Delete the string if we failed to add it */ + if (fdt_chk_basic() && allocated) + fdt_del_last_string_(fdt, name); return err; + } (*prop)->tag = cpu_to_fdt32(FDT_PROP); (*prop)->nameoff = cpu_to_fdt32(namestroff); @@ -252,7 +239,7 @@ int fdt_set_name(void *fdt, int nodeoffset, const char *name) int oldlen, newlen; int err; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); namep = (char *)(uintptr_t)fdt_get_name(fdt, nodeoffset, &oldlen); if (!namep) @@ -275,7 +262,7 @@ int fdt_setprop_placeholder(void *fdt, int nodeoffset, const char *name, struct fdt_property *prop; int err; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); err = fdt_resize_property_(fdt, nodeoffset, name, len, &prop); if (err == -FDT_ERR_NOTFOUND) @@ -308,7 +295,7 @@ int fdt_appendprop(void *fdt, int nodeoffset, const char *name, struct fdt_property *prop; int err, oldlen, newlen; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen); if (prop) { @@ -334,7 +321,7 @@ int fdt_delprop(void *fdt, int nodeoffset, const char *name) struct fdt_property *prop; int len, proplen; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); prop = fdt_get_property_w(fdt, nodeoffset, name, &len); if (!prop) @@ -354,7 +341,7 @@ int fdt_add_subnode_namelen(void *fdt, int parentoffset, uint32_t tag; fdt32_t *endtag; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen); if (offset >= 0) @@ -394,7 +381,7 @@ int fdt_del_node(void *fdt, int nodeoffset) { int endoffset; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); endoffset = fdt_node_end_offset_(fdt, nodeoffset); if (endoffset < 0) @@ -435,12 +422,12 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize) const char *fdtend = fdtstart + fdt_totalsize(fdt); char *tmp; - FDT_CHECK_HEADER(fdt); + FDT_RO_PROBE(fdt); mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) * sizeof(struct fdt_reserve_entry); - if (fdt_version(fdt) >= 17) { + if (!fdt_chk_version() || fdt_version(fdt) >= 17) { struct_size = fdt_size_dt_struct(fdt); } else { struct_size = 0; @@ -494,7 +481,7 @@ int fdt_pack(void *fdt) { int mem_rsv_size; - FDT_RW_CHECK_HEADER(fdt); + FDT_RW_PROBE(fdt); mem_rsv_size = (fdt_num_mem_rsv(fdt)+1) * sizeof(struct fdt_reserve_entry); diff --git a/scripts/dtc/libfdt/fdt_strerror.c b/scripts/dtc/libfdt/fdt_strerror.c index 9677a1887e..768db66ead 100644 --- a/scripts/dtc/libfdt/fdt_strerror.c +++ b/scripts/dtc/libfdt/fdt_strerror.c @@ -1,51 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -82,6 +38,7 @@ static struct fdt_errtabent fdt_errtable[] = { FDT_ERRTABENT(FDT_ERR_BADVALUE), FDT_ERRTABENT(FDT_ERR_BADOVERLAY), FDT_ERRTABENT(FDT_ERR_NOPHANDLES), + FDT_ERRTABENT(FDT_ERR_BADFLAGS), }; #define FDT_ERRTABSIZE (sizeof(fdt_errtable) / sizeof(fdt_errtable[0])) diff --git a/scripts/dtc/libfdt/fdt_sw.c b/scripts/dtc/libfdt/fdt_sw.c index d8ef748a72..a8c924675a 100644 --- a/scripts/dtc/libfdt/fdt_sw.c +++ b/scripts/dtc/libfdt/fdt_sw.c @@ -1,52 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -55,21 +10,90 @@ #include "libfdt_internal.h" -static int fdt_sw_check_header_(void *fdt) +static int fdt_sw_probe_(void *fdt) +{ + if (fdt_chk_basic()) { + if (fdt_magic(fdt) == FDT_MAGIC) + return -FDT_ERR_BADSTATE; + else if (fdt_magic(fdt) != FDT_SW_MAGIC) + return -FDT_ERR_BADMAGIC; + } + + return 0; +} + +#define FDT_SW_PROBE(fdt) \ + { \ + int err; \ + if (fdt_chk_basic() && (err = fdt_sw_probe_(fdt)) != 0) \ + return err; \ + } + +/* 'memrsv' state: Initial state after fdt_create() + * + * Allowed functions: + * fdt_add_reservmap_entry() + * fdt_finish_reservemap() [moves to 'struct' state] + */ +static int fdt_sw_probe_memrsv_(void *fdt) +{ + int err = fdt_sw_probe_(fdt); + if (err) + return err; + + if (fdt_chk_extra() && fdt_off_dt_strings(fdt) != 0) + return -FDT_ERR_BADSTATE; + return 0; +} + +#define FDT_SW_PROBE_MEMRSV(fdt) \ + { \ + int err; \ + if (fdt_chk_extra() && (err = fdt_sw_probe_memrsv_(fdt)) != 0) \ + return err; \ + } + +/* 'struct' state: Enter this state after fdt_finish_reservemap() + * + * Allowed functions: + * fdt_begin_node() + * fdt_end_node() + * fdt_property*() + * fdt_finish() [moves to 'complete' state] + */ +static int fdt_sw_probe_struct_(void *fdt) { - if (fdt_magic(fdt) != FDT_SW_MAGIC) - return -FDT_ERR_BADMAGIC; - /* FIXME: should check more details about the header state */ + int err; + + if (!fdt_chk_extra()) + return 0; + err = fdt_sw_probe_(fdt); + if (err) + return err; + + if (fdt_off_dt_strings(fdt) != fdt_totalsize(fdt)) + return -FDT_ERR_BADSTATE; return 0; } -#define FDT_SW_CHECK_HEADER(fdt) \ +#define FDT_SW_PROBE_STRUCT(fdt) \ { \ int err; \ - if ((err = fdt_sw_check_header_(fdt)) != 0) \ + if (fdt_chk_extra() && (err = fdt_sw_probe_struct_(fdt)) != 0) \ return err; \ } +static inline uint32_t sw_flags(void *fdt) +{ + /* assert: (fdt_magic(fdt) == FDT_SW_MAGIC) */ + return fdt_last_comp_version(fdt); +} + +/* 'complete' state: Enter this state after fdt_finish() + * + * Allowed functions: none + */ + static void *fdt_grab_space_(void *fdt, size_t len) { int offset = fdt_size_dt_struct(fdt); @@ -85,38 +109,58 @@ static void *fdt_grab_space_(void *fdt, size_t len) return fdt_offset_ptr_w_(fdt, offset); } -int fdt_create(void *buf, int bufsize) +int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags) { + const size_t hdrsize = FDT_ALIGN(sizeof(struct fdt_header), + sizeof(struct fdt_reserve_entry)); void *fdt = buf; - if (bufsize < sizeof(struct fdt_header)) + if (bufsize < hdrsize) return -FDT_ERR_NOSPACE; + if (flags & ~FDT_CREATE_FLAGS_ALL) + return -FDT_ERR_BADFLAGS; + memset(buf, 0, bufsize); + /* + * magic and last_comp_version keep intermediate state during the fdt + * creation process, which is replaced with the proper FDT format by + * fdt_finish(). + * + * flags should be accessed with sw_flags(). + */ fdt_set_magic(fdt, FDT_SW_MAGIC); fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION); - fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION); + fdt_set_last_comp_version(fdt, flags); + fdt_set_totalsize(fdt, bufsize); - fdt_set_off_mem_rsvmap(fdt, FDT_ALIGN(sizeof(struct fdt_header), - sizeof(struct fdt_reserve_entry))); + fdt_set_off_mem_rsvmap(fdt, hdrsize); fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt)); - fdt_set_off_dt_strings(fdt, bufsize); + fdt_set_off_dt_strings(fdt, 0); return 0; } +int fdt_create(void *buf, int bufsize) +{ + return fdt_create_with_flags(buf, bufsize, 0); +} + int fdt_resize(void *fdt, void *buf, int bufsize) { size_t headsize, tailsize; char *oldtail, *newtail; - FDT_SW_CHECK_HEADER(fdt); + FDT_SW_PROBE(fdt); headsize = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); tailsize = fdt_size_dt_strings(fdt); + if (fdt_chk_extra() && (headsize + tailsize) > fdt_totalsize(fdt)) + return -FDT_ERR_INTERNAL; + if ((headsize + tailsize) > bufsize) return -FDT_ERR_NOSPACE; @@ -133,8 +177,9 @@ int fdt_resize(void *fdt, void *buf, int bufsize) memmove(buf, fdt, headsize); } - fdt_set_off_dt_strings(buf, bufsize); fdt_set_totalsize(buf, bufsize); + if (fdt_off_dt_strings(buf)) + fdt_set_off_dt_strings(buf, bufsize); return 0; } @@ -144,10 +189,7 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) struct fdt_reserve_entry *re; int offset; - FDT_SW_CHECK_HEADER(fdt); - - if (fdt_size_dt_struct(fdt)) - return -FDT_ERR_BADSTATE; + FDT_SW_PROBE_MEMRSV(fdt); offset = fdt_off_dt_struct(fdt); if ((offset + sizeof(*re)) > fdt_totalsize(fdt)) @@ -164,16 +206,23 @@ int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size) int fdt_finish_reservemap(void *fdt) { - return fdt_add_reservemap_entry(fdt, 0, 0); + int err = fdt_add_reservemap_entry(fdt, 0, 0); + + if (err) + return err; + + fdt_set_off_dt_strings(fdt, fdt_totalsize(fdt)); + return 0; } int fdt_begin_node(void *fdt, const char *name) { struct fdt_node_header *nh; - int namelen = strlen(name) + 1; + int namelen; - FDT_SW_CHECK_HEADER(fdt); + FDT_SW_PROBE_STRUCT(fdt); + namelen = strlen(name) + 1; nh = fdt_grab_space_(fdt, sizeof(*nh) + FDT_TAGALIGN(namelen)); if (! nh) return -FDT_ERR_NOSPACE; @@ -187,7 +236,7 @@ int fdt_end_node(void *fdt) { fdt32_t *en; - FDT_SW_CHECK_HEADER(fdt); + FDT_SW_PROBE_STRUCT(fdt); en = fdt_grab_space_(fdt, FDT_TAGSIZE); if (! en) @@ -197,19 +246,13 @@ int fdt_end_node(void *fdt) return 0; } -static int fdt_find_add_string_(void *fdt, const char *s) +static int fdt_add_string_(void *fdt, const char *s) { char *strtab = (char *)fdt + fdt_totalsize(fdt); - const char *p; int strtabsize = fdt_size_dt_strings(fdt); int len = strlen(s) + 1; int struct_top, offset; - p = fdt_find_string_(strtab - strtabsize, strtabsize, s); - if (p) - return p - strtab; - - /* Add it */ offset = -strtabsize - len; struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt); if (fdt_totalsize(fdt) + offset < struct_top) @@ -220,20 +263,56 @@ static int fdt_find_add_string_(void *fdt, const char *s) return offset; } +/* Must only be used to roll back in case of error */ +static void fdt_del_last_string_(void *fdt, const char *s) +{ + int strtabsize = fdt_size_dt_strings(fdt); + int len = strlen(s) + 1; + + fdt_set_size_dt_strings(fdt, strtabsize - len); +} + +static int fdt_find_add_string_(void *fdt, const char *s, int *allocated) +{ + char *strtab = (char *)fdt + fdt_totalsize(fdt); + int strtabsize = fdt_size_dt_strings(fdt); + const char *p; + + *allocated = 0; + + p = fdt_find_string_(strtab - strtabsize, strtabsize, s); + if (p) + return p - strtab; + + *allocated = 1; + + return fdt_add_string_(fdt, s); +} + int fdt_property_placeholder(void *fdt, const char *name, int len, void **valp) { struct fdt_property *prop; int nameoff; + int allocated; - FDT_SW_CHECK_HEADER(fdt); + FDT_SW_PROBE_STRUCT(fdt); - nameoff = fdt_find_add_string_(fdt, name); + /* String de-duplication can be slow, _NO_NAME_DEDUP skips it */ + if (sw_flags(fdt) & FDT_CREATE_FLAG_NO_NAME_DEDUP) { + allocated = 1; + nameoff = fdt_add_string_(fdt, name); + } else { + nameoff = fdt_find_add_string_(fdt, name, &allocated); + } if (nameoff == 0) return -FDT_ERR_NOSPACE; prop = fdt_grab_space_(fdt, sizeof(*prop) + FDT_TAGALIGN(len)); - if (! prop) + if (! prop) { + if (allocated) + fdt_del_last_string_(fdt, name); return -FDT_ERR_NOSPACE; + } prop->tag = cpu_to_fdt32(FDT_PROP); prop->nameoff = cpu_to_fdt32(nameoff); @@ -262,7 +341,7 @@ int fdt_finish(void *fdt) uint32_t tag; int offset, nextoffset; - FDT_SW_CHECK_HEADER(fdt); + FDT_SW_PROBE_STRUCT(fdt); /* Add terminator */ end = fdt_grab_space_(fdt, sizeof(*end)); @@ -295,6 +374,10 @@ int fdt_finish(void *fdt) /* Finally, adjust the header */ fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt)); + + /* And fix up fields that were keeping intermediate state. */ + fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION); fdt_set_magic(fdt, FDT_MAGIC); + return 0; } diff --git a/scripts/dtc/libfdt/fdt_wip.c b/scripts/dtc/libfdt/fdt_wip.c index 534c1cbbb2..f64139e0b3 100644 --- a/scripts/dtc/libfdt/fdt_wip.c +++ b/scripts/dtc/libfdt/fdt_wip.c @@ -1,52 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" diff --git a/scripts/dtc/libfdt/libfdt.h b/scripts/dtc/libfdt/libfdt.h index c400f2f5d5..36fadcdea5 100644 --- a/scripts/dtc/libfdt/libfdt.h +++ b/scripts/dtc/libfdt/libfdt.h @@ -1,54 +1,9 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ #ifndef LIBFDT_H #define LIBFDT_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "libfdt_env.h" @@ -90,8 +45,9 @@ /* Error codes: codes for bad device tree blobs */ #define FDT_ERR_TRUNCATED 8 - /* FDT_ERR_TRUNCATED: Structure block of the given device tree - * ends without an FDT_END tag. */ + /* FDT_ERR_TRUNCATED: FDT or a sub-block is improperly + * terminated (overflows, goes outside allowed bounds, or + * isn't properly terminated). */ #define FDT_ERR_BADMAGIC 9 /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a * device tree at all - it is missing the flattened device @@ -137,7 +93,11 @@ /* FDT_ERR_NOPHANDLES: The device tree doesn't have any * phandle available anymore without causing an overflow */ -#define FDT_ERR_MAX 17 +#define FDT_ERR_BADFLAGS 18 + /* FDT_ERR_BADFLAGS: The function was passed a flags field that + * contains invalid flags or an invalid combination of flags. */ + +#define FDT_ERR_MAX 18 /* constants */ #define FDT_MAX_PHANDLE 0xfffffffe @@ -157,6 +117,61 @@ static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen) uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset); +/* + * Alignment helpers: + * These helpers access words from a device tree blob. They're + * built to work even with unaligned pointers on platforms (ike + * ARM) that don't like unaligned loads and stores + */ + +static inline uint32_t fdt32_ld(const fdt32_t *p) +{ + const uint8_t *bp = (const uint8_t *)p; + + return ((uint32_t)bp[0] << 24) + | ((uint32_t)bp[1] << 16) + | ((uint32_t)bp[2] << 8) + | bp[3]; +} + +static inline void fdt32_st(void *property, uint32_t value) +{ + uint8_t *bp = (uint8_t *)property; + + bp[0] = value >> 24; + bp[1] = (value >> 16) & 0xff; + bp[2] = (value >> 8) & 0xff; + bp[3] = value & 0xff; +} + +static inline uint64_t fdt64_ld(const fdt64_t *p) +{ + const uint8_t *bp = (const uint8_t *)p; + + return ((uint64_t)bp[0] << 56) + | ((uint64_t)bp[1] << 48) + | ((uint64_t)bp[2] << 40) + | ((uint64_t)bp[3] << 32) + | ((uint64_t)bp[4] << 24) + | ((uint64_t)bp[5] << 16) + | ((uint64_t)bp[6] << 8) + | bp[7]; +} + +static inline void fdt64_st(void *property, uint64_t value) +{ + uint8_t *bp = (uint8_t *)property; + + bp[0] = value >> 56; + bp[1] = (value >> 48) & 0xff; + bp[2] = (value >> 40) & 0xff; + bp[3] = (value >> 32) & 0xff; + bp[4] = (value >> 24) & 0xff; + bp[5] = (value >> 16) & 0xff; + bp[6] = (value >> 8) & 0xff; + bp[7] = value & 0xff; +} + /**********************************************************************/ /* Traversal functions */ /**********************************************************************/ @@ -199,7 +214,7 @@ int fdt_next_subnode(const void *fdt, int offset); * ... * } * - * if ((node < 0) && (node != -FDT_ERR_NOT_FOUND)) { + * if ((node < 0) && (node != -FDT_ERR_NOTFOUND)) { * Error handling * } * @@ -217,7 +232,7 @@ int fdt_next_subnode(const void *fdt, int offset); /* General functions */ /**********************************************************************/ #define fdt_get_header(fdt, field) \ - (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field)) + (fdt32_ld(&((const struct fdt_header *)(fdt))->field)) #define fdt_magic(fdt) (fdt_get_header(fdt, magic)) #define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize)) #define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct)) @@ -248,18 +263,32 @@ fdt_set_hdr_(size_dt_struct); #undef fdt_set_hdr_ /** - * fdt_check_header - sanity check a device tree or possible device tree + * fdt_header_size - return the size of the tree's header + * @fdt: pointer to a flattened device tree + */ +size_t fdt_header_size(const void *fdt); + +/** + * fdt_header_size_ - internal function which takes a version number + */ +size_t fdt_header_size_(uint32_t version); + +/** + * fdt_check_header - sanity check a device tree header + * @fdt: pointer to data which might be a flattened device tree * * fdt_check_header() checks that the given buffer contains what - * appears to be a flattened device tree with sane information in its - * header. + * appears to be a flattened device tree, and that the header contains + * valid information (to the extent that can be determined from the + * header alone). * * returns: * 0, if the buffer appears to contain a valid device tree * -FDT_ERR_BADMAGIC, * -FDT_ERR_BADVERSION, - * -FDT_ERR_BADSTATE, standard meanings, as above + * -FDT_ERR_BADSTATE, + * -FDT_ERR_TRUNCATED, standard meanings, as above */ int fdt_check_header(const void *fdt); @@ -288,6 +317,24 @@ int fdt_move(const void *fdt, void *buf, int bufsize); /* Read-only functions */ /**********************************************************************/ +int fdt_check_full(const void *fdt, size_t bufsize); + +/** + * fdt_get_string - retrieve a string from the strings block of a device tree + * @fdt: pointer to the device tree blob + * @stroffset: offset of the string within the strings block (native endian) + * @lenp: optional pointer to return the string's length + * + * fdt_get_string() retrieves a pointer to a single string from the + * strings block of the device tree blob at fdt, and optionally also + * returns the string's length in *lenp. + * + * returns: + * a pointer to the string, on success + * NULL, if stroffset is out of bounds, or doesn't point to a valid string + */ +const char *fdt_get_string(const void *fdt, int stroffset, int *lenp); + /** * fdt_string - retrieve a string from the strings block of a device tree * @fdt: pointer to the device tree blob @@ -298,11 +345,25 @@ int fdt_move(const void *fdt, void *buf, int bufsize); * * returns: * a pointer to the string, on success - * NULL, if stroffset is out of bounds + * NULL, if stroffset is out of bounds, or doesn't point to a valid string */ const char *fdt_string(const void *fdt, int stroffset); /** + * fdt_find_max_phandle - find and return the highest phandle in a tree + * @fdt: pointer to the device tree blob + * @phandle: return location for the highest phandle value found in the tree + * + * fdt_find_max_phandle() finds the highest phandle value in the given device + * tree. The value returned in @phandle is only valid if the function returns + * success. + * + * returns: + * 0 on success or a negative error code on failure + */ +int fdt_find_max_phandle(const void *fdt, uint32_t *phandle); + +/** * fdt_get_max_phandle - retrieves the highest phandle in a tree * @fdt: pointer to the device tree blob * @@ -310,12 +371,24 @@ const char *fdt_string(const void *fdt, int stroffset); * device tree. This will ignore badly formatted phandles, or phandles * with a value of 0 or -1. * + * This function is deprecated in favour of fdt_find_max_phandle(). + * * returns: * the highest phandle on success * 0, if no phandle was found in the device tree * -1, if an error occurred */ -uint32_t fdt_get_max_phandle(const void *fdt); +static inline uint32_t fdt_get_max_phandle(const void *fdt) +{ + uint32_t phandle; + int err; + + err = fdt_find_max_phandle(fdt, &phandle); + if (err < 0) + return (uint32_t)-1; + + return phandle; +} /** * fdt_generate_phandle - return a new, unused phandle for a device tree blob @@ -522,7 +595,7 @@ int fdt_next_property_offset(const void *fdt, int offset); * ... * } * - * if ((property < 0) && (property != -FDT_ERR_NOT_FOUND)) { + * if ((property < 0) && (property != -FDT_ERR_NOTFOUND)) { * Error handling * } * @@ -625,7 +698,7 @@ static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset, /** * fdt_getprop_by_offset - retrieve the value of a property at a given offset * @fdt: pointer to the device tree blob - * @ffset: offset of the property to read + * @offset: offset of the property to read * @namep: pointer to a string variable (will be overwritten) or NULL * @lenp: pointer to an integer variable (will be overwritten) or NULL * @@ -734,7 +807,7 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset); /** * fdt_get_alias_namelen - get alias based on substring * @fdt: pointer to the device tree blob - * @name: name of the alias to look up + * @name: name of the alias th look up * @namelen: number of characters of name to consider * * Identical to fdt_get_alias(), but only examine the first namelen @@ -1316,7 +1389,45 @@ int fdt_nop_node(void *fdt, int nodeoffset); /* Sequential write functions */ /**********************************************************************/ +/* fdt_create_with_flags flags */ +#define FDT_CREATE_FLAG_NO_NAME_DEDUP 0x1 + /* FDT_CREATE_FLAG_NO_NAME_DEDUP: Do not try to de-duplicate property + * names in the fdt. This can result in faster creation times, but + * a larger fdt. */ + +#define FDT_CREATE_FLAGS_ALL (FDT_CREATE_FLAG_NO_NAME_DEDUP) + +/** + * fdt_create_with_flags - begin creation of a new fdt + * @fdt: pointer to memory allocated where fdt will be created + * @bufsize: size of the memory space at fdt + * @flags: a valid combination of FDT_CREATE_FLAG_ flags, or 0. + * + * fdt_create_with_flags() begins the process of creating a new fdt with + * the sequential write interface. + * + * fdt creation process must end with fdt_finished() to produce a valid fdt. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt + * -FDT_ERR_BADFLAGS, flags is not valid + */ +int fdt_create_with_flags(void *buf, int bufsize, uint32_t flags); + +/** + * fdt_create - begin creation of a new fdt + * @fdt: pointer to memory allocated where fdt will be created + * @bufsize: size of the memory space at fdt + * + * fdt_create() is equivalent to fdt_create_with_flags() with flags=0. + * + * returns: + * 0, on success + * -FDT_ERR_NOSPACE, bufsize is insufficient for a minimal fdt + */ int fdt_create(void *buf, int bufsize); + int fdt_resize(void *fdt, void *buf, int bufsize); int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size); int fdt_finish_reservemap(void *fdt); @@ -1788,6 +1899,43 @@ static inline int fdt_appendprop_cell(void *fdt, int nodeoffset, fdt_appendprop((fdt), (nodeoffset), (name), (str), strlen(str)+1) /** + * fdt_appendprop_addrrange - append a address range property + * @fdt: pointer to the device tree blob + * @parent: offset of the parent node + * @nodeoffset: offset of the node to add a property at + * @name: name of property + * @addr: start address of a given range + * @size: size of a given range + * + * fdt_appendprop_addrrange() appends an address range value (start + * address and size) to the value of the named property in the given + * node, or creates a new property with that value if it does not + * already exist. + * If "name" is not specified, a default "reg" is used. + * Cell sizes are determined by parent's #address-cells and #size-cells. + * + * This function may insert data into the blob, and will therefore + * change the offsets of some existing nodes. + * + * returns: + * 0, on success + * -FDT_ERR_BADLAYOUT, + * -FDT_ERR_BADMAGIC, + * -FDT_ERR_BADNCELLS, if the node has a badly formatted or invalid + * #address-cells property + * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag + * -FDT_ERR_BADSTATE, + * -FDT_ERR_BADSTRUCTURE, + * -FDT_ERR_BADVERSION, + * -FDT_ERR_BADVALUE, addr or size doesn't fit to respective cells size + * -FDT_ERR_NOSPACE, there is insufficient free space in the blob to + * contain a new property + * -FDT_ERR_TRUNCATED, standard meanings + */ +int fdt_appendprop_addrrange(void *fdt, int parent, int nodeoffset, + const char *name, uint64_t addr, uint64_t size); + +/** * fdt_delprop - delete a property * @fdt: pointer to the device tree blob * @nodeoffset: offset of the node whose property to nop diff --git a/scripts/dtc/libfdt/libfdt_env.h b/scripts/dtc/libfdt/libfdt_env.h index 3ff9e28630..73b6d40450 100644 --- a/scripts/dtc/libfdt/libfdt_env.h +++ b/scripts/dtc/libfdt/libfdt_env.h @@ -1,55 +1,10 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ #ifndef LIBFDT_ENV_H #define LIBFDT_ENV_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. * Copyright 2012 Kim Phillips, Freescale Semiconductor. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <stdbool.h> @@ -57,6 +12,7 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <limits.h> #ifdef __CHECKER__ #define FDT_FORCE __attribute__((force)) diff --git a/scripts/dtc/libfdt/libfdt_internal.h b/scripts/dtc/libfdt/libfdt_internal.h index 7681e19229..5436e2ceea 100644 --- a/scripts/dtc/libfdt/libfdt_internal.h +++ b/scripts/dtc/libfdt/libfdt_internal.h @@ -1,65 +1,24 @@ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */ #ifndef LIBFDT_INTERNAL_H #define LIBFDT_INTERNAL_H /* * libfdt - Flat Device Tree manipulation * Copyright (C) 2006 David Gibson, IBM Corporation. - * - * libfdt is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * - * a) This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * Alternatively, - * - * b) Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * 1. Redistributions of source code must retain the above - * copyright notice, this list of conditions and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <fdt.h> #define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1)) #define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) -#define FDT_CHECK_HEADER(fdt) \ - { \ - int err_; \ - if ((err_ = fdt_check_header(fdt)) != 0) \ - return err_; \ +int fdt_ro_probe_(const void *fdt); +#define FDT_RO_PROBE(fdt) \ + { \ + int totalsize_; \ + if (fdt_chk_basic()) { \ + totalsize_ = fdt_ro_probe_(fdt); \ + if (totalsize_ < 0) \ + return totalsize_; \ + } \ } int fdt_check_node_offset_(const void *fdt, int offset); @@ -92,4 +51,87 @@ static inline struct fdt_reserve_entry *fdt_mem_rsv_w_(void *fdt, int n) #define FDT_SW_MAGIC (~FDT_MAGIC) +/**********************************************************************/ +/* Checking controls */ +/**********************************************************************/ + +#ifndef FDT_ASSUME_MASK +#define FDT_ASSUME_MASK 0 +#endif + +/* + * Defines assumptions which can be enabled. Each of these can be enabled + * individually. For maximum saftey, don't enable any assumptions! + * + * For minimal code size and no safety, use FDT_ASSUME_PERFECT at your own risk. + * You should have another method of validating the device tree, such as a + * signature or hash check before using libfdt. + * + * For situations where security is not a concern it may be safe to enable + * FDT_ASSUME_FRIENDLY. + */ +enum { + /* + * This does essentially no checks. Only the latest device-tree + * version is correctly handled. Incosistencies or errors in the device + * tree may cause undefined behaviour or crashes. + * + * If an error occurs when modifying the tree it may leave the tree in + * an intermediate (but valid) state. As an example, adding a property + * where there is insufficient space may result in the property name + * being added to the string table even though the property itself is + * not added to the struct section. + * + * Only use this if you have a fully validated device tree with + * the latest supported version and wish to minimise code size. + */ + FDT_ASSUME_PERFECT = 0xff, + + /* + * This assumes that the device tree is sane. i.e. header metadata + * and basic hierarchy are correct. + * + * These checks will be sufficient if you have a valid device tree with + * no internal inconsistencies. With this assumption, libfdt will + * generally not return -FDT_ERR_INTERNAL, -FDT_ERR_BADLAYOUT, etc. + */ + FDT_ASSUME_SANE = 1 << 0, + + /* + * This disables checks for device-tree version and removes all code + * which handles older versions. + * + * Only enable this if you know you have a device tree with the latest + * version. + */ + FDT_ASSUME_LATEST = 1 << 1, + + /* + * This disables any extensive checking of parameters and the device + * tree, making various assumptions about correctness. Normal device + * trees produced by libfdt and the compiler should be handled safely. + * Malicious device trees and complete garbage may cause libfdt to + * behave badly or crash. + */ + FDT_ASSUME_FRIENDLY = 1 << 2, +}; + +/** fdt_chk_basic() - see if basic checking of params and DT data is enabled */ +static inline bool fdt_chk_basic(void) +{ + return !(FDT_ASSUME_MASK & FDT_ASSUME_SANE); +} + +/** fdt_chk_version() - see if we need to handle old versions of the DT */ +static inline bool fdt_chk_version(void) +{ + return !(FDT_ASSUME_MASK & FDT_ASSUME_LATEST); +} + +/** fdt_chk_extra() - see if extra checking is enabled */ +static inline bool fdt_chk_extra(void) +{ + return !(FDT_ASSUME_MASK & FDT_ASSUME_FRIENDLY); +} + #endif /* LIBFDT_INTERNAL_H */ diff --git a/scripts/dtc/pylibfdt/Makefile b/scripts/dtc/pylibfdt/Makefile index 15e66ad44d..42342c75bb 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)/.." \ - $(PYTHON2) $< --quiet build_ext --inplace + $(PYTHON3) $< --quiet build_ext --inplace $(obj)/_libfdt.so: $(src)/setup.py $(PYLIBFDT_srcs) FORCE $(call if_changed,pymod) diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped index 76e61e98bd..fae0b27d7d 100644 --- a/scripts/dtc/pylibfdt/libfdt.i_shipped +++ b/scripts/dtc/pylibfdt/libfdt.i_shipped @@ -18,7 +18,7 @@ * a struct called fdt_property. That struct causes swig to create a class in * libfdt.py called fdt_property(), which confuses things. */ -static int fdt_property_stub(void *fdt, const char *name, const char *val, +static int fdt_property_stub(void *fdt, const char *name, const void *val, int len) { return fdt_property(fdt, name, val, len); @@ -92,7 +92,7 @@ def check_err(val, quiet=()): Raises FdtException if val < 0 """ - if val < 0: + if isinstance(val, int) and val < 0: if -val not in quiet: raise FdtException(val) return val @@ -417,7 +417,7 @@ class FdtRo(object): quiet) if isinstance(pdata, (int)): return pdata - return Property(prop_name, bytearray(pdata[0])) + return Property(prop_name, bytes(pdata[0])) def get_phandle(self, nodeoffset): """Get the phandle of a node @@ -431,6 +431,18 @@ class FdtRo(object): """ return fdt_get_phandle(self._fdt, nodeoffset) + def get_alias(self, name): + """Get the full path referenced by a given alias + + Args: + name: name of the alias to lookup + + Returns: + Full path to the node for the alias named 'name', if it exists + None, if the given alias or the /aliases node does not exist + """ + return fdt_get_alias(self._fdt, name) + def parent_offset(self, nodeoffset, quiet=()): """Get the offset of a node's parent @@ -624,7 +636,7 @@ class Fdt(FdtRo): Raises: FdtException if no parent found or other error occurs """ - val = val.encode('utf-8') + '\0' + val = val.encode('utf-8') + b'\0' return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, val, len(val)), quiet) @@ -727,8 +739,10 @@ class FdtSw(FdtRo): # First create the device tree with a node and property: sw = FdtSw() - with sw.add_node('node'): - sw.property_u32('reg', 2) + sw.finish_reservemap() + with sw.add_node(''): + with sw.add_node('node'): + sw.property_u32('reg', 2) fdt = sw.as_fdt() # Now we can use it as a real device tree @@ -1029,17 +1043,24 @@ typedef uint32_t fdt32_t; if (!$1) $result = Py_None; else - $result = Py_BuildValue("s#", $1, *arg4); + %#if PY_VERSION_HEX >= 0x03000000 + $result = Py_BuildValue("y#", $1, *arg4); + %#else + $result = Py_BuildValue("s#", $1, *arg4); + %#endif } /* typemap used for fdt_setprop() */ %typemap(in) (const void *val) { - $1 = PyString_AsString($input); /* char *str */ -} - -/* typemap used for fdt_add_reservemap_entry() */ -%typemap(in) uint64_t { - $1 = PyLong_AsUnsignedLong($input); + %#if PY_VERSION_HEX >= 0x03000000 + if (!PyBytes_Check($input)) { + SWIG_exception_fail(SWIG_TypeError, "bytes expected in method '" "$symname" + "', argument " "$argnum"" of type '" "$type""'"); + } + $1 = PyBytes_AsString($input); + %#else + $1 = PyString_AsString($input); /* char *str */ + %#endif } /* typemaps used for fdt_next_node() */ @@ -1061,7 +1082,7 @@ typedef uint32_t fdt32_t; } %typemap(argout) uint64_t * { - PyObject *val = PyLong_FromUnsignedLong(*arg$argnum); + PyObject *val = PyLong_FromUnsignedLongLong(*arg$argnum); if (!result) { if (PyTuple_GET_SIZE(resultobj) == 0) resultobj = val; @@ -1092,6 +1113,6 @@ int fdt_property_cell(void *fdt, const char *name, uint32_t val); * This function has a stub since the name fdt_property is used for both a * function and a struct, which confuses SWIG. */ -int fdt_property_stub(void *fdt, const char *name, const char *val, int len); +int fdt_property_stub(void *fdt, const char *name, const void *val, int len); %include <../libfdt/libfdt.h> diff --git a/scripts/dtc/pylibfdt/setup.py b/scripts/dtc/pylibfdt/setup.py index 4f7cf042bf..992cdec30f 100755 --- a/scripts/dtc/pylibfdt/setup.py +++ b/scripts/dtc/pylibfdt/setup.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 """ setup.py file for SWIG libfdt diff --git a/test/dm/regmap.c b/test/dm/regmap.c index 82de295cb8..6fd1f20656 100644 --- a/test/dm/regmap.c +++ b/test/dm/regmap.c @@ -99,18 +99,27 @@ static int dm_test_regmap_rw(struct unit_test_state *uts) struct regmap *map; uint reg; + sandbox_set_enable_memio(true); ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev)); map = syscon_get_regmap(dev); ut_assertok_ptr(map); ut_assertok(regmap_write(map, 0, 0xcacafafa)); - ut_assertok(regmap_write(map, 3, 0x55aa2211)); + ut_assertok(regmap_write(map, 5, 0x55aa2211)); ut_assertok(regmap_read(map, 0, ®)); - ut_assertok(regmap_read(map, 3, ®)); + ut_asserteq(0xcacafafa, reg); + ut_assertok(regmap_read(map, 5, ®)); + ut_asserteq(0x55aa2211, reg); + ut_assertok(regmap_read(map, 0, ®)); + ut_asserteq(0xcacafafa, reg); ut_assertok(regmap_update_bits(map, 0, 0xff00ff00, 0x55aa2211)); - ut_assertok(regmap_update_bits(map, 3, 0x00ff00ff, 0xcacafada)); + ut_assertok(regmap_read(map, 0, ®)); + ut_asserteq(0x55ca22fa, reg); + ut_assertok(regmap_update_bits(map, 5, 0x00ff00ff, 0xcacafada)); + ut_assertok(regmap_read(map, 5, ®)); + ut_asserteq(0x55ca22da, reg); return 0; } @@ -130,6 +139,7 @@ static int dm_test_regmap_getset(struct unit_test_state *uts) u32 val3; }; + sandbox_set_enable_memio(true); ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev)); map = syscon_get_regmap(dev); ut_assertok_ptr(map); @@ -138,7 +148,9 @@ static int dm_test_regmap_getset(struct unit_test_state *uts) regmap_set(map, struct layout, val3, 0x55aa2211); ut_assertok(regmap_get(map, struct layout, val0, ®)); + ut_asserteq(0xcacafafa, reg); ut_assertok(regmap_get(map, struct layout, val3, ®)); + ut_asserteq(0x55aa2211, reg); return 0; } @@ -159,6 +171,7 @@ static int dm_test_regmap_poll(struct unit_test_state *uts) start = get_timer(0); + ut_assertok(regmap_write(map, 0, 0x0)); ut_asserteq(-ETIMEDOUT, regmap_read_poll_timeout_test(map, 0, reg, (reg == 0xcacafafa), diff --git a/test/dm/sf.c b/test/dm/sf.c index 3788d59052..65aab4f2e9 100644 --- a/test/dm/sf.c +++ b/test/dm/sf.c @@ -23,6 +23,9 @@ static int dm_test_spi_flash(struct unit_test_state *uts) int full_size = 0x200000; int size = 0x10000; u8 *src, *dst; + uint map_size; + ulong map_base; + uint offset; int i; src = map_sysmem(0x20000, full_size); @@ -54,6 +57,12 @@ static int dm_test_spi_flash(struct unit_test_state *uts) sandbox_sf_set_block_protect(emul, 0); ut_asserteq(0, spl_flash_get_sw_write_prot(dev)); + /* Check mapping */ + ut_assertok(dm_spi_get_mmap(dev, &map_base, &map_size, &offset)); + ut_asserteq(0x1000, map_base); + ut_asserteq(0x2000, map_size); + ut_asserteq(0x100, offset); + /* * Since we are about to destroy all devices, we must tell sandbox * to forget the emulation device diff --git a/test/lib/Makefile b/test/lib/Makefile index 308c61708e..b13aaca7ce 100644 --- a/test/lib/Makefile +++ b/test/lib/Makefile @@ -6,3 +6,4 @@ obj-y += cmd_ut_lib.o obj-y += hexdump.o obj-y += lmb.o obj-y += string.o +obj-$(CONFIG_ERRNO_STR) += test_errno_str.o diff --git a/test/lib/test_errno_str.c b/test/lib/test_errno_str.c new file mode 100644 index 0000000000..8a9f1fd980 --- /dev/null +++ b/test/lib/test_errno_str.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2019 Heinrich Schuchardt <xypron.glpk@gmx.de> + * + * Unit tests for memory functions + * + * The architecture dependent implementations run through different lines of + * code depending on the alignment and length of memory regions copied or set. + * This has to be considered in testing. + */ + +#include <common.h> +#include <command.h> +#include <errno.h> +#include <test/lib.h> +#include <test/test.h> +#include <test/ut.h> + +/** + * lib_errno_str() - unit test for errno_str() + * + * Test errno_str() with varied alignment and length of the copied buffer. + * + * @uts: unit test state + * Return: 0 = success, 1 = failure + */ +static int lib_errno_str(struct unit_test_state *uts) +{ + const char *msg; + + msg = errno_str(1); + ut_asserteq_str("Success", msg); + + msg = errno_str(0); + ut_asserteq_str("Success", msg); + + msg = errno_str(-ENOMEM); + ut_asserteq_str("Out of memory", msg); + + msg = errno_str(-99999); + ut_asserteq_str("Unknown error", msg); + + return 0; +} + +LIB_TEST(lib_errno_str, 0); diff --git a/test/py/README.md b/test/py/README.md index 2156661d6c..3cbe01b73e 100644 --- a/test/py/README.md +++ b/test/py/README.md @@ -21,19 +21,26 @@ involves executing some binary and interacting with its stdin/stdout. You will need to implement various "hook" scripts that are called by the test suite at the appropriate time. -On Debian or Debian-like distributions, the following packages are required. -Some packages are required to execute any test, and others only for specific -tests. Similar package names should exist in other distributions. - -| Package | Version tested (Ubuntu 14.04) | -| -------------- | ----------------------------- | -| python | 2.7.5-5ubuntu3 | -| python-pytest | 2.5.1-1 | -| python-subunit | - | -| gdisk | 0.8.8-1ubuntu0.1 | -| dfu-util | 0.5-1 | -| dtc | 1.4.0+dfsg-1 | -| openssl | 1.0.1f-1ubuntu2.22 | +In order to run the testsuite at a minimum we require that both python3 and +pip for python3 be installed. All of the required python modules are +described in the requirements.txt file in this directory and can be installed +with the command ```pip install -r requirements.txt``` + +In order to execute certain tests on their supported platforms other tools +will be required. The following is an incomplete list: + +| Package | +| -------------- | +| gdisk | +| dfu-util | +| dtc | +| openssl | +| sudo OR guestmount | +| e2fsprogs | +| dosfstools | + +Please use the apporirate commands for your distribution to match these tools +up with the package that provides them. The test script supports either: @@ -45,18 +52,16 @@ The test script supports either: ### Using `virtualenv` to provide requirements -Older distributions (e.g. Ubuntu 10.04) may not provide all the required -packages, or may provide versions that are too old to run the test suite. One -can use the Python `virtualenv` script to locally install more up-to-date -versions of the required packages without interfering with the OS installation. -For example: +The recommended way to run the test suite, in order to ensure reproducibility +is to use `virtualenv` to set up the necessary environment. This can be done +via the following commands: ```bash $ cd /path/to/u-boot -$ sudo apt-get install python python-virtualenv -$ virtualenv venv +$ sudo apt-get install python3 python3-virtualenv +$ virtualenv -p /usr/bin/python3 venv $ . ./venv/bin/activate -$ pip install pytest +$ pip install -r test/py/requirements.txt ``` ## Testing sandbox diff --git a/test/py/conftest.py b/test/py/conftest.py index 00d8ef8ba9..bffee6b8a3 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -13,20 +13,16 @@ # - Implementing custom pytest markers. import atexit +import configparser import errno +import io import os import os.path import pytest -from _pytest.runner import runtestprotocol import re -import StringIO +from _pytest.runner import runtestprotocol import sys -try: - import configparser -except: - import ConfigParser as configparser - # Globals: The HTML log file, and the connection to the U-Boot console. log = None console = None @@ -169,9 +165,9 @@ def pytest_configure(config): with open(dot_config, 'rt') as f: ini_str = '[root]\n' + f.read() - ini_sio = StringIO.StringIO(ini_str) + ini_sio = io.StringIO(ini_str) parser = configparser.RawConfigParser() - parser.readfp(ini_sio) + parser.read_file(ini_sio) ubconfig.buildconfig.update(parser.items('root')) ubconfig.test_py_dir = test_py_dir @@ -431,11 +427,9 @@ def setup_boardspec(item): Nothing. """ - mark = item.get_marker('boardspec') - if not mark: - return required_boards = [] - for board in mark.args: + for boards in item.iter_markers('boardspec'): + board = boards.args[0] if board.startswith('!'): if ubconfig.board_type == board[1:]: pytest.skip('board "%s" not supported' % ubconfig.board_type) @@ -459,16 +453,14 @@ def setup_buildconfigspec(item): Nothing. """ - mark = item.get_marker('buildconfigspec') - if mark: - for option in mark.args: - if not ubconfig.buildconfig.get('config_' + option.lower(), None): - pytest.skip('.config feature "%s" not enabled' % option.lower()) - notmark = item.get_marker('notbuildconfigspec') - if notmark: - for option in notmark.args: - if ubconfig.buildconfig.get('config_' + option.lower(), None): - pytest.skip('.config feature "%s" enabled' % option.lower()) + for options in item.iter_markers('buildconfigspec'): + option = options.args[0] + if not ubconfig.buildconfig.get('config_' + option.lower(), None): + pytest.skip('.config feature "%s" not enabled' % option.lower()) + for option in item.iter_markers('notbuildconfigspec'): + option = options.args[0] + if ubconfig.buildconfig.get('config_' + option.lower(), None): + pytest.skip('.config feature "%s" enabled' % option.lower()) def tool_is_in_path(tool): for path in os.environ["PATH"].split(os.pathsep): @@ -491,10 +483,8 @@ def setup_requiredtool(item): Nothing. """ - mark = item.get_marker('requiredtool') - if not mark: - return - for tool in mark.args: + for tools in item.iter_markers('requiredtool'): + tool = tools.args[0] if not tool_is_in_path(tool): pytest.skip('tool "%s" not in $PATH' % tool) diff --git a/test/py/multiplexed_log.py b/test/py/multiplexed_log.py index 637a3bd257..545a774302 100644 --- a/test/py/multiplexed_log.py +++ b/test/py/multiplexed_log.py @@ -5,8 +5,8 @@ # Generate an HTML-formatted log file containing multiple streams of data, # each represented in a well-delineated/-structured fashion. -import cgi import datetime +import html import os.path import shutil import subprocess @@ -51,7 +51,7 @@ class LogfileStream(object): """Write data to the log stream. Args: - data: The data to write tot he file. + data: The data to write to the file. implicit: Boolean indicating whether data actually appeared in the stream, or was implicitly generated. A valid use-case is to repeat a shell prompt at the start of each separate log @@ -64,7 +64,8 @@ class LogfileStream(object): self.logfile.write(self, data, implicit) if self.chained_file: - self.chained_file.write(data) + # Chained file is console, convert things a little + self.chained_file.write((data.encode('ascii', 'replace')).decode()) def flush(self): """Flush the log stream, to ensure correct log interleaving. @@ -136,6 +137,10 @@ class RunAndLog(object): p = subprocess.Popen(cmd, cwd=cwd, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) (stdout, stderr) = p.communicate() + if stdout is not None: + stdout = stdout.decode('utf-8') + if stderr is not None: + stderr = stderr.decode('utf-8') output = '' if stdout: if stderr: @@ -215,7 +220,7 @@ class Logfile(object): Nothing. """ - self.f = open(fn, 'wt') + self.f = open(fn, 'wt', encoding='utf-8') self.last_stream = None self.blocks = [] self.cur_evt = 1 @@ -334,7 +339,7 @@ $(document).ready(function () { data = data.replace(chr(13), '') data = ''.join((ord(c) in self._nonprint) and ('%%%02x' % ord(c)) or c for c in data) - data = cgi.escape(data) + data = html.escape(data) return data def _terminate_stream(self): diff --git a/test/py/pytest.ini b/test/py/pytest.ini index 7e400682bf..e93d010f1f 100644 --- a/test/py/pytest.ini +++ b/test/py/pytest.ini @@ -8,3 +8,6 @@ markers = boardspec: U-Boot: Describes the set of boards a test can/can't run on. buildconfigspec: U-Boot: Describes Kconfig/config-header constraints. + notbuildconfigspec: U-Boot: Describes required disabled Kconfig options. + requiredtool: U-Boot: Required host tools for a test. + slow: U-Boot: Specific test will run slowly. diff --git a/test/py/requirements.txt b/test/py/requirements.txt new file mode 100644 index 0000000000..cf251186f4 --- /dev/null +++ b/test/py/requirements.txt @@ -0,0 +1,22 @@ +atomicwrites==1.3.0 +attrs==19.3.0 +coverage==4.5.4 +extras==1.0.0 +fixtures==3.0.0 +importlib-metadata==0.23 +linecache2==1.0.0 +more-itertools==7.2.0 +packaging==19.2 +pbr==5.4.3 +pluggy==0.13.0 +py==1.8.0 +pyparsing==2.4.2 +pytest==5.2.1 +python-mimeparse==1.6.0 +python-subunit==1.3.0 +six==1.12.0 +testtools==2.3.0 +traceback2==1.4.0 +unittest2==1.1.0 +wcwidth==0.1.7 +zipp==0.6.0 diff --git a/test/py/test.py b/test/py/test.py index a5140945d4..bee88d96bc 100755 --- a/test/py/test.py +++ b/test/py/test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0 # Copyright (c) 2015 Stephen Warren @@ -7,28 +7,14 @@ # Wrapper script to invoke pytest with the directory name that contains the # U-Boot tests. -from __future__ import print_function - import os import os.path import sys - -# Get rid of argv[0] -sys.argv.pop(0) +from pkg_resources import load_entry_point # argv; py.test test_directory_name user-supplied-arguments -args = ['py.test', os.path.dirname(__file__) + '/tests'] +args = [os.path.dirname(__file__) + '/tests'] args.extend(sys.argv) -try: - os.execvp('py.test', args) -except: - # Log full details of any exception for detailed analysis - import traceback - traceback.print_exc() - # Hint to the user that they likely simply haven't installed the required - # dependencies. - print(''' -exec(py.test) failed; perhaps you are missing some dependencies? -See test/py/README.md for the list.''', file=sys.stderr) - sys.exit(1) +if __name__ == '__main__': + sys.exit(load_entry_point('pytest', 'console_scripts', 'pytest')(args)) diff --git a/test/py/tests/test_android/test_avb.py b/test/py/tests/test_android/test_avb.py index 8132423435..20ccaf6712 100644 --- a/test/py/tests/test_android/test_avb.py +++ b/test/py/tests/test_android/test_avb.py @@ -23,7 +23,8 @@ mmc_dev = 1 temp_addr = 0x90000000 temp_addr2 = 0x90002000 -@pytest.mark.buildconfigspec('cmd_avb', 'cmd_mmc') +@pytest.mark.buildconfigspec('cmd_avb') +@pytest.mark.buildconfigspec('cmd_mmc') def test_avb_verify(u_boot_console): """Run AVB 2.0 boot verification chain with avb subset of commands """ @@ -36,7 +37,8 @@ def test_avb_verify(u_boot_console): assert response.find(success_str) -@pytest.mark.buildconfigspec('cmd_avb', 'cmd_mmc') +@pytest.mark.buildconfigspec('cmd_avb') +@pytest.mark.buildconfigspec('cmd_mmc') def test_avb_mmc_uuid(u_boot_console): """Check if 'avb get_uuid' works, compare results with 'part list mmc 1' output @@ -93,7 +95,8 @@ def test_avb_is_unlocked(u_boot_console): assert response == 'Unlocked = 1' -@pytest.mark.buildconfigspec('cmd_avb', 'cmd_mmc') +@pytest.mark.buildconfigspec('cmd_avb') +@pytest.mark.buildconfigspec('cmd_mmc') def test_avb_mmc_read(u_boot_console): """Test mmc read operation """ diff --git a/test/py/tests/test_bind.py b/test/py/tests/test_bind.py index 2d48484c6a..20c6050342 100644 --- a/test/py/tests/test_bind.py +++ b/test/py/tests/test_bind.py @@ -9,11 +9,11 @@ def in_tree(response, name, uclass, drv, depth, last_child): lines = [x.strip() for x in response.splitlines()] leaf = ' ' * 4 * depth; if not last_child: - leaf = leaf + '\|' + leaf = leaf + r'\|' else: leaf = leaf + '`' leaf = leaf + '-- ' + name - line = (' *{:10.10} [0-9]* \[ [ +] \] {:20.20} {}$' + line = (r' *{:10.10} [0-9]* \[ [ +] \] {:20.20} {}$' .format(uclass, drv, leaf)) prog = re.compile(line) for l in lines: diff --git a/test/py/tests/test_efi_selftest.py b/test/py/tests/test_efi_selftest.py index d5430f9c12..ca01542088 100644 --- a/test/py/tests/test_efi_selftest.py +++ b/test/py/tests/test_efi_selftest.py @@ -59,7 +59,7 @@ def test_efi_selftest_text_input(u_boot_console): u_boot_console.run_command(cmd='setenv efi_selftest text input') output = u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False) - m = u_boot_console.p.expect(['To terminate type \'x\'']) + m = u_boot_console.p.expect([r'To terminate type \'x\'']) if m != 0: raise Exception('No prompt for \'text input\' test') u_boot_console.drain_console() @@ -68,7 +68,7 @@ def test_efi_selftest_text_input(u_boot_console): u_boot_console.run_command(cmd=chr(4), wait_for_echo=False, send_nl=False, wait_for_prompt=False) m = u_boot_console.p.expect( - ['Unicode char 4 \(unknown\), scan code 0 \(Null\)']) + [r'Unicode char 4 \(unknown\), scan code 0 \(Null\)']) if m != 0: raise Exception('EOT failed in \'text input\' test') u_boot_console.drain_console() @@ -76,7 +76,7 @@ def test_efi_selftest_text_input(u_boot_console): u_boot_console.run_command(cmd=chr(8), wait_for_echo=False, send_nl=False, wait_for_prompt=False) m = u_boot_console.p.expect( - ['Unicode char 8 \(BS\), scan code 0 \(Null\)']) + [r'Unicode char 8 \(BS\), scan code 0 \(Null\)']) if m != 0: raise Exception('BS failed in \'text input\' test') u_boot_console.drain_console() @@ -84,7 +84,7 @@ def test_efi_selftest_text_input(u_boot_console): u_boot_console.run_command(cmd=chr(9), wait_for_echo=False, send_nl=False, wait_for_prompt=False) m = u_boot_console.p.expect( - ['Unicode char 9 \(TAB\), scan code 0 \(Null\)']) + [r'Unicode char 9 \(TAB\), scan code 0 \(Null\)']) if m != 0: raise Exception('BS failed in \'text input\' test') u_boot_console.drain_console() @@ -92,7 +92,7 @@ def test_efi_selftest_text_input(u_boot_console): u_boot_console.run_command(cmd='a', wait_for_echo=False, send_nl=False, wait_for_prompt=False) m = u_boot_console.p.expect( - ['Unicode char 97 \(\'a\'\), scan code 0 \(Null\)']) + [r'Unicode char 97 \(\'a\'\), scan code 0 \(Null\)']) if m != 0: raise Exception('\'a\' failed in \'text input\' test') u_boot_console.drain_console() @@ -100,14 +100,14 @@ def test_efi_selftest_text_input(u_boot_console): u_boot_console.run_command(cmd=chr(27) + '[A', wait_for_echo=False, send_nl=False, wait_for_prompt=False) m = u_boot_console.p.expect( - ['Unicode char 0 \(Null\), scan code 1 \(Up\)']) + [r'Unicode char 0 \(Null\), scan code 1 \(Up\)']) if m != 0: raise Exception('UP failed in \'text input\' test') u_boot_console.drain_console() # Euro sign - u_boot_console.run_command(cmd='\xe2\x82\xac', wait_for_echo=False, + u_boot_console.run_command(cmd=b'\xe2\x82\xac'.decode(), wait_for_echo=False, send_nl=False, wait_for_prompt=False) - m = u_boot_console.p.expect(['Unicode char 8364 \(\'']) + m = u_boot_console.p.expect([r'Unicode char 8364 \(\'']) if m != 0: raise Exception('Euro sign failed in \'text input\' test') u_boot_console.drain_console() @@ -129,7 +129,7 @@ def test_efi_selftest_text_input_ex(u_boot_console): u_boot_console.run_command(cmd='setenv efi_selftest extended text input') output = u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False) - m = u_boot_console.p.expect(['To terminate type \'CTRL\+x\'']) + m = u_boot_console.p.expect([r'To terminate type \'CTRL\+x\'']) if m != 0: raise Exception('No prompt for \'text input\' test') u_boot_console.drain_console() @@ -138,7 +138,7 @@ def test_efi_selftest_text_input_ex(u_boot_console): u_boot_console.run_command(cmd=chr(4), wait_for_echo=False, send_nl=False, wait_for_prompt=False) m = u_boot_console.p.expect( - ['Unicode char 100 \\(\'d\'\\), scan code 0 \\(CTRL\\+Null\\)']) + [r'Unicode char 100 \(\'d\'\), scan code 0 \(CTRL\+Null\)']) if m != 0: raise Exception('EOT failed in \'text input\' test') u_boot_console.drain_console() @@ -146,7 +146,7 @@ def test_efi_selftest_text_input_ex(u_boot_console): u_boot_console.run_command(cmd=chr(8), wait_for_echo=False, send_nl=False, wait_for_prompt=False) m = u_boot_console.p.expect( - ['Unicode char 8 \(BS\), scan code 0 \(\+Null\)']) + [r'Unicode char 8 \(BS\), scan code 0 \(\+Null\)']) if m != 0: raise Exception('BS failed in \'text input\' test') u_boot_console.drain_console() @@ -154,7 +154,7 @@ def test_efi_selftest_text_input_ex(u_boot_console): u_boot_console.run_command(cmd=chr(9), wait_for_echo=False, send_nl=False, wait_for_prompt=False) m = u_boot_console.p.expect( - ['Unicode char 9 \(TAB\), scan code 0 \(\+Null\)']) + [r'Unicode char 9 \(TAB\), scan code 0 \(\+Null\)']) if m != 0: raise Exception('TAB failed in \'text input\' test') u_boot_console.drain_console() @@ -162,7 +162,7 @@ def test_efi_selftest_text_input_ex(u_boot_console): u_boot_console.run_command(cmd='a', wait_for_echo=False, send_nl=False, wait_for_prompt=False) m = u_boot_console.p.expect( - ['Unicode char 97 \(\'a\'\), scan code 0 \(Null\)']) + [r'Unicode char 97 \(\'a\'\), scan code 0 \(Null\)']) if m != 0: raise Exception('\'a\' failed in \'text input\' test') u_boot_console.drain_console() @@ -170,23 +170,23 @@ def test_efi_selftest_text_input_ex(u_boot_console): u_boot_console.run_command(cmd=chr(27) + '[A', wait_for_echo=False, send_nl=False, wait_for_prompt=False) m = u_boot_console.p.expect( - ['Unicode char 0 \(Null\), scan code 1 \(\+Up\)']) + [r'Unicode char 0 \(Null\), scan code 1 \(\+Up\)']) if m != 0: raise Exception('UP failed in \'text input\' test') u_boot_console.drain_console() # Euro sign - u_boot_console.run_command(cmd='\xe2\x82\xac', wait_for_echo=False, + u_boot_console.run_command(cmd=b'\xe2\x82\xac'.decode(), wait_for_echo=False, send_nl=False, wait_for_prompt=False) - m = u_boot_console.p.expect(['Unicode char 8364 \(\'']) + m = u_boot_console.p.expect([r'Unicode char 8364 \(\'']) if m != 0: raise Exception('Euro sign failed in \'text input\' test') u_boot_console.drain_console() # SHIFT+ALT+FN 5 - u_boot_console.run_command(cmd='\x1b\x5b\x31\x35\x3b\x34\x7e', + u_boot_console.run_command(cmd=b'\x1b\x5b\x31\x35\x3b\x34\x7e'.decode(), wait_for_echo=False, send_nl=False, wait_for_prompt=False) m = u_boot_console.p.expect( - ['Unicode char 0 \(Null\), scan code 15 \(SHIFT\+ALT\+FN 5\)']) + [r'Unicode char 0 \(Null\), scan code 15 \(SHIFT\+ALT\+FN 5\)']) if m != 0: raise Exception('SHIFT+ALT+FN 5 failed in \'text input\' test') u_boot_console.drain_console() diff --git a/test/py/tests/test_fit.py b/test/py/tests/test_fit.py index e3210ed43f..356d9a20f2 100755 --- a/test/py/tests/test_fit.py +++ b/test/py/tests/test_fit.py @@ -3,8 +3,6 @@ # # Sanity check of the FIT handling in U-Boot -from __future__ import print_function - import os import pytest import struct @@ -155,7 +153,7 @@ def test_fit(u_boot_console): src = make_fname('u-boot.dts') dtb = make_fname('u-boot.dtb') with open(src, 'w') as fd: - print(base_fdt, file=fd) + fd.write(base_fdt) util.run_and_log(cons, ['dtc', src, '-O', 'dtb', '-o', dtb]) return dtb @@ -188,7 +186,7 @@ def test_fit(u_boot_console): its = make_its(params) util.run_and_log(cons, [mkimage, '-f', its, fit]) with open(make_fname('u-boot.dts'), 'w') as fd: - print(base_fdt, file=fd) + fd.write(base_fdt) return fit def make_kernel(filename, text): diff --git a/test/py/tests/test_fpga.py b/test/py/tests/test_fpga.py index e3bb7b41c7..ca7ef8ea40 100644 --- a/test/py/tests/test_fpga.py +++ b/test/py/tests/test_fpga.py @@ -175,29 +175,29 @@ def test_fpga_load_fail(u_boot_console): f, dev, addr, bit, bit_size = load_file_from_var(u_boot_console, 'bitstream_load') for cmd in ['dump', 'load', 'loadb']: - # missing dev parameter - expected = 'fpga: incorrect parameters passed' - output = u_boot_console.run_command('fpga %s %x $filesize' % (cmd, addr)) - #assert expected in output - assert expected_usage in output - - # more parameters - 0 at the end - expected = 'fpga: more parameters passed' - output = u_boot_console.run_command('fpga %s %x %x $filesize 0' % (cmd, dev, addr)) - #assert expected in output - assert expected_usage in output - - # 0 address - expected = 'fpga: zero fpga_data address' - output = u_boot_console.run_command('fpga %s %x 0 $filesize' % (cmd, dev)) - #assert expected in output - assert expected_usage in output - - # 0 filesize - expected = 'fpga: zero size' - output = u_boot_console.run_command('fpga %s %x %x 0' % (cmd, dev, addr)) - #assert expected in output - assert expected_usage in output + # missing dev parameter + expected = 'fpga: incorrect parameters passed' + output = u_boot_console.run_command('fpga %s %x $filesize' % (cmd, addr)) + #assert expected in output + assert expected_usage in output + + # more parameters - 0 at the end + expected = 'fpga: more parameters passed' + output = u_boot_console.run_command('fpga %s %x %x $filesize 0' % (cmd, dev, addr)) + #assert expected in output + assert expected_usage in output + + # 0 address + expected = 'fpga: zero fpga_data address' + output = u_boot_console.run_command('fpga %s %x 0 $filesize' % (cmd, dev)) + #assert expected in output + assert expected_usage in output + + # 0 filesize + expected = 'fpga: zero size' + output = u_boot_console.run_command('fpga %s %x %x 0' % (cmd, dev, addr)) + #assert expected in output + assert expected_usage in output @pytest.mark.buildconfigspec('cmd_fpga') @pytest.mark.buildconfigspec('cmd_echo') diff --git a/test/py/tests/test_fs/conftest.py b/test/py/tests/test_fs/conftest.py index 9324657d21..1949f91619 100644 --- a/test/py/tests/test_fs/conftest.py +++ b/test/py/tests/test_fs/conftest.py @@ -300,38 +300,38 @@ def fs_obj_basic(request, u_boot_config): # Generate the md5sums of reads that we will test against small file out = check_output( 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum' - % small_file, shell=True) + % small_file, shell=True).decode() md5val = [ out.split()[0] ] # Generate the md5sums of reads that we will test against big file # One from beginning of file. out = check_output( 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum' - % big_file, shell=True) + % big_file, shell=True).decode() md5val.append(out.split()[0]) # One from end of file. out = check_output( 'dd if=%s bs=1M skip=2499 count=1 2> /dev/null | md5sum' - % big_file, shell=True) + % big_file, shell=True).decode() md5val.append(out.split()[0]) # One from the last 1MB chunk of 2GB out = check_output( 'dd if=%s bs=1M skip=2047 count=1 2> /dev/null | md5sum' - % big_file, shell=True) + % big_file, shell=True).decode() md5val.append(out.split()[0]) # One from the start 1MB chunk from 2GB out = check_output( 'dd if=%s bs=1M skip=2048 count=1 2> /dev/null | md5sum' - % big_file, shell=True) + % big_file, shell=True).decode() md5val.append(out.split()[0]) # One 1MB chunk crossing the 2GB boundary out = check_output( 'dd if=%s bs=512K skip=4095 count=2 2> /dev/null | md5sum' - % big_file, shell=True) + % big_file, shell=True).decode() md5val.append(out.split()[0]) umount_fs(mount_dir) @@ -390,7 +390,7 @@ def fs_obj_ext(request, u_boot_config): % min_file, shell=True) out = check_output( 'dd if=%s bs=1K 2> /dev/null | md5sum' - % min_file, shell=True) + % min_file, shell=True).decode() md5val = [ out.split()[0] ] # Calculate md5sum of Test Case 4 @@ -399,7 +399,7 @@ def fs_obj_ext(request, u_boot_config): check_call('dd if=%s of=%s bs=1K seek=5 count=20' % (min_file, tmp_file), shell=True) out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum' - % tmp_file, shell=True) + % tmp_file, shell=True).decode() md5val.append(out.split()[0]) # Calculate md5sum of Test Case 5 @@ -408,7 +408,7 @@ def fs_obj_ext(request, u_boot_config): check_call('dd if=%s of=%s bs=1K seek=5 count=5' % (min_file, tmp_file), shell=True) out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum' - % tmp_file, shell=True) + % tmp_file, shell=True).decode() md5val.append(out.split()[0]) # Calculate md5sum of Test Case 7 @@ -417,7 +417,7 @@ def fs_obj_ext(request, u_boot_config): check_call('dd if=%s of=%s bs=1K seek=20 count=20' % (min_file, tmp_file), shell=True) out = check_output('dd if=%s bs=1K 2> /dev/null | md5sum' - % tmp_file, shell=True) + % tmp_file, shell=True).decode() md5val.append(out.split()[0]) check_call('rm %s' % tmp_file, shell=True) @@ -508,8 +508,8 @@ def fs_obj_unlink(request, u_boot_config): # Test Case 2 check_call('mkdir %s/dir2' % mount_dir, shell=True) - for i in range(0, 20): - check_call('mkdir %s/dir2/0123456789abcdef%02x' + for i in range(0, 20): + check_call('mkdir %s/dir2/0123456789abcdef%02x' % (mount_dir, i), shell=True) # Test Case 4 @@ -582,11 +582,11 @@ def fs_obj_symlink(request, u_boot_config): # Generate the md5sums of reads that we will test against small file out = check_output( 'dd if=%s bs=1M skip=0 count=1 2> /dev/null | md5sum' - % small_file, shell=True) + % small_file, shell=True).decode() md5val = [out.split()[0]] out = check_output( 'dd if=%s bs=10M skip=0 count=1 2> /dev/null | md5sum' - % medium_file, shell=True) + % medium_file, shell=True).decode() md5val.extend([out.split()[0]]) umount_fs(mount_dir) diff --git a/test/py/tests/test_log.py b/test/py/tests/test_log.py index cb183444c6..75325fad61 100644 --- a/test/py/tests/test_log.py +++ b/test/py/tests/test_log.py @@ -27,9 +27,9 @@ def test_log(u_boot_console): """ for i in range(max_level): if mask & 1: - assert 'log_run() log %d' % i == lines.next() + assert 'log_run() log %d' % i == next(lines) if mask & 3: - assert 'func() _log %d' % i == lines.next() + assert 'func() _log %d' % i == next(lines) def run_test(testnum): """Run a particular test number (the 'log test' command) @@ -43,7 +43,7 @@ def test_log(u_boot_console): output = u_boot_console.run_command('log test %d' % testnum) split = output.replace('\r', '').splitlines() lines = iter(split) - assert 'test %d' % testnum == lines.next() + assert 'test %d' % testnum == next(lines) return lines def test0(): @@ -88,7 +88,7 @@ def test_log(u_boot_console): def test10(): lines = run_test(10) for i in range(7): - assert 'log_test() level %d' % i == lines.next() + assert 'log_test() level %d' % i == next(lines) # TODO(sjg@chromium.org): Consider structuring this as separate tests cons = u_boot_console diff --git a/test/py/tests/test_mmc_wr.py b/test/py/tests/test_mmc_wr.py index 8b18781eac..05e5c1ee85 100644 --- a/test/py/tests/test_mmc_wr.py +++ b/test/py/tests/test_mmc_wr.py @@ -35,7 +35,9 @@ env__mmc_wr_configs = ( """ -@pytest.mark.buildconfigspec('cmd_mmc','cmd_memory', 'cmd_random') +@pytest.mark.buildconfigspec('cmd_mmc') +@pytest.mark.buildconfigspec('cmd_memory') +@pytest.mark.buildconfigspec('cmd_random') def test_mmc_wr(u_boot_console, env__mmc_wr_config): """Test the "mmc write" command. @@ -65,41 +67,39 @@ def test_mmc_wr(u_boot_console, env__mmc_wr_config): for i in range(test_iterations): - # Generate random data - cmd = 'random %s %x' % (src_addr, count_bytes) - response = u_boot_console.run_command(cmd) - good_response = '%d bytes filled with random data' % (count_bytes) - assert good_response in response - - # Select MMC device - cmd = 'mmc dev %d' % devid - if is_emmc: - cmd += ' %d' % partid - response = u_boot_console.run_command(cmd) - assert 'no card present' not in response - if is_emmc: - partid_response = "(part %d)" % partid - else: - partid_response = "" - good_response = 'mmc%d%s is current device' % (devid, partid_response) - assert good_response in response - - # Write data - cmd = 'mmc write %s %x %x' % (src_addr, sector, count_sectors) - response = u_boot_console.run_command(cmd) - good_response = 'MMC write: dev # %d, block # %d, count %d ... %d blocks written: OK' % ( - devid, sector, count_sectors, count_sectors) - assert good_response in response - - # Read data - cmd = 'mmc read %s %x %x' % (dst_addr, sector, count_sectors) - response = u_boot_console.run_command(cmd) - good_response = 'MMC read: dev # %d, block # %d, count %d ... %d blocks read: OK' % ( - devid, sector, count_sectors, count_sectors) - assert good_response in response - - # Compare src and dst data - cmd = 'cmp.b %s %s %x' % (src_addr, dst_addr, count_bytes) - response = u_boot_console.run_command(cmd) - good_response = 'Total of %d byte(s) were the same' % (count_bytes) - assert good_response in response + # Generate random data + cmd = 'random %s %x' % (src_addr, count_bytes) + response = u_boot_console.run_command(cmd) + good_response = '%d bytes filled with random data' % (count_bytes) + assert good_response in response + + # Select MMC device + cmd = 'mmc dev %d' % devid + if is_emmc: + cmd += ' %d' % partid + response = u_boot_console.run_command(cmd) + assert 'no card present' not in response + if is_emmc: + partid_response = "(part %d)" % partid + else: + partid_response = "" + good_response = 'mmc%d%s is current device' % (devid, partid_response) + assert good_response in response + + # Write data + cmd = 'mmc write %s %x %x' % (src_addr, sector, count_sectors) + response = u_boot_console.run_command(cmd) + good_response = 'MMC write: dev # %d, block # %d, count %d ... %d blocks written: OK' % (devid, sector, count_sectors, count_sectors) + assert good_response in response + + # Read data + cmd = 'mmc read %s %x %x' % (dst_addr, sector, count_sectors) + response = u_boot_console.run_command(cmd) + good_response = 'MMC read: dev # %d, block # %d, count %d ... %d blocks read: OK' % (devid, sector, count_sectors, count_sectors) + assert good_response in response + + # Compare src and dst data + cmd = 'cmp.b %s %s %x' % (src_addr, dst_addr, count_bytes) + response = u_boot_console.run_command(cmd) + good_response = 'Total of %d byte(s) were the same' % (count_bytes) + assert good_response in response diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index 62037d2c45..6c7b8dd2b3 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -10,14 +10,14 @@ def test_ut_dm_init(u_boot_console): fn = u_boot_console.config.source_dir + '/testflash.bin' if not os.path.exists(fn): - data = 'this is a test' - data += '\x00' * ((4 * 1024 * 1024) - len(data)) + data = b'this is a test' + data += b'\x00' * ((4 * 1024 * 1024) - len(data)) with open(fn, 'wb') as fh: fh.write(data) fn = u_boot_console.config.source_dir + '/spi.bin' if not os.path.exists(fn): - data = '\x00' * (2 * 1024 * 1024) + data = b'\x00' * (2 * 1024 * 1024) with open(fn, 'wb') as fh: fh.write(data) diff --git a/test/py/u_boot_spawn.py b/test/py/u_boot_spawn.py index b011a3e3da..6991b78cca 100644 --- a/test/py/u_boot_spawn.py +++ b/test/py/u_boot_spawn.py @@ -42,10 +42,7 @@ class Spawn(object): self.after = '' self.timeout = None # http://stackoverflow.com/questions/7857352/python-regex-to-match-vt100-escape-sequences - # Note that re.I doesn't seem to work with this regex (or perhaps the - # version of Python in Ubuntu 14.04), hence the inclusion of a-z inside - # [] instead. - self.re_vt100 = re.compile('(\x1b\[|\x9b)[^@-_a-z]*[@-_a-z]|\x1b[@-_a-z]') + self.re_vt100 = re.compile(r'(\x1b\[|\x9b)[^@-_]*[@-_]|\x1b[@-_]', re.I) (self.pid, self.fd) = pty.fork() if self.pid == 0: @@ -113,7 +110,7 @@ class Spawn(object): Nothing. """ - os.write(self.fd, data) + os.write(self.fd, data.encode(errors='replace')) def expect(self, patterns): """Wait for the sub-process to emit specific data. @@ -171,7 +168,7 @@ class Spawn(object): events = self.poll.poll(poll_maxwait) if not events: raise Timeout() - c = os.read(self.fd, 1024) + c = os.read(self.fd, 1024).decode(errors='replace') if not c: raise EOFError() if self.logfile_read: diff --git a/tools/binman/README.entries b/tools/binman/README.entries index bce2244596..1099433521 100644 --- a/tools/binman/README.entries +++ b/tools/binman/README.entries @@ -444,6 +444,39 @@ See README.x86 for information about x86 binary blobs. +Entry: intel-fsp-s: Entry containing Intel Firmware Support Package (FSP) silicon init +-------------------------------------------------------------------------------------- + +Properties / Entry arguments: + - filename: Filename of file to read into entry + +This file contains a binary blob which is used on some devices to set up +the silicon. U-Boot executes this code in U-Boot proper after SDRAM is +running, so that it can make full use of memory. Documentation is typically +not available in sufficient detail to allow U-Boot do this this itself. + +An example filename is 'fsp_s.bin' + +See README.x86 for information about x86 binary blobs. + + + +Entry: intel-fsp-t: Entry containing Intel Firmware Support Package (FSP) temp ram init +--------------------------------------------------------------------------------------- + +Properties / Entry arguments: + - filename: Filename of file to read into entry + +This file contains a binary blob which is used on some devices to set up +temporary memory (Cache-as-RAM or CAR). U-Boot executes this code in TPL so +that it has access to memory for its stack and initial storage. + +An example filename is 'fsp_t.bin' + +See README.x86 for information about x86 binary blobs. + + + Entry: intel-ifwi: Entry containing an Intel Integrated Firmware Image (IFWI) file ---------------------------------------------------------------------------------- diff --git a/tools/binman/binman.py b/tools/binman/binman.py index 8bd5868df2..9e6fd72117 100755 --- a/tools/binman/binman.py +++ b/tools/binman/binman.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0+ # Copyright (c) 2016 Google, Inc diff --git a/tools/binman/cbfs_util_test.py b/tools/binman/cbfs_util_test.py index 772c794ece..ddc2e09e35 100755 --- a/tools/binman/cbfs_util_test.py +++ b/tools/binman/cbfs_util_test.py @@ -56,7 +56,7 @@ class TestCbfs(unittest.TestCase): cls.have_lz4 = True try: tools.Run('lz4', '--no-frame-crc', '-c', - tools.GetInputFilename('u-boot.bin')) + tools.GetInputFilename('u-boot.bin'), binary=True) except: cls.have_lz4 = False diff --git a/tools/binman/elf.py b/tools/binman/elf.py index 7bc7cf61b5..0c1a5b44b6 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -135,9 +135,7 @@ def LookupAndWriteSymbols(elf_fname, entry, section): # Look up the symbol in our entry tables. value = section.LookupSymbol(name, sym.weak, msg) - if value is not None: - value += base.address - else: + if value is None: value = -1 pack_string = pack_string.lower() value_bytes = struct.pack(pack_string, value) diff --git a/tools/binman/entry.py b/tools/binman/entry.py index 409c0dca93..b6f1b2c93f 100644 --- a/tools/binman/entry.py +++ b/tools/binman/entry.py @@ -7,16 +7,7 @@ from __future__ import print_function from collections import namedtuple - -# importlib was introduced in Python 2.7 but there was a report of it not -# working in 2.7.12, so we work around this: -# http://lists.denx.de/pipermail/u-boot/2016-October/269729.html -try: - import importlib - have_importlib = True -except: - have_importlib = False - +import importlib import os import sys @@ -56,6 +47,8 @@ class Entry(object): offset: Offset of entry within the section, None if not known yet (in which case it will be calculated by Pack()) size: Entry size in bytes, None if not known + pre_reset_size: size as it was before ResetForPack(). This allows us to + keep track of the size we started with and detect size changes uncomp_size: Size of uncompressed data in bytes, if the entry is compressed, else None contents_size: Size of contents in bytes, 0 by default @@ -80,6 +73,7 @@ class Entry(object): self.name = node and (name_prefix + node.name) or 'none' self.offset = None self.size = None + self.pre_reset_size = None self.uncomp_size = None self.data = None self.contents_size = 0 @@ -119,10 +113,7 @@ class Entry(object): old_path = sys.path sys.path.insert(0, os.path.join(our_path, 'etype')) try: - if have_importlib: - module = importlib.import_module(module_name) - else: - module = __import__(module_name) + module = importlib.import_module(module_name) except ImportError as e: raise ValueError("Unknown entry type '%s' in node '%s' (expected etype/%s.py, error '%s'" % (etype, node_path, module_name, e)) @@ -326,6 +317,7 @@ class Entry(object): self.Detail('ResetForPack: offset %s->%s, size %s->%s' % (ToHex(self.offset), ToHex(self.orig_offset), ToHex(self.size), ToHex(self.orig_size))) + self.pre_reset_size = self.size self.offset = self.orig_offset self.size = self.orig_size @@ -769,7 +761,10 @@ features to produce new behaviours. True if the data did not result in a resize of this entry, False if the entry must be resized """ - self.contents_size = self.size + if self.size is not None: + self.contents_size = self.size + else: + self.contents_size = self.pre_reset_size ok = self.ProcessContentsUpdate(data) self.Detail('WriteData: size=%x, ok=%s' % (len(data), ok)) section_ok = self.section.WriteChildData(self) diff --git a/tools/binman/entry_test.py b/tools/binman/entry_test.py index 13f5864516..277e10b585 100644 --- a/tools/binman/entry_test.py +++ b/tools/binman/entry_test.py @@ -39,21 +39,6 @@ class TestEntry(unittest.TestCase): else: import entry - def test1EntryNoImportLib(self): - """Test that we can import Entry subclassess successfully""" - sys.modules['importlib'] = None - global entry - self._ReloadEntry() - entry.Entry.Create(None, self.GetNode(), 'u-boot') - self.assertFalse(entry.have_importlib) - - def test2EntryImportLib(self): - del sys.modules['importlib'] - global entry - self._ReloadEntry() - entry.Entry.Create(None, self.GetNode(), 'u-boot-spl') - self.assertTrue(entry.have_importlib) - def testEntryContents(self): """Test the Entry bass class""" import entry diff --git a/tools/binman/etype/intel_fit.py b/tools/binman/etype/intel_fit.py index 23606d27d0..2a34a05f95 100644 --- a/tools/binman/etype/intel_fit.py +++ b/tools/binman/etype/intel_fit.py @@ -27,6 +27,6 @@ class Entry_intel_fit(Entry_blob): self.align = 16 def ObtainContents(self): - data = struct.pack('<8sIHBB', '_FIT_ ', 1, 0x100, 0x80, 0x7d) + data = struct.pack('<8sIHBB', b'_FIT_ ', 1, 0x100, 0x80, 0x7d) self.SetContents(data) return True diff --git a/tools/binman/etype/intel_fsp_m.py b/tools/binman/etype/intel_fsp_m.py index 2d6b2b6621..bb1de73e41 100644 --- a/tools/binman/etype/intel_fsp_m.py +++ b/tools/binman/etype/intel_fsp_m.py @@ -2,7 +2,7 @@ # Copyright 2019 Google LLC # Written by Simon Glass <sjg@chromium.org> # -# Entry-type module for Intel Firmware Support Package binary blob (T section) +# Entry-type module for Intel Firmware Support Package binary blob (M section) # from entry import Entry diff --git a/tools/binman/etype/intel_fsp_s.py b/tools/binman/etype/intel_fsp_s.py new file mode 100644 index 0000000000..3d6900d1fb --- /dev/null +++ b/tools/binman/etype/intel_fsp_s.py @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2019 Google LLC +# Written by Simon Glass <sjg@chromium.org> +# +# Entry-type module for Intel Firmware Support Package binary blob (S section) +# + +from entry import Entry +from blob import Entry_blob + +class Entry_intel_fsp_s(Entry_blob): + """Entry containing Intel Firmware Support Package (FSP) silicon init + + Properties / Entry arguments: + - filename: Filename of file to read into entry + + This file contains a binary blob which is used on some devices to set up + the silicon. U-Boot executes this code in U-Boot proper after SDRAM is + running, so that it can make full use of memory. Documentation is typically + not available in sufficient detail to allow U-Boot do this this itself. + + An example filename is 'fsp_s.bin' + + See README.x86 for information about x86 binary blobs. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) diff --git a/tools/binman/etype/intel_fsp_t.py b/tools/binman/etype/intel_fsp_t.py new file mode 100644 index 0000000000..813a81f2e6 --- /dev/null +++ b/tools/binman/etype/intel_fsp_t.py @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2019 Google LLC +# Written by Simon Glass <sjg@chromium.org> +# +# Entry-type module for Intel Firmware Support Package binary blob (T section) +# + +from entry import Entry +from blob import Entry_blob + +class Entry_intel_fsp_t(Entry_blob): + """Entry containing Intel Firmware Support Package (FSP) temp ram init + + Properties / Entry arguments: + - filename: Filename of file to read into entry + + This file contains a binary blob which is used on some devices to set up + temporary memory (Cache-as-RAM or CAR). U-Boot executes this code in TPL so + that it has access to memory for its stack and initial storage. + + An example filename is 'fsp_t.bin' + + See README.x86 for information about x86 binary blobs. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 7000de9d42..80df0e3ca9 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -73,6 +73,8 @@ FILES_DATA = (b"sorry I'm late\nOh, don't bother apologising, I'm " + COMPRESS_DATA = b'compress xxxxxxxxxxxxxxxxxxxxxx data' REFCODE_DATA = b'refcode' FSP_M_DATA = b'fsp_m' +FSP_S_DATA = b'fsp_s' +FSP_T_DATA = b'fsp_t' # The expected size for the device tree in some tests EXTRACT_DTB_SIZE = 0x3c9 @@ -149,6 +151,8 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('bmpblk.bin', BMPBLK_DATA) TestFunctional._MakeInputFile('refcode.bin', REFCODE_DATA) TestFunctional._MakeInputFile('fsp_m.bin', FSP_M_DATA) + TestFunctional._MakeInputFile('fsp_s.bin', FSP_S_DATA) + TestFunctional._MakeInputFile('fsp_t.bin', FSP_T_DATA) cls._elf_testdir = os.path.join(cls._indir, 'elftest') elf_test.BuildElfTestFiles(cls._elf_testdir) @@ -170,7 +174,7 @@ class TestFunctional(unittest.TestCase): cls.have_lz4 = True try: tools.Run('lz4', '--no-frame-crc', '-c', - os.path.join(cls._indir, 'u-boot.bin')) + os.path.join(cls._indir, 'u-boot.bin'), binary=True) except: cls.have_lz4 = False @@ -2109,7 +2113,7 @@ class TestFunctional(unittest.TestCase): data = self.data = self._DoReadFileRealDtb('115_fdtmap.dts') fdtmap_data = data[len(U_BOOT_DATA):] magic = fdtmap_data[:8] - self.assertEqual('_FDTMAP_', magic) + self.assertEqual(b'_FDTMAP_', magic) self.assertEqual(tools.GetBytes(0, 8), fdtmap_data[8:16]) fdt_data = fdtmap_data[16:] @@ -2152,7 +2156,7 @@ class TestFunctional(unittest.TestCase): dtb = fdt.Fdt.FromData(fdt_data) fdt_size = dtb.GetFdtObj().totalsize() hdr_data = data[-8:] - self.assertEqual('BinM', hdr_data[:4]) + self.assertEqual(b'BinM', hdr_data[:4]) offset = struct.unpack('<I', hdr_data[4:])[0] & 0xffffffff self.assertEqual(fdtmap_pos - 0x400, offset - (1 << 32)) @@ -2161,7 +2165,7 @@ class TestFunctional(unittest.TestCase): data = self.data = self._DoReadFileRealDtb('117_fdtmap_hdr_start.dts') fdtmap_pos = 0x100 + len(U_BOOT_DATA) hdr_data = data[:8] - self.assertEqual('BinM', hdr_data[:4]) + self.assertEqual(b'BinM', hdr_data[:4]) offset = struct.unpack('<I', hdr_data[4:])[0] self.assertEqual(fdtmap_pos, offset) @@ -2170,7 +2174,7 @@ class TestFunctional(unittest.TestCase): data = self.data = self._DoReadFileRealDtb('118_fdtmap_hdr_pos.dts') fdtmap_pos = 0x100 + len(U_BOOT_DATA) hdr_data = data[0x80:0x88] - self.assertEqual('BinM', hdr_data[:4]) + self.assertEqual(b'BinM', hdr_data[:4]) offset = struct.unpack('<I', hdr_data[4:])[0] self.assertEqual(fdtmap_pos, offset) @@ -2431,9 +2435,9 @@ class TestFunctional(unittest.TestCase): ' section 100 %x section 100' % section_size, ' cbfs 100 400 cbfs 0', ' u-boot 138 4 u-boot 38', -' u-boot-dtb 180 10f u-boot-dtb 80 3c9', +' u-boot-dtb 180 105 u-boot-dtb 80 3c9', ' u-boot-dtb 500 %x u-boot-dtb 400 3c9' % fdt_size, -' fdtmap %x 3b4 fdtmap %x' % +' fdtmap %x 3bd fdtmap %x' % (fdtmap_offset, fdtmap_offset), ' image-header bf8 8 image-header bf8', ] @@ -2518,7 +2522,7 @@ class TestFunctional(unittest.TestCase): data = self._RunExtractCmd('section') cbfs_data = data[:0x400] cbfs = cbfs_util.CbfsReader(cbfs_data) - self.assertEqual(['u-boot', 'u-boot-dtb', ''], cbfs.files.keys()) + self.assertEqual(['u-boot', 'u-boot-dtb', ''], list(cbfs.files.keys())) dtb_data = data[0x400:] dtb = self._decompress(dtb_data) self.assertEqual(EXTRACT_DTB_SIZE, len(dtb)) @@ -3332,6 +3336,15 @@ class TestFunctional(unittest.TestCase): data = self._DoReadFile('152_intel_fsp_m.dts') self.assertEqual(FSP_M_DATA, data[:len(FSP_M_DATA)]) + def testPackFspS(self): + """Test that an image with a FSP silicon-init binary can be created""" + data = self._DoReadFile('153_intel_fsp_s.dts') + self.assertEqual(FSP_S_DATA, data[:len(FSP_S_DATA)]) + + def testPackFspT(self): + """Test that an image with a FSP temp-ram-init binary can be created""" + data = self._DoReadFile('154_intel_fsp_t.dts') + self.assertEqual(FSP_T_DATA, data[:len(FSP_T_DATA)]) if __name__ == "__main__": diff --git a/tools/binman/test/153_intel_fsp_s.dts b/tools/binman/test/153_intel_fsp_s.dts new file mode 100644 index 0000000000..579618a8fa --- /dev/null +++ b/tools/binman/test/153_intel_fsp_s.dts @@ -0,0 +1,14 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + size = <16>; + + intel-fsp-s { + filename = "fsp_s.bin"; + }; + }; +}; diff --git a/tools/binman/test/154_intel_fsp_t.dts b/tools/binman/test/154_intel_fsp_t.dts new file mode 100644 index 0000000000..8da749c157 --- /dev/null +++ b/tools/binman/test/154_intel_fsp_t.dts @@ -0,0 +1,14 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + size = <16>; + + intel-fsp-t { + filename = "fsp_t.bin"; + }; + }; +}; diff --git a/tools/binman/test/u_boot_binman_syms.lds b/tools/binman/test/u_boot_binman_syms.lds index 926df873cb..825fc3f649 100644 --- a/tools/binman/test/u_boot_binman_syms.lds +++ b/tools/binman/test/u_boot_binman_syms.lds @@ -9,7 +9,7 @@ ENTRY(_start) SECTIONS { - . = 0x00000000; + . = 0x00000010; _start = .; . = ALIGN(4); diff --git a/tools/buildman/board.py b/tools/buildman/board.py index 2a1d021574..447aaabea8 100644 --- a/tools/buildman/board.py +++ b/tools/buildman/board.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ # Copyright (c) 2012 The Chromium OS Authors. +from collections import OrderedDict import re class Expr: @@ -120,7 +121,7 @@ class Boards: Args: fname: Filename of boards.cfg file """ - with open(fname, 'r') as fd: + with open(fname, 'r', encoding='utf-8') as fd: for line in fd: if line[0] == '#': continue @@ -155,7 +156,7 @@ class Boards: key is board.target value is board """ - board_dict = {} + board_dict = OrderedDict() for board in self._boards: board_dict[board.target] = board return board_dict @@ -166,7 +167,7 @@ class Boards: Returns: List of Board objects that are marked selected """ - board_dict = {} + board_dict = OrderedDict() for board in self._boards: if board.build_it: board_dict[board.target] = board @@ -259,7 +260,7 @@ class Boards: due to each argument, arranged by argument. List of errors found """ - result = {} + result = OrderedDict() warnings = [] terms = self._BuildTerms(args) diff --git a/tools/buildman/bsettings.py b/tools/buildman/bsettings.py index 03d7439aa5..0b7208da37 100644 --- a/tools/buildman/bsettings.py +++ b/tools/buildman/bsettings.py @@ -1,9 +1,9 @@ # SPDX-License-Identifier: GPL-2.0+ # Copyright (c) 2012 The Chromium OS Authors. -import ConfigParser +import configparser import os -import StringIO +import io def Setup(fname=''): @@ -15,20 +15,20 @@ def Setup(fname=''): global settings global config_fname - settings = ConfigParser.SafeConfigParser() + settings = configparser.SafeConfigParser() if fname is not None: config_fname = fname if config_fname == '': config_fname = '%s/.buildman' % os.getenv('HOME') if not os.path.exists(config_fname): - print 'No config file found ~/.buildman\nCreating one...\n' + print('No config file found ~/.buildman\nCreating one...\n') CreateBuildmanConfigFile(config_fname) - print 'To install tool chains, please use the --fetch-arch option' + print('To install tool chains, please use the --fetch-arch option') if config_fname: settings.read(config_fname) def AddFile(data): - settings.readfp(StringIO.StringIO(data)) + settings.readfp(io.StringIO(data)) def GetItems(section): """Get the items from a section of the config. @@ -41,7 +41,7 @@ def GetItems(section): """ try: return settings.items(section) - except ConfigParser.NoSectionError as e: + except configparser.NoSectionError as e: return [] except: raise @@ -68,10 +68,10 @@ def CreateBuildmanConfigFile(config_fname): try: f = open(config_fname, 'w') except IOError: - print "Couldn't create buildman config file '%s'\n" % config_fname + print("Couldn't create buildman config file '%s'\n" % config_fname) raise - print >>f, '''[toolchain] + print('''[toolchain] # name = path # e.g. x86 = /opt/gcc-4.6.3-nolibc/x86_64-linux @@ -93,5 +93,5 @@ openrisc = or1k # snapper-boards=ENABLE_AT91_TEST=1 # snapper9260=${snapper-boards} BUILD_TAG=442 # snapper9g45=${snapper-boards} BUILD_TAG=443 -''' +''', file=f) f.close(); diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py index fbb236676c..cfbe4c26b1 100644 --- a/tools/buildman/builder.py +++ b/tools/buildman/builder.py @@ -9,7 +9,7 @@ from datetime import datetime, timedelta import glob import os import re -import Queue +import queue import shutil import signal import string @@ -92,11 +92,10 @@ u-boot/ source directory """ # Possible build outcomes -OUTCOME_OK, OUTCOME_WARNING, OUTCOME_ERROR, OUTCOME_UNKNOWN = range(4) +OUTCOME_OK, OUTCOME_WARNING, OUTCOME_ERROR, OUTCOME_UNKNOWN = list(range(4)) # Translate a commit subject into a valid filename (and handle unicode) -trans_valid_chars = string.maketrans('/: ', '---') -trans_valid_chars = trans_valid_chars.decode('latin-1') +trans_valid_chars = str.maketrans('/: ', '---') BASE_CONFIG_FILENAMES = [ 'u-boot.cfg', 'u-boot-spl.cfg', 'u-boot-tpl.cfg' @@ -122,8 +121,8 @@ class Config: def __hash__(self): val = 0 for fname in self.config: - for key, value in self.config[fname].iteritems(): - print key, value + for key, value in self.config[fname].items(): + print(key, value) val = val ^ hash(key) & hash(value) return val @@ -293,8 +292,8 @@ class Builder: self._re_dtb_warning = re.compile('(.*): Warning .*') self._re_note = re.compile('(.*):(\d*):(\d*): note: this is the location of the previous.*') - self.queue = Queue.Queue() - self.out_queue = Queue.Queue() + self.queue = queue.Queue() + self.out_queue = queue.Queue() for i in range(self.num_threads): t = builderthread.BuilderThread(self, i, incremental, per_board_out_dir) @@ -781,7 +780,7 @@ class Builder: config = {} environment = {} - for board in boards_selected.itervalues(): + for board in boards_selected.values(): outcome = self.GetBuildOutcome(commit_upto, board.target, read_func_sizes, read_config, read_environment) @@ -814,13 +813,13 @@ class Builder: tconfig = Config(self.config_filenames, board.target) for fname in self.config_filenames: if outcome.config: - for key, value in outcome.config[fname].iteritems(): + for key, value in outcome.config[fname].items(): tconfig.Add(fname, key, value) config[board.target] = tconfig tenvironment = Environment(board.target) if outcome.environment: - for key, value in outcome.environment.iteritems(): + for key, value in outcome.environment.items(): tenvironment.Add(key, value) environment[board.target] = tenvironment @@ -1040,12 +1039,12 @@ class Builder: # We now have a list of image size changes sorted by arch # Print out a summary of these - for arch, target_list in arch_list.iteritems(): + for arch, target_list in arch_list.items(): # Get total difference for each type totals = {} for result in target_list: total = 0 - for name, diff in result.iteritems(): + for name, diff in result.items(): if name.startswith('_'): continue total += diff @@ -1250,7 +1249,7 @@ class Builder: if self._show_unknown: self.AddOutcome(board_selected, arch_list, unknown_boards, '?', self.col.MAGENTA) - for arch, target_list in arch_list.iteritems(): + for arch, target_list in arch_list.items(): Print('%10s: %s' % (arch, target_list)) self._error_lines += 1 if better_err: @@ -1283,13 +1282,13 @@ class Builder: environment_minus = {} environment_change = {} base = tbase.environment - for key, value in tenvironment.environment.iteritems(): + for key, value in tenvironment.environment.items(): if key not in base: environment_plus[key] = value - for key, value in base.iteritems(): + for key, value in base.items(): if key not in tenvironment.environment: environment_minus[key] = value - for key, value in base.iteritems(): + for key, value in base.items(): new_value = tenvironment.environment.get(key) if new_value and value != new_value: desc = '%s -> %s' % (value, new_value) @@ -1342,15 +1341,15 @@ class Builder: config_minus = {} config_change = {} base = tbase.config[name] - for key, value in tconfig.config[name].iteritems(): + for key, value in tconfig.config[name].items(): if key not in base: config_plus[key] = value all_config_plus[key] = value - for key, value in base.iteritems(): + for key, value in base.items(): if key not in tconfig.config[name]: config_minus[key] = value all_config_minus[key] = value - for key, value in base.iteritems(): + for key, value in base.items(): new_value = tconfig.config.get(key) if new_value and value != new_value: desc = '%s -> %s' % (value, new_value) @@ -1368,7 +1367,7 @@ class Builder: summary[target] = '\n'.join(lines) lines_by_target = {} - for target, lines in summary.iteritems(): + for target, lines in summary.items(): if lines in lines_by_target: lines_by_target[lines].append(target) else: @@ -1392,7 +1391,7 @@ class Builder: Print('%s:' % arch) _OutputConfigInfo(lines) - for lines, targets in lines_by_target.iteritems(): + for lines, targets in lines_by_target.items(): if not lines: continue Print('%s :' % ' '.join(sorted(targets))) @@ -1463,7 +1462,7 @@ class Builder: commits: Selected commits to build """ # First work out how many commits we will build - count = (self.commit_count + self._step - 1) / self._step + count = (self.commit_count + self._step - 1) // self._step self.count = len(board_selected) * count self.upto = self.warned = self.fail = 0 self._timestamps = collections.deque() @@ -1566,7 +1565,7 @@ class Builder: self.ProcessResult(None) # Create jobs to build all commits for each board - for brd in board_selected.itervalues(): + for brd in board_selected.values(): job = builderthread.BuilderJob() job.board = brd job.commits = commits diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py index 8a9d47cd5e..570c1f6595 100644 --- a/tools/buildman/builderthread.py +++ b/tools/buildman/builderthread.py @@ -28,7 +28,7 @@ def Mkdir(dirname, parents = False): except OSError as err: if err.errno == errno.EEXIST: if os.path.realpath('.') == os.path.realpath(dirname): - print "Cannot create the current working directory '%s'!" % dirname + print("Cannot create the current working directory '%s'!" % dirname) sys.exit(1) pass else: @@ -291,15 +291,13 @@ class BuilderThread(threading.Thread): outfile = os.path.join(build_dir, 'log') with open(outfile, 'w') as fd: if result.stdout: - # We don't want unicode characters in log files - fd.write(result.stdout.decode('UTF-8').encode('ASCII', 'replace')) + fd.write(result.stdout) errfile = self.builder.GetErrFile(result.commit_upto, result.brd.target) if result.stderr: with open(errfile, 'w') as fd: - # We don't want unicode characters in log files - fd.write(result.stderr.decode('UTF-8').encode('ASCII', 'replace')) + fd.write(result.stderr) elif os.path.exists(errfile): os.remove(errfile) @@ -314,17 +312,17 @@ class BuilderThread(threading.Thread): else: fd.write('%s' % result.return_code) with open(os.path.join(build_dir, 'toolchain'), 'w') as fd: - print >>fd, 'gcc', result.toolchain.gcc - print >>fd, 'path', result.toolchain.path - print >>fd, 'cross', result.toolchain.cross - print >>fd, 'arch', result.toolchain.arch + print('gcc', result.toolchain.gcc, file=fd) + print('path', result.toolchain.path, file=fd) + print('cross', result.toolchain.cross, file=fd) + print('arch', result.toolchain.arch, file=fd) fd.write('%s' % result.return_code) # Write out the image and function size information and an objdump env = result.toolchain.MakeEnvironment(self.builder.full_path) with open(os.path.join(build_dir, 'env'), 'w') as fd: for var in sorted(env.keys()): - print >>fd, '%s="%s"' % (var, env[var]) + print('%s="%s"' % (var, env[var]), file=fd) lines = [] for fname in ['u-boot', 'spl/u-boot-spl']: cmd = ['%snm' % self.toolchain.cross, '--size-sort', fname] @@ -335,7 +333,7 @@ class BuilderThread(threading.Thread): nm = self.builder.GetFuncSizesFile(result.commit_upto, result.brd.target, fname) with open(nm, 'w') as fd: - print >>fd, nm_result.stdout, + print(nm_result.stdout, end=' ', file=fd) cmd = ['%sobjdump' % self.toolchain.cross, '-h', fname] dump_result = command.RunPipe([cmd], capture=True, @@ -346,7 +344,7 @@ class BuilderThread(threading.Thread): objdump = self.builder.GetObjdumpFile(result.commit_upto, result.brd.target, fname) with open(objdump, 'w') as fd: - print >>fd, dump_result.stdout, + print(dump_result.stdout, end=' ', file=fd) for line in dump_result.stdout.splitlines(): fields = line.split() if len(fields) > 5 and fields[1] == '.rodata': @@ -378,7 +376,7 @@ class BuilderThread(threading.Thread): sizes = self.builder.GetSizesFile(result.commit_upto, result.brd.target) with open(sizes, 'w') as fd: - print >>fd, '\n'.join(lines) + print('\n'.join(lines), file=fd) # Write out the configuration files, with a special case for SPL for dirname in ['', 'spl', 'tpl']: diff --git a/tools/buildman/buildman.py b/tools/buildman/buildman.py index f17aa15e7c..30a8690f93 100755 --- a/tools/buildman/buildman.py +++ b/tools/buildman/buildman.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0+ # # Copyright (c) 2012 The Chromium OS Authors. @@ -6,6 +6,8 @@ """See README for more information""" +from __future__ import print_function + import multiprocessing import os import re @@ -46,11 +48,11 @@ def RunTests(skip_net_tests): suite = unittest.TestLoader().loadTestsFromTestCase(module) suite.run(result) - print result + print(result) for test, err in result.errors: - print err + print(err) for test, err in result.failures: - print err + print(err) options, args = cmdline.ParseArgs() diff --git a/tools/buildman/control.py b/tools/buildman/control.py index 9787b86747..216012d001 100644 --- a/tools/buildman/control.py +++ b/tools/buildman/control.py @@ -30,7 +30,7 @@ def GetActionSummary(is_summary, commits, selected, options): """ if commits: count = len(commits) - count = (count + options.step - 1) / options.step + count = (count + options.step - 1) // options.step commit_str = '%d commit%s' % (count, GetPlural(count)) else: commit_str = 'current source' @@ -59,31 +59,31 @@ def ShowActions(series, why_selected, boards_selected, builder, options, board_warnings: List of warnings obtained from board selected """ col = terminal.Color() - print 'Dry run, so not doing much. But I would do this:' - print + print('Dry run, so not doing much. But I would do this:') + print() if series: commits = series.commits else: commits = None - print GetActionSummary(False, commits, boards_selected, - options) - print 'Build directory: %s' % builder.base_dir + print(GetActionSummary(False, commits, boards_selected, + options)) + print('Build directory: %s' % builder.base_dir) if commits: for upto in range(0, len(series.commits), options.step): commit = series.commits[upto] - print ' ', col.Color(col.YELLOW, commit.hash[:8], bright=False), - print commit.subject - print + print(' ', col.Color(col.YELLOW, commit.hash[:8], bright=False), end=' ') + print(commit.subject) + print() for arg in why_selected: if arg != 'all': - print arg, ': %d boards' % len(why_selected[arg]) + print(arg, ': %d boards' % len(why_selected[arg])) if options.verbose: - print ' %s' % ' '.join(why_selected[arg]) - print ('Total boards to build for each commit: %d\n' % - len(why_selected['all'])) + print(' %s' % ' '.join(why_selected[arg])) + print(('Total boards to build for each commit: %d\n' % + len(why_selected['all']))) if board_warnings: for warning in board_warnings: - print col.Color(col.YELLOW, warning) + print(col.Color(col.YELLOW, warning)) def CheckOutputDir(output_dir): """Make sure that the output directory is not within the current directory @@ -146,17 +146,17 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None, if options.fetch_arch: if options.fetch_arch == 'list': sorted_list = toolchains.ListArchs() - print col.Color(col.BLUE, 'Available architectures: %s\n' % - ' '.join(sorted_list)) + print(col.Color(col.BLUE, 'Available architectures: %s\n' % + ' '.join(sorted_list))) return 0 else: fetch_arch = options.fetch_arch if fetch_arch == 'all': fetch_arch = ','.join(toolchains.ListArchs()) - print col.Color(col.CYAN, '\nDownloading toolchains: %s' % - fetch_arch) + print(col.Color(col.CYAN, '\nDownloading toolchains: %s' % + fetch_arch)) for arch in fetch_arch.split(','): - print + print() ret = toolchains.FetchAndInstall(arch) if ret: return ret @@ -167,7 +167,7 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None, toolchains.Scan(options.list_tool_chains and options.verbose) if options.list_tool_chains: toolchains.List() - print + print() return 0 # Work out how many commits to build. We want to build everything on the @@ -191,7 +191,7 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None, sys.exit(col.Color(col.RED, "Range '%s' has no commits" % options.branch)) if msg: - print col.Color(col.YELLOW, msg) + print(col.Color(col.YELLOW, msg)) count += 1 # Build upstream commit also if not count: @@ -268,7 +268,7 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None, options.threads = min(multiprocessing.cpu_count(), len(selected)) if not options.jobs: options.jobs = max(1, (multiprocessing.cpu_count() + - len(selected) - 1) / len(selected)) + len(selected) - 1) // len(selected)) if not options.step: options.step = len(series.commits) - 1 diff --git a/tools/buildman/func_test.py b/tools/buildman/func_test.py index f90b8ea7f5..4c3d497294 100644 --- a/tools/buildman/func_test.py +++ b/tools/buildman/func_test.py @@ -270,7 +270,7 @@ class TestFunctional(unittest.TestCase): stdout=''.join(commit_log[:count])) # Not handled, so abort - print 'git log', args + print('git log', args) sys.exit(1) def _HandleCommandGitConfig(self, args): @@ -286,7 +286,7 @@ class TestFunctional(unittest.TestCase): stdout='refs/heads/master\n') # Not handled, so abort - print 'git config', args + print('git config', args) sys.exit(1) def _HandleCommandGit(self, in_args): @@ -320,7 +320,7 @@ class TestFunctional(unittest.TestCase): return command.CommandResult(return_code=0) # Not handled, so abort - print 'git', git_args, sub_cmd, args + print('git', git_args, sub_cmd, args) sys.exit(1) def _HandleCommandNm(self, args): @@ -351,7 +351,7 @@ class TestFunctional(unittest.TestCase): if pipe_list[1] == ['wc', '-l']: wc = True else: - print 'invalid pipe', kwargs + print('invalid pipe', kwargs) sys.exit(1) cmd = pipe_list[0][0] args = pipe_list[0][1:] @@ -371,7 +371,7 @@ class TestFunctional(unittest.TestCase): if not result: # Not handled, so abort - print 'unknown command', kwargs + print('unknown command', kwargs) sys.exit(1) if wc: @@ -404,14 +404,14 @@ class TestFunctional(unittest.TestCase): return command.CommandResult(return_code=0) # Not handled, so abort - print 'make', stage + print('make', stage) sys.exit(1) # Example function to print output lines def print_lines(self, lines): - print len(lines) + print(len(lines)) for line in lines: - print line + print(line) #self.print_lines(terminal.GetPrintTestLines()) def testNoBoards(self): diff --git a/tools/buildman/test.py b/tools/buildman/test.py index ed99b9375c..b4e28d6867 100644 --- a/tools/buildman/test.py +++ b/tools/buildman/test.py @@ -212,11 +212,11 @@ class TestBuild(unittest.TestCase): self.assertEqual(lines[1].text, '02: %s' % commits[1][1]) col = terminal.Color() - self.assertSummary(lines[2].text, 'sandbox', 'w+', ['board4'], + self.assertSummary(lines[2].text, 'arm', 'w+', ['board1'], outcome=OUTCOME_WARN) - self.assertSummary(lines[3].text, 'arm', 'w+', ['board1'], + self.assertSummary(lines[3].text, 'powerpc', 'w+', ['board2', 'board3'], outcome=OUTCOME_WARN) - self.assertSummary(lines[4].text, 'powerpc', 'w+', ['board2', 'board3'], + self.assertSummary(lines[4].text, 'sandbox', 'w+', ['board4'], outcome=OUTCOME_WARN) # Second commit: The warnings should be listed @@ -226,10 +226,10 @@ class TestBuild(unittest.TestCase): # Third commit: Still fails self.assertEqual(lines[6].text, '03: %s' % commits[2][1]) - self.assertSummary(lines[7].text, 'sandbox', '+', ['board4']) - self.assertSummary(lines[8].text, 'arm', '', ['board1'], + self.assertSummary(lines[7].text, 'arm', '', ['board1'], outcome=OUTCOME_OK) - self.assertSummary(lines[9].text, 'powerpc', '+', ['board2', 'board3']) + self.assertSummary(lines[8].text, 'powerpc', '+', ['board2', 'board3']) + self.assertSummary(lines[9].text, 'sandbox', '+', ['board4']) # Expect a compiler error self.assertEqual(lines[10].text, '+%s' % @@ -237,8 +237,6 @@ class TestBuild(unittest.TestCase): # Fourth commit: Compile errors are fixed, just have warning for board3 self.assertEqual(lines[11].text, '04: %s' % commits[3][1]) - self.assertSummary(lines[12].text, 'sandbox', 'w+', ['board4'], - outcome=OUTCOME_WARN) expect = '%10s: ' % 'powerpc' expect += ' ' + col.Color(col.GREEN, '') expect += ' ' @@ -246,7 +244,9 @@ class TestBuild(unittest.TestCase): expect += ' ' + col.Color(col.YELLOW, 'w+') expect += ' ' expect += col.Color(col.YELLOW, ' %s' % 'board3') - self.assertEqual(lines[13].text, expect) + self.assertEqual(lines[12].text, expect) + self.assertSummary(lines[13].text, 'sandbox', 'w+', ['board4'], + outcome=OUTCOME_WARN) # Compile error fixed self.assertEqual(lines[14].text, '-%s' % @@ -259,9 +259,9 @@ class TestBuild(unittest.TestCase): # Fifth commit self.assertEqual(lines[16].text, '05: %s' % commits[4][1]) - self.assertSummary(lines[17].text, 'sandbox', '+', ['board4']) - self.assertSummary(lines[18].text, 'powerpc', '', ['board3'], + self.assertSummary(lines[17].text, 'powerpc', '', ['board3'], outcome=OUTCOME_OK) + self.assertSummary(lines[18].text, 'sandbox', '+', ['board4']) # The second line of errors[3] is a duplicate, so buildman will drop it expect = errors[3].rstrip().split('\n') diff --git a/tools/buildman/toolchain.py b/tools/buildman/toolchain.py index a65737fdf8..cc26e2ede5 100644 --- a/tools/buildman/toolchain.py +++ b/tools/buildman/toolchain.py @@ -4,18 +4,19 @@ import re import glob -from HTMLParser import HTMLParser +from html.parser import HTMLParser import os import sys import tempfile -import urllib2 +import urllib.request, urllib.error, urllib.parse import bsettings import command import terminal +import tools (PRIORITY_FULL_PREFIX, PRIORITY_PREFIX_GCC, PRIORITY_PREFIX_GCC_PATH, - PRIORITY_CALC) = range(4) + PRIORITY_CALC) = list(range(4)) # Simple class to collect links from a page class MyHTMLParser(HTMLParser): @@ -100,15 +101,15 @@ class Toolchain: raise_on_error=False) self.ok = result.return_code == 0 if verbose: - print 'Tool chain test: ', + print('Tool chain test: ', end=' ') if self.ok: - print "OK, arch='%s', priority %d" % (self.arch, - self.priority) + print("OK, arch='%s', priority %d" % (self.arch, + self.priority)) else: - print 'BAD' - print 'Command: ', cmd - print result.stdout - print result.stderr + print('BAD') + print('Command: ', cmd) + print(result.stdout) + print(result.stderr) else: self.ok = True @@ -138,7 +139,7 @@ class Toolchain: value = '' for name, value in bsettings.GetItems('toolchain-wrapper'): if not value: - print "Warning: Wrapper not found" + print("Warning: Wrapper not found") if value: value = value + ' ' @@ -227,11 +228,11 @@ class Toolchains: """ toolchains = bsettings.GetItems('toolchain') if show_warning and not toolchains: - print ("Warning: No tool chains. Please run 'buildman " + print(("Warning: No tool chains. Please run 'buildman " "--fetch-arch all' to download all available toolchains, or " "add a [toolchain] section to your buildman config file " "%s. See README for details" % - bsettings.config_fname) + bsettings.config_fname)) paths = [] for name, value in toolchains: @@ -272,10 +273,10 @@ class Toolchains: if add_it: self.toolchains[toolchain.arch] = toolchain elif verbose: - print ("Toolchain '%s' at priority %d will be ignored because " + print(("Toolchain '%s' at priority %d will be ignored because " "another toolchain for arch '%s' has priority %d" % (toolchain.gcc, toolchain.priority, toolchain.arch, - self.toolchains[toolchain.arch].priority)) + self.toolchains[toolchain.arch].priority))) def ScanPath(self, path, verbose): """Scan a path for a valid toolchain @@ -289,9 +290,9 @@ class Toolchains: fnames = [] for subdir in ['.', 'bin', 'usr/bin']: dirname = os.path.join(path, subdir) - if verbose: print " - looking in '%s'" % dirname + if verbose: print(" - looking in '%s'" % dirname) for fname in glob.glob(dirname + '/*gcc'): - if verbose: print " - found '%s'" % fname + if verbose: print(" - found '%s'" % fname) fnames.append(fname) return fnames @@ -321,9 +322,9 @@ class Toolchains: Args: verbose: True to print out progress information """ - if verbose: print 'Scanning for tool chains' + if verbose: print('Scanning for tool chains') for name, value in self.prefixes: - if verbose: print " - scanning prefix '%s'" % value + if verbose: print(" - scanning prefix '%s'" % value) if os.path.exists(value): self.Add(value, True, verbose, PRIORITY_FULL_PREFIX, name) continue @@ -335,10 +336,10 @@ class Toolchains: for f in fname_list: self.Add(f, True, verbose, PRIORITY_PREFIX_GCC_PATH, name) if not fname_list: - raise ValueError, ("No tool chain found for prefix '%s'" % + raise ValueError("No tool chain found for prefix '%s'" % value) for path in self.paths: - if verbose: print " - scanning path '%s'" % path + if verbose: print(" - scanning path '%s'" % path) fnames = self.ScanPath(path, verbose) for fname in fnames: self.Add(fname, True, verbose) @@ -346,13 +347,13 @@ class Toolchains: def List(self): """List out the selected toolchains for each architecture""" col = terminal.Color() - print col.Color(col.BLUE, 'List of available toolchains (%d):' % - len(self.toolchains)) + print(col.Color(col.BLUE, 'List of available toolchains (%d):' % + len(self.toolchains))) if len(self.toolchains): - for key, value in sorted(self.toolchains.iteritems()): - print '%-10s: %s' % (key, value.gcc) + for key, value in sorted(self.toolchains.items()): + print('%-10s: %s' % (key, value.gcc)) else: - print 'None' + print('None') def Select(self, arch): """Returns the toolchain for a given architecture @@ -370,7 +371,7 @@ class Toolchains: return self.toolchains[alias] if not arch in self.toolchains: - raise ValueError, ("No tool chain found for arch '%s'" % arch) + raise ValueError("No tool chain found for arch '%s'" % arch) return self.toolchains[arch] def ResolveReferences(self, var_dict, args): @@ -464,9 +465,9 @@ class Toolchains: links = [] for version in versions: url = '%s/%s/%s/' % (base, arch, version) - print 'Checking: %s' % url - response = urllib2.urlopen(url) - html = response.read() + print('Checking: %s' % url) + response = urllib.request.urlopen(url) + html = tools.ToString(response.read()) parser = MyHTMLParser(fetch_arch) parser.feed(html) if fetch_arch == 'list': @@ -488,14 +489,14 @@ class Toolchains: Full path to the downloaded archive file in that directory, or None if there was an error while downloading """ - print 'Downloading: %s' % url + print('Downloading: %s' % url) leaf = url.split('/')[-1] tmpdir = tempfile.mkdtemp('.buildman') - response = urllib2.urlopen(url) + response = urllib.request.urlopen(url) fname = os.path.join(tmpdir, leaf) fd = open(fname, 'wb') meta = response.info() - size = int(meta.getheaders('Content-Length')[0]) + size = int(meta.get('Content-Length')) done = 0 block_size = 1 << 16 status = '' @@ -504,19 +505,19 @@ class Toolchains: while True: buffer = response.read(block_size) if not buffer: - print chr(8) * (len(status) + 1), '\r', + print(chr(8) * (len(status) + 1), '\r', end=' ') break done += len(buffer) fd.write(buffer) - status = r'%10d MiB [%3d%%]' % (done / 1024 / 1024, - done * 100 / size) + status = r'%10d MiB [%3d%%]' % (done // 1024 // 1024, + done * 100 // size) status = status + chr(8) * (len(status) + 1) - print status, + print(status, end=' ') sys.stdout.flush() fd.close() if done != size: - print 'Error, failed to download' + print('Error, failed to download') os.remove(fname) fname = None return tmpdir, fname @@ -565,11 +566,11 @@ class Toolchains: """ # Fist get the URL for this architecture col = terminal.Color() - print col.Color(col.BLUE, "Downloading toolchain for arch '%s'" % arch) + print(col.Color(col.BLUE, "Downloading toolchain for arch '%s'" % arch)) url = self.LocateArchUrl(arch) if not url: - print ("Cannot find toolchain for arch '%s' - use 'list' to list" % - arch) + print(("Cannot find toolchain for arch '%s' - use 'list' to list" % + arch)) return 2 home = os.environ['HOME'] dest = os.path.join(home, '.buildman-toolchains') @@ -580,28 +581,28 @@ class Toolchains: tmpdir, tarfile = self.Download(url) if not tarfile: return 1 - print col.Color(col.GREEN, 'Unpacking to: %s' % dest), + print(col.Color(col.GREEN, 'Unpacking to: %s' % dest), end=' ') sys.stdout.flush() path = self.Unpack(tarfile, dest) os.remove(tarfile) os.rmdir(tmpdir) - print + print() # Check that the toolchain works - print col.Color(col.GREEN, 'Testing') + print(col.Color(col.GREEN, 'Testing')) dirpath = os.path.join(dest, path) compiler_fname_list = self.ScanPath(dirpath, True) if not compiler_fname_list: - print 'Could not locate C compiler - fetch failed.' + print('Could not locate C compiler - fetch failed.') return 1 if len(compiler_fname_list) != 1: - print col.Color(col.RED, 'Warning, ambiguous toolchains: %s' % - ', '.join(compiler_fname_list)) + print(col.Color(col.RED, 'Warning, ambiguous toolchains: %s' % + ', '.join(compiler_fname_list))) toolchain = Toolchain(compiler_fname_list[0], True, True) # Make sure that it will be found by buildman if not self.TestSettingsHasPath(dirpath): - print ("Adding 'download' to config file '%s'" % - bsettings.config_fname) + print(("Adding 'download' to config file '%s'" % + bsettings.config_fname)) bsettings.SetItem('toolchain', 'download', '%s/*/*' % dest) return 0 diff --git a/tools/dtoc/dtoc.py b/tools/dtoc/dtoc.py index 514e0dd4a3..b3596a5918 100755 --- a/tools/dtoc/dtoc.py +++ b/tools/dtoc/dtoc.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0+ # # Copyright (C) 2016 Google, Inc diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py index 6770be79fb..1b7b730359 100644 --- a/tools/dtoc/fdt.py +++ b/tools/dtoc/fdt.py @@ -56,9 +56,6 @@ def BytesToValue(data): is_string = False break for ch in string: - # Handle Python 2 treating bytes as str - if type(ch) == str: - ch = ord(ch) if ch < 32 or ch > 127: is_string = False break @@ -66,15 +63,9 @@ def BytesToValue(data): is_string = False if is_string: if count == 1: - if sys.version_info[0] >= 3: # pragma: no cover - return TYPE_STRING, strings[0].decode() - else: - return TYPE_STRING, strings[0] + return TYPE_STRING, strings[0].decode() else: - if sys.version_info[0] >= 3: # pragma: no cover - return TYPE_STRING, [s.decode() for s in strings[:-1]] - else: - return TYPE_STRING, strings[:-1] + return TYPE_STRING, [s.decode() for s in strings[:-1]] if size % 4: if size == 1: return TYPE_BYTE, tools.ToChar(data[0]) @@ -415,8 +406,8 @@ class Node: prop_name: Name of property to set val: String value to set (will be \0-terminated in DT) """ - if sys.version_info[0] >= 3: # pragma: no cover - val = bytes(val, 'utf-8') + if type(val) == str: + val = val.encode('utf-8') self._CheckProp(prop_name).props[prop_name].SetData(val + b'\0') def AddString(self, prop_name, val): diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index b915b27856..d733b70655 100644..100755 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0+ # Copyright (c) 2012 The Chromium OS Authors. # diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index 028c8cbaa8..3316757e61 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0+ # Copyright (c) 2018 Google, Inc # Written by Simon Glass <sjg@chromium.org> diff --git a/tools/fit_image.c b/tools/fit_image.c index 5aca634b5e..0201cc44d8 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -229,6 +229,7 @@ static int fit_write_images(struct image_tool_params *params, char *fdt) for (cont = params->content_head; cont; cont = cont->next) { if (cont->type != IH_TYPE_FLATDT) continue; + typename = genimg_get_type_short_name(cont->type); snprintf(str, sizeof(str), "%s-%d", FIT_FDT_PROP, ++upto); fdt_begin_node(fdt, str); @@ -253,6 +254,8 @@ static int fit_write_images(struct image_tool_params *params, char *fdt) fdt_property_string(fdt, FIT_TYPE_PROP, FIT_RAMDISK_PROP); fdt_property_string(fdt, FIT_OS_PROP, genimg_get_os_short_name(params->os)); + fdt_property_string(fdt, FIT_ARCH_PROP, + genimg_get_arch_short_name(params->arch)); ret = fdt_property_file(params, fdt, FIT_DATA_PROP, params->fit_ramdisk); diff --git a/tools/libfdt/fdt_rw.c b/tools/libfdt/fdt_rw.c index 68fc7c8c88..7189f01429 100644 --- a/tools/libfdt/fdt_rw.c +++ b/tools/libfdt/fdt_rw.c @@ -11,6 +11,7 @@ int fdt_remove_unused_strings(const void *old, void *new) const char *str; int ret; int tag = FDT_PROP; + int allocated; /* Make a copy and remove the strings */ memcpy(new, old, size); @@ -25,7 +26,7 @@ int fdt_remove_unused_strings(const void *old, void *new) new_prop = (struct fdt_property *)(unsigned long) fdt_get_property_by_offset(new, offset, NULL); str = fdt_string(old, fdt32_to_cpu(old_prop->nameoff)); - ret = fdt_find_add_string_(new, str); + ret = fdt_find_add_string_(new, str, &allocated); if (ret < 0) return ret; new_prop->nameoff = cpu_to_fdt32(ret); diff --git a/tools/microcode-tool.py b/tools/microcode-tool.py index 249a33b8ca..24c02c4fca 100755 --- a/tools/microcode-tool.py +++ b/tools/microcode-tool.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0+ # # Copyright (c) 2014 Google, Inc @@ -126,15 +126,15 @@ def List(date, microcodes, model): microcodes: Dict of Microcode objects indexed by name model: Model string to search for, or None """ - print 'Date: %s' % date + print('Date: %s' % date) if model: mcode_list, tried = FindMicrocode(microcodes, model.lower()) - print 'Matching models %s:' % (', '.join(tried)) + print('Matching models %s:' % (', '.join(tried))) else: - print 'All models:' - mcode_list = [microcodes[m] for m in microcodes.keys()] + print('All models:') + mcode_list = [microcodes[m] for m in list(microcodes.keys())] for mcode in mcode_list: - print '%-20s: model %s' % (mcode.name, mcode.model) + print('%-20s: model %s' % (mcode.name, mcode.model)) def FindMicrocode(microcodes, model): """Find all the microcode chunks which match the given model. @@ -164,7 +164,7 @@ def FindMicrocode(microcodes, model): for i in range(3): abbrev = model[:-i] if i else model tried.append(abbrev) - for mcode in microcodes.values(): + for mcode in list(microcodes.values()): if mcode.model.startswith(abbrev): found.append(mcode) if found: @@ -229,17 +229,17 @@ data = <%s args += [mcode.words[i] for i in range(7)] args.append(words) if outfile == '-': - print out % tuple(args) + print(out % tuple(args)) else: if not outfile: if not os.path.exists(MICROCODE_DIR): - print >> sys.stderr, "Creating directory '%s'" % MICROCODE_DIR + print("Creating directory '%s'" % MICROCODE_DIR, file=sys.stderr) os.makedirs(MICROCODE_DIR) outfile = os.path.join(MICROCODE_DIR, mcode.name + '.dtsi') - print >> sys.stderr, "Writing microcode for '%s' to '%s'" % ( - ', '.join([mcode.name for mcode in mcodes]), outfile) + print("Writing microcode for '%s' to '%s'" % ( + ', '.join([mcode.name for mcode in mcodes]), outfile), file=sys.stderr) with open(outfile, 'w') as fd: - print >> fd, out % tuple(args) + print(out % tuple(args), file=fd) def MicrocodeTool(): """Run the microcode tool""" @@ -289,14 +289,14 @@ def MicrocodeTool(): if cmd == 'list': List(date, microcodes, options.model) elif cmd == 'license': - print '\n'.join(license_text) + print('\n'.join(license_text)) elif cmd == 'create': if not options.model: parser.error('You must specify a model to create') model = options.model.lower() if options.model == 'all': options.multiple = True - mcode_list = microcodes.values() + mcode_list = list(microcodes.values()) tried = [] else: mcode_list, tried = FindMicrocode(microcodes, model) diff --git a/tools/moveconfig.py b/tools/moveconfig.py index b99417e9d6..e2ff4cfc88 100755 --- a/tools/moveconfig.py +++ b/tools/moveconfig.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0+ # # Author: Masahiro Yamada <yamada.masahiro@socionext.com> @@ -304,7 +304,7 @@ import glob import multiprocessing import optparse import os -import Queue +import queue import re import shutil import subprocess @@ -450,8 +450,8 @@ def get_matched_defconfigs(defconfigs_file): line = line.split(' ')[0] # handle 'git log' input matched = get_matched_defconfig(line) if not matched: - print >> sys.stderr, "warning: %s:%d: no defconfig matched '%s'" % \ - (defconfigs_file, i + 1, line) + print("warning: %s:%d: no defconfig matched '%s'" % \ + (defconfigs_file, i + 1, line), file=sys.stderr) defconfigs += matched @@ -494,11 +494,11 @@ def show_diff(a, b, file_path, color_enabled): for line in diff: if line[0] == '-' and line[1] != '-': - print color_text(color_enabled, COLOR_RED, line), + print(color_text(color_enabled, COLOR_RED, line), end=' ') elif line[0] == '+' and line[1] != '+': - print color_text(color_enabled, COLOR_GREEN, line), + print(color_text(color_enabled, COLOR_GREEN, line), end=' ') else: - print line, + print(line, end=' ') def extend_matched_lines(lines, matched, pre_patterns, post_patterns, extend_pre, extend_post): @@ -554,9 +554,9 @@ def extend_matched_lines(lines, matched, pre_patterns, post_patterns, extend_pre def confirm(options, prompt): if not options.yes: while True: - choice = raw_input('{} [y/n]: '.format(prompt)) + choice = input('{} [y/n]: '.format(prompt)) choice = choice.lower() - print choice + print(choice) if choice == 'y' or choice == 'n': break @@ -809,10 +809,10 @@ def try_expand(line): val= val.strip('\"') if re.search("[*+-/]|<<|SZ_+|\(([^\)]+)\)", val): newval = hex(eval(val, SIZES)) - print "\tExpanded expression %s to %s" % (val, newval) + print("\tExpanded expression %s to %s" % (val, newval)) return cfg+'='+newval except: - print "\tFailed to expand expression in %s" % line + print("\tFailed to expand expression in %s" % line) return line @@ -838,7 +838,7 @@ class Progress: def show(self): """Display the progress.""" - print ' %d defconfigs out of %d\r' % (self.current, self.total), + print(' %d defconfigs out of %d\r' % (self.current, self.total), end=' ') sys.stdout.flush() @@ -1236,7 +1236,7 @@ class Slot: "Tool chain for '%s' is missing. Do nothing.\n" % arch) self.finish(False) return - env = toolchain.MakeEnvironment(False) + env = toolchain.MakeEnvironment(False) cmd = list(self.make_cmd) cmd.append('KCONFIG_IGNORE_DUPLICATES=1') @@ -1312,7 +1312,7 @@ class Slot: log += '\n'.join([ ' ' + s for s in self.log.split('\n') ]) # Some threads are running in parallel. # Print log atomically to not mix up logs from different threads. - print >> (sys.stdout if success else sys.stderr), log + print(log, file=(sys.stdout if success else sys.stderr)) if not success: if self.options.exit_on_error: @@ -1411,8 +1411,8 @@ class Slots: msg = "The following boards were not processed due to error:\n" msg += boards msg += "(the list has been saved in %s)\n" % output_file - print >> sys.stderr, color_text(self.options.color, COLOR_LIGHT_RED, - msg) + print(color_text(self.options.color, COLOR_LIGHT_RED, + msg), file=sys.stderr) with open(output_file, 'w') as f: f.write(boards) @@ -1431,8 +1431,8 @@ class Slots: msg += "It is highly recommended to check them manually:\n" msg += boards msg += "(the list has been saved in %s)\n" % output_file - print >> sys.stderr, color_text(self.options.color, COLOR_YELLOW, - msg) + print(color_text(self.options.color, COLOR_YELLOW, + msg), file=sys.stderr) with open(output_file, 'w') as f: f.write(boards) @@ -1448,11 +1448,11 @@ class ReferenceSource: commit: commit to git-clone """ self.src_dir = tempfile.mkdtemp() - print "Cloning git repo to a separate work directory..." + print("Cloning git repo to a separate work directory...") subprocess.check_output(['git', 'clone', os.getcwd(), '.'], cwd=self.src_dir) - print "Checkout '%s' to build the original autoconf.mk." % \ - subprocess.check_output(['git', 'rev-parse', '--short', commit]).strip() + print("Checkout '%s' to build the original autoconf.mk." % \ + subprocess.check_output(['git', 'rev-parse', '--short', commit]).strip()) subprocess.check_output(['git', 'checkout', commit], stderr=subprocess.STDOUT, cwd=self.src_dir) @@ -1480,14 +1480,14 @@ def move_config(toolchains, configs, options, db_queue): """ if len(configs) == 0: if options.force_sync: - print 'No CONFIG is specified. You are probably syncing defconfigs.', + print('No CONFIG is specified. You are probably syncing defconfigs.', end=' ') elif options.build_db: - print 'Building %s database' % CONFIG_DATABASE + print('Building %s database' % CONFIG_DATABASE) else: - print 'Neither CONFIG nor --force-sync is specified. Nothing will happen.', + print('Neither CONFIG nor --force-sync is specified. Nothing will happen.', end=' ') else: - print 'Move ' + ', '.join(configs), - print '(jobs: %d)\n' % options.jobs + print('Move ' + ', '.join(configs), end=' ') + print('(jobs: %d)\n' % options.jobs) if options.git_ref: reference_src = ReferenceSource(options.git_ref) @@ -1517,7 +1517,7 @@ def move_config(toolchains, configs, options, db_queue): while not slots.empty(): time.sleep(SLEEP_TIME) - print '' + print('') slots.show_failed_boards() slots.show_suspicious_boards() @@ -1691,15 +1691,15 @@ def do_imply_config(config_list, add_imply, imply_flags, skip_added, for config in config_list: defconfigs = defconfig_db.get(config) if not defconfigs: - print '%s not found in any defconfig' % config + print('%s not found in any defconfig' % config) continue # Get the set of defconfigs without this one (since a config cannot # imply itself) non_defconfigs = all_defconfigs - defconfigs num_defconfigs = len(defconfigs) - print '%s found in %d/%d defconfigs' % (config, num_defconfigs, - len(all_configs)) + print('%s found in %d/%d defconfigs' % (config, num_defconfigs, + len(all_configs))) # This will hold the results: key=config, value=defconfigs containing it imply_configs = {} @@ -1736,7 +1736,7 @@ def do_imply_config(config_list, add_imply, imply_flags, skip_added, if common_defconfigs: skip = False if find_superset: - for prev in imply_configs.keys(): + for prev in list(imply_configs.keys()): prev_count = len(imply_configs[prev]) count = len(common_defconfigs) if (prev_count > count and @@ -1806,15 +1806,15 @@ def do_imply_config(config_list, add_imply, imply_flags, skip_added, add_list[fname].append(linenum) if show and kconfig_info != 'skip': - print '%5d : %-30s%-25s %s' % (num_common, iconfig.ljust(30), - kconfig_info, missing_str) + print('%5d : %-30s%-25s %s' % (num_common, iconfig.ljust(30), + kconfig_info, missing_str)) # Having collected a list of things to add, now we add them. We process # each file from the largest line number to the smallest so that # earlier additions do not affect our line numbers. E.g. if we added an # imply at line 20 it would change the position of each line after # that. - for fname, linenums in add_list.iteritems(): + for fname, linenums in add_list.items(): for linenum in sorted(linenums, reverse=True): add_imply_rule(config[CONFIG_LEN:], fname, linenum) @@ -1891,11 +1891,11 @@ def main(): for flag in options.imply_flags.split(','): bad = flag not in IMPLY_FLAGS if bad: - print "Invalid flag '%s'" % flag + print("Invalid flag '%s'" % flag) if flag == 'help' or bad: - print "Imply flags: (separate with ',')" - for name, info in IMPLY_FLAGS.iteritems(): - print ' %-15s: %s' % (name, info[1]) + print("Imply flags: (separate with ',')") + for name, info in IMPLY_FLAGS.items(): + print(' %-15s: %s' % (name, info[1])) parser.print_usage() sys.exit(1) imply_flags |= IMPLY_FLAGS[flag][0] @@ -1905,14 +1905,14 @@ def main(): return config_db = {} - db_queue = Queue.Queue() + db_queue = queue.Queue() t = DatabaseThread(config_db, db_queue) t.setDaemon(True) t.start() if not options.cleanup_headers_only: check_clean_directory() - bsettings.Setup('') + bsettings.Setup('') toolchains = toolchain.Toolchains() toolchains.GetSettings() toolchains.Scan(verbose=False) @@ -1939,7 +1939,7 @@ def main(): if options.build_db: with open(CONFIG_DATABASE, 'w') as fd: - for defconfig, configs in config_db.iteritems(): + for defconfig, configs in config_db.items(): fd.write('%s\n' % defconfig) for config in sorted(configs.keys()): fd.write(' %s=%s\n' % (config, configs[config])) diff --git a/tools/patman/command.py b/tools/patman/command.py index 16299f3f5b..5fbd2c4a3e 100644 --- a/tools/patman/command.py +++ b/tools/patman/command.py @@ -4,6 +4,7 @@ import os import cros_subprocess +import tools """Shell command ease-ups for Python.""" @@ -31,6 +32,13 @@ class CommandResult: self.return_code = return_code self.exception = exception + def ToOutput(self, binary): + if not binary: + self.stdout = tools.ToString(self.stdout) + self.stderr = tools.ToString(self.stderr) + self.combined = tools.ToString(self.combined) + return self + # This permits interception of RunPipe for test purposes. If it is set to # a function, then that function is called with the pipe list being @@ -41,7 +49,7 @@ test_result = None def RunPipe(pipe_list, infile=None, outfile=None, capture=False, capture_stderr=False, oneline=False, - raise_on_error=True, cwd=None, **kwargs): + raise_on_error=True, cwd=None, binary=False, **kwargs): """ Perform a command pipeline, with optional input/output filenames. @@ -67,7 +75,7 @@ def RunPipe(pipe_list, infile=None, outfile=None, else: return test_result # No result: fall through to normal processing - result = CommandResult() + result = CommandResult(b'', b'', b'') last_pipe = None pipeline = list(pipe_list) user_pipestr = '|'.join([' '.join(pipe) for pipe in pipe_list]) @@ -93,29 +101,36 @@ def RunPipe(pipe_list, infile=None, outfile=None, if raise_on_error: raise Exception("Error running '%s': %s" % (user_pipestr, str)) result.return_code = 255 - return result + return result.ToOutput(binary) if capture: result.stdout, result.stderr, result.combined = ( last_pipe.CommunicateFilter(None)) if result.stdout and oneline: - result.output = result.stdout.rstrip('\r\n') + result.output = result.stdout.rstrip(b'\r\n') result.return_code = last_pipe.wait() else: result.return_code = os.waitpid(last_pipe.pid, 0)[1] if raise_on_error and result.return_code: raise Exception("Error running '%s'" % user_pipestr) - return result + return result.ToOutput(binary) def Output(*cmd, **kwargs): kwargs['raise_on_error'] = kwargs.get('raise_on_error', True) return RunPipe([cmd], capture=True, **kwargs).stdout def OutputOneLine(*cmd, **kwargs): + """Run a command and output it as a single-line string + + The command us expected to produce a single line of output + + Returns: + String containing output of command + """ raise_on_error = kwargs.pop('raise_on_error', True) - return (RunPipe([cmd], capture=True, oneline=True, - raise_on_error=raise_on_error, - **kwargs).stdout.strip()) + result = RunPipe([cmd], capture=True, oneline=True, + raise_on_error=raise_on_error, **kwargs).stdout.strip() + return result def Run(*cmd, **kwargs): return RunPipe([cmd], **kwargs).stdout diff --git a/tools/patman/func_test.py b/tools/patman/func_test.py index 50a2741439..76319fff37 100644 --- a/tools/patman/func_test.py +++ b/tools/patman/func_test.py @@ -51,7 +51,7 @@ class TestFunctional(unittest.TestCase): @classmethod def GetText(self, fname): - return open(self.GetPath(fname)).read() + return open(self.GetPath(fname), encoding='utf-8').read() @classmethod def GetPatchName(self, subject): @@ -160,7 +160,7 @@ class TestFunctional(unittest.TestCase): dry_run, not ignore_bad_tags, cc_file, in_reply_to=in_reply_to, thread=None) series.ShowActions(args, cmd, process_tags) - cc_lines = open(cc_file).read().splitlines() + cc_lines = open(cc_file, encoding='utf-8').read().splitlines() os.remove(cc_file) lines = out[0].splitlines() @@ -198,9 +198,9 @@ class TestFunctional(unittest.TestCase): line += 4 self.assertEqual(expected, tools.ToUnicode(lines[line])) - self.assertEqual(('%s %s, %s' % (args[0], rick, stefan)), + self.assertEqual(('%s %s\0%s' % (args[0], rick, stefan)), tools.ToUnicode(cc_lines[0])) - self.assertEqual(('%s %s, %s, %s, %s' % (args[1], fred, ed, rick, + self.assertEqual(('%s %s\0%s\0%s\0%s' % (args[1], fred, ed, rick, stefan)), tools.ToUnicode(cc_lines[1])) expected = ''' @@ -229,14 +229,14 @@ Simon Glass (2): 2.7.4 ''' - lines = open(cover_fname).read().splitlines() + lines = open(cover_fname, encoding='utf-8').read().splitlines() self.assertEqual( 'Subject: [RFC PATCH v3 0/2] test: A test patch series', lines[3]) self.assertEqual(expected.splitlines(), lines[7:]) for i, fname in enumerate(args): - lines = open(fname).read().splitlines() + lines = open(fname, encoding='utf-8').read().splitlines() subject = [line for line in lines if line.startswith('Subject')] self.assertEqual('Subject: [RFC %d/%d]' % (i + 1, count), subject[0][:18]) diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py index ef06606297..df3eb7483b 100644 --- a/tools/patman/patchstream.py +++ b/tools/patman/patchstream.py @@ -511,8 +511,8 @@ def FixPatch(backup_dir, fname, series, commit): A list of errors, or [] if all ok. """ handle, tmpname = tempfile.mkstemp() - outfd = os.fdopen(handle, 'w') - infd = open(fname, 'r') + outfd = os.fdopen(handle, 'w', encoding='utf-8') + infd = open(fname, 'r', encoding='utf-8') ps = PatchStream(series) ps.commit = commit ps.ProcessStream(infd, outfd) diff --git a/tools/patman/patman.py b/tools/patman/patman.py index 9605a36eff..cf53e532dd 100755 --- a/tools/patman/patman.py +++ b/tools/patman/patman.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # SPDX-License-Identifier: GPL-2.0+ # # Copyright (c) 2011 The Chromium OS Authors. @@ -112,7 +112,7 @@ elif options.cc_cmd: for line in fd.readlines(): match = re_line.match(line) if match and match.group(1) == args[0]: - for cc in match.group(2).split(', '): + for cc in match.group(2).split('\0'): cc = cc.strip() if cc: print(cc) diff --git a/tools/patman/series.py b/tools/patman/series.py index 67103f03e6..02a1113ad0 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -223,7 +223,7 @@ class Series(dict): col = terminal.Color() # Look for commit tags (of the form 'xxx:' at the start of the subject) fname = '/tmp/patman.%d' % os.getpid() - fd = open(fname, 'w') + fd = open(fname, 'w', encoding='utf-8') all_ccs = [] for commit in self.commits: cc = [] @@ -243,13 +243,13 @@ class Series(dict): if limit is not None: cc = cc[:limit] all_ccs += cc - print(commit.patch, ', '.join(sorted(set(cc))), file=fd) + print(commit.patch, '\0'.join(sorted(set(cc))), file=fd) self._generated_cc[commit.patch] = cc if cover_fname: cover_cc = gitutil.BuildEmailList(self.get('cover_cc', '')) cover_cc = [tools.FromUnicode(m) for m in cover_cc] - cc_list = ', '.join([tools.ToUnicode(x) + cc_list = '\0'.join([tools.ToUnicode(x) for x in sorted(set(cover_cc + all_ccs))]) print(cover_fname, cc_list.encode('utf-8'), file=fd) diff --git a/tools/patman/settings.py b/tools/patman/settings.py index c98911d522..5dc83a8500 100644 --- a/tools/patman/settings.py +++ b/tools/patman/settings.py @@ -165,7 +165,7 @@ def ReadGitAliases(fname): fname: Filename to read """ try: - fd = open(fname, 'r') + fd = open(fname, 'r', encoding='utf-8') except IOError: print("Warning: Cannot find alias file '%s'" % fname) return @@ -259,7 +259,7 @@ def _ReadAliasFile(fname): """ if os.path.exists(fname): bad_line = None - with open(fname) as fd: + with open(fname, encoding='utf-8') as fd: linenum = 0 for line in fd: linenum += 1 diff --git a/tools/patman/test.py b/tools/patman/test.py index cc61c20606..889e186606 100644 --- a/tools/patman/test.py +++ b/tools/patman/test.py @@ -72,12 +72,12 @@ Signed-off-by: Simon Glass <sjg@chromium.org> ''' out = '' inhandle, inname = tempfile.mkstemp() - infd = os.fdopen(inhandle, 'w') + infd = os.fdopen(inhandle, 'w', encoding='utf-8') infd.write(data) infd.close() exphandle, expname = tempfile.mkstemp() - expfd = os.fdopen(exphandle, 'w') + expfd = os.fdopen(exphandle, 'w', encoding='utf-8') expfd.write(expected) expfd.close() diff --git a/tools/patman/tools.py b/tools/patman/tools.py index 4a7fcdad21..3feddb292f 100644 --- a/tools/patman/tools.py +++ b/tools/patman/tools.py @@ -186,7 +186,7 @@ def PathHasFile(path_spec, fname): return True return False -def Run(name, *args): +def Run(name, *args, **kwargs): """Run a tool with some arguments This runs a 'tool', which is a program used by binman to process files and @@ -201,13 +201,14 @@ def Run(name, *args): CommandResult object """ try: + binary = kwargs.get('binary') env = None if tool_search_paths: env = dict(os.environ) env['PATH'] = ':'.join(tool_search_paths) + ':' + env['PATH'] all_args = (name,) + args result = command.RunPipe([all_args], capture=True, capture_stderr=True, - env=env, raise_on_error=False) + env=env, raise_on_error=False, binary=binary) if result.return_code: raise Exception("Error %d running '%s': %s" % (result.return_code,' '.join(all_args), @@ -375,7 +376,7 @@ def ToBytes(string): """Convert a str type into a bytes type Args: - string: string to convert value + string: string to convert Returns: Python 3: A bytes type @@ -385,6 +386,18 @@ def ToBytes(string): return string.encode('utf-8') return string +def ToString(bval): + """Convert a bytes type into a str type + + Args: + bval: bytes value to convert + + Returns: + Python 3: A bytes type + Python 2: A string type + """ + return bval.decode('utf-8') + def Compress(indata, algo, with_header=True): """Compress some data using a given algorithm @@ -406,14 +419,14 @@ def Compress(indata, algo, with_header=True): fname = GetOutputFilename('%s.comp.tmp' % algo) WriteFile(fname, indata) if algo == 'lz4': - data = Run('lz4', '--no-frame-crc', '-c', fname) + data = Run('lz4', '--no-frame-crc', '-c', fname, binary=True) # cbfstool uses a very old version of lzma elif algo == 'lzma': outfname = GetOutputFilename('%s.comp.otmp' % algo) Run('lzma_alone', 'e', fname, outfname, '-lc1', '-lp0', '-pb0', '-d8') data = ReadFile(outfname) elif algo == 'gzip': - data = Run('gzip', '-c', fname) + data = Run('gzip', '-c', fname, binary=True) else: raise ValueError("Unknown algorithm '%s'" % algo) if with_header: @@ -446,13 +459,13 @@ def Decompress(indata, algo, with_header=True): with open(fname, 'wb') as fd: fd.write(indata) if algo == 'lz4': - data = Run('lz4', '-dc', fname) + data = Run('lz4', '-dc', fname, binary=True) elif algo == 'lzma': outfname = GetOutputFilename('%s.decomp.otmp' % algo) Run('lzma_alone', 'd', fname, outfname) - data = ReadFile(outfname) + data = ReadFile(outfname, binary=True) elif algo == 'gzip': - data = Run('gzip', '-cd', fname) + data = Run('gzip', '-cd', fname, binary=True) else: raise ValueError("Unknown algorithm '%s'" % algo) return data diff --git a/tools/rkmux.py b/tools/rkmux.py index 11c192a073..1226ee201c 100755 --- a/tools/rkmux.py +++ b/tools/rkmux.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # Script to create enums from datasheet register tables # @@ -43,8 +43,8 @@ class RegField: self.desc.append(desc) def Show(self): - print self - print + print(self) + print() self.__init__() def __str__(self): @@ -65,11 +65,11 @@ class Printer: self.output_footer() def output_header(self): - print '/* %s */' % self.name - print 'enum {' + print('/* %s */' % self.name) + print('enum {') def output_footer(self): - print '};'; + print('};'); def output_regfield(self, regfield): lines = regfield.desc @@ -97,7 +97,7 @@ class Printer: self.first = False self.output_header() else: - print + print() out_enum(field, 'shift', bit_low) out_enum(field, 'mask', mask) next_val = -1 @@ -175,7 +175,7 @@ def out_enum(field, suffix, value, skip_val=False): val_str = '%d' % value str += '%s= %s' % ('\t' * tabs, val_str) - print '\t%s,' % str + print('\t%s,' % str) # Process a CSV file, e.g. from tabula def process_csv(name, fd): |