Merge branch '2019-07-17-master-imports'
authorTom Rini <trini@konsulko.com>
Thu, 18 Jul 2019 15:31:37 +0000 (11:31 -0400)
committerTom Rini <trini@konsulko.com>
Thu, 18 Jul 2019 15:31:37 +0000 (11:31 -0400)
- Various FS/disk related fixes with security implications.
- Proper fix for the pci_ep test.
- Assorted bugfixes
- Some MediaTek updates.
- 'env erase' support.

45 files changed:
.gitlab-ci.yml [new file with mode: 0644]
.travis.yml
arch/arm/dts/k3-am65-main.dtsi
arch/arm/dts/k3-am65-mcu.dtsi
arch/arm/dts/k3-am65-wakeup.dtsi
arch/arm/dts/k3-am65.dtsi
arch/arm/dts/k3-am654-base-board-u-boot.dtsi
arch/arm/dts/k3-am654-base-board.dts
arch/arm/dts/k3-am654-r5-base-board.dts
arch/arm/include/asm/omap_i2c.h
arch/arm/lib/crt0.S
arch/arm/mach-k3/Kconfig
arch/arm/mach-k3/Makefile
arch/arm/mach-k3/am6_init.c
arch/arm/mach-k3/include/mach/am6_hardware.h
arch/arm/mach-k3/include/mach/sys_proto.h
arch/arm/mach-k3/include/mach/sysfw-loader.h [new file with mode: 0644]
arch/arm/mach-k3/sysfw-loader.c [new file with mode: 0644]
board/ti/am65x/Kconfig
board/ti/am65x/README
board/ti/am65x/evm.c
board/ti/common/board_detect.c
board/ti/common/board_detect.h
common/spl/Kconfig
common/spl/spl_fit.c
common/spl/spl_mmc.c
configs/am335x_boneblack_vboot_defconfig
configs/am65x_evm_a53_defconfig
configs/am65x_evm_r5_defconfig
configs/am65x_hs_evm_a53_defconfig
configs/am65x_hs_evm_r5_defconfig
configs/evb-ast2500_defconfig
drivers/core/regmap.c
drivers/i2c/Kconfig
drivers/mmc/Kconfig
drivers/mmc/Makefile
drivers/mmc/am654_sdhci.c [new file with mode: 0644]
drivers/mmc/k3_arsan_sdhci.c [deleted file]
drivers/mmc/sdhci.c
drivers/mmc/xenon_sdhci.c
drivers/mmc/zynq_sdhci.c
include/configs/am65x_evm.h
include/regmap.h
include/sdhci.h
include/spl.h

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644 (file)
index 0000000..e27d86f
--- /dev/null
@@ -0,0 +1,361 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+# 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:xenial-20190222-24April2019
+
+# We run some tests in different order, to catch some failures quicker.
+stages:
+  - test.py
+  - testsuites
+  - world build
+
+.buildman_and_testpy_template: &buildman_and_testpy_dfn
+  tags: [ 'all' ]
+  stage: test.py
+  before_script:
+    # Clone uboot-test-hooks
+    - 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
+    - grub-mkimage -o ~/grub_x86.efi -O i386-efi normal  echo lsefimmap lsefi lsefisystab efinet tftp minicmd
+    - grub-mkimage -o ~/grub_x64.efi -O x86_64-efi normal  echo lsefimmap lsefi lsefisystab efinet tftp minicmd
+    - mkdir ~/grub2-arm
+    - ( cd ~/grub2-arm; wget -O - http://download.opensuse.org/ports/armv7hl/distribution/leap/42.2/repo/oss/suse/armv7hl/grub2-arm-efi-2.02~beta2-87.1.armv7hl.rpm | rpm2cpio | cpio -di )
+    - mkdir ~/grub2-arm64
+    - ( cd ~/grub2-arm64; wget -O - http://download.opensuse.org/ports/aarch64/distribution/leap/42.2/repo/oss/suse/aarch64/grub2-arm64-efi-2.02~beta2-87.1.aarch64.rpm | rpm2cpio | cpio -di )
+    - if [[ "${QEMU_TARGET}" != "" ]]; then
+        git clone git://git.qemu.org/qemu.git /tmp/qemu;
+        pushd /tmp/qemu;
+        git submodule update --init dtc &&
+        git checkout ${QEMU_VERSION} &&
+        ./configure --prefix=/tmp/qemu-install --target-list=${QEMU_TARGET} &&
+        make -j$(nproc) all install;
+        popd;
+      fi
+  after_script:
+    - rm -rf ~/grub2* /tmp/uboot-test-hooks /tmp/qemu /tmp/venv
+  script:
+    # From buildman, exit code 129 means warnings only.  If we've been asked to
+    # use clang only do one configuration.
+    - if [[ "${BUILDMAN}" != "" ]]; then
+        ret=0;
+        tools/buildman/buildman -P -E ${BUILDMAN} ${OVERRIDE}|| ret=$?;
+        if [[ $ret -ne 0 && $ret -ne 129 ]]; then
+          tools/buildman/buildman -sdeP ${BUILDMAN};
+          exit $ret;
+        fi;
+      fi
+    # "not a_test_which_does_not_exist" is a dummy -k parameter which will
+    # 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.
+    - export UBOOT_TRAVIS_BUILD_DIR=`cd .. && pwd`/.bm-work/${TEST_PY_BD};
+      export PATH=/tmp/qemu-install/bin:/tmp/uboot-test-hooks/bin:/usr/bin:/bin;
+      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";
+        ret=$?;
+        if [[ $ret -ne 0 ]]; then
+          exit $ret;
+        fi;
+      fi;
+
+build all 32bit ARM plaforms:
+  tags: [ 'all' ]
+  stage: world build
+  script:
+    - ret=0;
+     ./tools/buildman/buildman -P -E arm -x aarch64 || ret=$?;
+     if [[ $ret -ne 0 && $ret -ne 129 ]]; then
+       ./tools/buildman/buildman -sdeP;
+       exit $ret;
+     fi;
+
+build all 64bit ARM plaforms:
+  tags: [ 'all' ]
+  stage: world build
+  script:
+    - virtualenv /tmp/venv
+    - . /tmp/venv/bin/activate
+    - pip install pyelftools
+    - ret=0;
+     ./tools/buildman/buildman -P -E aarch64 || ret=$?;
+     if [[ $ret -ne 0 && $ret -ne 129 ]]; then
+       ./tools/buildman/buildman -sdeP;
+       exit $ret;
+     fi;
+
+build all PowerPC plaforms:
+  tags: [ 'all' ]
+  stage: world build
+  script:
+    - ret=0;
+     ./tools/buildman/buildman -P -E powerpc || ret=$?;
+     if [[ $ret -ne 0 && $ret -ne 129 ]]; then
+       ./tools/buildman/buildman -sdeP;
+       exit $ret;
+     fi;
+
+build all other plaforms:
+  tags: [ 'all' ]
+  stage: world build
+  script:
+    - ret=0;
+     ./tools/buildman/buildman -P -E -x arm,powerpc || ret=$?;
+     if [[ $ret -ne 0 && $ret -ne 129 ]]; then
+       ./tools/buildman/buildman -sdeP;
+       exit $ret;
+     fi;
+
+# QA jobs for code analytics
+# static code analysis with cppcheck (we can add --enable=all later)
+cppcheck:
+  tags: [ 'all' ]
+  stage: testsuites
+  script:
+    - cppcheck --force --quiet --inline-suppr .
+
+# search for TODO within source tree
+grep TODO/FIXME/HACK:
+  tags: [ 'all' ]
+  stage: testsuites
+  script:
+    - grep -r TODO .
+    - grep -r FIXME .
+    # search for HACK within source tree and ignore HACKKIT board
+    - grep -r HACK . | grep -v HACKKIT
+
+# some statistics about the code base
+sloccount:
+  tags: [ 'all' ]
+  stage: testsuites
+  script:
+    - sloccount .
+
+# ensure all configs have MAINTAINERS entries
+Check for configs without MAINTAINERS entry:
+  tags: [ 'all' ]
+  stage: testsuites
+  script:
+    - if [ `./tools/genboardscfg.py -f 2>&1 | wc -l` -ne 0 ]; then exit 1; fi
+
+# Ensure host tools build
+Build tools-only:
+  tags: [ 'all' ]
+  stage: testsuites
+  script:
+    - make tools-only_config tools-only -j$(nproc)
+
+# Run various tool tests
+Run patman testsuite:
+  tags: [ 'all' ]
+  stage: testsuites
+  script:
+    - git config --global user.name "GitLab CI Runner"
+    - git config --global user.email trini@konsulko.com
+    - ./tools/patman/patman --test
+
+Run buildman testsuite:
+  tags: [ 'all' ]
+  stage: testsuites
+  script:
+    - ./tools/buildman/buildman -t
+
+Run binman and dtoc testsuite:
+  tags: [ 'all' ]
+  stage: testsuites
+  script:
+    - export UBOOT_TRAVIS_BUILD_DIR=`cd .. && pwd`/.bm-work/sandbox_spl;
+      ./tools/buildman/buildman -P sandbox_spl && 
+     export PYTHONPATH="${UBOOT_TRAVIS_BUILD_DIR}/scripts/dtc/pylibfdt";
+     export PATH="${UBOOT_TRAVIS_BUILD_DIR}/scripts/dtc:${PATH}";
+     ./tools/binman/binman -t &&
+     ./tools/dtoc/dtoc -t
+
+# Test sandbox with test.py
+sandbox test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "sandbox"
+    BUILDMAN: "^sandbox$"
+  <<: *buildman_and_testpy_dfn
+
+sandbox_spl test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "sandbox_spl"
+    BUILDMAN: "^sandbox_spl$"
+    TEST_PY_TEST_SPEC: "test_ofplatdata"
+  <<: *buildman_and_testpy_dfn
+
+evb-ast2500 test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "evb-ast2500"
+    TEST_PY_ID: "--id qemu"
+    QEMU_TARGET: "arm-softmmu"
+    QEMU_VERSION: "506179e42112be77bfd071f050b15762d3b2cd43"
+    BUILDMAN: "^evb-ast2500$"
+  <<: *buildman_and_testpy_dfn
+
+sandbox_flattree test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "sandbox_flattree"
+    BUILDMAN: "^sandbox_flattree$"
+  <<: *buildman_and_testpy_dfn
+
+vexpress_ca15_tc2 test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "vexpress_ca15_tc2"
+    TEST_PY_ID: "--id qemu"
+    QEMU_TARGET: "arm-softmmu"
+    QEMU_VERSION: "v3.0.0"
+    BUILDMAN: "^vexpress_ca15_tc2$"
+  <<: *buildman_and_testpy_dfn
+
+vexpress_ca9x4 test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "vexpress_ca9x4"
+    TEST_PY_ID: "--id qemu"
+    QEMU_TARGET: "arm-softmmu"
+    BUILDMAN: "^vexpress_ca9x4$"
+  <<: *buildman_and_testpy_dfn
+
+integratorcp_cm926ejs test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "integratorcp_cm926ejs"
+    TEST_PY_TEST_SPEC: "not sleep"
+    TEST_PY_ID: "--id qemu"
+    QEMU_TARGET: "arm-softmmu"
+    BUILDMAN: "^integratorcp_cm926ejs$"
+  <<: *buildman_and_testpy_dfn
+
+qemu_arm test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "qemu_arm"
+    TEST_PY_TEST_SPEC: "not sleep"
+    QEMU_TARGET: "arm-softmmu"
+    BUILDMAN: "^qemu_arm$"
+  <<: *buildman_and_testpy_dfn
+
+qemu_arm64 test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "qemu_arm64"
+    TEST_PY_TEST_SPEC: "not sleep"
+    QEMU_TARGET: "aarch64-softmmu"
+    BUILDMAN: "^qemu_arm64$"
+  <<: *buildman_and_testpy_dfn
+
+qemu_mips test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "qemu_mips"
+    TEST_PY_TEST_SPEC: "not sleep"
+    QEMU_TARGET: "mips-softmmu"
+    BUILDMAN: "^qemu_mips$"
+    TOOLCHAIN: "mips"
+  <<: *buildman_and_testpy_dfn
+
+qemu_mipsel test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "qemu_mipsel"
+    TEST_PY_TEST_SPEC: "not sleep"
+    QEMU_TARGET: "mipsel-softmmu"
+    BUILDMAN: "^qemu_mipsel$"
+    TOOLCHAIN: "mips"
+  <<: *buildman_and_testpy_dfn
+
+qemu_mips64 test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "qemu_mips64"
+    TEST_PY_TEST_SPEC: "not sleep"
+    QEMU_TARGET: "mips64-softmmu"
+    BUILDMAN: "^qemu_mips64$"
+    TOOLCHAIN: "mips"
+  <<: *buildman_and_testpy_dfn
+
+qemu_mips64el test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "qemu_mips64el"
+    TEST_PY_TEST_SPEC: "not sleep"
+    QEMU_TARGET: "mips64el-softmmu"
+    BUILDMAN: "^qemu_mips64el$"
+    TOOLCHAIN: "mips"
+  <<: *buildman_and_testpy_dfn
+
+qemu-ppce500 test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "qemu-ppce500"
+    TEST_PY_TEST_SPEC: "not sleep"
+    QEMU_TARGET: "ppc-softmmu"
+    BUILDMAN: "^qemu-ppce500$"
+    TOOLCHAIN: "powerpc"
+  <<: *buildman_and_testpy_dfn
+
+qemu-x86 test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "qemu-x86"
+    TEST_PY_TEST_SPEC: "not sleep"
+    QEMU_TARGET: "i386-softmmu"
+    BUILDMAN: "^qemu-x86$"
+    TOOLCHAIN: "i386"
+  <<: *buildman_and_testpy_dfn
+
+qemu-x86_64 test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "qemu-x86_64"
+    TEST_PY_TEST_SPEC: "not sleep"
+    QEMU_TARGET: "x86_64-softmmu"
+    BUILDMAN: "^qemu-x86_64$"
+    TOOLCHAIN: "i386"
+  <<: *buildman_and_testpy_dfn
+
+zynq_zc702 test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "zynq_zc702"
+    TEST_PY_TEST_SPEC: "not sleep"
+    QEMU_TARGET: "arm-softmmu"
+    TEST_PY_ID: "--id qemu"
+    BUILDMAN: "^zynq_zc702$"
+  <<: *buildman_and_testpy_dfn
+
+xilinx_versal_virt test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "xilinx_versal_virt"
+    TEST_PY_TEST_SPEC: "not sleep"
+    QEMU_TARGET: "aarch64-softmmu"
+    TEST_PY_ID: "--id qemu"
+    BUILDMAN: "^xilinx_versal_virt$"
+  <<: *buildman_and_testpy_dfn
+
+xtfpga test.py:
+  tags: [ 'all' ]
+  variables:
+    TEST_PY_BD: "xtfpga"
+    TEST_PY_TEST_SPEC: "not sleep"
+    QEMU_TARGET: "xtensa-softmmu"
+    TEST_PY_ID: "--id qemu"
+    BUILDMAN: "^xtfpga$"
+    TOOLCHAIN: "xtensa-dc233c-elf"
+  <<: *buildman_and_testpy_dfn
index 6662ca126ab5db52f2c67e28a3933d5c37f7eb8d..f20268bde350a5b795244412f3f626e5dc568d6f 100644 (file)
@@ -384,6 +384,13 @@ matrix:
         - TEST_PY_BD="sandbox_flattree"
           BUILDMAN="^sandbox_flattree$"
           TOOLCHAIN="i386"
+    - name: "test/py evb-ast2500"
+      env:
+        - TEST_PY_BD="evb-ast2500"
+          TEST_PY_ID="--id qemu"
+          QEMU_TARGET="arm-softmmu"
+          QEMU_VERSION="506179e42112be77bfd071f050b15762d3b2cd43"
+          BUILDMAN="^evb-ast2500$"
     - name: "test/py vexpress_ca15_tc2"
       env:
         - TEST_PY_BD="vexpress_ca15_tc2"
index adcd6341e40c02aabef992516a075eb2a14245a8..39fec03b4a9269b5c62a7bf2ede575bce87dabb4 100644 (file)
                clock-frequency = <48000000>;
                current-speed = <115200>;
        };
+
+       main_pmx0: pinmux@11c000 {
+               compatible = "pinctrl-single";
+               reg = <0x0 0x11c000 0x0 0x2e4>;
+               #pinctrl-cells = <1>;
+               pinctrl-single,register-width = <32>;
+               pinctrl-single,function-mask = <0xffffffff>;
+       };
+
+       main_pmx1: pinmux@11c2e8 {
+               compatible = "pinctrl-single";
+               reg = <0x0 0x11c2e8 0x0 0x24>;
+               #pinctrl-cells = <1>;
+               pinctrl-single,register-width = <32>;
+               pinctrl-single,function-mask = <0xffffffff>;
+       };
+
+       sdhci0: sdhci@4f80000 {
+               compatible = "ti,am654-sdhci-5.1";
+               reg = <0x0 0x4f80000 0x0 0x260>, <0x0 0x4f90000 0x0 0x134>;
+               power-domains = <&k3_pds 47>;
+               clocks = <&k3_clks 47 0>, <&k3_clks 47 1>;
+               clock-names = "clk_ahb", "clk_xin";
+               interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
+               mmc-ddr-1_8v;
+               mmc-hs200-1_8v;
+               ti,otap-del-sel = <0x2>;
+               ti,trm-icp = <0x8>;
+               dma-coherent;
+       };
+
+       main_i2c0: i2c@2000000 {
+               compatible = "ti,am654-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2000000 0x0 0x100>;
+               interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 110 1>;
+               power-domains = <&k3_pds 110>;
+       };
+
+       main_i2c1: i2c@2010000 {
+               compatible = "ti,am654-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2010000 0x0 0x100>;
+               interrupts = <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 111 1>;
+               power-domains = <&k3_pds 111>;
+       };
+
+       main_i2c2: i2c@2020000 {
+               compatible = "ti,am654-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2020000 0x0 0x100>;
+               interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 112 1>;
+               power-domains = <&k3_pds 112>;
+       };
+
+       main_i2c3: i2c@2030000 {
+               compatible = "ti,am654-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2030000 0x0 0x100>;
+               interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 113 1>;
+               power-domains = <&k3_pds 113>;
+       };
 };
index 8c611d16df44bd80ef9ddd0032df241085f8b88f..1fd027748e1fa525922f412fa866f1ed7c2f9dfb 100644 (file)
                        clock-frequency = <96000000>;
                        current-speed = <115200>;
        };
+
+       mcu_i2c0: i2c@40b00000 {
+               compatible = "ti,am654-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x40b00000 0x0 0x100>;
+               interrupts = <GIC_SPI 564 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 114 1>;
+               power-domains = <&k3_pds 114>;
+       };
 };
index 1f591ef8bb9e0e9a95a43e1380dd21c1e6f6e217..1f85006f557167570544c9bae3ae0eb0aa54401d 100644 (file)
                };
        };
 
+       wkup_pmx0: pinmux@4301c000 {
+               compatible = "pinctrl-single";
+               reg = <0x4301c000 0x118>;
+               #pinctrl-cells = <1>;
+               pinctrl-single,register-width = <32>;
+               pinctrl-single,function-mask = <0xffffffff>;
+       };
+
        wkup_uart0: serial@42300000 {
                compatible = "ti,am654-uart";
                reg = <0x42300000 0x100>;
                clock-frequency = <48000000>;
                current-speed = <115200>;
        };
+
+       wkup_i2c0: i2c@42120000 {
+               compatible = "ti,am654-i2c", "ti,omap4-i2c";
+               reg = <0x42120000 0x100>;
+               interrupts = <GIC_SPI 696 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 115 1>;
+               power-domains = <&k3_pds 115>;
+       };
 };
index 9d1ed497532978382a0ec2449b1cad80de5faf94..47271938b38378e051559040c7bbf61459c79bd5 100644 (file)
@@ -8,6 +8,7 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/k3.h>
 
 / {
        model = "Texas Instruments K3 AM654 SoC";
                serial2 = &main_uart0;
                serial3 = &main_uart1;
                serial4 = &main_uart2;
+               i2c0 = &wkup_i2c0;
+               i2c1 = &mcu_i2c0;
+               i2c2 = &main_i2c0;
+               i2c3 = &main_i2c1;
+               i2c4 = &main_i2c2;
+               i2c5 = &main_i2c3;
        };
 
        chosen { };
index 844a5cd96ad4c1655c07c08a736caea8196cad49..449b1ddd79281b66a9b407c053f57e25d73b7927 100644 (file)
 &cbass_main{
        u-boot,dm-spl;
 
-       main_pmx0: pinmux@11c000 {
-               compatible = "pinctrl-single";
-               reg = <0x0 0x11c000 0x0 0x2e4>;
-               #pinctrl-cells = <1>;
-               pinctrl-single,register-width = <32>;
-               pinctrl-single,function-mask = <0xffffffff>;
-       };
-
-       main_pmx1: pinmux@11c2e8 {
-               compatible = "pinctrl-single";
-               reg = <0x0 0x11c2e8 0x0 0x24>;
-               #pinctrl-cells = <1>;
-               pinctrl-single,register-width = <32>;
-               pinctrl-single,function-mask = <0xffffffff>;
-       };
-
-       sdhci0: sdhci@04F80000 {
-               compatible = "arasan,sdhci-5.1";
-               reg = <0x0 0x4F80000 0x0 0x1000>,
-                     <0x0 0x4F90000 0x0 0x400>;
-               clocks = <&k3_clks 47 1>;
-               power-domains = <&k3_pds 47>;
-               max-frequency = <25000000>;
-       };
-
        sdhci1: sdhci@04FA0000 {
-               compatible = "arasan,sdhci-5.1";
+               compatible = "ti,am654-sdhci-5.1";
                reg = <0x0 0x4FA0000 0x0 0x1000>,
                      <0x0 0x4FB0000 0x0 0x400>;
                clocks = <&k3_clks 48 1>;
                power-domains = <&k3_pds 48>;
                max-frequency = <25000000>;
+               ti,otap-del-sel = <0x2>;
+               ti,trm-icp = <0x8>;
        };
 
 };
 
 &cbass_mcu {
        u-boot,dm-spl;
-       wkup_pmx0: pinmux@4301c000 {
-               compatible = "pinctrl-single";
-               reg = <0x0 0x4301c000 0x0 0x118>;
-               #pinctrl-cells = <1>;
-               pinctrl-single,register-width = <32>;
-               pinctrl-single,function-mask = <0xffffffff>;
-       };
 
        navss_mcu: navss-mcu {
                compatible = "simple-bus";
        u-boot,dm-spl;
 };
 
+&wkup_pmx0 {
+       u-boot,dm-spl;
+
+       wkup_i2c0_pins_default {
+               u-boot,dm-spl;
+       };
+};
+
 &main_pmx0 {
        u-boot,dm-spl;
        main_uart0_pins_default: main_uart0_pins_default {
                        AM65X_IOPAD(0x0190, PIN_INPUT_PULLUP, 0)        /* (A24) MMC0_DAT5 */
                        AM65X_IOPAD(0x018c, PIN_INPUT_PULLUP, 0)        /* (B26) MMC0_DAT6 */
                        AM65X_IOPAD(0x0188, PIN_INPUT_PULLUP, 0)        /* (D25) MMC0_DAT7 */
-                       AM65X_IOPAD(0x01b0, PIN_INPUT, 0)                       /* (C25) MMC0_DS */
+                       AM65X_IOPAD(0x01b4, PIN_INPUT_PULLUP, 0)        /* (A23) MMC0_SDCD */
+                       AM65X_IOPAD(0x01b0, PIN_INPUT, 0)               /* (C25) MMC0_DS */
                >;
                u-boot,dm-spl;
        };
 
 &sdhci0 {
        u-boot,dm-spl;
-       status = "okay";
-       non-removable;
-       bus-width = <8>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&main_mmc0_pins_default>;
 };
 
 &sdhci1 {
        pinctrl-names = "default";
        pinctrl-0 = <&main_mmc1_pins_default>;
        sdhci-caps-mask = <0x7 0x0>;
+       ti,driver-strength-ohm = <50>;
 };
 
 &mcu_cpsw {
                reg-names = "gmii-sel";
        };
 };
+
+&wkup_i2c0 {
+       u-boot,dm-spl;
+};
index af6956fdc13f49662c47e2750b4296b843851a2e..e73b9aa6b1a81c19c1000d18a59388917bd0b0fd 100644 (file)
@@ -6,6 +6,7 @@
 /dts-v1/;
 
 #include "k3-am654.dtsi"
+#include <dt-bindings/pinctrl/k3.h>
 
 / {
        compatible =  "ti,am654-evm", "ti,am654";
                };
        };
 };
+
+&main_pmx0 {
+       main_mmc0_pins_default: main_mmc0_pins_default {
+               pinctrl-single,pins = <
+                       AM65X_IOPAD(0x01a8, PIN_INPUT_PULLDOWN, 0)      /* (B25) MMC0_CLK */
+                       AM65X_IOPAD(0x01aC, PIN_INPUT_PULLUP, 0)        /* (B27) MMC0_CMD */
+                       AM65X_IOPAD(0x01a4, PIN_INPUT_PULLUP, 0)        /* (A26) MMC0_DAT0 */
+                       AM65X_IOPAD(0x01a0, PIN_INPUT_PULLUP, 0)        /* (E25) MMC0_DAT1 */
+                       AM65X_IOPAD(0x019c, PIN_INPUT_PULLUP, 0)        /* (C26) MMC0_DAT2 */
+                       AM65X_IOPAD(0x0198, PIN_INPUT_PULLUP, 0)        /* (A25) MMC0_DAT3 */
+                       AM65X_IOPAD(0x0194, PIN_INPUT_PULLUP, 0)        /* (E24) MMC0_DAT4 */
+                       AM65X_IOPAD(0x0190, PIN_INPUT_PULLUP, 0)        /* (A24) MMC0_DAT5 */
+                       AM65X_IOPAD(0x018c, PIN_INPUT_PULLUP, 0)        /* (B26) MMC0_DAT6 */
+                       AM65X_IOPAD(0x0188, PIN_INPUT_PULLUP, 0)        /* (D25) MMC0_DAT7 */
+                       AM65X_IOPAD(0x01b4, PIN_INPUT_PULLUP, 0)        /* (A23) MMC0_SDCD */
+                       AM65X_IOPAD(0x01b0, PIN_INPUT, 0)               /* (C25) MMC0_DS */
+               >;
+       };
+};
+
+&wkup_pmx0 {
+       wkup_i2c0_pins_default: wkup-i2c0-pins-default {
+               pinctrl-single,pins = <
+                       AM65X_WKUP_IOPAD(0x00e0, PIN_INPUT, 0) /* (AC7) WKUP_I2C0_SCL */
+                       AM65X_WKUP_IOPAD(0x00e4, PIN_INPUT, 0) /* (AD6) WKUP_I2C0_SDA */
+               >;
+       };
+};
+
+&sdhci0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_mmc0_pins_default>;
+       bus-width = <8>;
+       non-removable;
+       ti,driver-strength-ohm = <50>;
+};
+
+&wkup_i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&wkup_i2c0_pins_default>;
+       clock-frequency = <400000>;
+
+       tca9554: gpio@38 {
+               compatible = "nxp,pca9554";
+               reg = <0x38>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+};
index a07038be70912b490eb65769da10818944f6995e..9d9b3d585283b0c54b133a15c0d7f3d4ddbd1400 100644 (file)
                u-boot,dm-spl;
        };
 
+       clk_200mhz: dummy_clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <200000000>;
+               u-boot,dm-spl;
+       };
 };
 
 &dmsc {
                >;
                u-boot,dm-spl;
        };
+
+       wkup_i2c0_pins_default: wkup-i2c0-pins-default {
+               pinctrl-single,pins = <
+                       AM65X_WKUP_IOPAD(0x00e0, PIN_INPUT, 0) /* (AC7) WKUP_I2C0_SCL */
+                       AM65X_WKUP_IOPAD(0x00e4, PIN_INPUT, 0) /* (AD6) WKUP_I2C0_SDA */
+               >;
+       };
+};
+
+&main_pmx0 {
+       u-boot,dm-spl;
+       main_mmc0_pins_default: main_mmc0_pins_default {
+               pinctrl-single,pins = <
+                       AM65X_IOPAD(0x01a8, PIN_INPUT_PULLDOWN, 0)      /* (B25) MMC0_CLK */
+                       AM65X_IOPAD(0x01aC, PIN_INPUT_PULLUP, 0)        /* (B27) MMC0_CMD */
+                       AM65X_IOPAD(0x01a4, PIN_INPUT_PULLUP, 0)        /* (A26) MMC0_DAT0 */
+                       AM65X_IOPAD(0x01a0, PIN_INPUT_PULLUP, 0)        /* (E25) MMC0_DAT1 */
+                       AM65X_IOPAD(0x019c, PIN_INPUT_PULLUP, 0)        /* (C26) MMC0_DAT2 */
+                       AM65X_IOPAD(0x0198, PIN_INPUT_PULLUP, 0)        /* (A25) MMC0_DAT3 */
+                       AM65X_IOPAD(0x0194, PIN_INPUT_PULLUP, 0)        /* (E24) MMC0_DAT4 */
+                       AM65X_IOPAD(0x0190, PIN_INPUT_PULLUP, 0)        /* (A24) MMC0_DAT5 */
+                       AM65X_IOPAD(0x018c, PIN_INPUT_PULLUP, 0)        /* (B26) MMC0_DAT6 */
+                       AM65X_IOPAD(0x0188, PIN_INPUT_PULLUP, 0)        /* (D25) MMC0_DAT7 */
+                       AM65X_IOPAD(0x01b0, PIN_INPUT, 0)               /* (C25) MMC0_DS */
+               >;
+       };
 };
 
 &memorycontroller {
        pinctrl-names = "default";
        pinctrl-0 = <&wkup_vtt_pins_default>;
 };
+
+&sdhci0 {
+       clock-names = "clk_xin";
+       clocks = <&clk_200mhz>;
+       /delete-property/ power-domains;
+       ti,driver-strength-ohm = <50>;
+};
+
+&sdhci1 {
+       clock-names = "clk_xin";
+       clocks = <&clk_200mhz>;
+       /delete-property/ power-domains;
+       ti,driver-strength-ohm = <50>;
+};
+
+&wkup_i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&wkup_i2c0_pins_default>;
+       clock-frequency = <400000>;
+};
index c1695cbbee35e4e5d964b97e7702088a659083a8..a6975401dabd2b3aa5c937c19ee79c07d2805e3c 100644 (file)
@@ -3,8 +3,6 @@
 #ifndef _OMAP_I2C_H
 #define _OMAP_I2C_H
 
-#include <asm/arch/cpu.h>
-
 #ifdef CONFIG_DM_I2C
 
 /* Information about a GPIO bank */
index 30fba20e1babf75d87e3d39c2aef7f7c380f54fb..c74641dcd9b661fa97237d21b62a2b4019214c28 100644 (file)
  * For more information see 'Board Initialisation Flow in README.
  */
 
+/*
+ * Macro for clearing BSS during SPL execution. Usually called during the
+ * relocation process for most boards before entering board_init_r(), but
+ * can also be done early before entering board_init_f() on plaforms that
+ * can afford it due to sufficient memory being available early.
+ */
+
+.macro SPL_CLEAR_BSS
+       ldr     r0, =__bss_start        /* this is auto-relocated! */
+
+#ifdef CONFIG_USE_ARCH_MEMSET
+       ldr     r3, =__bss_end          /* this is auto-relocated! */
+       mov     r1, #0x00000000         /* prepare zero to clear BSS */
+
+       subs    r2, r3, r0              /* r2 = memset len */
+       bl      memset
+#else
+       ldr     r1, =__bss_end          /* this is auto-relocated! */
+       mov     r2, #0x00000000         /* prepare zero to clear BSS */
+
+clbss_l:cmp    r0, r1                  /* while not at end of BSS */
+       strlo   r2, [r0]                /* clear 32-bit BSS word */
+       addlo   r0, r0, #4              /* move to next */
+       blo     clbss_l
+#endif
+.endm
+
 /*
  * entry point of crt0 sequence
  */
@@ -82,6 +109,10 @@ ENTRY(_main)
        mov     r9, r0
        bl      board_init_f_init_reserve
 
+#if defined(CONFIG_SPL_EARLY_BSS)
+       SPL_CLEAR_BSS
+#endif
+
        mov     r0, #0
        bl      board_init_f
 
@@ -119,6 +150,11 @@ here:
        bl      c_runtime_cpu_setup     /* we still call old routine here */
 #endif
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_FRAMEWORK)
+
+#if !defined(CONFIG_SPL_EARLY_BSS)
+       SPL_CLEAR_BSS
+#endif
+
 # ifdef CONFIG_SPL_BUILD
        /* Use a DRAM stack for the rest of SPL, if requested */
        bl      spl_relocate_stack_gd
@@ -126,23 +162,6 @@ here:
        movne   sp, r0
        movne   r9, r0
 # endif
-       ldr     r0, =__bss_start        /* this is auto-relocated! */
-
-#ifdef CONFIG_USE_ARCH_MEMSET
-       ldr     r3, =__bss_end          /* this is auto-relocated! */
-       mov     r1, #0x00000000         /* prepare zero to clear BSS */
-
-       subs    r2, r3, r0              /* r2 = memset len */
-       bl      memset
-#else
-       ldr     r1, =__bss_end          /* this is auto-relocated! */
-       mov     r2, #0x00000000         /* prepare zero to clear BSS */
-
-clbss_l:cmp    r0, r1                  /* while not at end of BSS */
-       strlo   r2, [r0]                /* clear 32-bit BSS word */
-       addlo   r0, r0, #4              /* move to next */
-       blo     clbss_l
-#endif
 
 #if ! defined(CONFIG_SPL_BUILD)
        bl coloured_LED_init
index e677a2e01b8986ee1206d1f19069fa3b483790be..f25f8222055f87a74d1440b9ec5734ca04d86b36 100644 (file)
@@ -58,6 +58,45 @@ config SYS_K3_BOOT_CORE_ID
        int
        default 16
 
+config K3_LOAD_SYSFW
+       bool
+       depends on SPL
+
+config K3_SYSFW_IMAGE_NAME
+       string "File name of SYSFW firmware and configuration blob"
+       depends on K3_LOAD_SYSFW
+       default "sysfw.itb"
+       help
+         Filename of the combined System Firmware and configuration image tree
+         blob to be loaded when booting from a filesystem.
+
+config K3_SYSFW_IMAGE_MMCSD_RAW_MODE_SECT
+       hex "MMC sector to load SYSFW firmware and configuration blob from"
+       depends on K3_LOAD_SYSFW && SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
+       default 0x3600
+       help
+         Address on the MMC to load the combined System Firmware and
+         configuration image tree blob from, when the MMC is being used
+         in raw mode. Units: MMC sectors (1 sector = 512 bytes).
+
+config K3_SYSFW_IMAGE_MMCSD_RAW_MODE_PART
+       hex "MMC partition to load SYSFW firmware and configuration blob from"
+       depends on K3_LOAD_SYSFW && SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
+       default 2
+       help
+         Partition on the MMC to the combined System Firmware and configuration
+         image tree blob from, when the MMC is being used in raw mode.
+
+config K3_SYSFW_IMAGE_SIZE_MAX
+       int "Amount of memory dynamically allocated for loading SYSFW blob"
+       depends on K3_LOAD_SYSFW
+       default 269000
+       help
+         Amount of memory (in bytes) reserved through dynamic allocation at
+         runtime for loading the combined System Firmware and configuration image
+         tree blob. Keep it as tight as possible, as this directly affects the
+         overall SPL memory footprint.
+
 config SYS_K3_SPL_ATF
        bool "Start Cortex-A from SPL"
        depends on SPL && CPU_V7R
index 0c3a4f7db173bb1efc425e2d0a8c0b352e49c9a1..3af7f2ec960dd01dd2fbccd2fed4e7080fdb2105 100644 (file)
@@ -7,4 +7,7 @@ obj-$(CONFIG_SOC_K3_AM6) += am6_init.o
 obj-$(CONFIG_ARM64) += arm64-mmu.o
 obj-$(CONFIG_CPU_V7R) += r5_mpu.o lowlevel_init.o
 obj-$(CONFIG_TI_SECURE_DEVICE) += security.o
+ifeq ($(CONFIG_SPL_BUILD),y)
+obj-$(CONFIG_K3_LOAD_SYSFW) += sysfw-loader.o
+endif
 obj-y += common.o
index 60a580305df01d27e157d5696897fd748a436b92..cb96581bfbb5c2df0471e73a37b68328f81973aa 100644 (file)
 #include <asm/io.h>
 #include <spl.h>
 #include <asm/arch/hardware.h>
+#include <asm/arch/sysfw-loader.h>
+#include <asm/arch/sys_proto.h>
 #include "common.h"
 #include <dm.h>
+#include <dm/uclass-internal.h>
+#include <dm/pinctrl.h>
 
 #ifdef CONFIG_SPL_BUILD
 static void mmr_unlock(u32 base, u32 partition)
@@ -63,7 +67,7 @@ static void store_boot_index_from_rom(void)
 
 void board_init_f(ulong dummy)
 {
-#if defined(CONFIG_K3_AM654_DDRSS)
+#if defined(CONFIG_K3_LOAD_SYSFW) || defined(CONFIG_K3_AM654_DDRSS)
        struct udevice *dev;
        int ret;
 #endif
@@ -83,8 +87,33 @@ void board_init_f(ulong dummy)
        /* Init DM early in-order to invoke system controller */
        spl_early_init();
 
+#ifdef CONFIG_K3_LOAD_SYSFW
+       /*
+        * Process pinctrl for the serial0 a.k.a. WKUP_UART0 module and continue
+        * regardless of the result of pinctrl. Do this without probing the
+        * device, but instead by searching the device that would request the
+        * given sequence number if probed. The UART will be used by the system
+        * firmware (SYSFW) image for various purposes and SYSFW depends on us
+        * to initialize its pin settings.
+        */
+       ret = uclass_find_device_by_seq(UCLASS_SERIAL, 0, true, &dev);
+       if (!ret)
+               pinctrl_select_state(dev, "default");
+
+       /*
+        * Load, start up, and configure system controller firmware. Provide
+        * the U-Boot console init function to the SYSFW post-PM configuration
+        * callback hook, effectively switching on (or over) the console
+        * output.
+        */
+       k3_sysfw_loader(preloader_console_init);
+#else
        /* Prepare console output */
        preloader_console_init();
+#endif
+
+       /* Perform EEPROM-based board detection */
+       do_board_detect();
 
 #ifdef CONFIG_K3_AM654_DDRSS
        ret = uclass_get_device(UCLASS_RAM, 0, &dev);
index 3343233aa3ca735becb81ac088405a2c147898c3..6df76315456f923142f7b3f19e9800eaedea1c53 100644 (file)
@@ -44,4 +44,7 @@
 #define CTRLMMR_LOCK_KICK1                             0x0100c
 #define CTRLMMR_LOCK_KICK1_UNLOCK_VAL                  0xd172bc5a
 
+/* MCU SCRATCHPAD usage */
+#define TI_SRAM_SCRATCH_BOARD_EEPROM_START CONFIG_SYS_K3_MCU_SCRATCHPAD_BASE
+
 #endif /* __ASM_ARCH_AM6_HARDWARE_H */
index 018725b4d128fbafd46df8317ac52c5be333201c..787a2744925fab7f73a69cf541e81726ea6557e7 100644 (file)
@@ -12,4 +12,6 @@ u32 wait_on_value(u32 read_bit_mask, u32 match_value, void *read_addr,
                  u32 bound);
 struct ti_sci_handle *get_ti_sci_handle(void);
 int fdt_fixup_msmc_ram(void *blob, char *parent_path, char *node_name);
+int do_board_detect(void);
+
 #endif
diff --git a/arch/arm/mach-k3/include/mach/sysfw-loader.h b/arch/arm/mach-k3/include/mach/sysfw-loader.h
new file mode 100644 (file)
index 0000000..36eb265
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *     Andreas Dannenberg <dannenberg@ti.com>
+ */
+
+#ifndef _SYSFW_LOADER_H_
+#define _SYSFW_LOADER_H_
+
+void k3_sysfw_loader(void (*config_pm_done_callback)(void));
+
+#endif
diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c
new file mode 100644 (file)
index 0000000..2ede820
--- /dev/null
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * K3: System Firmware Loader
+ *
+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
+ *     Andreas Dannenberg <dannenberg@ti.com>
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <malloc.h>
+#include <remoteproc.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+#include <asm/arch/sys_proto.h>
+
+/* Name of the FIT image nodes for SYSFW and its config data */
+#define SYSFW_FIRMWARE                 "sysfw.bin"
+#define SYSFW_CFG_BOARD                        "board-cfg.bin"
+#define SYSFW_CFG_PM                   "pm-cfg.bin"
+#define SYSFW_CFG_RM                   "rm-cfg.bin"
+#define SYSFW_CFG_SEC                  "sec-cfg.bin"
+
+static bool sysfw_loaded;
+static void *sysfw_load_address;
+
+/*
+ * Populate SPL hook to override the default load address used by the SPL
+ * loader function with a custom address for SYSFW loading.
+ */
+struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
+{
+       if (sysfw_loaded)
+               return (struct image_header *)(CONFIG_SYS_TEXT_BASE + offset);
+       else if (sysfw_load_address)
+               return sysfw_load_address;
+       else
+               panic("SYSFW load address not defined!");
+}
+
+/*
+ * Populate SPL hook to skip the default SPL loader FIT post-processing steps
+ * during SYSFW loading and return to the calling function so we can perform
+ * our own custom processing.
+ */
+bool spl_load_simple_fit_skip_processing(void)
+{
+       return !sysfw_loaded;
+}
+
+static int fit_get_data_by_name(const void *fit, int images, const char *name,
+                               const void **addr, size_t *size)
+{
+       int node_offset;
+
+       node_offset = fdt_subnode_offset(fit, images, name);
+       if (node_offset < 0)
+               return -ENOENT;
+
+       return fit_image_get_data(fit, node_offset, addr, size);
+}
+
+static void k3_sysfw_load_using_fit(void *fit)
+{
+       int images;
+       const void *sysfw_addr;
+       size_t sysfw_size;
+       int ret;
+
+       /* Find the node holding the images information */
+       images = fdt_path_offset(fit, FIT_IMAGES_PATH);
+       if (images < 0)
+               panic("Cannot find /images node (%d)\n", images);
+
+       /* Extract System Firmware (SYSFW) image from FIT */
+       ret = fit_get_data_by_name(fit, images, SYSFW_FIRMWARE,
+                                  &sysfw_addr, &sysfw_size);
+       if (ret < 0)
+               panic("Error accessing %s node in FIT (%d)\n", SYSFW_FIRMWARE,
+                     ret);
+
+       /*
+        * Start up system controller firmware
+        *
+        * It is assumed that remoteproc device 0 is the corresponding
+        * system-controller that runs SYSFW. Make sure DT reflects the same.
+        */
+       ret = rproc_dev_init(0);
+       if (ret)
+               panic("rproc failed to be initialized (%d)\n", ret);
+
+       ret = rproc_load(0, (ulong)sysfw_addr, (ulong)sysfw_size);
+       if (ret)
+               panic("Firmware failed to start on rproc (%d)\n", ret);
+
+       ret = rproc_start(0);
+       if (ret)
+               panic("Firmware init failed on rproc (%d)\n", ret);
+}
+
+static void k3_sysfw_configure_using_fit(void *fit,
+                                        struct ti_sci_handle *ti_sci)
+{
+       struct ti_sci_board_ops *board_ops = &ti_sci->ops.board_ops;
+       int images;
+       const void *cfg_fragment_addr;
+       size_t cfg_fragment_size;
+       int ret;
+
+       /* Find the node holding the images information */
+       images = fdt_path_offset(fit, FIT_IMAGES_PATH);
+       if (images < 0)
+               panic("Cannot find /images node (%d)\n", images);
+
+       /* Extract board configuration from FIT */
+       ret = fit_get_data_by_name(fit, images, SYSFW_CFG_BOARD,
+                                  &cfg_fragment_addr, &cfg_fragment_size);
+       if (ret < 0)
+               panic("Error accessing %s node in FIT (%d)\n", SYSFW_CFG_BOARD,
+                     ret);
+
+       /* Apply board configuration to SYSFW */
+       ret = board_ops->board_config(ti_sci,
+                                     (u64)(u32)cfg_fragment_addr,
+                                     (u32)cfg_fragment_size);
+       if (ret)
+               panic("Failed to set board configuration (%d)\n", ret);
+
+       /* Extract power/clock (PM) specific configuration from FIT */
+       ret = fit_get_data_by_name(fit, images, SYSFW_CFG_PM,
+                                  &cfg_fragment_addr, &cfg_fragment_size);
+       if (ret < 0)
+               panic("Error accessing %s node in FIT (%d)\n", SYSFW_CFG_PM,
+                     ret);
+
+       /* Apply power/clock (PM) specific configuration to SYSFW */
+       ret = board_ops->board_config_pm(ti_sci,
+                                        (u64)(u32)cfg_fragment_addr,
+                                        (u32)cfg_fragment_size);
+       if (ret)
+               panic("Failed to set board PM configuration (%d)\n", ret);
+
+       /* Extract resource management (RM) specific configuration from FIT */
+       ret = fit_get_data_by_name(fit, images, SYSFW_CFG_RM,
+                                  &cfg_fragment_addr, &cfg_fragment_size);
+       if (ret < 0)
+               panic("Error accessing %s node in FIT (%d)\n", SYSFW_CFG_RM,
+                     ret);
+
+       /* Apply resource management (RM) configuration to SYSFW */
+       ret = board_ops->board_config_rm(ti_sci,
+                                        (u64)(u32)cfg_fragment_addr,
+                                        (u32)cfg_fragment_size);
+       if (ret)
+               panic("Failed to set board RM configuration (%d)\n", ret);
+
+       /* Extract security specific configuration from FIT */
+       ret = fit_get_data_by_name(fit, images, SYSFW_CFG_SEC,
+                                  &cfg_fragment_addr, &cfg_fragment_size);
+       if (ret < 0)
+               panic("Error accessing %s node in FIT (%d)\n", SYSFW_CFG_SEC,
+                     ret);
+
+       /* Apply security configuration to SYSFW */
+       ret = board_ops->board_config_security(ti_sci,
+                                              (u64)(u32)cfg_fragment_addr,
+                                              (u32)cfg_fragment_size);
+       if (ret)
+               panic("Failed to set board security configuration (%d)\n",
+                     ret);
+}
+
+void k3_sysfw_loader(void (*config_pm_done_callback)(void))
+{
+       struct spl_image_info spl_image = { 0 };
+       struct spl_boot_device bootdev = { 0 };
+       struct ti_sci_handle *ti_sci;
+       int ret;
+
+       /* Reserve a block of aligned memory for loading the SYSFW image */
+       sysfw_load_address = memalign(ARCH_DMA_MINALIGN,
+                                     CONFIG_K3_SYSFW_IMAGE_SIZE_MAX);
+       if (!sysfw_load_address)
+               panic("Error allocating %u bytes of memory for SYSFW image\n",
+                     CONFIG_K3_SYSFW_IMAGE_SIZE_MAX);
+
+       debug("%s: allocated %u bytes at 0x%p\n", __func__,
+             CONFIG_K3_SYSFW_IMAGE_SIZE_MAX, sysfw_load_address);
+
+       /* Set load address for legacy modes that bypass spl_get_load_buffer */
+       spl_image.load_addr = (uintptr_t)sysfw_load_address;
+
+       bootdev.boot_device = spl_boot_device();
+
+       /* Load combined System Controller firmware and config data image */
+       switch (bootdev.boot_device) {
+#if CONFIG_IS_ENABLED(MMC_SUPPORT)
+       case BOOT_DEVICE_MMC1:
+       case BOOT_DEVICE_MMC2:
+       case BOOT_DEVICE_MMC2_2:
+               ret = spl_mmc_load(&spl_image, &bootdev,
+#ifdef CONFIG_K3_SYSFW_IMAGE_NAME
+                                  CONFIG_K3_SYSFW_IMAGE_NAME,
+#else
+                                  NULL,
+#endif
+#ifdef CONFIG_K3_SYSFW_IMAGE_MMCSD_RAW_MODE_PART
+                                  CONFIG_K3_SYSFW_IMAGE_MMCSD_RAW_MODE_PART,
+#else
+                                  0,
+#endif
+#ifdef CONFIG_K3_SYSFW_IMAGE_MMCSD_RAW_MODE_SECT
+                                  CONFIG_K3_SYSFW_IMAGE_MMCSD_RAW_MODE_SECT);
+#else
+                                  0);
+#endif
+               break;
+#endif
+       default:
+               panic("Loading SYSFW image from device %u not supported!\n",
+                     bootdev.boot_device);
+       }
+
+       if (ret)
+               panic("Error %d occurred during loading SYSFW image!\n", ret);
+
+       /*
+        * Now that SYSFW got loaded set helper flag to restore regular SPL
+        * loader behavior so we can later boot into the next stage as expected.
+        */
+       sysfw_loaded = true;
+
+       /* Ensure the SYSFW image is in FIT format */
+       if (image_get_magic((const image_header_t *)sysfw_load_address) !=
+           FDT_MAGIC)
+               panic("SYSFW image not in FIT format!\n");
+
+       /* Extract and start SYSFW */
+       k3_sysfw_load_using_fit(sysfw_load_address);
+
+       /* Get handle for accessing SYSFW services */
+       ti_sci = get_ti_sci_handle();
+
+       /* Parse and apply the different SYSFW configuration fragments */
+       k3_sysfw_configure_using_fit(sysfw_load_address, ti_sci);
+
+       /*
+        * Now that all clocks and PM aspects are setup, invoke a user-
+        * provided callback function. Usually this callback would be used
+        * to setup or re-configure the U-Boot console UART.
+        */
+       if (config_pm_done_callback)
+               config_pm_done_callback();
+
+       /* Output System Firmware version info */
+       printf("SYSFW ABI: %d.%d (firmware rev 0x%04x '%.*s')\n",
+              ti_sci->version.abi_major, ti_sci->version.abi_minor,
+              ti_sci->version.firmware_revision,
+              sizeof(ti_sci->version.firmware_description),
+              ti_sci->version.firmware_description);
+}
index 98172c28f5d3daf08071cbb9a9db35e5bc6f9e9c..47b41cd6afe422ee4bac7bcad21de7503cc4b3f9 100644 (file)
@@ -12,14 +12,18 @@ config TARGET_AM654_A53_EVM
        select ARM64
        select SOC_K3_AM6
        select SYS_DISABLE_DCACHE_OPS
+       select BOARD_LATE_INIT
+       imply TI_I2C_BOARD_DETECT
 
 config TARGET_AM654_R5_EVM
        bool "TI K3 based AM654 EVM running on R5"
        select CPU_V7R
        select SYS_THUMB_BUILD
        select SOC_K3_AM6
+       select K3_LOAD_SYSFW
        select K3_AM654_DDRSS
        imply SYS_K3_SPL_ATF
+       imply TI_I2C_BOARD_DETECT
 
 endchoice
 
@@ -34,6 +38,8 @@ config SYS_VENDOR
 config SYS_CONFIG_NAME
        default "am65x_evm"
 
+source "board/ti/common/Kconfig"
+
 endif
 
 if TARGET_AM654_R5_EVM
@@ -50,4 +56,6 @@ config SYS_CONFIG_NAME
 config SPL_LDSCRIPT
        default "arch/arm/mach-omap2/u-boot-spl.lds"
 
+source "board/ti/common/Kconfig"
+
 endif
index 0b82bd557b502fb6dbdfd2d1e5848a92ff326df3..16384e05ea26c8718bbcf32ad6ef2f00ecf9fa97 100644 (file)
@@ -209,3 +209,55 @@ Image formats:
                 | |    Secure config  | |
                 | +-------------------+ |
                 +-----------------------+
+
+eMMC:
+-----
+ROM supports booting from eMMC from boot0 partition offset 0x0
+
+Flashing images to eMMC:
+
+The following commands can be used to download tiboot3.bin, tispl.bin,
+u-boot.img, and sysfw.itb from an SD card and write them to the eMMC boot0
+partition at respective addresses.
+
+=> mmc dev 0 1
+=> fatload mmc 1 ${loadaddr} tiboot3.bin
+=> mmc write ${loadaddr} 0x0 0x400
+=> fatload mmc 1 ${loadaddr} tispl.bin
+=> mmc write ${loadaddr} 0x400 0x1000
+=> fatload mmc 1 ${loadaddr} u-boot.img
+=> mmc write ${loadaddr} 0x1400 0x2000
+=> fatload mmc 1 ${loadaddr} sysfw.itb
+=> mmc write ${loadaddr} 0x3600 0x800
+
+To give the ROM access to the boot partition, the following commands must be
+used for the first time:
+=> mmc partconf 0 1 1 1
+=> mmc bootbus 0 1 0 0
+
+To create a software partition for the rootfs, the following command can be
+used:
+=> gpt write mmc 0 ${partitions}
+
+eMMC layout:
+
+           boot0 partition (8 MB)                        user partition
+   0x0+----------------------------------+      0x0+-------------------------+
+      |     tiboot3.bin (512 KB)         |         |                         |
+ 0x400+----------------------------------+         |                         |
+      |       tispl.bin (2 MB)           |         |                         |
+0x1400+----------------------------------+         |        rootfs           |
+      |       u-boot.img (4 MB)          |         |                         |
+0x3400+----------------------------------+         |                         |
+      |      environment (128 KB)        |         |                         |
+0x3500+----------------------------------+         |                         |
+      |   backup environment (128 KB)    |         |                         |
+0x3600+----------------------------------+         |                         |
+      |          sysfw (1 MB)            |         |                         |
+0x3E00+----------------------------------+         +-------------------------+
+
+Kernel image and DT are expected to be present in the /boot folder of rootfs.
+To boot kernel from eMMC, use the following commands:
+=> setenv mmcdev 0
+=> setenv bootpart 0
+=> boot
index 52f5d6b11e3a7a2b797afc01a50993d15a67d533..7bd8c4fa6655ce98097aca7ddf711f4d3a04b60b 100644 (file)
@@ -8,10 +8,31 @@
  */
 
 #include <common.h>
+#include <dm.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+#include <asm/gpio.h>
 #include <asm/io.h>
+#include <asm/omap_common.h>
 #include <spl.h>
 #include <asm/arch/sys_proto.h>
 
+#include "../common/board_detect.h"
+
+#define board_is_am65x_base_board()    board_ti_is("AM6-COMPROCEVM")
+
+/* Daughter card presence detection signals */
+enum {
+       AM65X_EVM_APP_BRD_DET,
+       AM65X_EVM_LCD_BRD_DET,
+       AM65X_EVM_SERDES_BRD_DET,
+       AM65X_EVM_HDMI_GPMC_BRD_DET,
+       AM65X_EVM_BRD_DET_COUNT,
+};
+
+/* Max number of MAC addresses that are parsed/processed per daughter card */
+#define DAUGHTER_CARD_NO_OF_MAC_ADDR   8
+
 DECLARE_GLOBAL_DATA_PTR;
 
 int board_init(void)
@@ -80,3 +101,223 @@ int ft_board_setup(void *blob, bd_t *bd)
        return ret;
 }
 #endif
+
+int do_board_detect(void)
+{
+       int ret;
+
+       ret = ti_i2c_eeprom_am6_get_base(CONFIG_EEPROM_BUS_ADDRESS,
+                                        CONFIG_EEPROM_CHIP_ADDRESS);
+       if (ret)
+               pr_err("Reading on-board EEPROM at 0x%02x failed %d\n",
+                      CONFIG_EEPROM_CHIP_ADDRESS, ret);
+
+       return ret;
+}
+
+static void setup_board_eeprom_env(void)
+{
+       char *name = "am65x";
+
+       if (do_board_detect())
+               goto invalid_eeprom;
+
+       if (board_is_am65x_base_board())
+               name = "am65x";
+       else
+               printf("Unidentified board claims %s in eeprom header\n",
+                      board_ti_get_name());
+
+invalid_eeprom:
+       set_board_info_env_am6(name);
+}
+
+static int init_daughtercard_det_gpio(char *gpio_name, struct gpio_desc *desc)
+{
+       int ret;
+
+       memset(desc, 0, sizeof(*desc));
+
+       ret = dm_gpio_lookup_name(gpio_name, desc);
+       if (ret < 0)
+               return ret;
+
+       /* Request GPIO, simply re-using the name as label */
+       ret = dm_gpio_request(desc, gpio_name);
+       if (ret < 0)
+               return ret;
+
+       return dm_gpio_set_dir_flags(desc, GPIOD_IS_IN);
+}
+
+static int probe_daughtercards(void)
+{
+       struct ti_am6_eeprom ep;
+       struct gpio_desc board_det_gpios[AM65X_EVM_BRD_DET_COUNT];
+       char mac_addr[DAUGHTER_CARD_NO_OF_MAC_ADDR][TI_EEPROM_HDR_ETH_ALEN];
+       u8 mac_addr_cnt;
+       char name_overlays[1024] = { 0 };
+       int i, j;
+       int ret;
+
+       /*
+        * Daughter card presence detection signal name to GPIO (via I2C I/O
+        * expander @ address 0x38) name and EEPROM I2C address mapping.
+        */
+       const struct {
+               char *gpio_name;
+               u8 i2c_addr;
+       } slot_map[AM65X_EVM_BRD_DET_COUNT] = {
+               { "gpio@38_0", 0x52, }, /* AM65X_EVM_APP_BRD_DET */
+               { "gpio@38_1", 0x55, }, /* AM65X_EVM_LCD_BRD_DET */
+               { "gpio@38_2", 0x54, }, /* AM65X_EVM_SERDES_BRD_DET */
+               { "gpio@38_3", 0x53, }, /* AM65X_EVM_HDMI_GPMC_BRD_DET */
+       };
+
+       /* Declaration of daughtercards to probe */
+       const struct {
+               u8 slot_index;          /* Slot the card is installed */
+               char *card_name;        /* EEPROM-programmed card name */
+               char *dtbo_name;        /* Device tree overlay to apply */
+               u8 eth_offset;          /* ethXaddr MAC address index offset */
+       } cards[] = {
+               {
+                       AM65X_EVM_APP_BRD_DET,
+                       "AM6-GPAPPEVM",
+                       "k3-am654-gp.dtbo",
+                       0,
+               },
+               {
+                       AM65X_EVM_APP_BRD_DET,
+                       "AM6-IDKAPPEVM",
+                       "k3-am654-idk.dtbo",
+                       3,
+               },
+               {
+                       AM65X_EVM_SERDES_BRD_DET,
+                       "SER-PCIE2LEVM",
+                       "k3-am654-pcie-usb2.dtbo",
+                       0,
+               },
+               {
+                       AM65X_EVM_SERDES_BRD_DET,
+                       "SER-PCIEUSBEVM",
+                       "k3-am654-pcie-usb3.dtbo",
+                       0,
+               },
+               {
+                       AM65X_EVM_LCD_BRD_DET,
+                       "OLDI-LCD1EVM",
+                       "k3-am654-evm-oldi-lcd1evm.dtbo",
+                       0,
+               },
+       };
+
+       /*
+        * Initialize GPIO used for daughtercard slot presence detection and
+        * keep the resulting handles in local array for easier access.
+        */
+       for (i = 0; i < AM65X_EVM_BRD_DET_COUNT; i++) {
+               ret = init_daughtercard_det_gpio(slot_map[i].gpio_name,
+                                                &board_det_gpios[i]);
+               if (ret < 0)
+                       return ret;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(cards); i++) {
+               /* Obtain card-specific slot index and associated I2C address */
+               u8 slot_index = cards[i].slot_index;
+               u8 i2c_addr = slot_map[slot_index].i2c_addr;
+
+               /*
+                * The presence detection signal is active-low, hence skip
+                * over this card slot if anything other than 0 is returned.
+                */
+               ret = dm_gpio_get_value(&board_det_gpios[slot_index]);
+               if (ret < 0)
+                       return ret;
+               else if (ret)
+                       continue;
+
+               /* Get and parse the daughter card EEPROM record */
+               ret = ti_i2c_eeprom_am6_get(CONFIG_EEPROM_BUS_ADDRESS, i2c_addr,
+                                           &ep,
+                                           (char **)mac_addr,
+                                           DAUGHTER_CARD_NO_OF_MAC_ADDR,
+                                           &mac_addr_cnt);
+               if (ret) {
+                       pr_err("Reading daughtercard EEPROM at 0x%02x failed %d\n",
+                              i2c_addr, ret);
+                       /*
+                        * Even this is pretty serious let's just skip over
+                        * this particular daughtercard, rather than ending
+                        * the probing process altogether.
+                        */
+                       continue;
+               }
+
+               /* Only process the parsed data if we found a match */
+               if (strncmp(ep.name, cards[i].card_name, sizeof(ep.name)))
+                       continue;
+
+               printf("detected %s\n", cards[i].card_name);
+
+               /*
+                * Populate any MAC addresses from daughtercard into the U-Boot
+                * environment, starting with a card-specific offset so we can
+                * have multiple cards contribute to the MAC pool in a well-
+                * defined manner.
+                */
+               for (j = 0; j < mac_addr_cnt; j++) {
+                       if (!is_valid_ethaddr((u8 *)mac_addr[j]))
+                               continue;
+
+                       eth_env_set_enetaddr_by_index("eth",
+                                                     cards[i].eth_offset + j,
+                                                     (uchar *)mac_addr[j]);
+               }
+
+               /* Skip if no overlays are to be added */
+               if (!strlen(cards[i].dtbo_name))
+                       continue;
+
+               /*
+                * Make sure we are not running out of buffer space by checking
+                * if we can fit the new overlay, a trailing space to be used
+                * as a separator, plus the terminating zero.
+                */
+               if (strlen(name_overlays) + strlen(cards[i].dtbo_name) + 2 >
+                   sizeof(name_overlays))
+                       return -ENOMEM;
+
+               /* Append to our list of overlays */
+               strcat(name_overlays, cards[i].dtbo_name);
+               strcat(name_overlays, " ");
+       }
+
+       /* Apply device tree overlay(s) to the U-Boot environment, if any */
+       if (strlen(name_overlays))
+               return env_set("name_overlays", name_overlays);
+
+       return 0;
+}
+
+int board_late_init(void)
+{
+       struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
+
+       setup_board_eeprom_env();
+
+       /*
+        * The first MAC address for ethernet a.k.a. ethernet0 comes from
+        * efuse populated via the am654 gigabit eth switch subsystem driver.
+        * All the other ones are populated via EEPROM, hence continue with
+        * an index of 1.
+        */
+       board_ti_am6_set_ethaddr(1, ep->mac_addr_cnt);
+
+       /* Check for and probe any plugged-in daughtercards */
+       probe_daughtercards();
+
+       return 0;
+}
index e258e22f3714c6c8052d8ddf80956cc7a89f779e..32fa10599e8250a518c9a5ea7c65492f2cd8c6b2 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <common.h>
+#include <asm/arch/hardware.h>
 #include <asm/omap_common.h>
 #include <dm/uclass.h>
 #include <i2c.h>
@@ -284,6 +285,191 @@ int __maybe_unused ti_i2c_eeprom_dra7_get(int bus_addr, int dev_addr)
        return 0;
 }
 
+static int ti_i2c_eeprom_am6_parse_record(struct ti_am6_eeprom_record *record,
+                                         struct ti_am6_eeprom *ep,
+                                         char **mac_addr,
+                                         u8 mac_addr_max_cnt,
+                                         u8 *mac_addr_cnt)
+{
+       switch (record->header.id) {
+       case TI_AM6_EEPROM_RECORD_BOARD_INFO:
+               if (record->header.len != sizeof(record->data.board_info))
+                       return -EINVAL;
+
+               if (!ep)
+                       break;
+
+               /* Populate (and clean, if needed) the board name */
+               strlcpy(ep->name, record->data.board_info.name,
+                       sizeof(ep->name));
+               ti_eeprom_string_cleanup(ep->name);
+
+               /* Populate selected other fields from the board info record */
+               strlcpy(ep->version, record->data.board_info.version,
+                       sizeof(ep->version));
+               strlcpy(ep->software_revision,
+                       record->data.board_info.software_revision,
+                       sizeof(ep->software_revision));
+               strlcpy(ep->serial, record->data.board_info.serial,
+                       sizeof(ep->serial));
+               break;
+       case TI_AM6_EEPROM_RECORD_MAC_INFO:
+               if (record->header.len != sizeof(record->data.mac_info))
+                       return -EINVAL;
+
+               if (!mac_addr || !mac_addr_max_cnt)
+                       break;
+
+               *mac_addr_cnt = ((record->data.mac_info.mac_control &
+                                TI_AM6_EEPROM_MAC_ADDR_COUNT_MASK) >>
+                                TI_AM6_EEPROM_MAC_ADDR_COUNT_SHIFT) + 1;
+
+               /*
+                * The EEPROM can (but may not) hold a very large amount
+                * of MAC addresses, by far exceeding what we want/can store
+                * in the common memory array, so only grab what we can fit.
+                * Note that a value of 0 means 1 MAC address, and so on.
+                */
+               *mac_addr_cnt = min(*mac_addr_cnt, mac_addr_max_cnt);
+
+               memcpy(mac_addr, record->data.mac_info.mac_addr,
+                      *mac_addr_cnt * TI_EEPROM_HDR_ETH_ALEN);
+               break;
+       case 0x00:
+               /* Illegal value... Fall through... */
+       case 0xFF:
+               /* Illegal value... Something went horribly wrong... */
+               return -EINVAL;
+       default:
+               pr_warn("%s: Ignoring record id %u\n", __func__,
+                       record->header.id);
+       }
+
+       return 0;
+}
+
+int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr,
+                                        struct ti_am6_eeprom *ep,
+                                        char **mac_addr,
+                                        u8 mac_addr_max_cnt,
+                                        u8 *mac_addr_cnt)
+{
+       struct udevice *dev;
+       struct udevice *bus;
+       unsigned int eeprom_addr;
+       struct ti_am6_eeprom_record_board_id board_id;
+       struct ti_am6_eeprom_record record;
+       int rc;
+
+       /* Initialize with a known bad marker for i2c fails.. */
+       memset(ep, 0, sizeof(*ep));
+       ep->header = TI_DEAD_EEPROM_MAGIC;
+
+       /* Read the board ID record which is always the first EEPROM record */
+       rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC,
+                              sizeof(board_id), (uint8_t *)&board_id);
+       if (rc)
+               return rc;
+
+       if (board_id.header.id != TI_AM6_EEPROM_RECORD_BOARD_ID) {
+               pr_err("%s: Invalid board ID record!\n", __func__);
+               return -EINVAL;
+       }
+
+       /* Establish DM handle to board config EEPROM */
+       rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
+       if (rc)
+               return rc;
+       rc = i2c_get_chip(bus, dev_addr, 1, &dev);
+       if (rc)
+               return rc;
+
+       ep->header = TI_EEPROM_HEADER_MAGIC;
+
+       /* Ready to parse TLV structure. Initialize variables... */
+       *mac_addr_cnt = 0;
+
+       /*
+        * After the all-encompassing board ID record all other records follow
+        * a TLV-type scheme. Point to the first such record and then start
+        * parsing those one by one.
+        */
+       eeprom_addr = sizeof(board_id);
+
+       while (true) {
+               rc = dm_i2c_read(dev, eeprom_addr, (uint8_t *)&record.header,
+                                sizeof(record.header));
+               if (rc)
+                       return rc;
+
+               /*
+                * Check for end of list marker. If we reached it don't go
+                * any further and stop parsing right here.
+                */
+               if (record.header.id == TI_AM6_EEPROM_RECORD_END_LIST)
+                       break;
+
+               eeprom_addr += sizeof(record.header);
+
+               debug("%s: dev_addr=0x%02x header.id=%u header.len=%u\n",
+                     __func__, dev_addr, record.header.id,
+                     record.header.len);
+
+               /* Read record into memory if it fits */
+               if (record.header.len <= sizeof(record.data)) {
+                       rc = dm_i2c_read(dev, eeprom_addr,
+                                        (uint8_t *)&record.data,
+                                        record.header.len);
+                       if (rc)
+                               return rc;
+
+                       /* Process record */
+                       rc = ti_i2c_eeprom_am6_parse_record(&record, ep,
+                                                           mac_addr,
+                                                           mac_addr_max_cnt,
+                                                           mac_addr_cnt);
+                       if (rc) {
+                               pr_err("%s: EEPROM parsing error!\n", __func__);
+                               return rc;
+                       }
+               } else {
+                       /*
+                        * We may get here in case of larger records which
+                        * are not yet understood.
+                        */
+                       pr_err("%s: Ignoring record id %u\n", __func__,
+                              record.header.id);
+               }
+
+               eeprom_addr += record.header.len;
+       }
+
+       return 0;
+}
+
+int __maybe_unused ti_i2c_eeprom_am6_get_base(int bus_addr, int dev_addr)
+{
+       struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
+       int ret;
+
+       /*
+        * Always execute EEPROM read by not allowing to bypass it during the
+        * first invocation of SPL which happens on the R5 core.
+        */
+#if !(defined(CONFIG_SPL_BUILD) && defined(CONFIG_CPU_V7R))
+       if (ep->header == TI_EEPROM_HEADER_MAGIC) {
+               debug("%s: EEPROM has already been read\n", __func__);
+               return 0;
+       }
+#endif
+
+       ret = ti_i2c_eeprom_am6_get(bus_addr, dev_addr, ep,
+                                   (char **)ep->mac_addr,
+                                   AM6_EEPROM_HDR_NO_OF_MAC_ADDR,
+                                   &ep->mac_addr_cnt);
+       return ret;
+}
+
 bool __maybe_unused board_ti_is(char *name_tag)
 {
        struct ti_common_eeprom *ep = TI_EEPROM_DATA;
@@ -348,6 +534,25 @@ fail:
        memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
 }
 
+void __maybe_unused
+board_ti_am6_get_eth_mac_addr(int index,
+                             u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])
+{
+       struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
+
+       if (ep->header == TI_DEAD_EEPROM_MAGIC)
+               goto fail;
+
+       if (index < 0 || index >= ep->mac_addr_cnt)
+               goto fail;
+
+       memcpy(mac_addr, ep->mac_addr[index], TI_EEPROM_HDR_ETH_ALEN);
+       return;
+
+fail:
+       memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
+}
+
 u64 __maybe_unused board_ti_get_emif1_size(void)
 {
        struct ti_common_eeprom *ep = TI_EEPROM_DATA;
@@ -391,6 +596,34 @@ void __maybe_unused set_board_info_env(char *name)
                env_set("board_serial", unknown);
 }
 
+void __maybe_unused set_board_info_env_am6(char *name)
+{
+       char *unknown = "unknown";
+       struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
+
+       if (name)
+               env_set("board_name", name);
+       else if (ep->name)
+               env_set("board_name", ep->name);
+       else
+               env_set("board_name", unknown);
+
+       if (ep->version)
+               env_set("board_rev", ep->version);
+       else
+               env_set("board_rev", unknown);
+
+       if (ep->software_revision)
+               env_set("board_software_revision", ep->software_revision);
+       else
+               env_set("board_software_revision", unknown);
+
+       if (ep->serial)
+               env_set("board_serial", ep->serial);
+       else
+               env_set("board_serial", unknown);
+}
+
 static u64 mac_to_u64(u8 mac[6])
 {
        int i;
@@ -453,6 +686,19 @@ void board_ti_set_ethaddr(int index)
        }
 }
 
+void board_ti_am6_set_ethaddr(int index, int count)
+{
+       u8 mac_addr[6];
+       int i;
+
+       for (i = 0; i < count; i++) {
+               board_ti_am6_get_eth_mac_addr(i, mac_addr);
+               if (is_valid_ethaddr(mac_addr))
+                       eth_env_set_enetaddr_by_index("eth", i + index,
+                                                     mac_addr);
+       }
+}
+
 bool __maybe_unused board_ti_was_eeprom_read(void)
 {
        struct ti_common_eeprom *ep = TI_EEPROM_DATA;
index f8495a7a7cf128f55b765d4e7cd370070f1bd28e..a45d8961b9ad89f2976b431b348137cf8d7a6988 100644 (file)
@@ -43,6 +43,133 @@ struct ti_am_eeprom {
        char mac_addr[TI_EEPROM_HDR_NO_OF_MAC_ADDR][TI_EEPROM_HDR_ETH_ALEN];
 } __attribute__ ((__packed__));
 
+/* AM6x TI EVM EEPROM Definitions */
+#define TI_AM6_EEPROM_RECORD_BOARD_ID          0x01
+#define TI_AM6_EEPROM_RECORD_BOARD_INFO                0x10
+#define TI_AM6_EEPROM_RECORD_DDR_INFO          0x11
+#define TI_AM6_EEPROM_RECORD_DDR_SPD           0x12
+#define TI_AM6_EEPROM_RECORD_MAC_INFO          0x13
+#define TI_AM6_EEPROM_RECORD_END_LIST          0xFE
+
+/*
+ * Common header for AM6x TI EVM EEPROM records. Used to encapsulate the config
+ * EEPROM in its entirety as well as for individual records contained within.
+ */
+struct ti_am6_eeprom_record_header {
+       u8 id;
+       u16 len;
+} __attribute__ ((__packed__));
+
+/* AM6x TI EVM EEPROM board ID structure */
+struct ti_am6_eeprom_record_board_id {
+       u32 magic_number;
+       struct ti_am6_eeprom_record_header header;
+} __attribute__ ((__packed__));
+
+/* AM6x TI EVM EEPROM board info structure */
+#define AM6_EEPROM_HDR_NAME_LEN                        16
+#define AM6_EEPROM_HDR_VERSION_LEN             2
+#define AM6_EEPROM_HDR_PROC_NR_LEN             4
+#define AM6_EEPROM_HDR_VARIANT_LEN             2
+#define AM6_EEPROM_HDR_PCB_REV_LEN             2
+#define AM6_EEPROM_HDR_SCH_BOM_REV_LEN         2
+#define AM6_EEPROM_HDR_SW_REV_LEN              2
+#define AM6_EEPROM_HDR_VID_LEN                 2
+#define AM6_EEPROM_HDR_BLD_WK_LEN              2
+#define AM6_EEPROM_HDR_BLD_YR_LEN              2
+#define AM6_EEPROM_HDR_4P_NR_LEN               6
+#define AM6_EEPROM_HDR_SERIAL_LEN              4
+
+struct ti_am6_eeprom_record_board_info {
+       char name[AM6_EEPROM_HDR_NAME_LEN];
+       char version[AM6_EEPROM_HDR_VERSION_LEN];
+       char proc_number[AM6_EEPROM_HDR_PROC_NR_LEN];
+       char variant[AM6_EEPROM_HDR_VARIANT_LEN];
+       char pcb_revision[AM6_EEPROM_HDR_PCB_REV_LEN];
+       char schematic_bom_revision[AM6_EEPROM_HDR_SCH_BOM_REV_LEN];
+       char software_revision[AM6_EEPROM_HDR_SW_REV_LEN];
+       char vendor_id[AM6_EEPROM_HDR_VID_LEN];
+       char build_week[AM6_EEPROM_HDR_BLD_WK_LEN];
+       char build_year[AM6_EEPROM_HDR_BLD_YR_LEN];
+       char board_4p_number[AM6_EEPROM_HDR_4P_NR_LEN];
+       char serial[AM6_EEPROM_HDR_SERIAL_LEN];
+} __attribute__ ((__packed__));
+
+/* Memory location to keep a copy of the AM6 board info record */
+#define TI_AM6_EEPROM_BD_INFO_DATA ((struct ti_am6_eeprom_record_board_info *) \
+                                            TI_SRAM_SCRATCH_BOARD_EEPROM_START)
+
+/* AM6x TI EVM EEPROM DDR info structure */
+#define TI_AM6_EEPROM_DDR_CTRL_INSTANCE_MASK           GENMASK(1, 0)
+#define TI_AM6_EEPROM_DDR_CTRL_INSTANCE_SHIFT          0
+#define TI_AM6_EEPROM_DDR_CTRL_SPD_DATA_LOC_MASK       GENMASK(3, 2)
+#define TI_AM6_EEPROM_DDR_CTRL_SPD_DATA_LOC_NA         (0 << 2)
+#define TI_AM6_EEPROM_DDR_CTRL_SPD_DATA_LOC_BOARDID    (2 << 2)
+#define TI_AM6_EEPROM_DDR_CTRL_SPD_DATA_LOC_I2C51      (3 << 2)
+#define TI_AM6_EEPROM_DDR_CTRL_MEM_TYPE_MASK           GENMASK(5, 4)
+#define TI_AM6_EEPROM_DDR_CTRL_MEM_TYPE_DDR3           (0 << 4)
+#define TI_AM6_EEPROM_DDR_CTRL_MEM_TYPE_DDR4           (1 << 4)
+#define TI_AM6_EEPROM_DDR_CTRL_MEM_TYPE_LPDDR4         (2 << 4)
+#define TI_AM6_EEPROM_DDR_CTRL_IF_DATA_WIDTH_MASK      GENMASK(7, 6)
+#define TI_AM6_EEPROM_DDR_CTRL_IF_DATA_WIDTH_16                (0 << 6)
+#define TI_AM6_EEPROM_DDR_CTRL_IF_DATA_WIDTH_32                (1 << 6)
+#define TI_AM6_EEPROM_DDR_CTRL_IF_DATA_WIDTH_64                (2 << 6)
+#define TI_AM6_EEPROM_DDR_CTRL_DEV_DATA_WIDTH_MASK     GENMASK(9, 8)
+#define TI_AM6_EEPROM_DDR_CTRL_DEV_DATA_WIDTH_8                (0 << 8)
+#define TI_AM6_EEPROM_DDR_CTRL_DEV_DATA_WIDTH_16       (1 << 8)
+#define TI_AM6_EEPROM_DDR_CTRL_DEV_DATA_WIDTH_32       (2 << 8)
+#define TI_AM6_EEPROM_DDR_CTRL_RANKS_2                 BIT(10)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_MASK               GENMASK(13, 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_1GB                        (0 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_2GB                        (1 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_4GB                        (2 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_8GB                        (3 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_12GB               (4 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_16GB               (5 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_24GB               (6 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_DENS_32GB               (7 << 11)
+#define TI_AM6_EEPROM_DDR_CTRL_ECC                     BIT(14)
+
+struct ti_am6_eeprom_record_ddr_info {
+       u16 ddr_control;
+} __attribute__ ((__packed__));
+
+/* AM6x TI EVM EEPROM DDR SPD structure */
+#define TI_AM6_EEPROM_DDR_SPD_INSTANCE_MASK            GENMASK(1, 0)
+#define TI_AM6_EEPROM_DDR_SPD_INSTANCE_SHIFT           0
+#define TI_AM6_EEPROM_DDR_SPD_MEM_TYPE_MASK            GENMASK(4, 3)
+#define TI_AM6_EEPROM_DDR_SPD_MEM_TYPE_DDR3            (0 << 3)
+#define TI_AM6_EEPROM_DDR_SPD_MEM_TYPE_DDR4            (1 << 3)
+#define TI_AM6_EEPROM_DDR_SPD_MEM_TYPE_LPDDR4          (2 << 3)
+#define TI_AM6_EEPROM_DDR_SPD_DATA_LEN                 512
+
+struct ti_am6_eeprom_record_ddr_spd {
+       u16 spd_control;
+       u8 data[TI_AM6_EEPROM_DDR_SPD_DATA_LEN];
+} __attribute__ ((__packed__));
+
+/* AM6x TI EVM EEPROM MAC info structure */
+#define TI_AM6_EEPROM_MAC_INFO_INSTANCE_MASK           GENMASK(2, 0)
+#define TI_AM6_EEPROM_MAC_INFO_INSTANCE_SHIFT          0
+#define TI_AM6_EEPROM_MAC_ADDR_COUNT_MASK              GENMASK(7, 3)
+#define TI_AM6_EEPROM_MAC_ADDR_COUNT_SHIFT             3
+#define TI_AM6_EEPROM_MAC_ADDR_MAX_COUNT               32
+
+struct ti_am6_eeprom_record_mac_info {
+       u16 mac_control;
+       u8 mac_addr[TI_AM6_EEPROM_MAC_ADDR_MAX_COUNT][TI_EEPROM_HDR_ETH_ALEN];
+} __attribute__ ((__packed__));
+
+struct ti_am6_eeprom_record {
+       struct ti_am6_eeprom_record_header header;
+       union {
+               struct ti_am6_eeprom_record_board_info board_info;
+               struct ti_am6_eeprom_record_ddr_info ddr_info;
+               struct ti_am6_eeprom_record_ddr_spd ddr_spd;
+               struct ti_am6_eeprom_record_mac_info mac_info;
+       } data;
+} __attribute__ ((__packed__));
+
 /* DRA7 EEPROM MAGIC Header identifier */
 #define DRA7_EEPROM_HEADER_MAGIC       0xAA5533EE
 #define DRA7_EEPROM_HDR_NAME_LEN       16
@@ -99,6 +226,37 @@ struct ti_common_eeprom {
 #define TI_EEPROM_DATA ((struct ti_common_eeprom *)\
                                TI_SRAM_SCRATCH_BOARD_EEPROM_START)
 
+/*
+ * Maximum number of Ethernet MAC addresses extracted from the AM6x on-board
+ * EEPROM during the initial probe and carried forward in SRAM.
+ */
+#define AM6_EEPROM_HDR_NO_OF_MAC_ADDR  8
+
+/**
+ * struct ti_am6_eeprom - Null terminated, usable EEPROM contents, as extracted
+ *     from the AM6 on-board EEPROM. Note that we only carry a subset of data
+ *     at this time to be considerate about memory consumption.
+ * @header:            Magic number for data validity indication
+ * @name:              NULL terminated name
+ * @version:           NULL terminated version
+ * @software_revision: NULL terminated software revision
+ * @serial:            Board serial number
+ * @mac_addr_cnt:      Number of MAC addresses stored in this object
+ * @mac_addr:          MAC addresses
+ */
+struct ti_am6_eeprom {
+       u32 header;
+       char name[AM6_EEPROM_HDR_NAME_LEN + 1];
+       char version[AM6_EEPROM_HDR_VERSION_LEN + 1];
+       char software_revision[AM6_EEPROM_HDR_SW_REV_LEN + 1];
+       char serial[AM6_EEPROM_HDR_SERIAL_LEN + 1];
+       u8 mac_addr_cnt;
+       char mac_addr[AM6_EEPROM_HDR_NO_OF_MAC_ADDR][TI_EEPROM_HDR_ETH_ALEN];
+};
+
+#define TI_AM6_EEPROM_DATA ((struct ti_am6_eeprom *) \
+                               TI_SRAM_SCRATCH_BOARD_EEPROM_START)
+
 /**
  * ti_i2c_eeprom_am_get() - Consolidated eeprom data collection for AM* TI EVMs
  * @bus_addr:  I2C bus address
@@ -116,6 +274,33 @@ int ti_i2c_eeprom_am_get(int bus_addr, int dev_addr);
  */
 int ti_i2c_eeprom_dra7_get(int bus_addr, int dev_addr);
 
+/**
+ * ti_i2c_eeprom_am6_get() - Consolidated eeprom data for AM6x TI EVMs and
+ *                          associated daughter cards, parsed into user-
+ *                          provided data structures
+ * @bus_addr:  I2C bus address
+ * @dev_addr:  I2C slave address
+ * @ep:                Pointer to structure receiving AM6-specific header data
+ * @mac_addr:  Pointer to memory receiving parsed MAC addresses. May be
+ *             NULL to skip MAC parsing.
+ * @mac_addr_max_cnt: Maximum number of MAC addresses that can be stored into
+ *                   mac_addr. May be NULL to skip MAC parsing.
+ * @mac_addr_cnt: Pointer to a location returning how many MAC addressed got
+ *               actually parsed.
+ */
+int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr,
+                                        struct ti_am6_eeprom *ep,
+                                        char **mac_addr,
+                                        u8 mac_addr_max_cnt,
+                                        u8 *mac_addr_cnt);
+
+/**
+ * ti_i2c_eeprom_am6_get_base() - Consolidated eeprom data for AM6x TI EVMs
+ * @bus_addr:  I2C bus address
+ * @dev_addr:  I2C slave address
+ */
+int __maybe_unused ti_i2c_eeprom_am6_get_base(int bus_addr, int dev_addr);
+
 /**
  * board_ti_is() - Board detection logic for TI EVMs
  * @name_tag:  Tag used in eeprom for the board
@@ -192,6 +377,15 @@ u64 board_ti_get_emif2_size(void);
  */
 void set_board_info_env(char *name);
 
+/**
+ * set_board_info_env_am6() - Setup commonly used board information environment
+ *                           vars for AM6-type boards
+ * @name:      Name of the board
+ *
+ * If name is NULL, default_name is used.
+ */
+void set_board_info_env_am6(char *name);
+
 /**
  * board_ti_set_ethaddr- Sets the ethaddr environment from EEPROM
  * @index: The first eth<index>addr environment variable to set
@@ -204,6 +398,18 @@ void set_board_info_env(char *name);
  */
 void board_ti_set_ethaddr(int index);
 
+/**
+ * board_ti_am6_set_ethaddr- Sets the ethaddr environment from EEPROM
+ * @index: The first eth<index>addr environment variable to set
+ * @count: The number of MAC addresses to process
+ *
+ * EEPROM should be already read before calling this function. The EEPROM
+ * contains n dedicated MAC addresses. This function sets the ethaddr
+ * environment variable for all the available MAC addresses starting
+ * from eth<index>addr.
+ */
+void board_ti_am6_set_ethaddr(int index, int count);
+
 /**
  * board_ti_was_eeprom_read() - Check to see if the eeprom contents have been read
  *
index 7122c069b2d218bcbef171541e9d46c0f58a1bb3..5978fb2934325e474de2bab0f21926c834ce1487 100644 (file)
@@ -248,6 +248,16 @@ config TPL_BANNER_PRINT
          info. Disabling this option could be useful to reduce SPL boot time
          (e.g. approx. 6 ms faster, when output on i.MX6 with 115200 baud).
 
+config SPL_EARLY_BSS
+       depends on ARM && !ARM64
+       bool "Allows initializing BSS early before entering board_init_f"
+       help
+         On some platform we have sufficient memory available early on to
+         allow setting up and using a basic BSS prior to entering
+         board_init_f. Activating this option will also de-activate the
+         clearing of BSS during the SPL relocation process, thus allowing
+         to carry state from board_init_f to board_init_r by way of BSS.
+
 config SPL_DISPLAY_PRINT
        bool "Display a board-specific message in SPL"
        help
index 87ecf0bb9e5046f0edfffcec5146d107d469701e..969f7775c18f5fcd65d1ea3c07caaa297bc862f5 100644 (file)
@@ -340,6 +340,16 @@ static int spl_fit_image_get_os(const void *fit, int noffset, uint8_t *os)
 #endif
 }
 
+/*
+ * Weak default function to allow customizing SPL fit loading for load-only
+ * use cases by allowing to skip the parsing/processing of the FIT contents
+ * (so that this can be done separately in a more customized fashion)
+ */
+__weak bool spl_load_simple_fit_skip_processing(void)
+{
+       return false;
+}
+
 int spl_load_simple_fit(struct spl_image_info *spl_image,
                        struct spl_load_info *info, ulong sector, void *fit)
 {
@@ -389,6 +399,10 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
        if (count == 0)
                return -EIO;
 
+       /* skip further processing if requested to enable load-only use cases */
+       if (spl_load_simple_fit_skip_processing())
+               return 0;
+
        /* find the node holding the images information */
        images = fdt_path_offset(fit, FIT_IMAGES_PATH);
        if (images < 0) {
index 324d91c88404b6e86d4e58f5ee0b77c8e00300b4..b3619889f794bdb714beeb85965bcf27af7fcf0d 100644 (file)
@@ -151,7 +151,8 @@ static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
 
 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
 static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
-                                       struct mmc *mmc, int partition)
+                                       struct mmc *mmc, int partition,
+                                       unsigned long sector)
 {
        disk_partition_t info;
        int err;
@@ -180,8 +181,7 @@ static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
        }
 
 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
-       return mmc_load_image_raw_sector(spl_image, mmc,
-                       info.start + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
+       return mmc_load_image_raw_sector(spl_image, mmc, info.start + sector);
 #else
        return mmc_load_image_raw_sector(spl_image, mmc, info.start);
 #endif
@@ -234,7 +234,8 @@ static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
 #endif
 
 #ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION
-static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc)
+static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc,
+                             const char *filename)
 {
        int err = -ENOSYS;
 
@@ -248,7 +249,7 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc)
 #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
        err = spl_load_image_fat(spl_image, mmc_get_blk_desc(mmc),
                                 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
-                                CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
+                                filename);
        if (!err)
                return err;
 #endif
@@ -263,7 +264,7 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc)
 #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
        err = spl_load_image_ext(spl_image, mmc_get_blk_desc(mmc),
                                 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
-                                CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
+                                filename);
        if (!err)
                return err;
 #endif
@@ -276,7 +277,8 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc)
        return err;
 }
 #else
-static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc)
+static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc,
+                             const char *filename)
 {
        return -ENOSYS;
 }
@@ -301,24 +303,31 @@ int spl_boot_partition(const u32 boot_device)
 }
 #endif
 
-int spl_mmc_load_image(struct spl_image_info *spl_image,
-                      struct spl_boot_device *bootdev)
+int spl_mmc_load(struct spl_image_info *spl_image,
+                struct spl_boot_device *bootdev,
+                const char *filename,
+                int raw_part,
+                unsigned long raw_sect)
 {
-       struct mmc *mmc = NULL;
+       static struct mmc *mmc;
        u32 boot_mode;
        int err = 0;
        __maybe_unused int part;
 
-       err = spl_mmc_find_device(&mmc, bootdev->boot_device);
-       if (err)
-               return err;
+       /* Perform peripheral init only once */
+       if (!mmc) {
+               err = spl_mmc_find_device(&mmc, bootdev->boot_device);
+               if (err)
+                       return err;
 
-       err = mmc_init(mmc);
-       if (err) {
+               err = mmc_init(mmc);
+               if (err) {
+                       mmc = NULL;
 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
-               printf("spl: mmc init failed with error: %d\n", err);
+                       printf("spl: mmc init failed with error: %d\n", err);
 #endif
-               return err;
+                       return err;
+               }
        }
 
        boot_mode = spl_boot_mode(bootdev->boot_device);
@@ -356,17 +365,13 @@ int spl_mmc_load_image(struct spl_image_info *spl_image,
                                return err;
                }
 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
-               err = spl_boot_partition(bootdev->boot_device);
-               if (!err)
-                       return err;
-
-               err = mmc_load_image_raw_partition(spl_image, mmc, err);
+               err = mmc_load_image_raw_partition(spl_image, mmc, raw_part,
+                                                  raw_sect);
                if (!err)
                        return err;
 #endif
 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
-               err = mmc_load_image_raw_sector(spl_image, mmc,
-                       CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
+               err = mmc_load_image_raw_sector(spl_image, mmc, raw_sect);
                if (!err)
                        return err;
 #endif
@@ -374,7 +379,7 @@ int spl_mmc_load_image(struct spl_image_info *spl_image,
        case MMCSD_MODE_FS:
                debug("spl: mmc boot mode: fs\n");
 
-               err = spl_mmc_do_fs_boot(spl_image, mmc);
+               err = spl_mmc_do_fs_boot(spl_image, mmc, filename);
                if (!err)
                        return err;
 
@@ -388,6 +393,27 @@ int spl_mmc_load_image(struct spl_image_info *spl_image,
        return err;
 }
 
+int spl_mmc_load_image(struct spl_image_info *spl_image,
+                      struct spl_boot_device *bootdev)
+{
+       return spl_mmc_load(spl_image, bootdev,
+#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
+                           CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
+#else
+                           NULL,
+#endif
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
+                           spl_boot_partition(bootdev->boot_device),
+#else
+                           0,
+#endif
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
+                           CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
+#else
+                           0);
+#endif
+}
+
 SPL_LOAD_IMAGE_METHOD("MMC1", 0, BOOT_DEVICE_MMC1, spl_mmc_load_image);
 SPL_LOAD_IMAGE_METHOD("MMC2", 0, BOOT_DEVICE_MMC2, spl_mmc_load_image);
 SPL_LOAD_IMAGE_METHOD("MMC2_2", 0, BOOT_DEVICE_MMC2_2, spl_mmc_load_image);
index ffe013fa2df7d7b136c66fb523e9e67764ac7d81..9ccbd682412b27989c886d1f2d38e28010d413c5 100644 (file)
@@ -1,4 +1,8 @@
 CONFIG_ARM=y
+# CONFIG_SPL_USE_ARCH_MEMCPY is not set
+# CONFIG_TPL_USE_ARCH_MEMCPY is not set
+# CONFIG_SPL_USE_ARCH_MEMSET is not set
+# CONFIG_TPL_USE_ARCH_MEMSET is not set
 CONFIG_ARCH_OMAP2PLUS=y
 CONFIG_TI_COMMON_CMD_OPTIONS=y
 CONFIG_AM33XX=y
index b940af3f56164b372b2784118b4a204a7dc39351..9d4c6a205cec19b1e5e26760a345e560a3ff069d 100644 (file)
@@ -2,7 +2,7 @@ CONFIG_ARM=y
 CONFIG_ARCH_K3=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SOC_K3_AM6=y
 CONFIG_TARGET_AM654_A53_EVM=y
 CONFIG_SPL_MMC_SUPPORT=y
@@ -16,12 +16,14 @@ CONFIG_DISTRO_DEFAULTS=y
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_OF_BOARD_SETUP=y
-CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_kern_${boot}; run get_fdt_${boot}; run run_kern"
+CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern"
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_TEXT_BASE=0x80080000
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
@@ -30,35 +32,41 @@ CONFIG_SPL_REMOTEPROC=y
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_REMOTEPROC=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_TIME=y
 # CONFIG_ISO_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
 CONFIG_OF_CONTROL=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_DEFAULT_DEVICE_TREE="k3-am654-base-board"
 CONFIG_SPL_MULTI_DTB_FIT=y
 CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y
-CONFIG_ENV_IS_IN_FAT=y
-CONFIG_ENV_FAT_INTERFACE="mmc"
-CONFIG_ENV_FAT_DEVICE_AND_PART="1:1"
+CONFIG_ENV_IS_IN_MMC=y
 CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
 CONFIG_CLK_TI_SCI=y
 CONFIG_DMA_CHANNELS=y
 CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_PCA953X=y
+CONFIG_DM_I2C=y
+CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
+CONFIG_SYS_I2C_OMAP24XX=y
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_K3_ARASAN=y
+CONFIG_MMC_SDHCI_AM654=y
 CONFIG_PHY_TI=y
 CONFIG_PHY_FIXED=y
 CONFIG_DM_ETH=y
@@ -80,3 +88,5 @@ CONFIG_SOC_TI=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_SYSRESET_TI_SCI=y
+CONFIG_FAT_WRITE=y
+CONFIG_OF_LIBFDT_OVERLAY=y
index 3814872ec7a18b9e6366ff33d152f426a5229915..7e81a98454d599adc1851b55d3e9e19a6938fc6e 100644 (file)
@@ -3,7 +3,7 @@ CONFIG_ARCH_K3=y
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_MALLOC_F_LEN=0x55000
 CONFIG_SOC_K3_AM6=y
 CONFIG_TARGET_AM654_R5_EVM=y
 CONFIG_SPL_MMC_SUPPORT=y
@@ -18,9 +18,11 @@ CONFIG_SPL_LOAD_FIT=y
 CONFIG_USE_BOOTCOMMAND=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_TEXT_BASE=0x41c00000
-CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SPL_EARLY_BSS=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
@@ -35,6 +37,7 @@ CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_REMOTEPROC=y
 # CONFIG_CMD_SETEXPR is not set
@@ -51,6 +54,8 @@ CONFIG_ENV_FAT_DEVICE_AND_PART="1:1"
 CONFIG_DM=y
 CONFIG_SPL_DM=y
 CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_REGMAP=y
+CONFIG_SPL_REGMAP=y
 CONFIG_SPL_OF_TRANSLATE=y
 CONFIG_CLK=y
 CONFIG_SPL_CLK=y
@@ -58,12 +63,15 @@ CONFIG_CLK_TI_SCI=y
 CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_DM_GPIO=y
 CONFIG_DA8XX_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
+CONFIG_SYS_I2C_OMAP24XX=y
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
 CONFIG_MISC=y
 CONFIG_DM_MMC=y
 CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_K3_ARASAN=y
+CONFIG_MMC_SDHCI_AM654=y
 CONFIG_PINCTRL=y
 # CONFIG_PINCTRL_GENERIC is not set
 CONFIG_SPL_PINCTRL=y
@@ -88,3 +96,4 @@ CONFIG_SYSRESET_TI_SCI=y
 CONFIG_TIMER=y
 CONFIG_SPL_TIMER=y
 CONFIG_OMAP_TIMER=y
+CONFIG_FS_FAT_MAX_CLUSTSIZE=16384
index 9c55cd37f65ef9fe88140320450a22b6ad3f8b7f..56052f73f38d83db503a99194eb7f399002dd301 100644 (file)
@@ -3,7 +3,7 @@ CONFIG_ARCH_K3=y
 CONFIG_TI_SECURE_DEVICE=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_MALLOC_F_LEN=0x8000
 CONFIG_SOC_K3_AM6=y
 CONFIG_TARGET_AM654_A53_EVM=y
 CONFIG_SPL_MMC_SUPPORT=y
@@ -19,12 +19,14 @@ CONFIG_FIT_IMAGE_POST_PROCESS=y
 CONFIG_SPL_LOAD_FIT=y
 CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
 CONFIG_OF_BOARD_SETUP=y
-CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_kern_${boot}; run get_fdt_${boot}; run run_kern"
+CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern"
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_TEXT_BASE=0x80080000
 CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
@@ -33,6 +35,7 @@ CONFIG_SPL_REMOTEPROC=y
 CONFIG_SPL_YMODEM_SUPPORT=y
 CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
+CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_REMOTEPROC=y
 # CONFIG_CMD_SETEXPR is not set
@@ -56,6 +59,11 @@ CONFIG_CLK_TI_SCI=y
 CONFIG_DMA_CHANNELS=y
 CONFIG_TI_K3_NAVSS_UDMA=y
 CONFIG_TI_SCI_PROTOCOL=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_PCA953X=y
+CONFIG_DM_I2C=y
+CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
+CONFIG_SYS_I2C_OMAP24XX=y
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
 CONFIG_DM_MMC=y
@@ -77,3 +85,4 @@ CONFIG_SOC_TI=y
 CONFIG_SYSRESET=y
 CONFIG_SPL_SYSRESET=y
 CONFIG_SYSRESET_TI_SCI=y
+CONFIG_OF_LIBFDT_OVERLAY=y
index 0b12f15782ef9c6d25d30105c74ab70781bf8b19..d378d1e9ee8a5c867a51ca44429c2910d4cc050d 100644 (file)
@@ -4,7 +4,7 @@ CONFIG_TI_SECURE_DEVICE=y
 CONFIG_SPL_GPIO_SUPPORT=y
 CONFIG_SPL_LIBCOMMON_SUPPORT=y
 CONFIG_SPL_LIBGENERIC_SUPPORT=y
-CONFIG_SYS_MALLOC_F_LEN=0x2000
+CONFIG_SYS_MALLOC_F_LEN=0x55000
 CONFIG_SOC_K3_AM6=y
 CONFIG_TARGET_AM654_R5_EVM=y
 CONFIG_SPL_MMC_SUPPORT=y
@@ -20,9 +20,11 @@ CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
 CONFIG_USE_BOOTCOMMAND=y
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_SPL_TEXT_BASE=0x41c00000
-CONFIG_SPL_SYS_MALLOC_SIMPLE=y
 CONFIG_SPL_STACK_R=y
 CONFIG_SPL_SEPARATE_BSS=y
+CONFIG_SPL_EARLY_BSS=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
+CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400
 CONFIG_SPL_I2C_SUPPORT=y
 CONFIG_SPL_DM_MAILBOX=y
 CONFIG_SPL_DM_RESET=y
@@ -37,6 +39,7 @@ CONFIG_CMD_BOOTZ=y
 CONFIG_CMD_ASKENV=y
 # CONFIG_CMD_FLASH is not set
 CONFIG_CMD_GPT=y
+CONFIG_CMD_I2C=y
 CONFIG_CMD_MMC=y
 CONFIG_CMD_REMOTEPROC=y
 # CONFIG_CMD_SETEXPR is not set
@@ -60,6 +63,9 @@ CONFIG_CLK_TI_SCI=y
 CONFIG_TI_SCI_PROTOCOL=y
 CONFIG_DM_GPIO=y
 CONFIG_DA8XX_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
+CONFIG_SYS_I2C_OMAP24XX=y
 CONFIG_DM_MAILBOX=y
 CONFIG_K3_SEC_PROXY=y
 CONFIG_MISC=y
@@ -90,3 +96,4 @@ CONFIG_SYSRESET_TI_SCI=y
 CONFIG_TIMER=y
 CONFIG_SPL_TIMER=y
 CONFIG_OMAP_TIMER=y
+CONFIG_FS_FAT_MAX_CLUSTSIZE=16384
index b73da72b1654fa44f40f9570495be9a01ee4e942..59d41cb5687b3966bd2c7adb5dcf096b5fb39f75 100644 (file)
@@ -11,16 +11,19 @@ CONFIG_BOOTARGS="console=ttyS4,115200n8 root=/dev/ram rw"
 CONFIG_PRE_CONSOLE_BUFFER=y
 CONFIG_PRE_CON_BUF_ADDR=0x1e720000
 # CONFIG_DISPLAY_CPUINFO is not set
+CONFIG_HUSH_PARSER=y
 # CONFIG_AUTO_COMPLETE is not set
 CONFIG_CMD_I2C=y
 CONFIG_CMD_DHCP=y
 CONFIG_CMD_MII=y
 CONFIG_CMD_PING=y
 CONFIG_DEFAULT_DEVICE_TREE="ast2500-evb"
+CONFIG_NET_RANDOM_ETHADDR=y
 CONFIG_REGMAP=y
 CONFIG_CLK=y
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_ASPEED=y
+# CONFIG_MMC is not set
 CONFIG_PHY_REALTEK=y
 CONFIG_DM_ETH=y
 CONFIG_FTGMAC100=y
index 5ef0f71c8b7d2d07f2884ea9f84215c683c66225..d1d12eef385f5757bd327cb01d2027bbe3bfb662 100644 (file)
@@ -108,6 +108,48 @@ static int init_range(ofnode node, struct regmap_range *range, int addr_len,
        return 0;
 }
 
+int regmap_init_mem_index(ofnode node, struct regmap **mapp, int index)
+{
+       struct regmap *map;
+       int addr_len, size_len;
+       int ret;
+
+       addr_len = ofnode_read_simple_addr_cells(ofnode_get_parent(node));
+       if (addr_len < 0) {
+               debug("%s: Error while reading the addr length (ret = %d)\n",
+                     ofnode_get_name(node), addr_len);
+               return addr_len;
+       }
+
+       size_len = ofnode_read_simple_size_cells(ofnode_get_parent(node));
+       if (size_len < 0) {
+               debug("%s: Error while reading the size length: (ret = %d)\n",
+                     ofnode_get_name(node), size_len);
+               return size_len;
+       }
+
+       map = regmap_alloc(1);
+       if (!map)
+               return -ENOMEM;
+
+       ret = init_range(node, map->ranges, addr_len, size_len, index);
+       if (ret)
+               return ret;
+
+       if (ofnode_read_bool(node, "little-endian"))
+               map->endianness = REGMAP_LITTLE_ENDIAN;
+       else if (ofnode_read_bool(node, "big-endian"))
+               map->endianness = REGMAP_BIG_ENDIAN;
+       else if (ofnode_read_bool(node, "native-endian"))
+               map->endianness = REGMAP_NATIVE_ENDIAN;
+       else /* Default: native endianness */
+               map->endianness = REGMAP_NATIVE_ENDIAN;
+
+       *mapp = map;
+
+       return ret;
+}
+
 int regmap_init_mem(ofnode node, struct regmap **mapp)
 {
        struct regmap_range *range;
index 095a9bc6a4d1a00fe3f53b6667ab72979bbd0829..4772db383722354b38ec679206df5dcdf6049517 100644 (file)
@@ -330,7 +330,7 @@ endif
 
 config SYS_I2C_OMAP24XX
        bool "TI OMAP2+ I2C driver"
-       depends on ARCH_OMAP2PLUS
+       depends on ARCH_OMAP2PLUS || ARCH_K3
        help
          Add support for the OMAP2+ I2C driver.
 
index 890ef358a004aa56c93f7abe26e195a17dbe2a10..4cdae41b59a6956e990d8e2259da03a0db6c04c4 100644 (file)
@@ -468,14 +468,15 @@ config MMC_SDHCI_CADENCE
 
          If unsure, say N.
 
-config MMC_SDHCI_K3_ARASAN
-       bool "Arasan SDHCI controller for TI's K3 based SoCs"
+config MMC_SDHCI_AM654
+       bool "SDHCI Controller on TI's Am654 devices"
        depends on ARCH_K3
        depends on MMC_SDHCI
        depends on DM_MMC && OF_CONTROL && BLK
+       depends on REGMAP
        help
-         Support for Arasan SDHCI host controller on Texas Instruments'
-         K3 family based SoC platforms
+         Support for Secure Digital Host Controller Interface (SDHCI)
+         controllers present on TI's AM654 SOCs.
 
 config MMC_SDHCI_KONA
        bool "SDHCI support on Broadcom KONA platform"
index 3c8c53a9e16121a0514fffe4c5f0ef3d52d334b5..6cc018bb6726cfef67d51444fa6a4ec8e2303cdf 100644 (file)
@@ -50,7 +50,7 @@ obj-$(CONFIG_MMC_SDHCI_ATMEL)         += atmel_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_BCM2835)                += bcm2835_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_BCMSTB)         += bcmstb_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_CADENCE)                += sdhci-cadence.o
-obj-$(CONFIG_MMC_SDHCI_K3_ARASAN)      += k3_arsan_sdhci.o
+obj-$(CONFIG_MMC_SDHCI_AM654)          += am654_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_KONA)           += kona_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_MSM)            += msm_sdhci.o
 obj-$(CONFIG_MMC_SDHCI_MV)             += mv_sdhci.o
diff --git a/drivers/mmc/am654_sdhci.c b/drivers/mmc/am654_sdhci.c
new file mode 100644 (file)
index 0000000..fb0fb58
--- /dev/null
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * Texas Instruments' K3 SD Host Controller Interface
+ */
+
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <malloc.h>
+#include <power-domain.h>
+#include <regmap.h>
+#include <sdhci.h>
+
+/* CTL_CFG Registers */
+#define CTL_CFG_2              0x14
+
+#define SLOTTYPE_MASK          GENMASK(31, 30)
+#define SLOTTYPE_EMBEDDED      BIT(30)
+
+/* PHY Registers */
+#define PHY_CTRL1      0x100
+#define PHY_CTRL2      0x104
+#define PHY_CTRL3      0x108
+#define PHY_CTRL4      0x10C
+#define PHY_CTRL5      0x110
+#define PHY_CTRL6      0x114
+#define PHY_STAT1      0x130
+#define PHY_STAT2      0x134
+
+#define IOMUX_ENABLE_SHIFT     31
+#define IOMUX_ENABLE_MASK      BIT(IOMUX_ENABLE_SHIFT)
+#define OTAPDLYENA_SHIFT       20
+#define OTAPDLYENA_MASK                BIT(OTAPDLYENA_SHIFT)
+#define OTAPDLYSEL_SHIFT       12
+#define OTAPDLYSEL_MASK                GENMASK(15, 12)
+#define STRBSEL_SHIFT          24
+#define STRBSEL_MASK           GENMASK(27, 24)
+#define SEL50_SHIFT            8
+#define SEL50_MASK             BIT(SEL50_SHIFT)
+#define SEL100_SHIFT           9
+#define SEL100_MASK            BIT(SEL100_SHIFT)
+#define DLL_TRIM_ICP_SHIFT     4
+#define DLL_TRIM_ICP_MASK      GENMASK(7, 4)
+#define DR_TY_SHIFT            20
+#define DR_TY_MASK             GENMASK(22, 20)
+#define ENDLL_SHIFT            1
+#define ENDLL_MASK             BIT(ENDLL_SHIFT)
+#define DLLRDY_SHIFT           0
+#define DLLRDY_MASK            BIT(DLLRDY_SHIFT)
+#define PDB_SHIFT              0
+#define PDB_MASK               BIT(PDB_SHIFT)
+#define CALDONE_SHIFT          1
+#define CALDONE_MASK           BIT(CALDONE_SHIFT)
+#define RETRIM_SHIFT           17
+#define RETRIM_MASK            BIT(RETRIM_SHIFT)
+
+#define DRIVER_STRENGTH_50_OHM 0x0
+#define DRIVER_STRENGTH_33_OHM 0x1
+#define DRIVER_STRENGTH_66_OHM 0x2
+#define DRIVER_STRENGTH_100_OHM        0x3
+#define DRIVER_STRENGTH_40_OHM 0x4
+
+#define AM654_SDHCI_MIN_FREQ   400000
+
+struct am654_sdhci_plat {
+       struct mmc_config cfg;
+       struct mmc mmc;
+       struct regmap *base;
+       bool non_removable;
+       u32 otap_del_sel;
+       u32 trm_icp;
+       u32 drv_strength;
+       bool dll_on;
+};
+
+static void am654_sdhci_set_control_reg(struct sdhci_host *host)
+{
+       struct mmc *mmc = (struct mmc *)host->mmc;
+       u32 reg;
+
+       if (IS_SD(host->mmc) &&
+           mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
+               reg = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+               reg |= SDHCI_CTRL_VDD_180;
+               sdhci_writew(host, reg, SDHCI_HOST_CONTROL2);
+       }
+
+       sdhci_set_uhs_timing(host);
+}
+
+static int am654_sdhci_set_ios_post(struct sdhci_host *host)
+{
+       struct udevice *dev = host->mmc->dev;
+       struct am654_sdhci_plat *plat = dev_get_platdata(dev);
+       unsigned int speed = host->mmc->clock;
+       int sel50, sel100;
+       u32 mask, val;
+       int ret;
+
+       /* Reset SD Clock Enable */
+       val = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+       val &= ~SDHCI_CLOCK_CARD_EN;
+       sdhci_writew(host, val, SDHCI_CLOCK_CONTROL);
+
+       /* power off phy */
+       if (plat->dll_on) {
+               regmap_update_bits(plat->base, PHY_CTRL1, ENDLL_MASK, 0);
+
+               plat->dll_on = false;
+       }
+
+       /* restart clock */
+       sdhci_set_clock(host->mmc, speed);
+
+       /* switch phy back on */
+       if (speed > AM654_SDHCI_MIN_FREQ) {
+               mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
+               val = (1 << OTAPDLYENA_SHIFT) |
+                     (plat->otap_del_sel << OTAPDLYSEL_SHIFT);
+               regmap_update_bits(plat->base, PHY_CTRL4, mask, val);
+               switch (speed) {
+               case 200000000:
+                       sel50 = 0;
+                       sel100 = 0;
+                       break;
+               case 100000000:
+                       sel50 = 0;
+                       sel100 = 1;
+                       break;
+               default:
+                       sel50 = 1;
+                       sel100 = 0;
+               }
+
+               /* Configure PHY DLL frequency */
+               mask = SEL50_MASK | SEL100_MASK;
+               val = (sel50 << SEL50_SHIFT) | (sel100 << SEL100_SHIFT);
+               regmap_update_bits(plat->base, PHY_CTRL5, mask, val);
+
+               /* Enable DLL */
+               regmap_update_bits(plat->base, PHY_CTRL1, ENDLL_MASK,
+                                  0x1 << ENDLL_SHIFT);
+               /*
+                * Poll for DLL ready. Use a one second timeout.
+                * Works in all experiments done so far
+                */
+               ret = regmap_read_poll_timeout(plat->base, PHY_STAT1, val,
+                                        val & DLLRDY_MASK, 1000, 1000000);
+               if (ret)
+                       return ret;
+
+               plat->dll_on = true;
+       }
+
+       return 0;
+}
+
+const struct sdhci_ops am654_sdhci_ops = {
+       .set_ios_post           = &am654_sdhci_set_ios_post,
+       .set_control_reg        = &am654_sdhci_set_control_reg,
+};
+
+int am654_sdhci_init(struct am654_sdhci_plat *plat)
+{
+       u32 ctl_cfg_2 = 0;
+       u32 mask, val;
+       int ret;
+
+       /* Reset OTAP to default value */
+       mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK;
+       regmap_update_bits(plat->base, PHY_CTRL4, mask, 0x0);
+
+       regmap_read(plat->base, PHY_STAT1, &val);
+       if (~val & CALDONE_MASK) {
+               /* Calibrate IO lines */
+               regmap_update_bits(plat->base, PHY_CTRL1, PDB_MASK, PDB_MASK);
+               ret = regmap_read_poll_timeout(plat->base, PHY_STAT1, val,
+                                              val & CALDONE_MASK, 1, 20);
+               if (ret)
+                       return ret;
+       }
+
+       /* Configure DLL TRIM */
+       mask = DLL_TRIM_ICP_MASK;
+       val = plat->trm_icp << DLL_TRIM_ICP_SHIFT;
+
+       /* Configure DLL driver strength */
+       mask |= DR_TY_MASK;
+       val |= plat->drv_strength << DR_TY_SHIFT;
+       regmap_update_bits(plat->base, PHY_CTRL1, mask, val);
+
+       /* Enable pins by setting IO mux to 0 */
+       regmap_update_bits(plat->base, PHY_CTRL1, IOMUX_ENABLE_MASK, 0);
+
+       /* Set slot type based on SD or eMMC */
+       if (plat->non_removable)
+               ctl_cfg_2 = SLOTTYPE_EMBEDDED;
+
+       regmap_update_bits(plat->base, CTL_CFG_2, SLOTTYPE_MASK, ctl_cfg_2);
+
+       return 0;
+}
+
+static int am654_sdhci_probe(struct udevice *dev)
+{
+       struct am654_sdhci_plat *plat = dev_get_platdata(dev);
+       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+       struct sdhci_host *host = dev_get_priv(dev);
+       struct mmc_config *cfg = &plat->cfg;
+       struct power_domain sdhci_pwrdmn;
+       struct clk clk;
+       unsigned long clock;
+       int ret;
+
+       ret = power_domain_get_by_index(dev, &sdhci_pwrdmn, 0);
+       if (!ret) {
+               ret = power_domain_on(&sdhci_pwrdmn);
+               if (ret) {
+                       dev_err(dev, "Power domain on failed (%d)\n", ret);
+                       return ret;
+               }
+       } else if (ret != -ENOENT && ret != -ENODEV && ret != -ENOSYS) {
+               dev_err(dev, "failed to get power domain (%d)\n", ret);
+               return ret;
+       }
+
+       ret = clk_get_by_index(dev, 0, &clk);
+       if (ret) {
+               dev_err(dev, "failed to get clock\n");
+               return ret;
+       }
+
+       clock = clk_get_rate(&clk);
+       if (IS_ERR_VALUE(clock)) {
+               dev_err(dev, "failed to get rate\n");
+               return clock;
+       }
+
+       host->max_clk = clock;
+       host->mmc = &plat->mmc;
+       host->mmc->dev = dev;
+       ret = sdhci_setup_cfg(cfg, host, cfg->f_max,
+                             AM654_SDHCI_MIN_FREQ);
+       if (ret)
+               return ret;
+       host->ops = &am654_sdhci_ops;
+       host->mmc->priv = host;
+       upriv->mmc = host->mmc;
+
+       regmap_init_mem_index(dev_ofnode(dev), &plat->base, 1);
+
+       am654_sdhci_init(plat);
+
+       return sdhci_probe(dev);
+}
+
+static int am654_sdhci_ofdata_to_platdata(struct udevice *dev)
+{
+       struct am654_sdhci_plat *plat = dev_get_platdata(dev);
+       struct sdhci_host *host = dev_get_priv(dev);
+       struct mmc_config *cfg = &plat->cfg;
+       u32 drv_strength;
+       int ret;
+
+       host->name = dev->name;
+       host->ioaddr = (void *)dev_read_addr(dev);
+       plat->non_removable = dev_read_bool(dev, "non-removable");
+
+       ret = dev_read_u32(dev, "ti,trm-icp", &plat->trm_icp);
+       if (ret)
+               return ret;
+
+       ret = dev_read_u32(dev, "ti,otap-del-sel", &plat->otap_del_sel);
+       if (ret)
+               return ret;
+
+       ret = dev_read_u32(dev, "ti,driver-strength-ohm", &drv_strength);
+       if (ret)
+               return ret;
+
+       switch (drv_strength) {
+       case 50:
+               plat->drv_strength = DRIVER_STRENGTH_50_OHM;
+               break;
+       case 33:
+               plat->drv_strength = DRIVER_STRENGTH_33_OHM;
+               break;
+       case 66:
+               plat->drv_strength = DRIVER_STRENGTH_66_OHM;
+               break;
+       case 100:
+               plat->drv_strength = DRIVER_STRENGTH_100_OHM;
+               break;
+       case 40:
+               plat->drv_strength = DRIVER_STRENGTH_40_OHM;
+               break;
+       default:
+               dev_err(dev, "Invalid driver strength\n");
+               return -EINVAL;
+       }
+
+       ret = mmc_of_parse(dev, cfg);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int am654_sdhci_bind(struct udevice *dev)
+{
+       struct am654_sdhci_plat *plat = dev_get_platdata(dev);
+
+       return sdhci_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static const struct udevice_id am654_sdhci_ids[] = {
+       { .compatible = "ti,am654-sdhci-5.1" },
+       { }
+};
+
+U_BOOT_DRIVER(am654_sdhci_drv) = {
+       .name           = "am654_sdhci",
+       .id             = UCLASS_MMC,
+       .of_match       = am654_sdhci_ids,
+       .ofdata_to_platdata = am654_sdhci_ofdata_to_platdata,
+       .ops            = &sdhci_ops,
+       .bind           = am654_sdhci_bind,
+       .probe          = am654_sdhci_probe,
+       .priv_auto_alloc_size = sizeof(struct sdhci_host),
+       .platdata_auto_alloc_size = sizeof(struct am654_sdhci_plat),
+};
diff --git a/drivers/mmc/k3_arsan_sdhci.c b/drivers/mmc/k3_arsan_sdhci.c
deleted file mode 100644 (file)
index d5f2857..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
- *
- * Texas Instruments' K3 SD Host Controller Interface
- */
-
-#include <clk.h>
-#include <common.h>
-#include <dm.h>
-#include <malloc.h>
-#include <power-domain.h>
-#include <sdhci.h>
-
-#define K3_ARASAN_SDHCI_MIN_FREQ       0
-
-struct k3_arasan_sdhci_plat {
-       struct mmc_config cfg;
-       struct mmc mmc;
-       unsigned int f_max;
-};
-
-static int k3_arasan_sdhci_probe(struct udevice *dev)
-{
-       struct k3_arasan_sdhci_plat *plat = dev_get_platdata(dev);
-       struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
-       struct sdhci_host *host = dev_get_priv(dev);
-       struct power_domain sdhci_pwrdmn;
-       struct clk clk;
-       unsigned long clock;
-       int ret;
-
-       ret = power_domain_get_by_index(dev, &sdhci_pwrdmn, 0);
-       if (ret) {
-               dev_err(dev, "failed to get power domain\n");
-               return ret;
-       }
-
-       ret = power_domain_on(&sdhci_pwrdmn);
-       if (ret) {
-               dev_err(dev, "Power domain on failed\n");
-               return ret;
-       }
-
-       ret = clk_get_by_index(dev, 0, &clk);
-       if (ret) {
-               dev_err(dev, "failed to get clock\n");
-               return ret;
-       }
-
-       clock = clk_get_rate(&clk);
-       if (IS_ERR_VALUE(clock)) {
-               dev_err(dev, "failed to get rate\n");
-               return clock;
-       }
-
-       host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
-                      SDHCI_QUIRK_BROKEN_R1B;
-
-       host->max_clk = clock;
-
-       ret = sdhci_setup_cfg(&plat->cfg, host, plat->f_max,
-                             K3_ARASAN_SDHCI_MIN_FREQ);
-       host->mmc = &plat->mmc;
-       if (ret)
-               return ret;
-       host->mmc->priv = host;
-       host->mmc->dev = dev;
-       upriv->mmc = host->mmc;
-
-       return sdhci_probe(dev);
-}
-
-static int k3_arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
-{
-       struct k3_arasan_sdhci_plat *plat = dev_get_platdata(dev);
-       struct sdhci_host *host = dev_get_priv(dev);
-
-       host->name = dev->name;
-       host->ioaddr = (void *)dev_read_addr(dev);
-       host->bus_width = dev_read_u32_default(dev, "bus-width", 4);
-       plat->f_max = dev_read_u32_default(dev, "max-frequency", 0);
-
-       return 0;
-}
-
-static int k3_arasan_sdhci_bind(struct udevice *dev)
-{
-       struct k3_arasan_sdhci_plat *plat = dev_get_platdata(dev);
-
-       return sdhci_bind(dev, &plat->mmc, &plat->cfg);
-}
-
-static const struct udevice_id k3_arasan_sdhci_ids[] = {
-       { .compatible = "arasan,sdhci-5.1" },
-       { }
-};
-
-U_BOOT_DRIVER(k3_arasan_sdhci_drv) = {
-       .name           = "k3_arasan_sdhci",
-       .id             = UCLASS_MMC,
-       .of_match       = k3_arasan_sdhci_ids,
-       .ofdata_to_platdata = k3_arasan_sdhci_ofdata_to_platdata,
-       .ops            = &sdhci_ops,
-       .bind           = k3_arasan_sdhci_bind,
-       .probe          = k3_arasan_sdhci_probe,
-       .priv_auto_alloc_size = sizeof(struct sdhci_host),
-       .platdata_auto_alloc_size = sizeof(struct k3_arasan_sdhci_plat),
-};
index c4e88790bc68e713c834871164ffa3a53114dc4f..0a0770cc2035ca609896e8b10a267c5312e24786 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <common.h>
+#include <dm.h>
 #include <errno.h>
 #include <malloc.h>
 #include <mmc.h>
@@ -409,7 +410,7 @@ static int sdhci_execute_tuning(struct udevice *dev, uint opcode)
        return 0;
 }
 #endif
-static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
+int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
 {
        struct sdhci_host *host = mmc->priv;
        unsigned int div, clk = 0, timeout;
@@ -533,6 +534,34 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
        sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
 }
 
+void sdhci_set_uhs_timing(struct sdhci_host *host)
+{
+       struct mmc *mmc = (struct mmc *)host->mmc;
+       u32 reg;
+
+       reg = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+       reg &= ~SDHCI_CTRL_UHS_MASK;
+
+       switch (mmc->selected_mode) {
+       case UHS_SDR50:
+       case MMC_HS_52:
+               reg |= SDHCI_CTRL_UHS_SDR50;
+               break;
+       case UHS_DDR50:
+       case MMC_DDR_52:
+               reg |= SDHCI_CTRL_UHS_DDR50;
+               break;
+       case UHS_SDR104:
+       case MMC_HS_200:
+               reg |= SDHCI_CTRL_UHS_SDR104;
+               break;
+       default:
+               reg |= SDHCI_CTRL_UHS_SDR12;
+       }
+
+       sdhci_writew(host, reg, SDHCI_HOST_CONTROL2);
+}
+
 #ifdef CONFIG_DM_MMC
 static int sdhci_set_ios(struct udevice *dev)
 {
@@ -583,7 +612,7 @@ static int sdhci_set_ios(struct mmc *mmc)
 
        /* If available, call the driver specific "post" set_ios() function */
        if (host->ops && host->ops->set_ios_post)
-               host->ops->set_ios_post(host);
+               return host->ops->set_ios_post(host);
 
        return 0;
 }
@@ -681,8 +710,18 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
                u32 f_max, u32 f_min)
 {
        u32 caps, caps_1 = 0;
+#if CONFIG_IS_ENABLED(DM_MMC)
+       u32 mask[2] = {0};
+       int ret;
+       ret = dev_read_u32_array(host->mmc->dev, "sdhci-caps-mask",
+                                mask, 2);
+       if (ret && ret != -1)
+               return ret;
 
+       caps = ~mask[1] & sdhci_readl(host, SDHCI_CAPABILITIES);
+#else
        caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+#endif
 
 #ifdef CONFIG_MMC_SDHCI_SDMA
        if (!(caps & SDHCI_CAN_DO_SDMA)) {
@@ -722,7 +761,11 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
 
        /* Check whether the clock multiplier is supported or not */
        if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
+#if CONFIG_IS_ENABLED(DM_MMC)
+               caps_1 = ~mask[0] & sdhci_readl(host, SDHCI_CAPABILITIES_1);
+#else
                caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
+#endif
                host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >>
                                SDHCI_CLOCK_MUL_SHIFT;
        }
@@ -779,9 +822,6 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
                cfg->host_caps &= ~MMC_MODE_HS_52MHz;
        }
 
-       if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
-               caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
-
        if (!(cfg->voltages & MMC_VDD_165_195) ||
            (host->quirks & SDHCI_QUIRK_NO_1_8_V))
                caps_1 &= ~(SDHCI_SUPPORT_SDR104 | SDHCI_SUPPORT_SDR50 |
index b576511338089c5be5f1336cc89c06e108c710a1..829b75683b2c80c680aab56a12162949b38c8585 100644 (file)
@@ -326,7 +326,7 @@ static void xenon_mask_cmd_conflict_err(struct sdhci_host *host)
 }
 
 /* Platform specific function for post set_ios configuration */
-static void xenon_sdhci_set_ios_post(struct sdhci_host *host)
+static int xenon_sdhci_set_ios_post(struct sdhci_host *host)
 {
        struct xenon_sdhci_priv *priv = host->mmc->priv;
        uint speed = host->mmc->tran_speed;
@@ -364,6 +364,8 @@ static void xenon_sdhci_set_ios_post(struct sdhci_host *host)
 
        /* Re-init the PHY */
        xenon_mmc_phy_set(host);
+
+       return 0;
 }
 
 /* Install a driver specific handler for post set_ios configuration */
index 08023783de48d78dc1c8a2735646e3de12ce6801..c525084250c6ca2669e192d1bf7c2fd76349b4bc 100644 (file)
@@ -48,11 +48,6 @@ static const u8 mode2timing[] = {
        [MMC_HS_200] = MMC_HS200_BUS_SPEED,
 };
 
-#define SDHCI_HOST_CTRL2       0x3E
-#define SDHCI_CTRL2_MODE_MASK  0x7
-#define SDHCI_18V_SIGNAL       0x8
-#define SDHCI_CTRL_EXEC_TUNING 0x0040
-#define SDHCI_CTRL_TUNED_CLK   0x80
 #define SDHCI_TUNING_LOOP_COUNT        40
 
 static void arasan_zynqmp_dll_reset(struct sdhci_host *host, u8 deviceid)
@@ -99,9 +94,9 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
        host = priv->host;
        deviceid = priv->deviceid;
 
-       ctrl = sdhci_readw(host, SDHCI_HOST_CTRL2);
+       ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
        ctrl |= SDHCI_CTRL_EXEC_TUNING;
-       sdhci_writew(host, ctrl, SDHCI_HOST_CTRL2);
+       sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
 
        mdelay(1);
 
@@ -133,7 +128,7 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
                sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
 
                mmc_send_cmd(mmc, &cmd, NULL);
-               ctrl = sdhci_readw(host, SDHCI_HOST_CTRL2);
+               ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
 
                if (cmd.cmdidx == MMC_CMD_SEND_TUNING_BLOCK)
                        udelay(1);
@@ -142,7 +137,7 @@ static int arasan_sdhci_execute_tuning(struct mmc *mmc, u8 opcode)
 
        if (tuning_loop_counter < 0) {
                ctrl &= ~SDHCI_CTRL_TUNED_CLK;
-               sdhci_writel(host, ctrl, SDHCI_HOST_CTRL2);
+               sdhci_writel(host, ctrl, SDHCI_HOST_CONTROL2);
        }
 
        if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) {
@@ -184,36 +179,14 @@ static void arasan_sdhci_set_control_reg(struct sdhci_host *host)
                return;
 
        if (mmc->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
-               reg = sdhci_readw(host, SDHCI_HOST_CTRL2);
-               reg |= SDHCI_18V_SIGNAL;
-               sdhci_writew(host, reg, SDHCI_HOST_CTRL2);
+               reg = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+               reg |= SDHCI_CTRL_VDD_180;
+               sdhci_writew(host, reg, SDHCI_HOST_CONTROL2);
        }
 
        if (mmc->selected_mode > SD_HS &&
-           mmc->selected_mode <= UHS_DDR50) {
-               reg = sdhci_readw(host, SDHCI_HOST_CTRL2);
-               reg &= ~SDHCI_CTRL2_MODE_MASK;
-               switch (mmc->selected_mode) {
-               case UHS_SDR12:
-                       reg |= UHS_SDR12_BUS_SPEED;
-                       break;
-               case UHS_SDR25:
-                       reg |= UHS_SDR25_BUS_SPEED;
-                       break;
-               case UHS_SDR50:
-                       reg |= UHS_SDR50_BUS_SPEED;
-                       break;
-               case UHS_SDR104:
-                       reg |= UHS_SDR104_BUS_SPEED;
-                       break;
-               case UHS_DDR50:
-                       reg |= UHS_DDR50_BUS_SPEED;
-                       break;
-               default:
-                       break;
-               }
-               sdhci_writew(host, reg, SDHCI_HOST_CTRL2);
-       }
+           mmc->selected_mode <= UHS_DDR50)
+               sdhci_set_uhs_timing(host);
 }
 #endif
 
index b043bf886bf828d2150b082b18e9cb4c953ecea9..1415bb1b153736e27d0113496c300f46dcb32b41 100644 (file)
 #define CONFIG_SYS_SDRAM_BASE1         0x880000000
 
 /* SPL Loader Configuration */
+#ifdef CONFIG_TARGET_AM654_A53_EVM
+#define CONFIG_SYS_INIT_SP_ADDR         (CONFIG_SPL_TEXT_BASE +        \
+                                        CONFIG_SYS_K3_NON_SECURE_MSRAM_SIZE)
+#else
+/*
+ * Maximum size in memory allocated to the SPL BSS. Keep it as tight as
+ * possible (to allow the build to go through), as this directly affects
+ * our memory footprint. The less we use for BSS the more we have available
+ * for everything else.
+ */
+#define CONFIG_SPL_BSS_MAX_SIZE                0x5000
+/*
+ * Link BSS to be within SPL in a dedicated region located near the top of
+ * the MCU SRAM, this way making it available also before relocation. Note
+ * that we are not using the actual top of the MCU SRAM as there is a memory
+ * location filled in by the boot ROM that we want to read out without any
+ * interference from the C context.
+ */
+#define CONFIG_SPL_BSS_START_ADDR      (CONFIG_SYS_K3_BOOT_PARAM_TABLE_INDEX -\
+                                        CONFIG_SPL_BSS_MAX_SIZE)
+/* Set the stack right below the SPL BSS section */
+#define CONFIG_SYS_INIT_SP_ADDR         CONFIG_SPL_BSS_START_ADDR
+/* Configure R5 SPL post-relocation malloc pool in DDR */
+#define CONFIG_SYS_SPL_MALLOC_START    0x84000000
+#define CONFIG_SYS_SPL_MALLOC_SIZE     SZ_16M
+#endif
 
 #ifdef CONFIG_SYS_K3_SPL_ATF
 #define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME        "tispl.bin"
 #endif
 
 #define CONFIG_SPL_MAX_SIZE            CONFIG_SYS_K3_MAX_DOWNLODABLE_IMAGE_SIZE
-#define CONFIG_SYS_INIT_SP_ADDR         (CONFIG_SPL_TEXT_BASE +        \
-                                       CONFIG_SYS_K3_NON_SECURE_MSRAM_SIZE - 4)
 
 #define CONFIG_SYS_BOOTM_LEN           SZ_64M
 
+#define PARTS_DEFAULT \
+       /* Linux partitions */ \
+       "name=rootfs,start=0,size=-,uuid=${uuid_gpt_rootfs}\0"
+
 /* U-Boot general configuration */
 #define EXTRA_ENV_AM65X_BOARD_SETTINGS                                 \
        "findfdt="                                                      \
-               "if test $board_name = am65x; then "                    \
-                       "setenv name_fdt k3-am654-base-board.dtb; "     \
-               "else if test $name_fdt = undefined; then "             \
-                       "echo WARNING: Could not determine device tree to use;"\
-               "fi; fi; "                                              \
-               "setenv fdtfile ${name_fdt}\0"                          \
+               "setenv name_fdt k3-am654-base-board.dtb;"              \
+               "setenv fdtfile ${name_fdt};"                           \
+               "setenv overlay_files ${name_overlays}\0"               \
        "loadaddr=0x80080000\0"                                         \
        "fdtaddr=0x82000000\0"                                          \
+       "overlayaddr=0x83000000\0"                                      \
        "name_kern=Image\0"                                             \
        "console=ttyS2,115200n8\0"                                      \
        "args_all=setenv optargs earlycon=ns16550a,mmio32,0x02800000\0" \
-       "run_kern=booti ${loadaddr} ${rd_spec} ${fdtaddr}\0"
+       "run_kern=booti ${loadaddr} ${rd_spec} ${fdtaddr}\0"            \
 
 /* U-Boot MMC-specific configuration */
 #define EXTRA_ENV_AM65X_BOARD_SETTINGS_MMC                             \
        "rd_spec=-\0"                                                   \
        "init_mmc=run args_all args_mmc\0"                              \
        "get_fdt_mmc=load mmc ${bootpart} ${fdtaddr} ${bootdir}/${name_fdt}\0" \
+       "get_overlay_mmc="                                              \
+               "fdt address ${fdtaddr};"                               \
+               "fdt resize 0x100000;"                                  \
+               "for overlay in $overlay_files;"                        \
+               "do;"                                                   \
+               "load mmc ${bootpart} ${overlayaddr} ${bootdir}/${overlay};"    \
+               "fdt apply ${overlayaddr};"                             \
+               "done;\0"                                               \
        "get_kern_mmc=load mmc ${bootpart} ${loadaddr} "                \
-               "${bootdir}/${name_kern}\0"
+               "${bootdir}/${name_kern}\0"                             \
+       "partitions=" PARTS_DEFAULT
 
 /* Incorporate settings into the U-Boot environment */
 #define CONFIG_EXTRA_ENV_SETTINGS                                      \
        EXTRA_ENV_AM65X_BOARD_SETTINGS                                  \
        EXTRA_ENV_AM65X_BOARD_SETTINGS_MMC
 
+/* MMC ENV related defines */
+#ifdef CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV         0
+#define CONFIG_SYS_MMC_ENV_PART        1
+#define CONFIG_ENV_SIZE                (128 << 10)
+#define CONFIG_ENV_OFFSET              0x680000
+#define CONFIG_ENV_OFFSET_REDUND       (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
+#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
+#endif
+
+#define CONFIG_SUPPORT_EMMC_BOOT
+
 /* Now for the remaining common defines */
 #include <configs/ti_armv7_common.h>
 
index 3cd7a66cea70a16ad3161ac73ab25146e1263743..0854200a9c162811a96b47e3d14f6e0779b3121c 100644 (file)
@@ -330,6 +330,8 @@ int regmap_init_mem(ofnode node, struct regmap **mapp);
 int regmap_init_mem_platdata(struct udevice *dev, fdt_val_t *reg, int count,
                             struct regmap **mapp);
 
+int regmap_init_mem_index(ofnode node, struct regmap **mapp, int index);
+
 /**
  * regmap_get_range() - Obtain the base memory address of a regmap range
  *
index eee493ab5f578fdd81082827ae2cf1f4ab65e8a3..01addb7a6036585606179a2257dca0233475b67d 100644 (file)
 
 #define SDHCI_ACMD12_ERR       0x3C
 
-/* 3E-3F reserved */
+#define SDHCI_HOST_CONTROL2    0x3E
+#define  SDHCI_CTRL_UHS_MASK   0x0007
+#define  SDHCI_CTRL_UHS_SDR12  0x0000
+#define  SDHCI_CTRL_UHS_SDR25  0x0001
+#define  SDHCI_CTRL_UHS_SDR50  0x0002
+#define  SDHCI_CTRL_UHS_SDR104 0x0003
+#define  SDHCI_CTRL_UHS_DDR50  0x0004
+#define  SDHCI_CTRL_HS400      0x0005 /* Non-standard */
+#define  SDHCI_CTRL_VDD_180    0x0008
+#define  SDHCI_CTRL_DRV_TYPE_MASK      0x0030
+#define  SDHCI_CTRL_DRV_TYPE_B 0x0000
+#define  SDHCI_CTRL_DRV_TYPE_A 0x0010
+#define  SDHCI_CTRL_DRV_TYPE_C 0x0020
+#define  SDHCI_CTRL_DRV_TYPE_D 0x0030
+#define  SDHCI_CTRL_EXEC_TUNING        0x0040
+#define  SDHCI_CTRL_TUNED_CLK  0x0080
+#define  SDHCI_CTRL_PRESET_VAL_ENABLE  0x8000
 
 #define SDHCI_CAPABILITIES     0x40
 #define  SDHCI_TIMEOUT_CLK_MASK        0x0000003F
@@ -247,7 +263,7 @@ struct sdhci_ops {
 #endif
        int     (*get_cd)(struct sdhci_host *host);
        void    (*set_control_reg)(struct sdhci_host *host);
-       void    (*set_ios_post)(struct sdhci_host *host);
+       int     (*set_ios_post)(struct sdhci_host *host);
        void    (*set_clock)(struct sdhci_host *host, u32 div);
        int (*platform_execute_tuning)(struct mmc *host, u8 opcode);
        void (*set_delay)(struct sdhci_host *host);
@@ -467,9 +483,11 @@ int sdhci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
 int add_sdhci(struct sdhci_host *host, u32 f_max, u32 f_min);
 #endif /* !CONFIG_BLK */
 
+void sdhci_set_uhs_timing(struct sdhci_host *host);
 #ifdef CONFIG_DM_MMC
 /* Export the operations to drivers */
 int sdhci_probe(struct udevice *dev);
+int sdhci_set_clock(struct mmc *mmc, unsigned int clock);
 extern const struct dm_mmc_ops sdhci_ops;
 #else
 #endif
index a9aaef345faf3821272d56bd7633da80984f1c28..a90f971a2393eae6171ae001b723e8e62e1a41d5 100644 (file)
@@ -108,6 +108,15 @@ struct spl_load_info {
  */
 binman_sym_extern(ulong, u_boot_any, image_pos);
 
+/**
+ * spl_load_simple_fit_skip_processing() - Hook to allow skipping the FIT
+ *     image processing during spl_load_simple_fit().
+ *
+ * Return true to skip FIT processing, false to preserve the full code flow
+ * of spl_load_simple_fit().
+ */
+bool spl_load_simple_fit_skip_processing(void);
+
 /**
  * spl_load_simple_fit() - Loads a fit image from a device.
  * @spl_image: Image description to set up
@@ -330,6 +339,23 @@ int spl_dfu_cmd(int usbctrl, char *dfu_alt_info, char *interface, char *devstr);
 int spl_mmc_load_image(struct spl_image_info *spl_image,
                       struct spl_boot_device *bootdev);
 
+/**
+ * spl_mmc_load() - Load an image file from MMC/SD media
+ *
+ * @param spl_image    Image data filled in by loading process
+ * @param bootdev      Describes which device to load from
+ * @param filename     Name of file to load (in FS mode)
+ * @param raw_part     Partition to load from (in RAW mode)
+ * @param raw_sect     Sector to load from (in RAW mode)
+ *
+ * @return 0 on success, otherwise error code
+ */
+int spl_mmc_load(struct spl_image_info *spl_image,
+                struct spl_boot_device *bootdev,
+                const char *filename,
+                int raw_part,
+                unsigned long raw_sect);
+
 /**
  * spl_invoke_atf - boot using an ARM trusted firmware image
  */