diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 0fa92479b4..d78a170d0c 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -243,6 +243,9 @@ stages: sandbox_clang: TEST_PY_BD: "sandbox" OVERRIDE: "-O clang-13" + sandbox_nolto: + TEST_PY_BD: "sandbox" + BUILD_ENV: "NO_LTO=1" sandbox_spl: TEST_PY_BD: "sandbox_spl" TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_spl" @@ -354,6 +357,7 @@ stages: export TEST_PY_ID="${TEST_PY_ID}" export TEST_PY_TEST_SPEC="${TEST_PY_TEST_SPEC}" export OVERRIDE="${OVERRIDE}" + export BUILD_ENV="${BUILD_ENV}" EOF cat << "EOF" >> test.sh # the below corresponds to .gitlab-ci.yml "before_script" diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cebd76d050..29af8c645e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -33,6 +33,7 @@ stages: script: # If we've been asked to use clang only do one configuration. - export UBOOT_TRAVIS_BUILD_DIR=/tmp/${TEST_PY_BD} + - echo BUILD_ENV ${BUILD_ENV} - tools/buildman/buildman -o ${UBOOT_TRAVIS_BUILD_DIR} -w -E -W -e --board ${TEST_PY_BD} ${OVERRIDE} - cp ~/grub_x86.efi $UBOOT_TRAVIS_BUILD_DIR/ @@ -254,6 +255,12 @@ sandbox with clang test.py: OVERRIDE: "-O clang-13" <<: *buildman_and_testpy_dfn +sandbox without LTO test.py: + variables: + TEST_PY_BD: "sandbox" + BUILD_ENV: "NO_LTO=1" + <<: *buildman_and_testpy_dfn + sandbox_spl test.py: variables: TEST_PY_BD: "sandbox_spl" diff --git a/Kconfig b/Kconfig index c8c22555a9..2ea735d38e 100644 --- a/Kconfig +++ b/Kconfig @@ -540,7 +540,7 @@ config PLATFORM_ELFENTRY config STACK_SIZE hex "Define max stack size that can be used by U-Boot" - default 0x4000000 if ARCH_VERSAL || ARCH_ZYNQMP + default 0x4000000 if ARCH_VERSAL_NET || ARCH_VERSAL || ARCH_ZYNQMP default 0x200000 if MICROBLAZE default 0x1000000 help diff --git a/MAINTAINERS b/MAINTAINERS index 83346183ee..b4b185aacd 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -356,20 +356,26 @@ F: doc/device-tree-bindings/phy/phy-mtk-* F: doc/device-tree-bindings/usb/mediatek,* F: doc/README.mediatek F: drivers/clk/mediatek/ +F: drivers/cpu/mtk_cpu.c +F: drivers/i2c/mtk_i2c.c F: drivers/mmc/mtk-sd.c F: drivers/phy/phy-mtk-* F: drivers/pinctrl/mediatek/ F: drivers/power/domain/mtk-power-domain.c F: drivers/ram/mediatek/ F: drivers/spi/mtk_snfi_spi.c +F: drivers/spi/mtk_spim.c F: drivers/timer/mtk_timer.c F: drivers/usb/host/xhci-mtk.c F: drivers/usb/mtu3/ F: drivers/watchdog/mtk_wdt.c F: drivers/net/mtk_eth.c +F: drivers/net/mtk_eth.h F: drivers/reset/reset-mediatek.c F: tools/mtk_image.c F: tools/mtk_image.h +F: tools/mtk_nand_headers.c +F: tools/mtk_nand_headers.h N: mediatek ARM METHODE SUPPORT @@ -629,6 +635,13 @@ F: arch/arm/mach-uniphier/ F: configs/uniphier_*_defconfig N: uniphier +ARM VERSAL NET +M: Michal Simek +S: Maintained +T: git https://source.denx.de/u-boot/custodians/u-boot-microblaze.git +F: arch/arm/mach-versal-net/ +N: (? S: Maintained @@ -725,6 +738,13 @@ S: Maintained F: drivers/pci/pcie_phytium.c F: arch/arm/dts/phytium-durian.dts +ASPEED FMC SPI DRIVER +M: Chin-Ting Kuo +M: Cédric Le Goater +R: Aspeed BMC SW team +S: Maintained +F: drivers/spi/spi-aspeed-smc.c + BINMAN M: Simon Glass M: Alper Nebi Yasak @@ -789,6 +809,13 @@ T: git https://source.denx.de/u-boot/custodians/u-boot-coldfire.git F: arch/m68k/ F: doc/arch/m68k.rst +CYCLIC +M: Stefan Roese +S: Maintained +F: cmd/cyclic.c +F: common/cyclic.c +F: include/cyclic.h + DFU M: Lukasz Majewski S: Maintained @@ -1376,8 +1403,12 @@ F: configs/k2g_hs_evm_defconfig F: configs/k2l_hs_evm_defconfig F: configs/am65x_hs_evm_r5_defconfig F: configs/am65x_hs_evm_a53_defconfig -F: configs/j721e_hs_evm_r5_defconfig +F: configs/j7200_hs_evm_a72_defconfig +F: configs/j7200_hs_evm_r5_defconfig F: configs/j721e_hs_evm_a72_defconfig +F: configs/j721e_hs_evm_r5_defconfig +F: configs/j721s2_hs_evm_a72_defconfig +F: configs/j721s2_hs_evm_r5_defconfig TPM DRIVERS M: Ilias Apalodimas diff --git a/Makefile b/Makefile index 50077027ba..45f10759a1 100644 --- a/Makefile +++ b/Makefile @@ -521,8 +521,8 @@ env_h := include/generated/environment.h no-dot-config-targets := clean clobber mrproper distclean \ help %docs check% coccicheck \ - ubootversion backup tests check qcheck tcheck pylint \ - pylint_err + ubootversion backup tests check pcheck qcheck tcheck \ + pylint pylint_err config-targets := 0 mixed-targets := 0 @@ -643,6 +643,13 @@ export CFLAGS_EFI # Compiler flags to add when building EFI app export CFLAGS_NON_EFI # Compiler flags to remove when building EFI app export EFI_TARGET # binutils target if EFI is natively supported +export LTO_ENABLE + +# This is y if LTO is enabled for this build. See NO_LTO=1 to disable LTO +ifeq ($(NO_LTO),) +LTO_ENABLE=$(if $(CONFIG_LTO),y) +endif + # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use # that (or fail if absent). Otherwise, search for a linker script in a # standard location. @@ -708,16 +715,16 @@ endif LTO_CFLAGS := LTO_FINAL_LDFLAGS := export LTO_CFLAGS LTO_FINAL_LDFLAGS -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) ifeq ($(cc-name),clang) - LTO_CFLAGS += -flto + LTO_CFLAGS += -DLTO_ENABLE -flto LTO_FINAL_LDFLAGS += -flto AR = $(shell $(CC) -print-prog-name=llvm-ar) NM = $(shell $(CC) -print-prog-name=llvm-nm) else NPROC := $(shell nproc 2>/dev/null || echo 1) - LTO_CFLAGS += -flto=$(NPROC) + LTO_CFLAGS += -DLTO_ENABLE -flto=$(NPROC) LTO_FINAL_LDFLAGS += -fuse-linker-plugin -flto=$(NPROC) # use plugin aware tools @@ -1467,6 +1474,7 @@ endif u-boot-spl.kwb: u-boot.bin spl/u-boot-spl.bin FORCE $(call if_changed,mkimage) + $(BOARD_SIZE_CHECK) u-boot.sha1: u-boot.bin tools/ubsha1 u-boot.bin @@ -1724,7 +1732,7 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink) # Generate linker list symbols references to force compiler to not optimize # them away when compiling with LTO -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) u-boot-keep-syms-lto := keep-syms-lto.o u-boot-keep-syms-lto_c := $(patsubst %.o,%.c,$(u-boot-keep-syms-lto)) @@ -1746,7 +1754,7 @@ endif # Rule to link u-boot # May be overridden by arch/$(ARCH)/config.mk -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) quiet_cmd_u-boot__ ?= LTO $@ cmd_u-boot__ ?= \ $(CC) -nostdlib -nostartfiles \ @@ -2318,6 +2326,7 @@ help: @echo 'Test targets:' @echo '' @echo ' check - Run all automated tests that use sandbox' + @echo ' pcheck - Run quick automated tests in parallel' @echo ' qcheck - Run quick automated tests that use sandbox' @echo ' tcheck - Run quick automated tests on tools' @echo ' pylint - Run pylint on all Python files' @@ -2363,6 +2372,9 @@ help: tests check: $(srctree)/test/run +pcheck: + $(srctree)/test/run parallel + qcheck: $(srctree)/test/run quick diff --git a/README b/README index 98185af624..186f1f9a5f 100644 --- a/README +++ b/README @@ -415,8 +415,6 @@ The following options need to be configured: the defaults discussed just above. - Cache Configuration for ARM: - CONFIG_SYS_L2_PL310 - Enable support for ARM PL310 L2 cache - controller CONFIG_SYS_PL310_BASE - Physical base address of PL310 controller register space diff --git a/arch/Kconfig b/arch/Kconfig index c4dc47dccb..1ffd77c0f4 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -146,7 +146,6 @@ config SANDBOX select DM_SPI select DM_SPI_FLASH select GZIP_COMPRESSED - select HAVE_BLOCK_DEVICE select LZO select OF_BOARD_SETUP select PCI_ENDPOINT @@ -167,7 +166,6 @@ config SANDBOX imply CMD_IO imply CMD_IOTRACE imply CMD_LZMADEC - imply CMD_SATA imply CMD_SF imply CMD_SF_TEST imply CRC32_VERIFY diff --git a/arch/arc/lib/bootm.c b/arch/arc/lib/bootm.c index 628addd87e..07b2c1540d 100644 --- a/arch/arc/lib/bootm.c +++ b/arch/arc/lib/bootm.c @@ -22,10 +22,10 @@ static int cleanup_before_linux(void) return 0; } -__weak int board_prep_linux(bootm_headers_t *images) { return 0; } +__weak int board_prep_linux(struct bootm_headers *images) { return 0; } /* Subcommand: PREP */ -static int boot_prep_linux(bootm_headers_t *images) +static int boot_prep_linux(struct bootm_headers *images) { int ret; @@ -49,7 +49,7 @@ __weak void board_jump_and_run(ulong entry, int zero, int arch, uint params) } /* Subcommand: GO */ -static void boot_jump_linux(bootm_headers_t *images, int flag) +static void boot_jump_linux(struct bootm_headers *images, int flag) { ulong kernel_entry; unsigned int r0, r2; @@ -79,7 +79,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) board_jump_and_run(kernel_entry, r0, 0, r2); } -int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +int do_bootm_linux(int flag, int argc, char *argv[], struct bootm_headers *images) { /* No need for those on ARC */ if ((flag & BOOTM_STATE_OS_BD_T) || (flag & BOOTM_STATE_OS_CMDLINE)) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 82cd456f51..2e83394052 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -488,6 +488,15 @@ config TPL_SYS_THUMB_BUILD density. For ARM architectures that support Thumb2 this flag will result in Thumb2 code generated by GCC. +config SYS_L2_PL310 + bool "ARM PL310 L2 cache controller" + help + Enable support for ARM PL310 L2 cache controller in U-Boot + +config SPL_SYS_L2_PL310 + bool "ARM PL310 L2 cache controller in SPL" + help + Enable support for ARM PL310 L2 cache controller in SPL config SYS_L2CACHE_OFF bool "L2cache off" @@ -618,6 +627,7 @@ config ARCH_KIRKWOOD select BOARD_EARLY_INIT_F select CPU_ARM926EJS select GPIO_EXTRA_HEADER + select TIMER config ARCH_MVEBU bool "Marvell MVEBU family (Armada XP/375/38x/3700/7K/8K)" @@ -629,6 +639,8 @@ config ARCH_MVEBU select GPIO_EXTRA_HEADER select SPL_DM_SPI if SPL select SPL_DM_SPI_FLASH if SPL + select SPL_TIMER if SPL + select TIMER select OF_CONTROL select OF_SEPARATE select SPI @@ -639,6 +651,7 @@ config ARCH_ORION5X select CPU_ARM926EJS select GPIO_EXTRA_HEADER select SPL_SEPARATE_BSS if SPL + select TIMER config TARGET_STV0991 bool "Support stv0991" @@ -989,6 +1002,7 @@ config ARCH_MX6 select SYS_FSL_HAS_SEC select SYS_FSL_SEC_COMPAT_4 select SYS_FSL_SEC_LE + select SYS_L2_PL310 if !SYS_L2CACHE_OFF imply MXC_GPIO imply SYS_THUMB_BUILD imply SPL_SEPARATE_BSS @@ -1016,7 +1030,6 @@ config ARCH_NPCM config ARCH_APPLE bool "Apple SoCs" select ARM64 - select BLK select CLK select CMD_USB select DM @@ -1238,6 +1251,18 @@ config ARCH_VERSAL imply BOARD_LATE_INIT imply ENV_VARS_UBOOT_RUNTIME_CONFIG +config ARCH_VERSAL_NET + bool "Support Xilinx Keystone Platform" + select ARM64 + select CLK + select DM + select DM_ETH if NET + select DM_MMC if MMC + select DM_SERIAL + select OF_CONTROL + imply BOARD_LATE_INIT + imply ENV_VARS_UBOOT_RUNTIME_CONFIG + config ARCH_VF610 bool "Freescale Vybrid" select CPU_V7A @@ -1249,6 +1274,7 @@ config ARCH_VF610 config ARCH_ZYNQ bool "Xilinx Zynq based platform" + select ARM_TWD_TIMER select CLK select CLK_ZYNQ select CPU_V7A @@ -1268,7 +1294,9 @@ config ARCH_ZYNQ select SPL_DM_SPI_FLASH if SPL select SPL_OF_CONTROL if SPL select SPL_SEPARATE_BSS if SPL + select SPL_TIMER if SPL select SUPPORT_SPL + select TIMER imply ARCH_EARLY_INIT_R imply BOARD_LATE_INIT imply CMD_CLK @@ -2284,6 +2312,8 @@ source "arch/arm/mach-zynqmp/Kconfig" source "arch/arm/mach-versal/Kconfig" +source "arch/arm/mach-versal-net/Kconfig" + source "arch/arm/mach-zynqmp-r5/Kconfig" source "arch/arm/cpu/armv7/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1f4a1d5788..ac602aed9c 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -88,6 +88,7 @@ machine-$(CONFIG_ARCH_OCTEONTX) += octeontx machine-$(CONFIG_ARCH_OCTEONTX2) += octeontx2 machine-$(CONFIG_ARCH_UNIPHIER) += uniphier machine-$(CONFIG_ARCH_VERSAL) += versal +machine-$(CONFIG_ARCH_VERSAL_NET) += versal-net machine-$(CONFIG_ARCH_ZYNQ) += zynq machine-$(CONFIG_ARCH_ZYNQMP) += zynqmp machine-$(CONFIG_ARCH_ZYNQMP_R5) += zynqmp-r5 diff --git a/arch/arm/config.mk b/arch/arm/config.mk index b3548ce243..2065438d05 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -15,11 +15,11 @@ CFLAGS_NON_EFI := -fno-pic -ffixed-r9 -ffunction-sections -fdata-sections \ -fstack-protector-strong CFLAGS_EFI := -fpic -fshort-wchar -ifneq ($(CONFIG_LTO)$(CONFIG_USE_PRIVATE_LIBGCC),yy) +ifneq ($(LTO_ENABLE)$(CONFIG_USE_PRIVATE_LIBGCC),yy) LDFLAGS_FINAL += --gc-sections endif -ifndef CONFIG_LTO +ifneq ($(LTO_ENABLE),y) PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections endif diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 965895bc2a..71e9bd4da3 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -233,8 +233,11 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ tegra210-p3450-0000.dtb ifdef CONFIG_ARMADA_32BIT +ifdef CONFIG_ARMADA_375 +dtb-$(CONFIG_ARCH_MVEBU) += \ + armada-375-db.dtb +else dtb-$(CONFIG_ARCH_MVEBU) += \ - armada-375-db.dtb \ armada-385-atl-x530.dtb \ armada-385-atl-x530DP.dtb \ armada-385-db-88f6820-amc.dtb \ @@ -254,6 +257,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ armada-xp-maxbcm.dtb \ armada-xp-synology-ds414.dtb \ armada-xp-theadorable.dtb +endif else dtb-$(CONFIG_ARCH_MVEBU) += \ armada-3720-db.dtb \ @@ -379,6 +383,9 @@ dtb-$(CONFIG_ARCH_VERSAL) += \ versal-mini-emmc0.dtb \ versal-mini-emmc1.dtb \ xilinx-versal-virt.dtb +dtb-$(CONFIG_ARCH_VERSAL_NET) += \ + versal-net-mini.dtb \ + xilinx-versal-net-virt.dtb dtb-$(CONFIG_ARCH_ZYNQMP_R5) += \ zynqmp-r5.dtb dtb-$(CONFIG_AM33XX) += \ @@ -388,8 +395,6 @@ dtb-$(CONFIG_AM33XX) += \ am335x-boneblack-wireless.dtb \ am335x-boneblue.dtb \ am335x-brppt1-mmc.dtb \ - am335x-brppt1-nand.dtb \ - am335x-brppt1-spi.dtb \ am335x-brxre1.dtb \ am335x-brsmarc1.dtb \ am335x-draco.dtb \ @@ -1233,6 +1238,15 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt7622-bananapi-bpi-r64.dtb \ mt7623n-bananapi-bpi-r2.dtb \ mt7629-rfb.dtb \ + mt7981-rfb.dtb \ + mt7981-emmc-rfb.dtb \ + mt7981-sd-rfb.dtb \ + mt7986a-rfb.dtb \ + mt7986b-rfb.dtb \ + mt7986a-sd-rfb.dtb \ + mt7986b-sd-rfb.dtb \ + mt7986a-emmc-rfb.dtb \ + mt7986b-emmc-rfb.dtb \ mt8183-pumpkin.dtb \ mt8512-bm1-emmc.dtb \ mt8516-pumpkin.dtb \ diff --git a/arch/arm/dts/am335x-brppt1-mmc-u-boot.dtsi b/arch/arm/dts/am335x-brppt1-mmc-u-boot.dtsi new file mode 100644 index 0000000000..a3d5650e48 --- /dev/null +++ b/arch/arm/dts/am335x-brppt1-mmc-u-boot.dtsi @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 B&R Industrial Automation GmbH - + * https://www.br-automation.com/ + */ + +/ { + ocp { + u-boot,dm-pre-reloc; + }; +}; + +&l4_wkup { + u-boot,dm-pre-reloc; + segment@200000 { + u-boot,dm-pre-reloc; + target-module@0 + { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + }; + target-module@7000 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + }; + target-module@9000 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + }; + }; +}; + +&wkup_cm { + u-boot,dm-pre-reloc; +}; + +&l4_wkup_clkctrl { + u-boot,dm-pre-reloc; +}; + +&l4_per { + u-boot,dm-pre-reloc; + segment@0 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + target-module@4c000 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + }; + }; + + segment@100000 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + target-module@ac000 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + }; + target-module@ae000 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + }; + }; +}; + +&prcm { + u-boot,dm-pre-reloc; +}; + +&gpio0_target { + u-boot,dm-pre-reloc; +}; + +&prcm_clocks { + compatible = "simple-bus"; +}; + +&scm_clocks { + compatible = "simple-bus"; +}; + +&i2c0 { + u-boot,dm-pre-reloc; +}; + +&uart0 { + u-boot,dm-pre-reloc; +}; + +&mmc1 { + u-boot,dm-pre-reloc; +}; + +&mmc2 { + u-boot,dm-pre-reloc; +}; + +&gpio0 { + u-boot,dm-pre-reloc; +}; + +&gpio1 { + u-boot,dm-pre-reloc; +}; + +&gpio2 { + u-boot,dm-pre-reloc; +}; + +&gpio3 { + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/dts/am335x-brppt1-mmc.dts b/arch/arm/dts/am335x-brppt1-mmc.dts index bd2f6c2e3e..4db279b65e 100644 --- a/arch/arm/dts/am335x-brppt1-mmc.dts +++ b/arch/arm/dts/am335x-brppt1-mmc.dts @@ -12,25 +12,10 @@ model = "BRPPT1 (MMC) Panel"; compatible = "ti,am33xx"; - fset: factory-settings { - bl-version = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456890"; - version = <0x0100>; - order-no = "6PPT30 (MMC)"; - hw-revision = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456890"; - serial-no = "0"; - device-id = <0x0>; - parent-id = <0x0>; - hw-variant = <0x1>; - }; aliases { - ds1bkl0 = &pwmbacklight; - ds1bkl1 = &tps_bl; - ds1timing = &timing0; - ds1ctrl = &lcdc; gpmc = &gpmc; mmc = &mmc2; - fset = &fset; }; chosen { @@ -43,110 +28,21 @@ reg = <0x80000000 0x10000000>; /* 256 MB */ }; - panel { - status = "disabled"; - - compatible = "ti,tilcdc,panel"; - enable-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; - - backlight = <&pwmbacklight>; - bkl-pwm = <&pwmbacklight>; - bkl-tps = <&tps_bl>; - - panel-info { - ac-bias = <255>; - ac-bias-intrpt = <0>; - dma-burst-sz = <16>; - bpp = <32>; - fdd = <0x80>; - sync-edge = <0>; - sync-ctrl = <1>; - raster-order = <0>; - fifo-th = <0>; - }; - - display-timings { - native-mode = <&timing0>; - timing0: lcd { - clock-frequency = <32000000>; - hactive = <800>; - vactive = <480>; - hfront-porch = <2>; - hback-porch = <192>; - hsync-len = <1>; - vfront-porch = <20>; - vback-porch = <2>; - vsync-len = <1>; - hsync-active = <1>; - vsync-active = <1>; - pupdelay = <10>; - pondelay = <10>; - }; - }; - }; - vmmcsd_fixed: fixedregulator@0 { compatible = "regulator-fixed"; regulator-name = "vmmcsd_fixed"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; }; - - pwm0: omap-pwm@timer5 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer5>; - #pwm-cells = <3>; - }; - - pwm1: omap-pwm@timer6 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer6>; - #pwm-cells = <3>; - }; - - beeper: pwm-beep { - compatible = "pwm-beeper"; - pwms = <&pwm0 0 0 0>; - }; - - pwmbacklight: pwm-bkl { - compatible = "pwm-backlight"; - pwms = <&pwm1 0 5000000 0>; - - default-brightness-level = <255>; - brightness-levels = <0 16 32 64 128 170 202 234 255>; - - power-supply = <&vmmcsd_fixed>; - enable-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; - }; }; &uart0 { /* console uart */ - u-boot,dm-spl; - status = "okay"; -}; - -&uart1 { status = "okay"; }; &i2c0 { - u-boot,dm-spl; status = "okay"; clock-frequency = <400000>; - - tps: tps@24 { /* PMIC controller */ - u-boot,dm-spl; - reg = <0x24>; - compatible = "ti,tps65217"; - - tps_bl: backlight { - compatible = "ti,tps65217-bl"; - isel = <1>; /* 1 - ISET1, 2 ISET2 */ - fdim = <1000>; /* TPS65217_BL_FDIM_1kHZ */ - default-brightness = <50>; - }; - }; }; &i2c2 { @@ -158,10 +54,6 @@ status = "okay"; }; -&cppi41dma { - status = "okay"; -}; - &usb { status = "okay"; }; @@ -217,7 +109,6 @@ }; &mmc1 { - u-boot,dm-spl; vmmc-supply = <&vmmcsd_fixed>; bus-width = <0x4>; ti,non-removable; @@ -227,7 +118,6 @@ }; &mmc2 { - u-boot,dm-spl; vmmc-supply = <&vmmcsd_fixed>; bus-width = <0x8>; ti,non-removable; @@ -236,79 +126,22 @@ status = "okay"; }; -&l4_per { - - segment@300000 { - - target-module@e000 { - u-boot,dm-pre-reloc; - - lcdc: lcdc@0 { - u-boot,dm-pre-reloc; - status = "disabled"; - }; - }; - }; -}; - -&elm { - status = "okay"; -}; - -&sham { - status = "okay"; -}; - -&aes { - status = "okay"; -}; - &gpio0 { - u-boot,dm-spl; ti,no-reset-on-init; }; &gpio1 { - u-boot,dm-spl; ti,no-reset-on-init; }; &gpio2 { - u-boot,dm-spl; ti,no-reset-on-init; }; &gpio3 { - u-boot,dm-spl; ti,no-reset-on-init; }; -&wdt2 { - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&tscadc { - status = "okay"; - tsc { - ti,wires = <4>; - ti,x-plate-resistance = <200>; - ti,zx-cutoff-ratio = <40>; - ti,min_deviation = <60>; - ti,max_deviation = <600>; - ti,coordinate-readouts = <5>; - ti,wire-config = <0x00 0x11 0x22 0x33>; - - bnr-buttons { - Home-Button {}; - }; - }; - - adc { - ti,adc-channels = <5 6 7>; - }; -}; - &timer6 { /* used for cpsw end device */ status = "okay"; ti,no-reset-on-init; @@ -320,37 +153,3 @@ ti,no-reset-on-init; ti,no-idle-on-init; }; - -&wdt2 { - status = "okay"; - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&epwmss0 { - status = "okay"; -}; - -&tscadc { - status = "okay"; -}; - -&dcan0 { - status = "okay"; -}; - -&dcan1 { - status = "okay"; -}; - -&sham { - status = "disabled"; -}; - -&aes { - status = "disabled"; -}; - -&rng { - status = "disabled"; -}; diff --git a/arch/arm/dts/am335x-brppt1-nand.dts b/arch/arm/dts/am335x-brppt1-nand.dts deleted file mode 100644 index 67c609739f..0000000000 --- a/arch/arm/dts/am335x-brppt1-nand.dts +++ /dev/null @@ -1,374 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2018 B&R Industrial Automation GmbH - * http://www.br-automation.com - * - */ -/dts-v1/; - -#include "am33xx.dtsi" - -/ { - model = "BRPPT1 (NAND) Panel"; - compatible = "ti,am33xx"; - - fset: factory-settings { - bl-version = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456890"; - version = <0x0100>; - order-no = "6PPT30 (NAND)"; - hw-revision = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456890"; - serial-no = "0"; - device-id = <0x0>; - parent-id = <0x0>; - hw-variant = <0x1>; - }; - - aliases { - ds1bkl0 = &pwmbacklight; - ds1bkl1 = &tps_bl; - ds1timing = &timing0; - ds1ctrl = &lcdc; - gpmc = &gpmc; - mmc = &mmc2; - fset = &fset; - }; - - chosen { - bootargs = "console=ttyO0,115200 earlyprintk"; - stdout-path = &uart0; - }; - - memory { - device_type = "memory"; - reg = <0x80000000 0x10000000>; /* 256 MB */ - }; - - panel { - status = "disabled"; - - compatible = "ti,tilcdc,panel"; - enable-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; - - backlight = <&pwmbacklight>; - bkl-pwm = <&pwmbacklight>; - bkl-tps = <&tps_bl>; - - panel-info { - ac-bias = <255>; - ac-bias-intrpt = <0>; - dma-burst-sz = <16>; - bpp = <32>; - fdd = <0x80>; - sync-edge = <0>; - sync-ctrl = <1>; - raster-order = <0>; - fifo-th = <0>; - }; - - display-timings { - native-mode = <&timing0>; - timing0: lcd { - clock-frequency = <32000000>; - hactive = <800>; - vactive = <480>; - hfront-porch = <2>; - hback-porch = <192>; - hsync-len = <1>; - vfront-porch = <20>; - vback-porch = <2>; - vsync-len = <1>; - hsync-active = <1>; - vsync-active = <1>; - pupdelay = <10>; - pondelay = <10>; - }; - }; - }; - - vmmcsd_fixed: fixedregulator@0 { - compatible = "regulator-fixed"; - regulator-name = "vmmcsd_fixed"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - pwm0: omap-pwm@timer5 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer5>; - #pwm-cells = <3>; - }; - - pwm1: omap-pwm@timer6 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer6>; - #pwm-cells = <3>; - }; - - beeper: pwm-beep { - compatible = "pwm-beeper"; - pwms = <&pwm0 0 0 0>; - }; - - pwmbacklight: pwm-bkl { - compatible = "pwm-backlight"; - pwms = <&pwm1 0 5000000 0>; - - default-brightness-level = <255>; - brightness-levels = <0 16 32 64 128 170 202 234 255>; - - power-supply = <&vmmcsd_fixed>; - enable-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; - }; -}; - -&uart0 { /* console uart */ - u-boot,dm-spl; - status = "okay"; -}; - -&uart1 { - status = "okay"; -}; - -&i2c0 { - u-boot,dm-spl; - status = "okay"; - clock-frequency = <400000>; - - tps: tps@24 { /* PMIC controller */ - u-boot,dm-spl; - reg = <0x24>; - compatible = "ti,tps65217"; - - tps_bl: backlight { - compatible = "ti,tps65217-bl"; - isel = <1>; /* 1 - ISET1, 2 ISET2 */ - fdim = <1000>; /* TPS65217_BL_FDIM_1kHZ */ - default-brightness = <50>; - }; - }; -}; - -&i2c2 { - status = "okay"; - clock-frequency = <100000>; -}; - -&edma { - status = "okay"; -}; - -&cppi41dma { - status = "okay"; -}; - -&usb { - status = "okay"; -}; - -&usb_ctrl_mod { - status = "okay"; -}; - -&usb0_phy { - status = "okay"; -}; - -&usb1_phy { - status = "okay"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; - -&usb1 { - status = "okay"; - dr_mode = "host"; -}; - -&davinci_mdio { - status = "okay"; - - phy0: ethernet-phy@0 { - reg = <1>; - }; - - phy1: ethernet-phy@1 { - reg = <2>; - }; -}; - -&mac { - dual_emac; - status = "okay"; -}; - -&cpsw_emac0 { - phy-handle = <&phy0>; - dual_emac_res_vlan = <1>; - phy-mode = "mii"; -}; - -&cpsw_emac1 { - phy-handle = <&phy1>; - dual_emac_res_vlan = <2>; - phy-mode = "mii"; -}; - -&mmc2 { - vmmc-supply = <&vmmcsd_fixed>; - bus-width = <0x4>; - ti,non-removable; - ti,needs-special-hs-handling; - ti,vcc-aux-disable-is-sleep; - status = "disabled"; -}; - -&l4_per { - - segment@300000 { - - target-module@e000 { - u-boot,dm-pre-reloc; - - lcdc: lcdc@0 { - u-boot,dm-pre-reloc; - status = "disabled"; - }; - }; - }; -}; - -&elm { - status = "okay"; -}; - -&sham { - status = "okay"; -}; - -&aes { - status = "okay"; -}; - -&gpio0 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&gpio1 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&gpio2 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&gpio3 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&wdt2 { - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&tscadc { - status = "okay"; - tsc { - ti,wires = <4>; - ti,x-plate-resistance = <200>; - ti,zx-cutoff-ratio = <40>; - ti,min_deviation = <60>; - ti,max_deviation = <600>; - ti,coordinate-readouts = <5>; - ti,wire-config = <0x00 0x11 0x22 0x33>; - - bnr-buttons { - Home-Button {}; - }; - }; - - adc { - ti,adc-channels = <5 6 7>; - }; -}; - -&gpmc { - u-boot,dm-spl; - status = "okay"; - pinctrl-names = "default"; - ranges = <0 0 0x08000000 0x10000000>; /* CS0: NAND */ - nand@0,0 { - compatible = "ti,omap2-nand"; - reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ - interrupt-parent = <&gpmc>; - rb-gpios = <&gpmc 1 GPIO_ACTIVE_HIGH>; /* gpmc_wait1 */ - ti,nand-ecc-opt = "bch8"; - ti,elm-id = <&elm>; - nand-bus-width = <8>; - gpmc,device-width = <1>; - gpmc,sync-clk-ps = <0>; - gpmc,cs-on-ns = <0>; - gpmc,cs-rd-off-ns = <44>; - gpmc,cs-wr-off-ns = <44>; - gpmc,adv-on-ns = <6>; - gpmc,adv-rd-off-ns = <34>; - gpmc,adv-wr-off-ns = <44>; - gpmc,we-on-ns = <0>; - gpmc,we-off-ns = <40>; - gpmc,oe-on-ns = <0>; - gpmc,oe-off-ns = <54>; - gpmc,access-ns = <64>; - gpmc,rd-cycle-ns = <82>; - gpmc,wr-cycle-ns = <82>; - gpmc,wait-on-read = "true"; - gpmc,wait-on-write = "true"; - gpmc,bus-turnaround-ns = <0>; - gpmc,cycle2cycle-delay-ns = <0>; - gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; - gpmc,wr-access-ns = <40>; - gpmc,wr-data-mux-bus-ns = <0>; - gpmc,wait-pin = <1>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "NAND.MLO"; - reg = <0x00000000 0x000020000>; - }; - partition@1 { - label = "NAND.cfgscr"; - reg = <0x00020000 0x00020000>; - }; - partition@2 { - label = "NAND.dtb"; - reg = <0x00040000 0x00020000>; - }; - partition@3 { - label = "NAND.u-boot-env"; - reg = <0x00060000 0x00020000>; - }; - partition@4 { - label = "NAND.u-boot"; - reg = <0x00080000 0x00080000>; - }; - partition@5 { - label = "NAND.kernel"; - reg = <0x00100000 0x00400000>; - }; - partition@6 { - label = "NAND.rootfs"; - reg = <0x00500000 0x08000000>; - }; - partition@7 { - label = "NAND.user"; - reg = <0x08500000 0x17b00000>; - }; - }; -}; diff --git a/arch/arm/dts/am335x-brppt1-spi.dts b/arch/arm/dts/am335x-brppt1-spi.dts deleted file mode 100644 index ce3dce204d..0000000000 --- a/arch/arm/dts/am335x-brppt1-spi.dts +++ /dev/null @@ -1,377 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2018 B&R Industrial Automation GmbH - * http://www.br-automation.com - * - */ -/dts-v1/; - -#include "am33xx.dtsi" - -/ { - model = "BRPPT1 (MMC) Panel"; - compatible = "ti,am33xx"; - - fset: factory-settings { - bl-version = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456890"; - version = <0x0100>; - order-no = "6PPT30 (SPI)"; - hw-revision = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456890"; - serial-no = "0"; - device-id = <0x0>; - parent-id = <0x0>; - hw-variant = <0x1>; - }; - - aliases { - ds1bkl0 = &pwmbacklight; - ds1bkl1 = &tps_bl; - ds1timing = &timing0; - ds1ctrl = &lcdc; - gpmc = &gpmc; - mmc = &mmc2; - spi0 = &spi0; - fset = &fset; - }; - - chosen { - bootargs = "console=ttyO0,115200 earlyprintk"; - stdout-path = &uart0; - }; - - memory { - device_type = "memory"; - reg = <0x80000000 0x10000000>; /* 256 MB */ - }; - - panel { - status = "disabled"; - - compatible = "ti,tilcdc,panel"; - enable-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; - - backlight = <&pwmbacklight>; - bkl-pwm = <&pwmbacklight>; - bkl-tps = <&tps_bl>; - - panel-info { - ac-bias = <255>; - ac-bias-intrpt = <0>; - dma-burst-sz = <16>; - bpp = <32>; - fdd = <0x80>; - sync-edge = <0>; - sync-ctrl = <1>; - raster-order = <0>; - fifo-th = <0>; - }; - - display-timings { - native-mode = <&timing0>; - timing0: lcd { - clock-frequency = <32000000>; - hactive = <800>; - vactive = <480>; - hfront-porch = <2>; - hback-porch = <192>; - hsync-len = <1>; - vfront-porch = <20>; - vback-porch = <2>; - vsync-len = <1>; - hsync-active = <1>; - vsync-active = <1>; - pupdelay = <10>; - pondelay = <10>; - }; - }; - }; - - vmmcsd_fixed: fixedregulator@0 { - compatible = "regulator-fixed"; - regulator-name = "vmmcsd_fixed"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - pwm0: omap-pwm@timer5 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer5>; - #pwm-cells = <3>; - }; - - pwm1: omap-pwm@timer6 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer6>; - #pwm-cells = <3>; - }; - - beeper: pwm-beep { - compatible = "pwm-beeper"; - pwms = <&pwm0 0 0 0>; - }; - - pwmbacklight: pwm-bkl { - compatible = "pwm-backlight"; - pwms = <&pwm1 0 5000000 0>; - - default-brightness-level = <255>; - brightness-levels = <0 16 32 64 128 170 202 234 255>; - - power-supply = <&vmmcsd_fixed>; - enable-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; - }; -}; - -&uart0 { /* console uart */ - u-boot,dm-spl; - status = "okay"; -}; - -&uart1 { - status = "okay"; -}; - -&i2c0 { - u-boot,dm-spl; - status = "okay"; - clock-frequency = <400000>; - - tps: tps@24 { /* PMIC controller */ - u-boot,dm-spl; - reg = <0x24>; - compatible = "ti,tps65217"; - - tps_bl: backlight { - compatible = "ti,tps65217-bl"; - isel = <1>; /* 1 - ISET1, 2 ISET2 */ - fdim = <1000>; /* TPS65217_BL_FDIM_1kHZ */ - default-brightness = <50>; - }; - }; -}; - -&i2c2 { - status = "okay"; - clock-frequency = <100000>; -}; - -&spi0 { - u-boot,dm-spl; - status = "okay"; - - cs-gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>, - <&gpio0 6 GPIO_ACTIVE_HIGH>, - <0>, - <0>; - - spi-max-frequency = <24000000>; - - spi_flash: spiflash@0 { - u-boot,dm-spl; - u-boot,dm-pre-reloc; - compatible = "spidev", "jedec,spi-nor"; - spi-max-frequency = <24000000>; - reg = <0>; - }; -}; - -&edma { - status = "okay"; -}; - -&cppi41dma { - status = "okay"; -}; - -&usb { - status = "okay"; -}; - -&usb_ctrl_mod { - status = "okay"; -}; - -&usb0_phy { - status = "okay"; -}; - -&usb1_phy { - status = "okay"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; - -&usb1 { - status = "okay"; - dr_mode = "host"; -}; - -&davinci_mdio { - status = "okay"; - - phy0: ethernet-phy@0 { - reg = <1>; - }; - - phy1: ethernet-phy@1 { - reg = <2>; - }; -}; - -&mac { - status = "okay"; -}; - -&cpsw_emac0 { - phy-handle = <&phy0>; - dual_emac_res_vlan = <1>; - phy-mode = "mii"; -}; - -&cpsw_emac1 { - phy-handle = <&phy1>; - dual_emac_res_vlan = <2>; - phy-mode = "mii"; -}; - -&mmc1 { - u-boot,dm-spl; - vmmc-supply = <&vmmcsd_fixed>; - bus-width = <0x4>; - ti,non-removable; - ti,needs-special-hs-handling; - ti,vcc-aux-disable-is-sleep; - status = "okay"; -}; - -&mmc2 { - u-boot,dm-spl; - vmmc-supply = <&vmmcsd_fixed>; - bus-width = <0x8>; - ti,non-removable; - ti,needs-special-hs-handling; - ti,vcc-aux-disable-is-sleep; - status = "okay"; -}; - -&l4_per { - - segment@300000 { - - target-module@e000 { - u-boot,dm-pre-reloc; - - lcdc: lcdc@0 { - u-boot,dm-pre-reloc; - status = "disabled"; - }; - }; - }; -}; - -&elm { - status = "okay"; -}; - -&sham { - status = "okay"; -}; - -&aes { - status = "okay"; -}; - -&gpio0 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&gpio1 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&gpio2 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&gpio3 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&wdt2 { - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&tscadc { - status = "okay"; - tsc { - ti,wires = <4>; - ti,x-plate-resistance = <200>; - ti,zx-cutoff-ratio = <40>; - ti,min_deviation = <60>; - ti,max_deviation = <600>; - ti,coordinate-readouts = <5>; - ti,wire-config = <0x00 0x11 0x22 0x33>; - - bnr-buttons { - Home-Button {}; - }; - }; - - adc { - ti,adc-channels = <5 6 7>; - }; -}; - -&timer6 { /* used for cpsw end device */ - status = "okay"; - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&timer7 { /* used for cpsw end device */ - status = "okay"; - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&wdt2 { - status = "okay"; - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&epwmss0 { - status = "okay"; -}; - -&tscadc { - status = "okay"; -}; - -&dcan0 { - status = "okay"; -}; - -&dcan1 { - status = "okay"; -}; - -&sham { - status = "disabled"; -}; - -&aes { - status = "disabled"; -}; - -&rng { - status = "disabled"; -}; diff --git a/arch/arm/dts/armada-375.dtsi b/arch/arm/dts/armada-375.dtsi index 20a8c352b2..a044b3fc99 100644 --- a/arch/arm/dts/armada-375.dtsi +++ b/arch/arm/dts/armada-375.dtsi @@ -187,7 +187,7 @@ reg = <0xc000 0x58>; }; - timer@c600 { + timer0: timer@c600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0xc600 0x20>; interrupts = ; @@ -416,7 +416,7 @@ interrupts = ; }; - timer@20300 { + timer1: timer@20300 { compatible = "marvell,armada-375-timer", "marvell,armada-370-timer"; reg = <0x20300 0x30>, <0x21040 0x30>; interrupts-extended = <&gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, diff --git a/arch/arm/dts/armada-xp-theadorable.dts b/arch/arm/dts/armada-xp-theadorable.dts index ba73386d4f..7d833640b6 100644 --- a/arch/arm/dts/armada-xp-theadorable.dts +++ b/arch/arm/dts/armada-xp-theadorable.dts @@ -107,20 +107,6 @@ status = "okay"; }; - mdio { - #address-cells = <1>; - #size-cells = <0>; - phy0: ethernet-phy@0 { - reg = <0>; - }; - }; - - ethernet@70000 { - status = "okay"; - phy = <&phy0>; - phy-mode = "sgmii"; - }; - usb@50000 { status = "okay"; }; @@ -166,6 +152,18 @@ clock-frequency = <100000>; }; +&mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + +ð0 { + status = "okay"; + phy = <&phy0>; + phy-mode = "sgmii"; +}; + &spi0 { status = "okay"; @@ -198,7 +196,6 @@ }; }; - &pciec { status = "okay"; diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts index cc577761fa..1fbacf985f 100644 --- a/arch/arm/dts/ast2500-evb.dts +++ b/arch/arm/dts/ast2500-evb.dts @@ -78,6 +78,39 @@ pinctrl-0 = <&pinctrl_sd2_default>; }; +&fmc { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fwspics1_default>; + + flash@0 { + status = "okay"; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <2>; + spi-rx-bus-width = <2>; + }; + + flash@1 { + status = "okay"; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <2>; + spi-rx-bus-width = <2>; + }; +}; + +&spi1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1cs1_default>; + + flash@0 { + status = "okay"; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <2>; + spi-rx-bus-width = <2>; + }; +}; + &i2c3 { status = "okay"; diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi index cea08e6f08..320d2e5340 100644 --- a/arch/arm/dts/ast2500.dtsi +++ b/arch/arm/dts/ast2500.dtsi @@ -57,23 +57,26 @@ ranges; fmc: flash-controller@1e620000 { - reg = < 0x1e620000 0xc4 - 0x20000000 0x10000000 >; + reg = <0x1e620000 0xc4>, <0x20000000 0x10000000>; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2500-fmc"; + clocks = <&scu ASPEED_CLK_AHB>; + num-cs = <3>; status = "disabled"; - interrupts = <19>; + flash@0 { reg = < 0 >; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@1 { reg = < 1 >; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@2 { reg = < 2 >; compatible = "jedec,spi-nor"; @@ -82,17 +85,20 @@ }; spi1: flash-controller@1e630000 { - reg = < 0x1e630000 0xc4 - 0x30000000 0x08000000 >; + reg = <0x1e630000 0xc4>, <0x30000000 0x08000000>; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2500-spi"; + clocks = <&scu ASPEED_CLK_AHB>; + num-cs = <2>; status = "disabled"; + flash@0 { reg = < 0 >; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@1 { reg = < 1 >; compatible = "jedec,spi-nor"; @@ -101,17 +107,20 @@ }; spi2: flash-controller@1e631000 { - reg = < 0x1e631000 0xc4 - 0x38000000 0x08000000 >; + reg = <0x1e631000 0xc4>, <0x38000000 0x08000000>; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2500-spi"; + clocks = <&scu ASPEED_CLK_AHB>; + num-cs = <2>; status = "disabled"; + flash@0 { reg = < 0 >; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@1 { reg = < 1 >; compatible = "jedec,spi-nor"; diff --git a/arch/arm/dts/ast2600-evb.dts b/arch/arm/dts/ast2600-evb.dts index a9bba96816..a097f320e4 100644 --- a/arch/arm/dts/ast2600-evb.dts +++ b/arch/arm/dts/ast2600-evb.dts @@ -72,12 +72,10 @@ &fmc { status = "okay"; - pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fmcquad_default>; flash@0 { - compatible = "spi-flash", "sst,w25q256"; status = "okay"; spi-max-frequency = <50000000>; spi-tx-bus-width = <4>; @@ -85,7 +83,6 @@ }; flash@1 { - compatible = "spi-flash", "sst,w25q256"; status = "okay"; spi-max-frequency = <50000000>; spi-tx-bus-width = <4>; @@ -93,7 +90,6 @@ }; flash@2 { - compatible = "spi-flash", "sst,w25q256"; status = "okay"; spi-max-frequency = <50000000>; spi-tx-bus-width = <4>; @@ -103,14 +99,12 @@ &spi1 { status = "okay"; - pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi1_default &pinctrl_spi1abr_default &pinctrl_spi1cs1_default &pinctrl_spi1wp_default &pinctrl_spi1wp_default &pinctrl_spi1quad_default>; flash@0 { - compatible = "spi-flash", "sst,w25q256"; status = "okay"; spi-max-frequency = <50000000>; spi-tx-bus-width = <4>; @@ -120,13 +114,11 @@ &spi2 { status = "okay"; - pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi2_default &pinctrl_spi2cs1_default &pinctrl_spi2cs2_default &pinctrl_spi2quad_default>; flash@0 { - compatible = "spi-flash", "sst,w25q256"; status = "okay"; spi-max-frequency = <50000000>; spi-tx-bus-width = <4>; diff --git a/arch/arm/dts/ast2600.dtsi b/arch/arm/dts/ast2600.dtsi index ac8cd4d67d..8d91eedc17 100644 --- a/arch/arm/dts/ast2600.dtsi +++ b/arch/arm/dts/ast2600.dtsi @@ -129,74 +129,78 @@ }; fmc: flash-controller@1e620000 { - reg = < 0x1e620000 0xc4 - 0x20000000 0x10000000 >; + reg = <0x1e620000 0xc4>, <0x20000000 0x10000000>; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2600-fmc"; status = "disabled"; - interrupts = ; clocks = <&scu ASPEED_CLK_AHB>; num-cs = <3>; + flash@0 { - reg = < 0 >; + reg = <0>; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@1 { - reg = < 1 >; + reg = <1>; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@2 { - reg = < 2 >; + reg = <2>; compatible = "jedec,spi-nor"; status = "disabled"; }; }; spi1: flash-controller@1e630000 { - reg = < 0x1e630000 0xc4 - 0x30000000 0x08000000 >; + reg = <0x1e630000 0xc4>, <0x30000000 0x10000000>; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2600-spi"; clocks = <&scu ASPEED_CLK_AHB>; num-cs = <2>; status = "disabled"; + flash@0 { - reg = < 0 >; + reg = <0>; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@1 { - reg = < 1 >; + reg = <1>; compatible = "jedec,spi-nor"; status = "disabled"; }; }; spi2: flash-controller@1e631000 { - reg = < 0x1e631000 0xc4 - 0x50000000 0x08000000 >; + reg = <0x1e631000 0xc4>, <0x50000000 0x10000000>; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2600-spi"; clocks = <&scu ASPEED_CLK_AHB>; num-cs = <3>; status = "disabled"; + flash@0 { - reg = < 0 >; + reg = <0>; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@1 { - reg = < 1 >; + reg = <1>; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@2 { - reg = < 2 >; + reg = <2>; compatible = "jedec,spi-nor"; status = "disabled"; }; diff --git a/arch/arm/dts/at91-sam9x60_curiosity.dts b/arch/arm/dts/at91-sam9x60_curiosity.dts index 2e7ccb0ffb..7c5b6ae2b8 100644 --- a/arch/arm/dts/at91-sam9x60_curiosity.dts +++ b/arch/arm/dts/at91-sam9x60_curiosity.dts @@ -44,6 +44,11 @@ ; }; + + pinctrl_onewire_tm_default: onewire_tm_default { + atmel,pins = + ; + }; }; }; }; @@ -66,6 +71,18 @@ memory { reg = <0x20000000 0x8000000>; }; + + onewire_tm: onewire { + gpios = <&pioD 14 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_onewire_tm_default>; + status = "okay"; + + w1_eeprom: w1_eeprom@0 { + compatible = "maxim,ds24b33"; + status = "okay"; + }; + }; }; &macb0 { diff --git a/arch/arm/dts/at91-sama5d27_giantboard.dts b/arch/arm/dts/at91-sama5d27_giantboard.dts index e81ca60ca0..2625f81c8b 100644 --- a/arch/arm/dts/at91-sama5d27_giantboard.dts +++ b/arch/arm/dts/at91-sama5d27_giantboard.dts @@ -30,7 +30,7 @@ sdmmc1: sdio-host@b0000000 { bus-width = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc1_cmd_dat_default &pinctrl_sdmmc1_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc1_default>; status = "okay"; u-boot,dm-pre-reloc; }; @@ -73,10 +73,9 @@ u-boot,dm-pre-reloc; }; - pioA: gpio@fc038000 { - pinctrl { - - pinctrl_sdmmc1_cmd_dat_default: sdmmc1_cmd_dat_default { + pioA: pinctrl@fc038000 { + pinctrl_sdmmc1_default: sdmmc1_default { + cmd_data { pinmux = , , , @@ -86,41 +85,41 @@ u-boot,dm-pre-reloc; }; - pinctrl_sdmmc1_ck_cd_default: sdmmc1_ck_cd_default { + ck_cd { pinmux = , ; bias-disable; u-boot,dm-pre-reloc; }; + }; - pinctrl_uart1_default: uart1_default { - pinmux = , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_uart1_default: uart1_default { + pinmux = , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; - pinctrl_i2c0_default: i2c0_default { - pinmux = , - ; - bias-disable; - }; + pinctrl_i2c0_default: i2c0_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_i2c1_default: i2c1_default { - pinmux = , - ; - bias-disable; - }; + pinctrl_i2c1_default: i2c1_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_usb_default: usb_default { - pinmux = ; - bias-disable; - }; + pinctrl_usb_default: usb_default { + pinmux = ; + bias-disable; + }; - pinctrl_usba_vbus: usba_vbus { - pinmux = ; - bias-disable; - }; + pinctrl_usba_vbus: usba_vbus { + pinmux = ; + bias-disable; }; }; }; diff --git a/arch/arm/dts/at91-sama5d27_som1_ek.dts b/arch/arm/dts/at91-sama5d27_som1_ek.dts index efd1a5d197..70d15c8a62 100644 --- a/arch/arm/dts/at91-sama5d27_som1_ek.dts +++ b/arch/arm/dts/at91-sama5d27_som1_ek.dts @@ -83,7 +83,7 @@ sdmmc0: sdio-host@a0000000 { bus-width = <8>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc0_cmd_dat_default &pinctrl_sdmmc0_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc0_default>; status = "okay"; u-boot,dm-pre-reloc; }; @@ -91,7 +91,7 @@ sdmmc1: sdio-host@b0000000 { bus-width = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc1_cmd_dat_default &pinctrl_sdmmc1_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc1_default>; status = "okay"; /* conflict with qspi0 */ u-boot,dm-pre-reloc; }; @@ -129,7 +129,7 @@ u-boot,dm-pre-reloc; }; - pioA: gpio@fc038000 { + pioA: pinctrl@fc038000 { pinctrl { pinctrl_lcd_base: pinctrl_lcd_base { pinmux = , @@ -166,43 +166,47 @@ bias-disable; }; - pinctrl_sdmmc0_cmd_dat_default: sdmmc0_cmd_dat_default { - pinmux = , - , - , - , - , - , - , - , - ; - bias-pull-up; - u-boot,dm-pre-reloc; + pinctrl_sdmmc0_default: sdmmc0_default { + cmd_dat { + pinmux = , + , + , + , + , + , + , + , + ; + bias-pull-up; + u-boot,dm-pre-reloc; + }; + + ck_cd { + pinmux = , + , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; }; - pinctrl_sdmmc0_ck_cd_default: sdmmc0_ck_cd_default { - pinmux = , - , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_sdmmc1_default: sdmmc1_default { + cmd_dat { + pinmux = , + , + , + , + ; + bias-pull-up; + u-boot,dm-pre-reloc; + }; - pinctrl_sdmmc1_cmd_dat_default: sdmmc1_cmd_dat_default { - pinmux = , - , - , - , - ; - bias-pull-up; - u-boot,dm-pre-reloc; - }; - - pinctrl_sdmmc1_ck_cd_default: sdmmc1_ck_cd_default { - pinmux = , - ; - bias-disable; - u-boot,dm-pre-reloc; + ck_cd { + pinmux = , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; }; pinctrl_uart1_default: uart1_default { diff --git a/arch/arm/dts/at91-sama5d27_wlsom1_ek-u-boot.dtsi b/arch/arm/dts/at91-sama5d27_wlsom1_ek-u-boot.dtsi index 8c84dd08fd..41cf9061a1 100644 --- a/arch/arm/dts/at91-sama5d27_wlsom1_ek-u-boot.dtsi +++ b/arch/arm/dts/at91-sama5d27_wlsom1_ek-u-boot.dtsi @@ -37,11 +37,7 @@ u-boot,dm-pre-reloc; }; -&pinctrl_sdmmc0_cmd_dat_default { - u-boot,dm-pre-reloc; -}; - -&pinctrl_sdmmc0_ck_cd_default { +&pinctrl_sdmmc0_default { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/at91-sama5d27_wlsom1_ek.dts b/arch/arm/dts/at91-sama5d27_wlsom1_ek.dts index f3f6942143..eec183d5de 100644 --- a/arch/arm/dts/at91-sama5d27_wlsom1_ek.dts +++ b/arch/arm/dts/at91-sama5d27_wlsom1_ek.dts @@ -34,7 +34,7 @@ sdmmc0: sdio-host@a0000000 { bus-width = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc0_cmd_dat_default &pinctrl_sdmmc0_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc0_default>; status = "okay"; }; @@ -78,44 +78,44 @@ status = "okay"; }; - pioA: gpio@fc038000 { - pinctrl { - pinctrl_lcd_base: pinctrl_lcd_base { - pinmux = , - , - , - ; - bias-disable; - }; + pioA: pinctrl@fc038000 { + pinctrl_lcd_base: pinctrl_lcd_base { + pinmux = , + , + , + ; + bias-disable; + }; - pinctrl_lcd_pwm: pinctrl_lcd_pwm { - pinmux = ; - bias-disable; - }; + pinctrl_lcd_pwm: pinctrl_lcd_pwm { + pinmux = ; + bias-disable; + }; - pinctrl_lcd_rgb666: pinctrl_lcd_rgb666 { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_lcd_rgb666: pinctrl_lcd_rgb666 { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_sdmmc0_cmd_dat_default: sdmmc0_cmd_dat_default { + pinctrl_sdmmc0_default: sdmmc0_default { + cmd_data { pinmux = , , , @@ -124,24 +124,24 @@ bias-disable; }; - pinctrl_sdmmc0_ck_cd_default: sdmmc0_ck_cd_default { + ck_cd_vddsel { pinmux = , , , ; bias-disable; }; + }; - pinctrl_uart0_default: uart0_default { - pinmux = , - ; - bias-disable; - }; + pinctrl_uart0_default: uart0_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_onewire_tm_default: onewire_tm_default { - pinmux = ; - bias-pull-up; - }; + pinctrl_onewire_tm_default: onewire_tm_default { + pinmux = ; + bias-pull-up; }; }; }; diff --git a/arch/arm/dts/at91-sama5d2_icp.dts b/arch/arm/dts/at91-sama5d2_icp.dts index 0b0db1b2be..2dffae9c5c 100644 --- a/arch/arm/dts/at91-sama5d2_icp.dts +++ b/arch/arm/dts/at91-sama5d2_icp.dts @@ -86,75 +86,73 @@ }; }; - pioA: gpio@fc038000 { + pioA: pinctrl@fc038000 { status = "okay"; - pinctrl { - pinctrl_i2c1_default: i2c1_default { - pinmux = , - ; - bias-disable; - }; + pinctrl_i2c1_default: i2c1_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_macb0_rmii: macb0_rmii { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_macb0_rmii: macb0_rmii { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_macb0_phy_irq: macb0_phy_irq { - pinmux = ; - bias-disable; - }; + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = ; + bias-disable; + }; - pinctrl_macb0_rst: macb0_sw_rst { - pinmux = ; - bias-pull-up; - }; + pinctrl_macb0_rst: macb0_sw_rst { + pinmux = ; + bias-pull-up; + }; - pinctrl_mikrobus1_uart: mikrobus1_uart { - pinmux = , - ; - bias-disable; - }; + pinctrl_mikrobus1_uart: mikrobus1_uart { + pinmux = , + ; + bias-disable; + }; - pinctrl_qspi1_sck_cs_default: qspi1_sck_cs_default { - pinmux = , - ; - bias-disable; - }; + pinctrl_qspi1_sck_cs_default: qspi1_sck_cs_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_qspi1_dat_default: qspi1_dat_default { - pinmux = , - , - , - ; - bias-pull-up; - }; + pinctrl_qspi1_dat_default: qspi1_dat_default { + pinmux = , + , + , + ; + bias-pull-up; + }; - pinctrl_sdmmc0_default: sdmmc0_default { - pinmux = , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_sdmmc0_default: sdmmc0_default { + pinmux = , + , + , + , + , + , + ; + bias-disable; }; }; }; diff --git a/arch/arm/dts/at91-sama5d2_ptc_ek.dts b/arch/arm/dts/at91-sama5d2_ptc_ek.dts index f45fb1ef26..36d52c2c5e 100644 --- a/arch/arm/dts/at91-sama5d2_ptc_ek.dts +++ b/arch/arm/dts/at91-sama5d2_ptc_ek.dts @@ -94,7 +94,7 @@ sdmmc0: sdio-host@a0000000 { bus-width = <8>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc0_cmd_dat_default &pinctrl_sdmmc0_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc0_default>; status = "okay"; u-boot,dm-pre-reloc; }; @@ -102,7 +102,7 @@ sdmmc1: sdio-host@b0000000 { bus-width = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc1_cmd_dat_default &pinctrl_sdmmc1_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc1_default>; status = "disabled"; /* conflicts with nand and qspi0*/ u-boot,dm-pre-reloc; }; @@ -137,34 +137,34 @@ }; }; - pioA: gpio@fc038000 { - pinctrl { - pinctrl_i2c1_default: i2c1_default { - pinmux = , - ; - bias-disable; - }; + pioA: pinctrl@fc038000 { + pinctrl_i2c1_default: i2c1_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_macb0_phy_irq: macb0_phy_irq { - pinmux = ; - bias-disable; - }; + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = ; + bias-disable; + }; - pinctrl_macb0_rmii: macb0_rmii { - pinmux = , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_macb0_rmii: macb0_rmii { + pinmux = , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_sdmmc0_cmd_dat_default: sdmmc0_cmd_dat_default { + pinctrl_sdmmc0_default: sdmmc0_default { + cmd_dat { pinmux = , , , @@ -178,7 +178,7 @@ u-boot,dm-pre-reloc; }; - pinctrl_sdmmc0_ck_cd_default: sdmmc0_ck_cd_default { + ck_cd { pinmux = , , , @@ -186,8 +186,10 @@ bias-disable; u-boot,dm-pre-reloc; }; + }; - pinctrl_sdmmc1_cmd_dat_default: sdmmc1_cmd_dat_default { + pinctrl_sdmmc1_default: sdmmc1_default { + cmd_dat { pinmux = , , , @@ -197,34 +199,34 @@ u-boot,dm-pre-reloc; }; - pinctrl_sdmmc1_ck_cd_default: sdmmc1_ck_cd_default { + ck_cd { pinmux = , ; bias-disable; u-boot,dm-pre-reloc; }; + }; - pinctrl_uart0_default: uart0_default { - pinmux = , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_uart0_default: uart0_default { + pinmux = , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; - pinctrl_usb_default: usb_default { - pinmux = ; - bias-disable; - }; + pinctrl_usb_default: usb_default { + pinmux = ; + bias-disable; + }; - pinctrl_usba_vbus: usba_vbus { - pinmux = ; - bias-disable; - }; + pinctrl_usba_vbus: usba_vbus { + pinmux = ; + bias-disable; + }; - pinctrl_onewire_tm_default: onewire_tm_default { - pinmux = ; - bias-pull-up; - }; + pinctrl_onewire_tm_default: onewire_tm_default { + pinmux = ; + bias-pull-up; }; }; }; diff --git a/arch/arm/dts/at91-sama5d2_xplained.dts b/arch/arm/dts/at91-sama5d2_xplained.dts index 34b64a22af..78a3a851bb 100644 --- a/arch/arm/dts/at91-sama5d2_xplained.dts +++ b/arch/arm/dts/at91-sama5d2_xplained.dts @@ -44,7 +44,7 @@ sdmmc0: sdio-host@a0000000 { bus-width = <8>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc0_cmd_dat_default &pinctrl_sdmmc0_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc0_default>; status = "okay"; u-boot,dm-pre-reloc; }; @@ -52,7 +52,7 @@ sdmmc1: sdio-host@b0000000 { bus-width = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc1_cmd_dat_default &pinctrl_sdmmc1_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc1_default>; status = "okay"; /* conflict with qspi0 */ u-boot,dm-pre-reloc; }; @@ -143,85 +143,85 @@ }; }; - pioA: gpio@fc038000 { - pinctrl { - pinctrl_i2c1_default: i2c1_default { - pinmux = , - ; - bias-disable; - }; + pioA: pinctrl@fc038000 { + pinctrl_i2c1_default: i2c1_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_lcd_base: pinctrl_lcd_base { - pinmux = , - , - , - ; - bias-disable; - }; + pinctrl_lcd_base: pinctrl_lcd_base { + pinmux = , + , + , + ; + bias-disable; + }; - pinctrl_lcd_pwm: pinctrl_lcd_pwm { - pinmux = ; - bias-disable; - }; + pinctrl_lcd_pwm: pinctrl_lcd_pwm { + pinmux = ; + bias-disable; + }; - pinctrl_lcd_rgb666: pinctrl_lcd_rgb666 { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_lcd_rgb666: pinctrl_lcd_rgb666 { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_macb0_phy_irq: macb0_phy_irq { - pinmux = ; - bias-disable; - }; + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = ; + bias-disable; + }; - pinctrl_macb0_rmii: macb0_rmii { - pinmux = , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_macb0_rmii: macb0_rmii { + pinmux = , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_qspi0_sck_cs_default: qspi0_sck_cs_default { - pinmux = , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_qspi0_sck_cs_default: qspi0_sck_cs_default { + pinmux = , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; - pinctrl_qspi0_dat_default: qspi0_dat_default { - pinmux = , - , - , - ; - bias-pull-up; - u-boot,dm-pre-reloc; - }; + pinctrl_qspi0_dat_default: qspi0_dat_default { + pinmux = , + , + , + ; + bias-pull-up; + u-boot,dm-pre-reloc; + }; - pinctrl_sdmmc0_cmd_dat_default: sdmmc0_cmd_dat_default { + pinctrl_sdmmc0_default: sdmmc0_default { + cmd_dat { pinmux = , , , @@ -235,7 +235,7 @@ u-boot,dm-pre-reloc; }; - pinctrl_sdmmc0_ck_cd_default: sdmmc0_ck_cd_default { + ck_cd_default { pinmux = , , , @@ -243,8 +243,10 @@ bias-disable; u-boot,dm-pre-reloc; }; + }; - pinctrl_sdmmc1_cmd_dat_default: sdmmc1_cmd_dat_default { + pinctrl_sdmmc1_default: sdmmc1_default { + cmd_dat { pinmux = , , , @@ -254,42 +256,42 @@ u-boot,dm-pre-reloc; }; - pinctrl_sdmmc1_ck_cd_default: sdmmc1_ck_cd_default { + ck_cd { pinmux = , ; bias-disable; u-boot,dm-pre-reloc; }; + }; - pinctrl_spi0_default: spi0_default { - pinmux = , - , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_spi0_default: spi0_default { + pinmux = , + , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; - pinctrl_uart1_default: uart1_default { - pinmux = , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_uart1_default: uart1_default { + pinmux = , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; - pinctrl_usb_default: usb_default { - pinmux = ; - bias-disable; - }; + pinctrl_usb_default: usb_default { + pinmux = ; + bias-disable; + }; - pinctrl_usba_vbus: usba_vbus { - pinmux = ; - bias-disable; - }; + pinctrl_usba_vbus: usba_vbus { + pinmux = ; + bias-disable; + }; - pinctrl_onewire_tm_default: onewire_tm_default { - pinmux = ; - bias-pull-up; - }; + pinctrl_onewire_tm_default: onewire_tm_default { + pinmux = ; + bias-pull-up; }; }; }; diff --git a/arch/arm/dts/at91-sama7g5ek-u-boot.dtsi b/arch/arm/dts/at91-sama7g5ek-u-boot.dtsi index 601386788f..d294ddb54a 100644 --- a/arch/arm/dts/at91-sama7g5ek-u-boot.dtsi +++ b/arch/arm/dts/at91-sama7g5ek-u-boot.dtsi @@ -28,7 +28,7 @@ u-boot,dm-pre-reloc; }; -&pinctrl { +&pioA { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/at91-sama7g5ek.dts b/arch/arm/dts/at91-sama7g5ek.dts index eaba0de3f7..aed84f15a1 100644 --- a/arch/arm/dts/at91-sama7g5ek.dts +++ b/arch/arm/dts/at91-sama7g5ek.dts @@ -690,46 +690,67 @@ }; pinctrl_sdmmc0_default: sdmmc0_default { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - ; + cmd_data { + pinmux = , + , + , + , + , + , + , + , + ; slew-rate = <0>; bias-pull-up; + }; + + ck_cd_rstn_vddsel { + pinmux = , + , + , + ; + slew-rate = <0>; + bias-pull-up; + }; }; pinctrl_sdmmc1_default: sdmmc1_default { - pinmux = , - , - , - , - , - , - , - , - ; - slew-rate = <0>; - bias-pull-up; + cmd_data { + pinmux = , + , + , + , + ; + slew-rate = <0>; + bias-pull-up; + }; + + ck_cd_rstn_vddsel { + pinmux = , + , + , + ; + slew-rate = <0>; + bias-pull-up; + }; }; pinctrl_sdmmc2_default: sdmmc2_default { - pinmux = , - , - , - , - , - ; - slew-rate = <0>; - bias-pull-up; + cmd_data { + pinmux = , + , + , + , + ; + slew-rate = <0>; + bias-pull-up; + }; + + ck { + pinmux = ; + slew-rate = <0>; + bias-pull-up; + }; }; pinctrl_spdifrx_default: spdifrx_default { diff --git a/arch/arm/dts/dragonboard410c-uboot.dtsi b/arch/arm/dts/dragonboard410c-uboot.dtsi index 9c1be2566f..e4fecaa19e 100644 --- a/arch/arm/dts/dragonboard410c-uboot.dtsi +++ b/arch/arm/dts/dragonboard410c-uboot.dtsi @@ -14,7 +14,7 @@ soc { u-boot,dm-pre-reloc; - qcom,tlmm@1000000 { + pinctrl@1000000 { u-boot,dm-pre-reloc; uart { diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts index 50523712cb..59cf45eb17 100644 --- a/arch/arm/dts/dragonboard410c.dts +++ b/arch/arm/dts/dragonboard410c.dts @@ -60,9 +60,13 @@ reg = <0x60000 0x8000>; }; - pinctrl: qcom,tlmm@1000000 { - compatible = "qcom,tlmm-apq8016"; + soc_gpios: pinctrl@1000000 { + compatible = "qcom,msm8916-pinctrl"; reg = <0x1000000 0x400000>; + gpio-controller; + gpio-count = <122>; + gpio-bank-name="soc"; + #gpio-cells = <2>; blsp1_uart: uart { function = "blsp1_uart"; @@ -86,15 +90,6 @@ pinctrl-0 = <&blsp1_uart>; }; - soc_gpios: pinctrl@1000000 { - compatible = "qcom,apq8016-pinctrl"; - reg = <0x1000000 0x300000>; - gpio-controller; - gpio-count = <122>; - gpio-bank-name="soc"; - #gpio-cells = <2>; - }; - ehci@78d9000 { compatible = "qcom,ehci-host"; reg = <0x78d9000 0x400>; diff --git a/arch/arm/dts/dragonboard820c-uboot.dtsi b/arch/arm/dts/dragonboard820c-uboot.dtsi index 8610d7ec37..2270ac73bf 100644 --- a/arch/arm/dts/dragonboard820c-uboot.dtsi +++ b/arch/arm/dts/dragonboard820c-uboot.dtsi @@ -13,7 +13,7 @@ soc { u-boot,dm-pre-reloc; - qcom,tlmm@1010000 { + pinctrl@1010000 { u-boot,dm-pre-reloc; uart { diff --git a/arch/arm/dts/dragonboard820c.dts b/arch/arm/dts/dragonboard820c.dts index b72a2471cf..aaca681d2e 100644 --- a/arch/arm/dts/dragonboard820c.dts +++ b/arch/arm/dts/dragonboard820c.dts @@ -64,8 +64,8 @@ reg = <0x300000 0x90000>; }; - pinctrl: qcom,tlmm@1010000 { - compatible = "qcom,tlmm-apq8096"; + pinctrl: pinctrl@1010000 { + compatible = "qcom,msm8996-pinctrl"; reg = <0x1010000 0x400000>; blsp8_uart: uart { diff --git a/arch/arm/dts/mt7622-rfb.dts b/arch/arm/dts/mt7622-rfb.dts index 30a9137407..b44f19f05a 100644 --- a/arch/arm/dts/mt7622-rfb.dts +++ b/arch/arm/dts/mt7622-rfb.dts @@ -159,6 +159,14 @@ }; }; + + i2c1_pins_default: i2c1-default { + mux { + function = "i2c"; + groups = "i2c1_0"; + }; + }; + }; &snfi { @@ -242,3 +250,13 @@ &u3phy { status = "okay"; }; + +&soft_i2c { + status = "disabled"; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_default>; + status = "okay"; +}; diff --git a/arch/arm/dts/mt7622.dtsi b/arch/arm/dts/mt7622.dtsi index 0127474c95..2d89fa08b4 100644 --- a/arch/arm/dts/mt7622.dtsi +++ b/arch/arm/dts/mt7622.dtsi @@ -175,6 +175,7 @@ status = "disabled"; assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>; assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>; + mediatek,force-highspeed; }; mmc0: mmc@11230000 { @@ -423,4 +424,28 @@ status = "disabled"; }; + soft_i2c: soft_i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "i2c-gpio"; + gpios = <&gpio 56 GPIO_ACTIVE_HIGH>, /* SDA */ + <&gpio 55 GPIO_ACTIVE_HIGH>; /* CLK */ + i2c-gpio,delay-us = <5>; + status = "disabled"; + }; + + i2c1: i2c@11008000 { + compatible = "mediatek,mt7622-i2c"; + reg = <0x11008000 0x90>, + <0x11000180 0x80>; + interrupts = ; + clock-div = <16>; + clocks = <&pericfg CLK_PERI_I2C1_PD>, + <&pericfg CLK_PERI_AP_DMA_PD>; + clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; diff --git a/arch/arm/dts/mt7981-emmc-rfb.dts b/arch/arm/dts/mt7981-emmc-rfb.dts new file mode 100644 index 0000000000..2b7eae99ce --- /dev/null +++ b/arch/arm/dts/mt7981-emmc-rfb.dts @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7981.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7981-rfb"; + compatible = "mediatek,mt7981", "mediatek,mt7981-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_1"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + /* pin15 as pwm0 */ + one_pwm_pins: one-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1"; + }; + }; + + /* pin15 as pwm0 and pin14 as pwm1 */ + two_pwm_pins: two-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1", "pwm1_0"; + }; + }; + + /* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */ + three_pwm_pins: three-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1", "pwm1_0", "pwm2"; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "flash"; + groups = "emmc_45"; + }; + conf-cmd-dat { + pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO", + "SPI0_CS", "SPI0_HOLD", "SPI0_WP", + "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + conf-clk { + pins = "SPI1_CS"; + drive-strength = ; + bias-pull-down = ; + }; + conf-rst { + pins = "PWM0"; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&two_pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + bus-width = <8>; + max-frequency = <52000000>; + cap-mmc-highspeed; + cap-mmc-hw-reset; + vmmc-supply = <®_3p3v>; + non-removable; + status = "okay"; +}; diff --git a/arch/arm/dts/mt7981-rfb.dts b/arch/arm/dts/mt7981-rfb.dts new file mode 100644 index 0000000000..5559ace953 --- /dev/null +++ b/arch/arm/dts/mt7981-rfb.dts @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7981.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7981-rfb"; + compatible = "mediatek,mt7981", "mediatek,mt7981-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spi_flash_pins: spi0-pins-func-1 { + mux { + function = "flash"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pu { + pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + spi2_flash_pins: spi2-spi2-pins { + mux { + function = "spi"; + groups = "spi2", "spi2_wp_hold"; + }; + + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_1"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + /* pin15 as pwm0 */ + one_pwm_pins: one-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1"; + }; + }; + + /* pin15 as pwm0 and pin14 as pwm1 */ + two_pwm_pins: two-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1", "pwm1_0"; + }; + }; + + /* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */ + three_pwm_pins: three-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1", "pwm1_0", "pwm2"; + }; + }; +}; + +&spi0 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + must_tx; + enhance_timing; + dma_ext; + ipm_design; + support_quad; + tick_dly = <2>; + sample_sel = <0>; + + spi_nand@0 { + compatible = "spi-nand"; + reg = <0>; + spi-max-frequency = <52000000>; + }; +}; + +&spi2 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi2_flash_pins>; + status = "okay"; + must_tx; + enhance_timing; + dma_ext; + ipm_design; + support_quad; + tick_dly = <2>; + sample_sel = <0>; + + spi_nor@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <52000000>; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&two_pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; diff --git a/arch/arm/dts/mt7981-sd-rfb.dts b/arch/arm/dts/mt7981-sd-rfb.dts new file mode 100644 index 0000000000..34ac227ecf --- /dev/null +++ b/arch/arm/dts/mt7981-sd-rfb.dts @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7981.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7981-rfb"; + compatible = "mediatek,mt7981", "mediatek,mt7981-sd-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_1"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + /* pin15 as pwm0 */ + one_pwm_pins: one-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1"; + }; + }; + + /* pin15 as pwm0 and pin14 as pwm1 */ + two_pwm_pins: two-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1", "pwm1_0"; + }; + }; + + /* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */ + three_pwm_pins: three-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1", "pwm1_0", "pwm2"; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "flash"; + groups = "emmc_45"; + }; + conf-cmd-dat { + pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO", + "SPI0_CS", "SPI0_HOLD", "SPI0_WP", + "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + conf-clk { + pins = "SPI1_CS"; + drive-strength = ; + bias-pull-down = ; + }; + conf-rst { + pins = "PWM0"; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&two_pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + bus-width = <4>; + max-frequency = <52000000>; + cap-sd-highspeed; + r_smpl = <0>; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + status = "okay"; +}; diff --git a/arch/arm/dts/mt7981.dtsi b/arch/arm/dts/mt7981.dtsi new file mode 100644 index 0000000000..3089371805 --- /dev/null +++ b/arch/arm/dts/mt7981.dtsi @@ -0,0 +1,295 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include +#include +#include +#include + +/ { + compatible = "mediatek,mt7981"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0>; + mediatek,hwver = <&hwver>; + }; + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x1>; + mediatek,hwver = <&hwver>; + }; + }; + + gpt_clk: gpt_dummy20m { + compatible = "fixed-clock"; + clock-frequency = <13000000>; + #clock-cells = <0>; + u-boot,dm-pre-reloc; + }; + + hwver: hwver { + compatible = "mediatek,hwver", "syscon"; + reg = <0x8000000 0x1000>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + clock-frequency = <13000000>; + interrupts = , + , + , + ; + arm,cpu-registers-not-fw-configured; + }; + + timer0: timer@10008000 { + compatible = "mediatek,mt7986-timer"; + reg = <0x10008000 0x1000>; + interrupts = ; + clocks = <&gpt_clk>; + clock-names = "gpt-clk"; + u-boot,dm-pre-reloc; + }; + + watchdog: watchdog@1001c000 { + compatible = "mediatek,mt7986-wdt"; + reg = <0x1001c000 0x1000>; + interrupts = ; + #reset-cells = <1>; + status = "disabled"; + }; + + gic: interrupt-controller@c000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + interrupt-controller; + reg = <0x0c000000 0x40000>, /* GICD */ + <0x0c080000 0x200000>; /* GICR */ + + interrupts = ; + }; + + fixed_plls: apmixedsys@1001e000 { + compatible = "mediatek,mt7981-fixed-plls"; + reg = <0x1001e000 0x1000>; + #clock-cells = <1>; + u-boot,dm-pre-reloc; + }; + + topckgen: topckgen@1001b000 { + compatible = "mediatek,mt7981-topckgen"; + reg = <0x1001b000 0x1000>; + clock-parent = <&fixed_plls>; + #clock-cells = <1>; + u-boot,dm-pre-reloc; + }; + + infracfg_ao: infracfg_ao@10001000 { + compatible = "mediatek,mt7981-infracfg_ao"; + reg = <0x10001000 0x80>; + clock-parent = <&infracfg>; + #clock-cells = <1>; + u-boot,dm-pre-reloc; + }; + + infracfg: infracfg@10001000 { + compatible = "mediatek,mt7981-infracfg"; + reg = <0x10001000 0x30>; + clock-parent = <&topckgen>; + #clock-cells = <1>; + u-boot,dm-pre-reloc; + }; + + pinctrl: pinctrl@11d00000 { + compatible = "mediatek,mt7981-pinctrl"; + reg = <0x11d00000 0x1000>, + <0x11c00000 0x1000>, + <0x11c10000 0x1000>, + <0x11d20000 0x1000>, + <0x11e00000 0x1000>, + <0x11e20000 0x1000>, + <0x11f00000 0x1000>, + <0x11f10000 0x1000>, + <0x1000b000 0x1000>; + reg-names = "gpio_base", "iocfg_rt_base", "iocfg_rm_base", + "iocfg_rb_base", "iocfg_lb_base", "iocfg_bl_base", + "iocfg_tm_base", "iocfg_tl_base", "eint"; + gpio: gpio-controller { + gpio-controller; + #gpio-cells = <2>; + }; + }; + + pwm: pwm@10048000 { + compatible = "mediatek,mt7981-pwm"; + reg = <0x10048000 0x1000>; + #clock-cells = <1>; + #pwm-cells = <2>; + interrupts = ; + clocks = <&infracfg CK_INFRA_PWM>, + <&infracfg_ao CK_INFRA_PWM_BSEL>, + <&infracfg_ao CK_INFRA_PWM1_CK>, + <&infracfg_ao CK_INFRA_PWM2_CK>, + /* FIXME */ + <&infracfg_ao CK_INFRA_PWM2_CK>; + assigned-clocks = <&topckgen CK_TOP_PWM_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>; + clock-names = "top", "main", "pwm1", "pwm2", "pwm3"; + status = "disabled"; + }; + + uart0: serial@11002000 { + compatible = "mediatek,hsuart"; + reg = <0x11002000 0x400>; + interrupts = ; + clocks = <&infracfg_ao CK_INFRA_UART0_CK>; + assigned-clocks = <&topckgen CK_TOP_UART_SEL>, + <&infracfg_ao CK_INFRA_UART0_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>, + <&infracfg CK_INFRA_UART>; + mediatek,force-highspeed; + status = "disabled"; + u-boot,dm-pre-reloc; + }; + + uart1: serial@11003000 { + compatible = "mediatek,hsuart"; + reg = <0x11003000 0x400>; + interrupts = ; + clocks = <&infracfg_ao CK_INFRA_UART1_CK>; + assigned-clocks = <&topckgen CK_TOP_UART_SEL>, + <&infracfg_ao CK_INFRA_UART1_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>, + <&infracfg CK_INFRA_UART>; + mediatek,force-highspeed; + status = "disabled"; + }; + + uart2: serial@11004000 { + compatible = "mediatek,hsuart"; + reg = <0x11004000 0x400>; + interrupts = ; + clocks = <&infracfg_ao CK_INFRA_UART2_CK>; + assigned-clocks = <&topckgen CK_TOP_UART_SEL>, + <&infracfg_ao CK_INFRA_UART2_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>, + <&infracfg CK_INFRA_UART>; + mediatek,force-highspeed; + status = "disabled"; + }; + + snand: snand@11005000 { + compatible = "mediatek,mt7986-snand"; + reg = <0x11005000 0x1000>, + <0x11006000 0x1000>; + reg-names = "nfi", "ecc"; + clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>, + <&infracfg_ao CK_INFRA_NFI1_CK>, + <&infracfg_ao CK_INFRA_NFI_HCK_CK>; + clock-names = "pad_clk", "nfi_clk", "nfi_hclk"; + assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>, + <&topckgen CK_TOP_NFI1X_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_D8>, + <&topckgen CK_TOP_CB_M_D8>; + status = "disabled"; + }; + + ethsys: syscon@15000000 { + compatible = "mediatek,mt7981-ethsys", "syscon"; + reg = <0x15000000 0x1000>; + clock-parent = <&topckgen>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + eth: ethernet@15100000 { + compatible = "mediatek,mt7981-eth", "syscon"; + reg = <0x15100000 0x20000>; + resets = <ðsys ETHSYS_FE_RST>; + reset-names = "fe"; + mediatek,ethsys = <ðsys>; + mediatek,sgmiisys = <&sgmiisys0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + sgmiisys0: syscon@10060000 { + compatible = "mediatek,mt7986-sgmiisys", "syscon"; + reg = <0x10060000 0x1000>; + pn_swap; + #clock-cells = <1>; + }; + + sgmiisys1: syscon@10070000 { + compatible = "mediatek,mt7986-sgmiisys", "syscon"; + reg = <0x10070000 0x1000>; + #clock-cells = <1>; + }; + + spi0: spi@1100a000 { + compatible = "mediatek,ipm-spi"; + reg = <0x1100a000 0x100>; + clocks = <&infracfg_ao CK_INFRA_SPI0_CK>, + <&topckgen CK_TOP_SPI_SEL>; + assigned-clocks = <&topckgen CK_TOP_SPI_SEL>, + <&infracfg CK_INFRA_SPI0_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>, + <&topckgen CK_INFRA_ISPI0>; + clock-names = "sel-clk", "spi-clk"; + interrupts = ; + status = "disabled"; + }; + + spi1: spi@1100b000 { + compatible = "mediatek,ipm-spi"; + reg = <0x1100b000 0x100>; + interrupts = ; + status = "disabled"; + }; + + spi2: spi@11009000 { + compatible = "mediatek,ipm-spi"; + reg = <0x11009000 0x100>; + clocks = <&infracfg_ao CK_INFRA_SPI0_CK>, + <&topckgen CK_TOP_SPI_SEL>; + assigned-clocks = <&topckgen CK_TOP_SPI_SEL>, + <&infracfg CK_INFRA_SPI0_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>, + <&topckgen CK_INFRA_ISPI0>; + clock-names = "sel-clk", "spi-clk"; + interrupts = ; + status = "disabled"; + }; + + mmc0: mmc@11230000 { + compatible = "mediatek,mt7981-mmc"; + reg = <0x11230000 0x1000>, + <0x11C20000 0x1000>; + interrupts = ; + clocks = <&topckgen CK_TOP_EMMC_400M>, + <&topckgen CK_TOP_EMMC_208M>, + <&infracfg_ao CK_INFRA_MSDC_CK>; + assigned-clocks = <&topckgen CK_TOP_EMMC_400M_SEL>, + <&topckgen CK_TOP_EMMC_208M_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_NET2_D2>, + <&topckgen CK_TOP_CB_M_D2>; + clock-names = "source", "hclk", "source_cg"; + status = "disabled"; + }; + +}; diff --git a/arch/arm/dts/mt7986-u-boot.dtsi b/arch/arm/dts/mt7986-u-boot.dtsi new file mode 100644 index 0000000000..95671f8afa --- /dev/null +++ b/arch/arm/dts/mt7986-u-boot.dtsi @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +&topckgen { + u-boot,dm-pre-reloc; +}; + +&pericfg { + u-boot,dm-pre-reloc; +}; + +&apmixedsys { + u-boot,dm-pre-reloc; +}; + +&timer0 { + u-boot,dm-pre-reloc; +}; + +&uart0 { + u-boot,dm-pre-reloc; +}; + +&snand { + u-boot,dm-pre-reloc; +}; + +&pinctrl { + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/dts/mt7986.dtsi b/arch/arm/dts/mt7986.dtsi new file mode 100644 index 0000000000..794ab1f4bd --- /dev/null +++ b/arch/arm/dts/mt7986.dtsi @@ -0,0 +1,350 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include +#include +#include +#include +#include + +/ { + compatible = "mediatek,mt7986"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + config { + u-boot,mmc-env-partition = "u-boot-env"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0>; + mediatek,hwver = <&hwver>; + }; + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x1>; + mediatek,hwver = <&hwver>; + }; + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x2>; + mediatek,hwver = <&hwver>; + }; + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x3>; + mediatek,hwver = <&hwver>; + }; + }; + + dummy_clk: dummy12m { + compatible = "fixed-clock"; + clock-frequency = <12000000>; + #clock-cells = <0>; + /* must need this line, or uart uanable to get dummy_clk */ + u-boot,dm-pre-reloc; + }; + + hwver: hwver { + compatible = "mediatek,hwver", "syscon"; + reg = <0x8000000 0x1000>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + clock-frequency = <13000000>; + interrupts = , + , + , + ; + arm,cpu-registers-not-fw-configured; + }; + + timer0: timer@10008000 { + compatible = "mediatek,mt7986-timer"; + reg = <0x10008000 0x1000>; + interrupts = ; + clocks = <&infracfg CK_INFRA_CK_F26M>; + clock-names = "gpt-clk"; + u-boot,dm-pre-reloc; + }; + + watchdog: watchdog@1001c000 { + compatible = "mediatek,mt7986-wdt"; + reg = <0x1001c000 0x1000>; + interrupts = ; + #reset-cells = <1>; + status = "disabled"; + }; + + gic: interrupt-controller@c000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + interrupt-controller; + reg = <0x0c000000 0x40000>, /* GICD */ + <0x0c080000 0x200000>; /* GICR */ + + interrupts = ; + }; + + fixed_plls: apmixedsys@1001E000 { + compatible = "mediatek,mt7986-fixed-plls"; + reg = <0x1001E000 0x1000>; + #clock-cells = <1>; + }; + + topckgen: topckgen@1001B000 { + compatible = "mediatek,mt7986-topckgen"; + reg = <0x1001B000 0x1000>; + clock-parent = <&fixed_plls>; + #clock-cells = <1>; + }; + + infracfg_ao: infracfg_ao@10001000 { + compatible = "mediatek,mt7986-infracfg_ao"; + reg = <0x10001000 0x68>; + clock-parent = <&infracfg>; + #clock-cells = <1>; + }; + + infracfg: infracfg@10001040 { + compatible = "mediatek,mt7986-infracfg"; + reg = <0x10001000 0x1000>; + clock-parent = <&topckgen>; + #clock-cells = <1>; + }; + + pinctrl: pinctrl@1001f000 { + compatible = "mediatek,mt7986-pinctrl"; + reg = <0x1001f000 0x1000>, + <0x11c30000 0x1000>, + <0x11c40000 0x1000>, + <0x11e20000 0x1000>, + <0x11e30000 0x1000>, + <0x11f00000 0x1000>, + <0x11f10000 0x1000>, + <0x1000b000 0x1000>; + reg-names = "gpio_base", "iocfg_rt_base", "iocfg_rb_base", + "iocfg_lt_base", "iocfg_lb_base", "iocfg_tr_base", + "iocfg_tl_base", "eint"; + gpio: gpio-controller { + gpio-controller; + #gpio-cells = <2>; + }; + }; + + pwm: pwm@10048000 { + compatible = "mediatek,mt7986-pwm"; + reg = <0x10048000 0x1000>; + #clock-cells = <1>; + #pwm-cells = <2>; + interrupts = ; + clocks = <&infracfg CK_INFRA_PWM>, + <&infracfg_ao CK_INFRA_PWM_BSEL>, + <&infracfg_ao CK_INFRA_PWM1_CK>, + <&infracfg_ao CK_INFRA_PWM2_CK>; + assigned-clocks = <&topckgen CK_TOP_PWM_SEL>, + <&infracfg CK_INFRA_PWM_BSEL>, + <&infracfg CK_INFRA_PWM1_SEL>, + <&infracfg CK_INFRA_PWM2_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_D4>, + <&infracfg CK_INFRA_PWM>, + <&infracfg CK_INFRA_PWM>, + <&infracfg CK_INFRA_PWM>; + clock-names = "top", "main", "pwm1", "pwm2"; + status = "disabled"; + u-boot,dm-pre-reloc; + }; + + uart0: serial@11002000 { + compatible = "mediatek,hsuart"; + reg = <0x11002000 0x400>; + interrupts = ; + clocks = <&infracfg_ao CK_INFRA_UART0_CK>; + assigned-clocks = <&topckgen CK_TOP_UART_SEL>, + <&infracfg_ao CK_INFRA_UART0_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>, + <&infracfg CK_INFRA_UART>; + mediatek,force-highspeed; + status = "disabled"; + u-boot,dm-pre-reloc; + }; + + uart1: serial@11003000 { + compatible = "mediatek,hsuart"; + reg = <0x11003000 0x400>; + interrupts = ; + clocks = <&infracfg_ao CK_INFRA_UART1_CK>; + assigned-clocks = <&infracfg CK_INFRA_UART1_SEL>; + assigned-clock-parents = <&infracfg CK_INFRA_CK_F26M>; + mediatek,force-highspeed; + status = "disabled"; + }; + + uart2: serial@11004000 { + compatible = "mediatek,hsuart"; + reg = <0x11004000 0x400>; + interrupts = ; + clocks = <&infracfg_ao CK_INFRA_UART2_CK>; + assigned-clocks = <&infracfg CK_INFRA_UART2_SEL>; + assigned-clock-parents = <&infracfg CK_INFRA_CK_F26M>; + mediatek,force-highspeed; + status = "disabled"; + }; + + snand: snand@11005000 { + compatible = "mediatek,mt7986-snand"; + reg = <0x11005000 0x1000>, + <0x11006000 0x1000>; + reg-names = "nfi", "ecc"; + clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>, + <&infracfg_ao CK_INFRA_NFI1_CK>, + <&infracfg_ao CK_INFRA_NFI_HCK_CK>; + clock-names = "pad_clk", "nfi_clk", "nfi_hclk"; + assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>, + <&topckgen CK_TOP_NFI1X_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_D8>, + <&topckgen CK_TOP_CB_M_D8>; + status = "disabled"; + }; + + ethsys: syscon@15000000 { + compatible = "mediatek,mt7986-ethsys", "syscon"; + reg = <0x15000000 0x1000>; + clock-parent = <&topckgen>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + eth: ethernet@15100000 { + compatible = "mediatek,mt7986-eth", "syscon"; + reg = <0x15100000 0x20000>; + resets = <ðsys ETHSYS_FE_RST>; + reset-names = "fe"; + mediatek,ethsys = <ðsys>; + mediatek,sgmiisys = <&sgmiisys0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + sgmiisys0: syscon@10060000 { + compatible = "mediatek,mt7986-sgmiisys", "syscon"; + reg = <0x10060000 0x1000>; + #clock-cells = <1>; + }; + + sgmiisys1: syscon@10070000 { + compatible = "mediatek,mt7986-sgmiisys", "syscon"; + reg = <0x10070000 0x1000>; + #clock-cells = <1>; + }; + + spi0: spi@1100a000 { + compatible = "mediatek,ipm-spi"; + reg = <0x1100a000 0x100>; + clocks = <&infracfg_ao CK_INFRA_SPI0_CK>, + <&topckgen CK_TOP_SPI_SEL>; + assigned-clocks = <&topckgen CK_TOP_SPI_SEL>, + <&infracfg CK_INFRA_SPI0_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>, + <&topckgen CK_INFRA_ISPI0>; + clock-names = "sel-clk", "spi-clk"; + interrupts = ; + status = "disabled"; + }; + + spi1: spi@1100b000 { + compatible = "mediatek,ipm-spi"; + reg = <0x1100b000 0x100>; + interrupts = ; + status = "disabled"; + }; + + mmc0: mmc@11230000 { + compatible = "mediatek,mt7986-mmc"; + reg = <0x11230000 0x1000>, + <0x11C20000 0x1000>; + interrupts = ; + clocks = <&topckgen CK_TOP_EMMC_416M>, + <&topckgen CK_TOP_EMMC_250M>, + <&infracfg_ao CK_INFRA_MSDC_CK>; + assigned-clocks = <&topckgen CK_TOP_EMMC_416M_SEL>, + <&topckgen CK_TOP_EMMC_250M_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_416M>, + <&topckgen CK_TOP_NET1_D5_D2>; + clock-names = "source", "hclk", "source_cg"; + status = "disabled"; + }; + + xhci: xhci@11200000 { + compatible = "mediatek,mt7986-xhci", + "mediatek,mtk-xhci"; + reg = <0x11200000 0x2e00>, + <0x11203e00 0x0100>; + reg-names = "mac", "ippc"; + interrupts = ; + phys = <&u2port0 PHY_TYPE_USB2>, + <&u3port0 PHY_TYPE_USB3>, + <&u2port1 PHY_TYPE_USB2>; + clocks = <&dummy_clk>, + <&dummy_clk>, + <&dummy_clk>, + <&dummy_clk>, + <&dummy_clk>; + clock-names = "sys_ck", + "xhci_ck", + "ref_ck", + "mcu_ck", + "dma_ck"; + tpl-support; + status = "okay"; + }; + + usbtphy: usb-phy@11e10000 { + compatible = "mediatek,mt7986", + "mediatek,generic-tphy-v2"; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + + u2port0: usb-phy@11e10000 { + reg = <0x11e10000 0x700>; + clocks = <&dummy_clk>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + + u3port0: usb-phy@11e10700 { + reg = <0x11e10700 0x900>; + clocks = <&dummy_clk>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + + u2port1: usb-phy@11e11000 { + reg = <0x11e11000 0x700>; + clocks = <&dummy_clk>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/dts/mt7986a-emmc-rfb.dts b/arch/arm/dts/mt7986a-emmc-rfb.dts new file mode 100644 index 0000000000..315bdd0b14 --- /dev/null +++ b/arch/arm/dts/mt7986a-emmc-rfb.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7986a-rfb.dts" + +/ { + compatible = "mediatek,mt7986", "mediatek,mt7986-rfb", + "mediatek,mt7986-emmc-rfb"; + bl2_verify { + bl2_compatible = "emmc"; + }; +}; diff --git a/arch/arm/dts/mt7986a-rfb.dts b/arch/arm/dts/mt7986a-rfb.dts new file mode 100644 index 0000000000..80def57e1a --- /dev/null +++ b/arch/arm/dts/mt7986a-rfb.dts @@ -0,0 +1,218 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7986.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7986-rfb"; + compatible = "mediatek,mt7986", "mediatek,mt7986-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spi_flash_pins: spi0-pins-func-1 { + mux { + function = "flash"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + snfi_pins: snfi-pins-func-1 { + mux { + function = "flash"; + groups = "snfi"; + }; + + clk { + pins = "SPI0_CLK"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-pu { + pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI0_MOSI", "SPI0_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_2"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + pwm_pins: pwm0-pins-func-1 { + mux { + function = "pwm"; + groups = "pwm0"; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "flash"; + groups = "emmc_51"; + }; + + conf-cmd-dat { + pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2", + "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5", + "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD"; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + conf-clk { + pins = "EMMC_CK"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-dsl { + pins = "EMMC_DSL"; + bias-pull-down = ; + }; + + conf-rst { + pins = "EMMC_RSTB"; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; + +&snand { + pinctrl-names = "default"; + pinctrl-0 = <&snfi_pins>; + status = "okay"; + quad-spi; +}; + +&spi0 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + must_tx; + enhance_timing; + dma_ext; + ipm_design; + support_quad; + tick_dly = <2>; + sample_sel = <0>; + + spi_nor@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <52000000>; + }; + + spi_nand@1 { + compatible = "spi-nand"; + reg = <1>; + spi-max-frequency = <52000000>; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + bus-width = <8>; + max-frequency = <52000000>; + cap-mmc-highspeed; + cap-mmc-hw-reset; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_1p8v>; + non-removable; + status = "okay"; +}; diff --git a/arch/arm/dts/mt7986a-sd-rfb.dts b/arch/arm/dts/mt7986a-sd-rfb.dts new file mode 100644 index 0000000000..5807c5d5cc --- /dev/null +++ b/arch/arm/dts/mt7986a-sd-rfb.dts @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7986.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7986-rfb"; + compatible = "mediatek,mt7986", "mediatek,mt7986-rfb", + "mediatek,mt7986-sd-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spi_flash_pins: spi0-pins-func-1 { + mux { + function = "flash"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_2"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + pwm_pins: pwm0-pins-func-1 { + mux { + function = "pwm"; + groups = "pwm0"; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "flash"; + groups = "emmc_51"; + }; + + conf-cmd-dat { + pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2", + "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5", + "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD"; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + conf-clk { + pins = "EMMC_CK"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-dsl { + pins = "EMMC_DSL"; + bias-pull-down = ; + }; + + conf-rst { + pins = "EMMC_RSTB"; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; + +&spi0 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + must_tx; + enhance_timing; + dma_ext; + ipm_design; + support_quad; + tick_dly = <2>; + sample_sel = <0>; + + spi_nor@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <52000000>; + }; + + spi_nand@1 { + compatible = "spi-nand"; + reg = <1>; + spi-max-frequency = <52000000>; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + bus-width = <4>; + max-frequency = <52000000>; + cap-sd-highspeed; + r_smpl = <1>; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + status = "okay"; +}; diff --git a/arch/arm/dts/mt7986b-emmc-rfb.dts b/arch/arm/dts/mt7986b-emmc-rfb.dts new file mode 100644 index 0000000000..315bdd0b14 --- /dev/null +++ b/arch/arm/dts/mt7986b-emmc-rfb.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7986a-rfb.dts" + +/ { + compatible = "mediatek,mt7986", "mediatek,mt7986-rfb", + "mediatek,mt7986-emmc-rfb"; + bl2_verify { + bl2_compatible = "emmc"; + }; +}; diff --git a/arch/arm/dts/mt7986b-rfb.dts b/arch/arm/dts/mt7986b-rfb.dts new file mode 100644 index 0000000000..0c4e3e878f --- /dev/null +++ b/arch/arm/dts/mt7986b-rfb.dts @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7986.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7986-rfb"; + compatible = "mediatek,mt7986", "mediatek,mt7986-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spi_flash_pins: spi0-pins-func-1 { + mux { + function = "flash"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + snfi_pins: snfi-pins-func-1 { + mux { + function = "flash"; + groups = "snfi"; + }; + + clk { + pins = "SPI0_CLK"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-pu { + pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI0_MOSI", "SPI0_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_2"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + pwm_pins: pwm0-pins-func-1 { + mux { + function = "pwm"; + groups = "pwm0"; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "flash"; + groups = "emmc_45"; + input-schmitt-enable; + }; + + conf-cmd-dat { + pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO", + "SPI0_CS", "SPI0_HOLD", "SPI0_WP", + "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + conf-clk { + pins = "SPI1_CS"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-rst { + pins = "PWM1"; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; + +&snand { + pinctrl-names = "default"; + pinctrl-0 = <&snfi_pins>; + status = "okay"; + quad-spi; +}; + +&spi0 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + must_tx; + enhance_timing; + dma_ext; + ipm_design; + support_quad; + tick_dly = <2>; + sample_sel = <0>; + + spi_nor@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <52000000>; + }; + + spi_nand@1 { + compatible = "spi-nand"; + reg = <1>; + spi-max-frequency = <52000000>; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + bus-width = <8>; + max-frequency = <52000000>; + cap-mmc-highspeed; + cap-mmc-hw-reset; + vmmc-supply = <®_3p3v>; + non-removable; + status = "okay"; +}; diff --git a/arch/arm/dts/mt7986b-sd-rfb.dts b/arch/arm/dts/mt7986b-sd-rfb.dts new file mode 100644 index 0000000000..48f9320e7a --- /dev/null +++ b/arch/arm/dts/mt7986b-sd-rfb.dts @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7986.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7986-rfb"; + compatible = "mediatek,mt7986", "mediatek,mt7986-rfb", + "mediatek,mt7986-sd-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spi_flash_pins: spi0-pins-func-1 { + mux { + function = "flash"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_2"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + pwm_pins: pwm0-pins-func-1 { + mux { + function = "pwm"; + groups = "pwm0"; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "flash"; + groups = "emmc_45"; + input-schmitt-enable; + }; + + conf-cmd-dat { + pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO", + "SPI0_CS", "SPI0_HOLD", "SPI0_WP", + "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + conf-clk { + pins = "SPI1_CS"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-rst { + pins = "PWM1"; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; + +&spi0 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + must_tx; + enhance_timing; + dma_ext; + ipm_design; + support_quad; + tick_dly = <2>; + sample_sel = <0>; + + spi_nor@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <52000000>; + }; + + spi_nand@1 { + compatible = "spi-nand"; + reg = <1>; + spi-max-frequency = <52000000>; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + bus-width = <4>; + max-frequency = <52000000>; + cap-sd-highspeed; + r_smpl = <1>; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + status = "okay"; +}; diff --git a/arch/arm/dts/mvebu-u-boot.dtsi b/arch/arm/dts/mvebu-u-boot.dtsi index 5538f95148..db4bf39920 100644 --- a/arch/arm/dts/mvebu-u-boot.dtsi +++ b/arch/arm/dts/mvebu-u-boot.dtsi @@ -15,6 +15,17 @@ u-boot,dm-pre-reloc; }; +#ifdef CONFIG_ARMADA_375 +/* Armada 375 has multiple timers, use timer1 here */ +&timer1 { + u-boot,dm-pre-reloc; +}; +#else +&timer { + u-boot,dm-pre-reloc; +}; +#endif + #ifdef CONFIG_SPL_SPI &spi0 { u-boot,dm-pre-reloc; diff --git a/arch/arm/dts/qcom-ipq4019.dtsi b/arch/arm/dts/qcom-ipq4019.dtsi index 7a52ea2c4e..181732d262 100644 --- a/arch/arm/dts/qcom-ipq4019.dtsi +++ b/arch/arm/dts/qcom-ipq4019.dtsi @@ -75,9 +75,13 @@ u-boot,dm-pre-reloc; }; - pinctrl: qcom,tlmm@1000000 { - compatible = "qcom,tlmm-ipq4019"; + soc_gpios: pinctrl@1000000 { + compatible = "qcom,ipq4019-pinctrl"; reg = <0x1000000 0x300000>; + gpio-controller; + gpio-count = <100>; + gpio-bank-name="soc"; + #gpio-cells = <2>; u-boot,dm-pre-reloc; }; @@ -90,16 +94,6 @@ u-boot,dm-pre-reloc; }; - soc_gpios: pinctrl@1000000 { - compatible = "qcom,ipq4019-pinctrl"; - reg = <0x1000000 0x300000>; - gpio-controller; - gpio-count = <100>; - gpio-bank-name="soc"; - #gpio-cells = <2>; - u-boot,dm-pre-reloc; - }; - blsp1_spi1: spi@78b5000 { compatible = "qcom,spi-qup-v2.2.1"; reg = <0x78b5000 0x600>; diff --git a/arch/arm/dts/qcs404-evb-uboot.dtsi b/arch/arm/dts/qcs404-evb-uboot.dtsi index c18080a483..c73d71e8c7 100644 --- a/arch/arm/dts/qcs404-evb-uboot.dtsi +++ b/arch/arm/dts/qcs404-evb-uboot.dtsi @@ -22,3 +22,9 @@ }; }; }; + +&pms405_gpios { + usb_vbus_boost_pin { + gpios = <&pms405_gpios 2 0>; + }; +}; diff --git a/arch/arm/dts/qcs404-evb.dts b/arch/arm/dts/qcs404-evb.dts index 4f0ae20bdb..0639af8fe3 100644 --- a/arch/arm/dts/qcs404-evb.dts +++ b/arch/arm/dts/qcs404-evb.dts @@ -38,7 +38,7 @@ compatible = "simple-bus"; pinctrl_north@1300000 { - compatible = "qcom,tlmm-qcs404"; + compatible = "qcom,qcs404-pinctrl"; reg = <0x1300000 0x200000>; blsp1_uart2: uart { @@ -52,6 +52,13 @@ reg = <0x1800000 0x80000>; #address-cells = <0x1>; #size-cells = <0x0>; + #clock-cells = <1>; + }; + + reset: gcc-reset@1800000 { + compatible = "qcom,gcc-reset-qcs404"; + reg = <0x1800000 0x80000>; + #reset-cells = <1>; }; debug_uart: serial@78b1000 { @@ -75,6 +82,117 @@ mmc-ddr-1_8v; mmc-hs400-1_8v; }; + + usb3_phy: phy@78000 { + compatible = "qcom,usb-ss-28nm-phy"; + #phy-cells = <0>; + reg = <0x78000 0x400>; + clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, + <&gcc GCC_USB3_PHY_PIPE_CLK>; + clock-names = "ahb", "pipe"; + resets = <&reset GCC_USB3_PHY_BCR>, + <&reset GCC_USB3PHY_PHY_BCR>; + reset-names = "com", "phy"; + }; + + usb2_phy_prim: phy@7a000 { + compatible = "qcom,usb-hs-28nm-femtophy"; + #phy-cells = <0>; + reg = <0x7a000 0x200>; + clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, + <&gcc GCC_USB2A_PHY_SLEEP_CLK>; + clock-names = "ahb", "sleep"; + resets = <&reset GCC_USB_HS_PHY_CFG_AHB_BCR>, + <&reset GCC_USB2A_PHY_BCR>; + reset-names = "phy", "por"; + }; + + usb2_phy_sec: phy@7c000 { + compatible = "qcom,usb-hs-28nm-femtophy"; + #phy-cells = <0>; + reg = <0x7c000 0x200>; + clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, + <&gcc GCC_USB2A_PHY_SLEEP_CLK>; + clock-names = "ahb", "sleep"; + resets = <&reset GCC_QUSB2_PHY_BCR>, + <&reset GCC_USB2_HS_PHY_ONLY_BCR>; + reset-names = "phy", "por"; + }; + + usb3: usb@7678800 { + compatible = "qcom,dwc3"; + reg = <0x7678800 0x400>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + clocks = <&gcc GCC_USB30_MASTER_CLK>, + <&gcc GCC_SYS_NOC_USB3_CLK>, + <&gcc GCC_USB30_SLEEP_CLK>, + <&gcc GCC_USB30_MOCK_UTMI_CLK>; + clock-names = "core", "iface", "sleep", "mock_utmi"; + + dwc3@7580000 { + compatible = "snps,dwc3"; + reg = <0x7580000 0xcd00>; + phys = <&usb2_phy_prim>, <&usb3_phy>; + phy-names = "usb2-phy", "usb3-phy"; + dr_mode = "host"; + snps,has-lpm-erratum; + snps,hird-threshold = /bits/ 8 <0x10>; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; + }; + }; + + usb2: usb@79b8800 { + compatible = "qcom,dwc3"; + reg = <0x79b8800 0x400>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>, + <&gcc GCC_PCNOC_USB2_CLK>, + <&gcc GCC_USB_HS_INACTIVITY_TIMERS_CLK>, + <&gcc GCC_USB20_MOCK_UTMI_CLK>; + clock-names = "core", "iface", "sleep", "mock_utmi"; + + dwc3@78c0000 { + compatible = "snps,dwc3"; + reg = <0x78c0000 0xcc00>; + phys = <&usb2_phy_sec>; + phy-names = "usb2-phy"; + dr_mode = "peripheral"; + snps,has-lpm-erratum; + snps,hird-threshold = /bits/ 8 <0x10>; + snps,usb3_lpm_capable; + maximum-speed = "high-speed"; + }; + }; + + spmi@200f000 { + compatible = "qcom,spmi-pmic-arb"; + reg = <0x200f000 0x1000 + 0x2400000 0x400000 + 0x2c00000 0x400000>; + #address-cells = <0x1>; + #size-cells = <0x1>; + + pms405_0: pms405@0 { + compatible = "qcom,spmi-pmic"; + reg = <0x0 0x1>; + #address-cells = <0x1>; + #size-cells = <0x1>; + + pms405_gpios: pms405_gpios@c000 { + compatible = "qcom,pms405-gpio"; + reg = <0xc000 0x400>; + gpio-controller; + gpio-count = <12>; + #gpio-cells = <2>; + gpio-bank-name="pmic"; + }; + }; + }; }; }; diff --git a/arch/arm/dts/sama5d2.dtsi b/arch/arm/dts/sama5d2.dtsi index d92bdd5588..790b746ed1 100644 --- a/arch/arm/dts/sama5d2.dtsi +++ b/arch/arm/dts/sama5d2.dtsi @@ -799,18 +799,13 @@ status = "disabled"; }; - pioA: gpio@fc038000 { - compatible = "atmel,sama5d2-gpio"; + pioA: pinctrl@fc038000 { + compatible = "atmel,sama5d2-pinctrl"; reg = <0xfc038000 0x600>; clocks = <&pioA_clk>; gpio-controller; #gpio-cells = <2>; u-boot,dm-pre-reloc; - - pinctrl { - compatible = "atmel,sama5d2-pinctrl"; - u-boot,dm-pre-reloc; - }; }; }; }; diff --git a/arch/arm/dts/sama5d27_som1.dtsi b/arch/arm/dts/sama5d27_som1.dtsi index db4fefadcd..f920077449 100644 --- a/arch/arm/dts/sama5d27_som1.dtsi +++ b/arch/arm/dts/sama5d27_som1.dtsi @@ -103,54 +103,52 @@ status = "okay"; }; - pioA: gpio@fc038000 { - pinctrl { - pinctrl_i2c0_default: i2c0_default { - pinmux = , - ; - bias-disable; - }; + pioA: pinctrl@fc038000 { + pinctrl_i2c0_default: i2c0_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_i2c1_default: i2c1_default { - pinmux = , - ; - bias-disable; - }; + pinctrl_i2c1_default: i2c1_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_macb0_phy_irq: macb0_phy_irq { - pinmux = ; - bias-disable; - }; + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = ; + bias-disable; + }; - pinctrl_macb0_rmii: macb0_rmii { - pinmux = , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_macb0_rmii: macb0_rmii { + pinmux = , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_qspi1_sck_cs_default: qspi1_sck_cs_default { - pinmux = , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_qspi1_sck_cs_default: qspi1_sck_cs_default { + pinmux = , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; - pinctrl_qspi1_dat_default: qspi1_dat_default { - pinmux = , - , - , - ; - bias-pull-up; - u-boot,dm-pre-reloc; - }; + pinctrl_qspi1_dat_default: qspi1_dat_default { + pinmux = , + , + , + ; + bias-pull-up; + u-boot,dm-pre-reloc; }; }; }; diff --git a/arch/arm/dts/sama5d27_wlsom1.dtsi b/arch/arm/dts/sama5d27_wlsom1.dtsi index 889a0034d1..1c23b8c737 100644 --- a/arch/arm/dts/sama5d27_wlsom1.dtsi +++ b/arch/arm/dts/sama5d27_wlsom1.dtsi @@ -41,36 +41,34 @@ }; }; - pioA: gpio@fc038000 { - pinctrl { - pinctrl_macb0_phy_irq: macb0_phy_irq { - pinmux = ; - bias-disable; - }; + pioA: pinctrl@fc038000 { + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = ; + bias-disable; + }; - pinctrl_macb0_rmii: macb0_rmii { - pinmux = , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_macb0_rmii: macb0_rmii { + pinmux = , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_qspi1_default: qspi1_default { - pinmux = , - , - , - , - , - ; - bias-pull-up; - }; + pinctrl_qspi1_default: qspi1_default { + pinmux = , + , + , + , + , + ; + bias-pull-up; }; }; }; diff --git a/arch/arm/dts/sama7g5.dtsi b/arch/arm/dts/sama7g5.dtsi index 97400dc18e..d38090d7dd 100644 --- a/arch/arm/dts/sama7g5.dtsi +++ b/arch/arm/dts/sama7g5.dtsi @@ -187,8 +187,8 @@ reg = <0xe0008000 0x20>; }; - pinctrl: pinctrl@e0014000 { - compatible = "microchip,sama7g5-gpio"; + pioA: pinctrl@e0014000 { + compatible = "microchip,sama7g5-pinctrl"; reg = <0xe0014000 0x800>; interrupts = , , @@ -196,14 +196,10 @@ , ; clocks = <&pmc PMC_TYPE_PERIPHERAL 11>; - - pioA: pinctrl_default { - interrupt-controller; - #interrupt-cells = <2>; - gpio-controller; - #gpio-cells = <2>; - compatible = "microchip,sama7g5-pinctrl"; - }; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; }; pmc: pmc@e0018000 { diff --git a/arch/arm/dts/sdm845.dtsi b/arch/arm/dts/sdm845.dtsi index df5b6dfcfc..607af277f8 100644 --- a/arch/arm/dts/sdm845.dtsi +++ b/arch/arm/dts/sdm845.dtsi @@ -37,7 +37,7 @@ }; tlmm_north: pinctrl_north@3900000 { - compatible = "qcom,tlmm-sdm845"; + compatible = "qcom,sdm845-pinctrl"; reg = <0x3900000 0x400000>; gpio-count = <150>; gpio-controller; diff --git a/arch/arm/dts/stm32429i-eval-u-boot.dtsi b/arch/arm/dts/stm32429i-eval-u-boot.dtsi index fcab9ae977..030da47b7a 100644 --- a/arch/arm/dts/stm32429i-eval-u-boot.dtsi +++ b/arch/arm/dts/stm32429i-eval-u-boot.dtsi @@ -218,6 +218,6 @@ }; }; -&timer5 { +&timers5 { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32746g-eval.dts b/arch/arm/dts/stm32746g-eval.dts index 9940cf1873..0e6445a539 100644 --- a/arch/arm/dts/stm32746g-eval.dts +++ b/arch/arm/dts/stm32746g-eval.dts @@ -45,12 +45,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "Wake up"; linux,code = ; gpios = <&gpioc 13 0>; @@ -160,6 +158,18 @@ bus-width = <4>; }; +&timers5 { + /* Override timer5 to act as clockevent */ + compatible = "st,stm32-timer"; + interrupts = <50>; + status = "okay"; + /delete-property/#address-cells; + /delete-property/#size-cells; + /delete-property/clock-names; + /delete-node/pwm; + /delete-node/timer@4; +}; + &usart1 { pinctrl-0 = <&usart1_pins_a>; pinctrl-names = "default"; diff --git a/arch/arm/dts/stm32f4-pinctrl.dtsi b/arch/arm/dts/stm32f4-pinctrl.dtsi index adf502694b..46815c965d 100644 --- a/arch/arm/dts/stm32f4-pinctrl.dtsi +++ b/arch/arm/dts/stm32f4-pinctrl.dtsi @@ -9,7 +9,7 @@ / { soc { - pinctrl: pin-controller { + pinctrl: pinctrl@40020000 { #address-cells = <1>; #size-cells = <1>; ranges = <0 0x40020000 0x3000>; diff --git a/arch/arm/dts/stm32f429-disco-u-boot.dtsi b/arch/arm/dts/stm32f429-disco-u-boot.dtsi index c993f86be8..45f899662d 100644 --- a/arch/arm/dts/stm32f429-disco-u-boot.dtsi +++ b/arch/arm/dts/stm32f429-disco-u-boot.dtsi @@ -27,10 +27,6 @@ soc { u-boot,dm-pre-reloc; - pin-controller { - u-boot,dm-pre-reloc; - }; - fmc: fmc@A0000000 { compatible = "st,stm32-fmc"; reg = <0xa0000000 0x1000>; @@ -123,6 +119,8 @@ }; &pinctrl { + u-boot,dm-pre-reloc; + usart1_pins_a: usart1-0 { u-boot,dm-pre-reloc; pins1 { @@ -193,6 +191,6 @@ u-boot,dm-pre-reloc; }; -&timer5 { +&timers5 { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32f429-disco.dts b/arch/arm/dts/stm32f429-disco.dts index 42477c8d3f..30daabd10a 100644 --- a/arch/arm/dts/stm32f429-disco.dts +++ b/arch/arm/dts/stm32f429-disco.dts @@ -39,12 +39,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "User"; linux,code = ; gpios = <&gpioa 0 0>; @@ -152,7 +150,7 @@ display: display@1{ /* Connect panel-ilitek-9341 to ltdc */ - compatible = "st,sf-tc240t-9370-t"; + compatible = "st,sf-tc240t-9370-t", "ilitek,ili9341"; reg = <1>; spi-3wire; spi-max-frequency = <10000000>; @@ -165,6 +163,18 @@ }; }; +&timers5 { + /* Override timer5 to act as clockevent */ + compatible = "st,stm32-timer"; + interrupts = <50>; + status = "okay"; + /delete-property/#address-cells; + /delete-property/#size-cells; + /delete-property/clock-names; + /delete-node/pwm; + /delete-node/timer@4; +}; + &usart1 { pinctrl-0 = <&usart1_pins_a>; pinctrl-names = "default"; diff --git a/arch/arm/dts/stm32f429-pinctrl.dtsi b/arch/arm/dts/stm32f429-pinctrl.dtsi index 575c7eecab..5be171eea5 100644 --- a/arch/arm/dts/stm32f429-pinctrl.dtsi +++ b/arch/arm/dts/stm32f429-pinctrl.dtsi @@ -6,54 +6,50 @@ #include "stm32f4-pinctrl.dtsi" -/ { - soc { - pinctrl: pin-controller { - compatible = "st,stm32f429-pinctrl"; +&pinctrl { + compatible = "st,stm32f429-pinctrl"; - gpioa: gpio@40020000 { - gpio-ranges = <&pinctrl 0 0 16>; - }; + gpioa: gpio@40020000 { + gpio-ranges = <&pinctrl 0 0 16>; + }; - gpiob: gpio@40020400 { - gpio-ranges = <&pinctrl 0 16 16>; - }; + gpiob: gpio@40020400 { + gpio-ranges = <&pinctrl 0 16 16>; + }; - gpioc: gpio@40020800 { - gpio-ranges = <&pinctrl 0 32 16>; - }; + gpioc: gpio@40020800 { + gpio-ranges = <&pinctrl 0 32 16>; + }; - gpiod: gpio@40020c00 { - gpio-ranges = <&pinctrl 0 48 16>; - }; + gpiod: gpio@40020c00 { + gpio-ranges = <&pinctrl 0 48 16>; + }; - gpioe: gpio@40021000 { - gpio-ranges = <&pinctrl 0 64 16>; - }; + gpioe: gpio@40021000 { + gpio-ranges = <&pinctrl 0 64 16>; + }; - gpiof: gpio@40021400 { - gpio-ranges = <&pinctrl 0 80 16>; - }; + gpiof: gpio@40021400 { + gpio-ranges = <&pinctrl 0 80 16>; + }; - gpiog: gpio@40021800 { - gpio-ranges = <&pinctrl 0 96 16>; - }; + gpiog: gpio@40021800 { + gpio-ranges = <&pinctrl 0 96 16>; + }; - gpioh: gpio@40021c00 { - gpio-ranges = <&pinctrl 0 112 16>; - }; + gpioh: gpio@40021c00 { + gpio-ranges = <&pinctrl 0 112 16>; + }; - gpioi: gpio@40022000 { - gpio-ranges = <&pinctrl 0 128 16>; - }; + gpioi: gpio@40022000 { + gpio-ranges = <&pinctrl 0 128 16>; + }; - gpioj: gpio@40022400 { - gpio-ranges = <&pinctrl 0 144 16>; - }; + gpioj: gpio@40022400 { + gpio-ranges = <&pinctrl 0 144 16>; + }; - gpiok: gpio@40022800 { - gpio-ranges = <&pinctrl 0 160 8>; - }; - }; + gpiok: gpio@40022800 { + gpio-ranges = <&pinctrl 0 160 8>; }; }; diff --git a/arch/arm/dts/stm32f429.dtsi b/arch/arm/dts/stm32f429.dtsi index a81e916064..e5b13aca40 100644 --- a/arch/arm/dts/stm32f429.dtsi +++ b/arch/arm/dts/stm32f429.dtsi @@ -52,14 +52,6 @@ }; }; - timer2: timer@40000000 { - compatible = "st,stm32-timer"; - reg = <0x40000000 0x400>; - interrupts = <28>; - clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM2)>; - status = "disabled"; - }; - timers2: timers@40000000 { #address-cells = <1>; #size-cells = <0>; @@ -82,14 +74,6 @@ }; }; - timer3: timer@40000400 { - compatible = "st,stm32-timer"; - reg = <0x40000400 0x400>; - interrupts = <29>; - clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM3)>; - status = "disabled"; - }; - timers3: timers@40000400 { #address-cells = <1>; #size-cells = <0>; @@ -112,14 +96,6 @@ }; }; - timer4: timer@40000800 { - compatible = "st,stm32-timer"; - reg = <0x40000800 0x400>; - interrupts = <30>; - clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM4)>; - status = "disabled"; - }; - timers4: timers@40000800 { #address-cells = <1>; #size-cells = <0>; @@ -142,13 +118,6 @@ }; }; - timer5: timer@40000c00 { - compatible = "st,stm32-timer"; - reg = <0x40000c00 0x400>; - interrupts = <50>; - clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM5)>; - }; - timers5: timers@40000c00 { #address-cells = <1>; #size-cells = <0>; @@ -171,14 +140,6 @@ }; }; - timer6: timer@40001000 { - compatible = "st,stm32-timer"; - reg = <0x40001000 0x400>; - interrupts = <54>; - clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM6)>; - status = "disabled"; - }; - timers6: timers@40001000 { #address-cells = <1>; #size-cells = <0>; @@ -195,14 +156,6 @@ }; }; - timer7: timer@40001400 { - compatible = "st,stm32-timer"; - reg = <0x40001400 0x400>; - interrupts = <55>; - clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM7)>; - status = "disabled"; - }; - timers7: timers@40001400 { #address-cells = <1>; #size-cells = <0>; @@ -242,8 +195,6 @@ }; timers13: timers@40001c00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40001C00 0x400>; clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM13)>; @@ -258,8 +209,6 @@ }; timers14: timers@40002000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40002000 0x400>; clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM14)>; @@ -525,7 +474,7 @@ }; }; - sdio: sdio@40012c00 { + sdio: mmc@40012c00 { compatible = "arm,pl180", "arm,primecell"; arm,primecell-periphid = <0x00880180>; reg = <0x40012c00 0x400>; @@ -592,8 +541,6 @@ }; timers10: timers@40014400 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014400 0x400>; clocks = <&rcc 0 STM32F4_APB2_CLOCK(TIM10)>; @@ -608,8 +555,6 @@ }; timers11: timers@40014800 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014800 0x400>; clocks = <&rcc 0 STM32F4_APB2_CLOCK(TIM11)>; @@ -668,7 +613,7 @@ status = "disabled"; }; - rcc: rcc@40023810 { + rcc: rcc@40023800 { #reset-cells = <1>; #clock-cells = <2>; compatible = "st,stm32f42xx-rcc", "st,stm32-rcc"; @@ -726,6 +671,16 @@ status = "disabled"; }; + dma2d: dma2d@4002b000 { + compatible = "st,stm32-dma2d"; + reg = <0x4002b000 0xc00>; + interrupts = <90>; + resets = <&rcc STM32F4_AHB1_RESET(DMA2D)>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(DMA2D)>; + clock-names = "dma2d"; + status = "disabled"; + }; + usbotg_hs: usb@40040000 { compatible = "snps,dwc2"; reg = <0x40040000 0x40000>; diff --git a/arch/arm/dts/stm32f469-disco-u-boot.dtsi b/arch/arm/dts/stm32f469-disco-u-boot.dtsi index cd173623ef..ee0c82b53e 100644 --- a/arch/arm/dts/stm32f469-disco-u-boot.dtsi +++ b/arch/arm/dts/stm32f469-disco-u-boot.dtsi @@ -28,9 +28,6 @@ soc { u-boot,dm-pre-reloc; - pin-controller { - u-boot,dm-pre-reloc; - }; fmc: fmc@A0000000 { compatible = "st,stm32-fmc"; @@ -138,6 +135,8 @@ }; &pinctrl { + u-boot,dm-pre-reloc; + fmc_pins_d32: fmc_d32@0 { u-boot,dm-pre-reloc; pins @@ -256,6 +255,6 @@ u-boot,dm-pre-reloc; }; -&timer5 { +&timers5 { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32f469-disco.dts b/arch/arm/dts/stm32f469-disco.dts index 23d87ee27a..6e0ffc1903 100644 --- a/arch/arm/dts/stm32f469-disco.dts +++ b/arch/arm/dts/stm32f469-disco.dts @@ -19,7 +19,7 @@ stdout-path = "serial0:115200n8"; }; - memory@00000000 { + memory@0 { device_type = "memory"; reg = <0x00000000 0x1000000>; }; @@ -63,12 +63,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "User"; linux,code = ; gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>; @@ -93,6 +91,10 @@ clock-frequency = <8000000>; }; +&dma2d { + status = "okay"; +}; + &dsi { #address-cells = <1>; #size-cells = <0>; @@ -185,6 +187,18 @@ bus-width = <4>; }; +&timers5 { + /* Override timer5 to act as clockevent */ + compatible = "st,stm32-timer"; + interrupts = <50>; + status = "okay"; + /delete-property/#address-cells; + /delete-property/#size-cells; + /delete-property/clock-names; + /delete-node/pwm; + /delete-node/timer@4; +}; + &usart3 { pinctrl-0 = <&usart3_pins_a>; pinctrl-names = "default"; diff --git a/arch/arm/dts/stm32f469-pinctrl.dtsi b/arch/arm/dts/stm32f469-pinctrl.dtsi index 1e2bb0191e..0610407c7b 100644 --- a/arch/arm/dts/stm32f469-pinctrl.dtsi +++ b/arch/arm/dts/stm32f469-pinctrl.dtsi @@ -5,55 +5,51 @@ #include "stm32f4-pinctrl.dtsi" -/ { - soc { - pinctrl: pin-controller { - compatible = "st,stm32f469-pinctrl"; +&pinctrl { + compatible = "st,stm32f469-pinctrl"; - gpioa: gpio@40020000 { - gpio-ranges = <&pinctrl 0 0 16>; - }; + gpioa: gpio@40020000 { + gpio-ranges = <&pinctrl 0 0 16>; + }; - gpiob: gpio@40020400 { - gpio-ranges = <&pinctrl 0 16 16>; - }; + gpiob: gpio@40020400 { + gpio-ranges = <&pinctrl 0 16 16>; + }; - gpioc: gpio@40020800 { - gpio-ranges = <&pinctrl 0 32 16>; - }; + gpioc: gpio@40020800 { + gpio-ranges = <&pinctrl 0 32 16>; + }; - gpiod: gpio@40020c00 { - gpio-ranges = <&pinctrl 0 48 16>; - }; + gpiod: gpio@40020c00 { + gpio-ranges = <&pinctrl 0 48 16>; + }; - gpioe: gpio@40021000 { - gpio-ranges = <&pinctrl 0 64 16>; - }; + gpioe: gpio@40021000 { + gpio-ranges = <&pinctrl 0 64 16>; + }; - gpiof: gpio@40021400 { - gpio-ranges = <&pinctrl 0 80 16>; - }; + gpiof: gpio@40021400 { + gpio-ranges = <&pinctrl 0 80 16>; + }; - gpiog: gpio@40021800 { - gpio-ranges = <&pinctrl 0 96 16>; - }; + gpiog: gpio@40021800 { + gpio-ranges = <&pinctrl 0 96 16>; + }; - gpioh: gpio@40021c00 { - gpio-ranges = <&pinctrl 0 112 16>; - }; + gpioh: gpio@40021c00 { + gpio-ranges = <&pinctrl 0 112 16>; + }; - gpioi: gpio@40022000 { - gpio-ranges = <&pinctrl 0 128 16>; - }; + gpioi: gpio@40022000 { + gpio-ranges = <&pinctrl 0 128 16>; + }; - gpioj: gpio@40022400 { - gpio-ranges = <&pinctrl 0 144 6>, - <&pinctrl 12 156 4>; - }; + gpioj: gpio@40022400 { + gpio-ranges = <&pinctrl 0 144 6>, + <&pinctrl 12 156 4>; + }; - gpiok: gpio@40022800 { - gpio-ranges = <&pinctrl 3 163 5>; - }; - }; + gpiok: gpio@40022800 { + gpio-ranges = <&pinctrl 3 163 5>; }; }; diff --git a/arch/arm/dts/stm32f7-pinctrl.dtsi b/arch/arm/dts/stm32f7-pinctrl.dtsi index fe4cfda72a..8f37aefa73 100644 --- a/arch/arm/dts/stm32f7-pinctrl.dtsi +++ b/arch/arm/dts/stm32f7-pinctrl.dtsi @@ -9,7 +9,7 @@ / { soc { - pinctrl: pin-controller { + pinctrl: pinctrl@40020000 { #address-cells = <1>; #size-cells = <1>; ranges = <0 0x40020000 0x3000>; diff --git a/arch/arm/dts/stm32f7-u-boot.dtsi b/arch/arm/dts/stm32f7-u-boot.dtsi index c1b2ac25c3..0ba8031c33 100644 --- a/arch/arm/dts/stm32f7-u-boot.dtsi +++ b/arch/arm/dts/stm32f7-u-boot.dtsi @@ -119,7 +119,7 @@ u-boot,dm-pre-reloc; }; -&timer5 { +&timers5 { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32f746-disco.dts b/arch/arm/dts/stm32f746-disco.dts index 9430dc08ec..1ed58f2361 100644 --- a/arch/arm/dts/stm32f746-disco.dts +++ b/arch/arm/dts/stm32f746-disco.dts @@ -73,6 +73,18 @@ bus-width = <4>; }; +&timers5 { + /* Override timer5 to act as clockevent */ + compatible = "st,stm32-timer"; + interrupts = <50>; + status = "okay"; + /delete-property/#address-cells; + /delete-property/#size-cells; + /delete-property/clock-names; + /delete-node/pwm; + /delete-node/timer@4; +}; + &usart1 { pinctrl-0 = <&usart1_pins_b>; pinctrl-names = "default"; diff --git a/arch/arm/dts/stm32f746.dtsi b/arch/arm/dts/stm32f746.dtsi index 78facde2b5..c97b3d0d07 100644 --- a/arch/arm/dts/stm32f746.dtsi +++ b/arch/arm/dts/stm32f746.dtsi @@ -39,14 +39,6 @@ }; soc { - timer2: timer@40000000 { - compatible = "st,stm32-timer"; - reg = <0x40000000 0x400>; - interrupts = <28>; - clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM2)>; - status = "disabled"; - }; - timers2: timers@40000000 { #address-cells = <1>; #size-cells = <0>; @@ -69,14 +61,6 @@ }; }; - timer3: timer@40000400 { - compatible = "st,stm32-timer"; - reg = <0x40000400 0x400>; - interrupts = <29>; - clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM3)>; - status = "disabled"; - }; - timers3: timers@40000400 { #address-cells = <1>; #size-cells = <0>; @@ -99,14 +83,6 @@ }; }; - timer4: timer@40000800 { - compatible = "st,stm32-timer"; - reg = <0x40000800 0x400>; - interrupts = <30>; - clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM4)>; - status = "disabled"; - }; - timers4: timers@40000800 { #address-cells = <1>; #size-cells = <0>; @@ -129,13 +105,6 @@ }; }; - timer5: timer@40000c00 { - compatible = "st,stm32-timer"; - reg = <0x40000c00 0x400>; - interrupts = <50>; - clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM5)>; - }; - timers5: timers@40000c00 { #address-cells = <1>; #size-cells = <0>; @@ -158,14 +127,6 @@ }; }; - timer6: timer@40001000 { - compatible = "st,stm32-timer"; - reg = <0x40001000 0x400>; - interrupts = <54>; - clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM6)>; - status = "disabled"; - }; - timers6: timers@40001000 { #address-cells = <1>; #size-cells = <0>; @@ -182,14 +143,6 @@ }; }; - timer7: timer@40001400 { - compatible = "st,stm32-timer"; - reg = <0x40001400 0x400>; - interrupts = <55>; - clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM7)>; - status = "disabled"; - }; - timers7: timers@40001400 { #address-cells = <1>; #size-cells = <0>; @@ -229,8 +182,6 @@ }; timers13: timers@40001c00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40001C00 0x400>; clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM13)>; @@ -245,8 +196,6 @@ }; timers14: timers@40002000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40002000 0x400>; clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM14)>; @@ -313,7 +262,6 @@ clocks = <&rcc 1 CLK_I2C1>; #address-cells = <1>; #size-cells = <0>; - i2c-analog-filter; status = "disabled"; }; @@ -326,20 +274,18 @@ clocks = <&rcc 1 CLK_I2C2>; #address-cells = <1>; #size-cells = <0>; - i2c-analog-filter; status = "disabled"; }; - i2c3: i2c@40005C00 { + i2c3: i2c@40005c00 { compatible = "st,stm32f7-i2c"; - reg = <0x40005C00 0x400>; + reg = <0x40005c00 0x400>; interrupts = <72>, <73>; resets = <&rcc STM32F7_APB1_RESET(I2C3)>; clocks = <&rcc 1 CLK_I2C3>; #address-cells = <1>; #size-cells = <0>; - i2c-analog-filter; status = "disabled"; }; @@ -352,7 +298,6 @@ clocks = <&rcc 1 CLK_I2C4>; #address-cells = <1>; #size-cells = <0>; - i2c-analog-filter; status = "disabled"; }; @@ -441,7 +386,7 @@ status = "disabled"; }; - sdio2: sdio2@40011c00 { + sdio2: mmc@40011c00 { compatible = "arm,pl180", "arm,primecell"; arm,primecell-periphid = <0x00880180>; reg = <0x40011c00 0x400>; @@ -452,7 +397,7 @@ status = "disabled"; }; - sdio1: sdio1@40012c00 { + sdio1: mmc@40012c00 { compatible = "arm,pl180", "arm,primecell"; arm,primecell-periphid = <0x00880180>; reg = <0x40012c00 0x400>; @@ -499,8 +444,6 @@ }; timers10: timers@40014400 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014400 0x400>; clocks = <&rcc 0 STM32F7_APB2_CLOCK(TIM10)>; @@ -515,8 +458,6 @@ }; timers11: timers@40014800 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014800 0x400>; clocks = <&rcc 0 STM32F7_APB2_CLOCK(TIM11)>; diff --git a/arch/arm/dts/stm32f769-disco.dts b/arch/arm/dts/stm32f769-disco.dts index 03cfbd7cc2..6f93fc7bcf 100644 --- a/arch/arm/dts/stm32f769-disco.dts +++ b/arch/arm/dts/stm32f769-disco.dts @@ -39,12 +39,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "User"; linux,code = ; gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>; @@ -103,6 +101,18 @@ bus-width = <4>; }; +&timers5 { + /* Override timer5 to act as clockevent */ + compatible = "st,stm32-timer"; + interrupts = <50>; + status = "okay"; + /delete-property/#address-cells; + /delete-property/#size-cells; + /delete-property/clock-names; + /delete-node/pwm; + /delete-node/timer@4; +}; + &usart1 { pinctrl-0 = <&usart1_pins_a>; pinctrl-names = "default"; diff --git a/arch/arm/dts/stm32h743.dtsi b/arch/arm/dts/stm32h743.dtsi index dbfebf07f2..ceb629c4fa 100644 --- a/arch/arm/dts/stm32h743.dtsi +++ b/arch/arm/dts/stm32h743.dtsi @@ -124,7 +124,6 @@ <32>; resets = <&rcc STM32H7_APB1L_RESET(I2C1)>; clocks = <&rcc I2C1_CK>; - i2c-analog-filter; status = "disabled"; }; @@ -137,7 +136,6 @@ <34>; resets = <&rcc STM32H7_APB1L_RESET(I2C2)>; clocks = <&rcc I2C2_CK>; - i2c-analog-filter; status = "disabled"; }; @@ -150,7 +148,6 @@ <73>; resets = <&rcc STM32H7_APB1L_RESET(I2C3)>; clocks = <&rcc I2C3_CK>; - i2c-analog-filter; status = "disabled"; }; @@ -337,12 +334,12 @@ dma-requests = <32>; }; - sdmmc1: sdmmc@52007000 { + sdmmc1: mmc@52007000 { compatible = "arm,pl18x", "arm,primecell"; arm,primecell-periphid = <0x10153180>; reg = <0x52007000 0x1000>; interrupts = <49>; - interrupt-names = "cmd_irq"; + interrupt-names = "cmd_irq"; clocks = <&rcc SDMMC1_CK>; clock-names = "apb_pclk"; resets = <&rcc STM32H7_AHB3_RESET(SDMMC1)>; @@ -351,18 +348,19 @@ max-frequency = <120000000>; }; - sdmmc2: sdmmc@48022400 { + sdmmc2: mmc@48022400 { compatible = "arm,pl18x", "arm,primecell"; arm,primecell-periphid = <0x10153180>; reg = <0x48022400 0x400>; interrupts = <124>; - interrupt-names = "cmd_irq"; + interrupt-names = "cmd_irq"; clocks = <&rcc SDMMC2_CK>; clock-names = "apb_pclk"; resets = <&rcc STM32H7_AHB2_RESET(SDMMC2)>; cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <120000000>; + status = "disabled"; }; exti: interrupt-controller@58000000 { @@ -398,7 +396,6 @@ <96>; resets = <&rcc STM32H7_APB4_RESET(I2C4)>; clocks = <&rcc I2C4_CK>; - i2c-analog-filter; status = "disabled"; }; @@ -452,8 +449,6 @@ }; lptimer4: timer@58002c00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-lptimer"; reg = <0x58002c00 0x400>; clocks = <&rcc LPTIM4_CK>; @@ -468,8 +463,6 @@ }; lptimer5: timer@58003000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-lptimer"; reg = <0x58003000 0x400>; clocks = <&rcc LPTIM5_CK>; @@ -554,7 +547,7 @@ status = "disabled"; }; - pinctrl: pin-controller@58020000 { + pinctrl: pinctrl@58020000 { #address-cells = <1>; #size-cells = <1>; compatible = "st,stm32h743-pinctrl"; diff --git a/arch/arm/dts/stm32h743i-disco.dts b/arch/arm/dts/stm32h743i-disco.dts index 3a01ebd563..b31188f8b9 100644 --- a/arch/arm/dts/stm32h743i-disco.dts +++ b/arch/arm/dts/stm32h743i-disco.dts @@ -41,10 +41,10 @@ &mac { status = "disabled"; - pinctrl-0 = <ðernet_rmii>; - pinctrl-names = "default"; - phy-mode = "rmii"; - phy-handle = <&phy0>; + pinctrl-0 = <ðernet_rmii>; + pinctrl-names = "default"; + phy-mode = "rmii"; + phy-handle = <&phy0>; mdio0 { #address-cells = <1>; diff --git a/arch/arm/dts/stm32h743i-eval.dts b/arch/arm/dts/stm32h743i-eval.dts index 38cc7faf68..5c5d8059bd 100644 --- a/arch/arm/dts/stm32h743i-eval.dts +++ b/arch/arm/dts/stm32h743i-eval.dts @@ -115,10 +115,10 @@ &mac { status = "disabled"; - pinctrl-0 = <ðernet_rmii>; - pinctrl-names = "default"; - phy-mode = "rmii"; - phy-handle = <&phy0>; + pinctrl-0 = <ðernet_rmii>; + pinctrl-names = "default"; + phy-mode = "rmii"; + phy-handle = <&phy0>; mdio0 { #address-cells = <1>; diff --git a/arch/arm/dts/stm32h750i-art-pi.dts b/arch/arm/dts/stm32h750i-art-pi.dts index 2a4d1cb496..c7c7132f22 100644 --- a/arch/arm/dts/stm32h750i-art-pi.dts +++ b/arch/arm/dts/stm32h750i-art-pi.dts @@ -87,10 +87,10 @@ &mac { status = "disabled"; - pinctrl-0 = <ðernet_rmii>; - pinctrl-names = "default"; - phy-mode = "rmii"; - phy-handle = <&phy0>; + pinctrl-0 = <ðernet_rmii>; + pinctrl-names = "default"; + phy-mode = "rmii"; + phy-handle = <&phy0>; mdio0 { #address-cells = <1>; diff --git a/arch/arm/dts/stm32mp13-u-boot.dtsi b/arch/arm/dts/stm32mp13-u-boot.dtsi index 01552adb7c..47a43649bb 100644 --- a/arch/arm/dts/stm32mp13-u-boot.dtsi +++ b/arch/arm/dts/stm32mp13-u-boot.dtsi @@ -17,6 +17,12 @@ pinctrl0 = &pinctrl; }; + firmware { + optee { + u-boot,dm-pre-reloc; + }; + }; + /* need PSCI for sysreset during board_f */ psci { u-boot,dm-pre-proper; @@ -82,10 +88,6 @@ u-boot,dm-pre-reloc; }; -&optee { - u-boot,dm-pre-reloc; -}; - &pinctrl { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32mp131.dtsi b/arch/arm/dts/stm32mp131.dtsi index 84e16bb2f2..a1c6d0d00b 100644 --- a/arch/arm/dts/stm32mp131.dtsi +++ b/arch/arm/dts/stm32mp131.dtsi @@ -27,21 +27,8 @@ interrupt-parent = <&intc>; }; - scmi_sram: sram@2ffff000 { - compatible = "mmio-sram"; - reg = <0x2ffff000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0x2ffff000 0x1000>; - - scmi_shm: scmi_shm@0 { - compatible = "arm,scmi-shmem"; - reg = <0 0x80>; - }; - }; - firmware { - optee: optee { + optee { method = "smc"; compatible = "linaro,optee-tz"; }; @@ -151,6 +138,19 @@ interrupt-parent = <&intc>; ranges; + scmi_sram: sram@2ffff000 { + compatible = "mmio-sram"; + reg = <0x2ffff000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x2ffff000 0x1000>; + + scmi_shm: scmi-sram@0 { + compatible = "arm,scmi-shmem"; + reg = <0 0x80>; + }; + }; + uart4: serial@40010000 { compatible = "st,stm32h7-uart"; reg = <0x40010000 0x400>; diff --git a/arch/arm/dts/stm32mp135f-dk.dts b/arch/arm/dts/stm32mp135f-dk.dts index f436ffab99..e6b8ffd332 100644 --- a/arch/arm/dts/stm32mp135f-dk.dts +++ b/arch/arm/dts/stm32mp135f-dk.dts @@ -31,8 +31,8 @@ #size-cells = <1>; ranges; - optee@de000000 { - reg = <0xde000000 0x2000000>; + optee@dd000000 { + reg = <0xdd000000 0x3000000>; no-map; }; }; diff --git a/arch/arm/dts/stm32mp15-ddr.dtsi b/arch/arm/dts/stm32mp15-ddr.dtsi index 0aac9131a6..d02f79dac6 100644 --- a/arch/arm/dts/stm32mp15-ddr.dtsi +++ b/arch/arm/dts/stm32mp15-ddr.dtsi @@ -4,7 +4,22 @@ */ #include +#ifdef CONFIG_SPL &ddr { + clocks = <&rcc AXIDCG>, + <&rcc DDRC1>, + <&rcc DDRC2>, + <&rcc DDRPHYC>, + <&rcc DDRCAPB>, + <&rcc DDRPHYCAPB>; + + clock-names = "axidcg", + "ddrc1", + "ddrc2", + "ddrphyc", + "ddrcapb", + "ddrphycapb"; + config-DDR_MEM_COMPATIBLE { u-boot,dm-pre-reloc; @@ -119,6 +134,7 @@ status = "okay"; }; }; +#endif #undef DDR_MEM_COMPATIBLE #undef DDR_MEM_NAME diff --git a/arch/arm/dts/stm32mp15-pinctrl.dtsi b/arch/arm/dts/stm32mp15-pinctrl.dtsi index d3ed10335d..2cc9341d43 100644 --- a/arch/arm/dts/stm32mp15-pinctrl.dtsi +++ b/arch/arm/dts/stm32mp15-pinctrl.dtsi @@ -151,6 +151,43 @@ }; }; + dcmi_pins_c: dcmi-2 { + pins { + pinmux = ,/* DCMI_HSYNC */ + ,/* DCMI_VSYNC */ + ,/* DCMI_PIXCLK */ + ,/* DCMI_D0 */ + ,/* DCMI_D1 */ + ,/* DCMI_D2 */ + ,/* DCMI_D3 */ + ,/* DCMI_D4 */ + ,/* DCMI_D5 */ + ,/* DCMI_D6 */ + ,/* DCMI_D7 */ + ,/* DCMI_D8 */ + ;/* DCMI_D9 */ + bias-pull-up; + }; + }; + + dcmi_sleep_pins_c: dcmi-sleep-2 { + pins { + pinmux = ,/* DCMI_HSYNC */ + ,/* DCMI_VSYNC */ + ,/* DCMI_PIXCLK */ + ,/* DCMI_D0 */ + ,/* DCMI_D1 */ + ,/* DCMI_D2 */ + ,/* DCMI_D3 */ + ,/* DCMI_D4 */ + ,/* DCMI_D5 */ + ,/* DCMI_D6 */ + ,/* DCMI_D7 */ + ,/* DCMI_D8 */ + ;/* DCMI_D9 */ + }; + }; + ethernet0_rgmii_pins_a: rgmii-0 { pins1 { pinmux = , /* ETH_RGMII_CLK125 */ @@ -923,6 +960,21 @@ }; }; + mco1_pins_a: mco1-0 { + pins { + pinmux = ; /* MCO1 */ + bias-disable; + drive-push-pull; + slew-rate = <1>; + }; + }; + + mco1_sleep_pins_a: mco1-sleep-0 { + pins { + pinmux = ; /* MCO1 */ + }; + }; + mco2_pins_a: mco2-0 { pins { pinmux = ; /* MCO2 */ @@ -1814,30 +1866,30 @@ spi2_pins_a: spi2-0 { pins1 { - pinmux = , /* SPI1_SCK */ - ; /* SPI1_MOSI */ + pinmux = , /* SPI2_SCK */ + ; /* SPI2_MOSI */ bias-disable; drive-push-pull; slew-rate = <1>; }; pins2 { - pinmux = ; /* SPI1_MISO */ + pinmux = ; /* SPI2_MISO */ bias-disable; }; }; spi2_pins_b: spi2-1 { pins1 { - pinmux = , /* SPI1_SCK */ - ; /* SPI1_MOSI */ + pinmux = , /* SPI2_SCK */ + ; /* SPI2_MOSI */ bias-disable; drive-push-pull; slew-rate = <1>; }; pins2 { - pinmux = ; /* SPI1_MISO */ + pinmux = ; /* SPI2_MISO */ bias-disable; }; }; diff --git a/arch/arm/dts/stm32mp15-u-boot.dtsi b/arch/arm/dts/stm32mp15-u-boot.dtsi index d9d04743ac..d5c87d29d8 100644 --- a/arch/arm/dts/stm32mp15-u-boot.dtsi +++ b/arch/arm/dts/stm32mp15-u-boot.dtsi @@ -53,20 +53,6 @@ reg = <0x5a003000 0x550 0x5a004000 0x234>; - clocks = <&rcc AXIDCG>, - <&rcc DDRC1>, - <&rcc DDRC2>, - <&rcc DDRPHYC>, - <&rcc DDRCAPB>, - <&rcc DDRPHYCAPB>; - - clock-names = "axidcg", - "ddrc1", - "ddrc2", - "ddrphyc", - "ddrcapb", - "ddrphycapb"; - status = "okay"; }; }; diff --git a/arch/arm/dts/stm32mp151.dtsi b/arch/arm/dts/stm32mp151.dtsi index 767a06ef68..f0fb022fc6 100644 --- a/arch/arm/dts/stm32mp151.dtsi +++ b/arch/arm/dts/stm32mp151.dtsi @@ -1143,10 +1143,9 @@ reg = <0x4c001000 0x400>; st,proc-id = <0>; interrupts-extended = - <&intc GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, - <&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, - <&exti 61 1>; - interrupt-names = "rx", "tx", "wakeup"; + <&exti 61 1>, + <&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "rx", "tx"; clocks = <&rcc IPCC>; wakeup-source; status = "disabled"; diff --git a/arch/arm/dts/stm32mp157a-dk1-scmi-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-scmi-u-boot.dtsi index 2db045e7ce..1209dfe009 100644 --- a/arch/arm/dts/stm32mp157a-dk1-scmi-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157a-dk1-scmi-u-boot.dtsi @@ -5,7 +5,6 @@ #include #include "stm32mp15-scmi-u-boot.dtsi" -#include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi" / { aliases { diff --git a/arch/arm/dts/stm32mp157c-ed1-scmi-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ed1-scmi-u-boot.dtsi index 54662f7e29..c265745ff1 100644 --- a/arch/arm/dts/stm32mp157c-ed1-scmi-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157c-ed1-scmi-u-boot.dtsi @@ -5,7 +5,6 @@ #include #include "stm32mp15-scmi-u-boot.dtsi" -#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" / { aliases { diff --git a/arch/arm/dts/stm32mp15xx-dkx.dtsi b/arch/arm/dts/stm32mp15xx-dkx.dtsi index 3d36cac9ed..5a045d7156 100644 --- a/arch/arm/dts/stm32mp15xx-dkx.dtsi +++ b/arch/arm/dts/stm32mp15xx-dkx.dtsi @@ -685,6 +685,14 @@ &usbh_ehci { phys = <&usbphyc_port0>; status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + /* onboard HUB */ + hub@1 { + compatible = "usb424,2514"; + reg = <1>; + vdd-supply = <&v3v3>; + }; }; &usbotg_hs { diff --git a/arch/arm/dts/total_compute.dts b/arch/arm/dts/total_compute.dts index 4399269a44..96edacda0b 100644 --- a/arch/arm/dts/total_compute.dts +++ b/arch/arm/dts/total_compute.dts @@ -45,4 +45,8 @@ clock-frequency = <24000000>; clock-output-names = "bp:clock24mhz"; }; + psci { + compatible = "arm,psci-1.0", "arm,psci-0.2"; + method = "smc"; + }; }; diff --git a/arch/arm/dts/versal-net-mini.dts b/arch/arm/dts/versal-net-mini.dts new file mode 100644 index 0000000000..8c29a6ed6b --- /dev/null +++ b/arch/arm/dts/versal-net-mini.dts @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal NET + * + * Copyright (C) 2021 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; + +#include + +/ { + compatible = "xlnx,versal-net-mini"; + model = "Xilinx Versal NET MINI"; + #address-cells = <2>; + #size-cells = <2>; + + memory: memory@0 { + reg = <0 0xBBF00000 0 0x100000>, <0 0 0 0x80000000>; + device_type = "memory"; + }; + + aliases { + /* serial0 = &serial0; */ + serial0 = &dcc; + }; + + chosen { + stdout-path = "serial0:115200"; + }; + + clk1: clk1 { + u-boot,dm-pre-reloc; + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + }; + + dcc: dcc { + compatible = "arm,dcc"; + status = "okay"; + u-boot,dm-pre-reloc; + }; + + amba: axi { + compatible = "simple-bus"; + u-boot,dm-pre-reloc; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + serial0: serial@f1920000 { + u-boot,dm-pre-reloc; + compatible = "arm,pl011", "arm,primecell"; + reg = <0 0xf1920000 0 0x1000>; + reg-io-width = <4>; + clock-names = "uartclk", "apb_pclk"; + clocks = <&clk1>, <&clk1>; + clock = <1000000>; + current-speed = <115200>; + skip-init; + }; + }; +}; diff --git a/arch/arm/dts/xilinx-versal-net-virt.dts b/arch/arm/dts/xilinx-versal-net-virt.dts new file mode 100644 index 0000000000..c99257cb08 --- /dev/null +++ b/arch/arm/dts/xilinx-versal-net-virt.dts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Empty device tree for versal-net-virt board + * + * Copyright (C) 2022, Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/ { +}; diff --git a/arch/arm/dts/zynq-7000.dtsi b/arch/arm/dts/zynq-7000.dtsi index 37155df0fd..edc147d63f 100644 --- a/arch/arm/dts/zynq-7000.dtsi +++ b/arch/arm/dts/zynq-7000.dtsi @@ -192,6 +192,17 @@ reg = <0xf8006000 0x1000>; }; + ocm: sram@fffc0000 { + compatible = "mmio-sram"; + reg = <0xfffc0000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0xfffc0000 0x10000>; + ocm-sram@0 { + reg = <0x0 0x10000>; + }; + }; + uart0: serial@e0000000 { compatible = "xlnx,xuartps", "cdns,uart-r1p8"; status = "disabled"; @@ -235,19 +246,19 @@ }; qspi: spi@e000d000 { - clock-names = "ref_clk", "pclk"; - clocks = <&clkc 10>, <&clkc 43>; compatible = "xlnx,zynq-qspi-1.0"; - status = "disabled"; + reg = <0xe000d000 0x1000>; interrupt-parent = <&intc>; interrupts = <0 19 4>; - reg = <0xe000d000 0x1000>; + clocks = <&clkc 10>, <&clkc 43>; + clock-names = "ref_clk", "pclk"; + status = "disabled"; #address-cells = <1>; #size-cells = <0>; }; gem0: ethernet@e000b000 { - compatible = "cdns,zynq-gem", "cdns,gem"; + compatible = "xlnx,zynq-gem", "cdns,zynq-gem", "cdns,gem"; reg = <0xe000b000 0x1000>; status = "disabled"; interrupts = <0 22 4>; @@ -258,7 +269,7 @@ }; gem1: ethernet@e000c000 { - compatible = "cdns,zynq-gem", "cdns,gem"; + compatible = "xlnx,zynq-gem", "cdns,zynq-gem", "cdns,gem"; reg = <0xe000c000 0x1000>; status = "disabled"; interrupts = <0 45 4>; @@ -378,9 +389,9 @@ devcfg: devcfg@f8007000 { compatible = "xlnx,zynq-devcfg-1.0"; + reg = <0xf8007000 0x100>; interrupt-parent = <&intc>; interrupts = <0 8 4>; - reg = <0xf8007000 0x100>; clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>; clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3"; syscon = <&slcr>; @@ -416,6 +427,7 @@ }; scutimer: timer@f8f00600 { + u-boot,dm-pre-reloc; interrupt-parent = <&intc>; interrupts = <1 13 0x301>; compatible = "arm,cortex-a9-twd-timer"; diff --git a/arch/arm/dts/zynq-zc702.dts b/arch/arm/dts/zynq-zc702.dts index f2e05a55b9..1bd4f8c9f6 100644 --- a/arch/arm/dts/zynq-zc702.dts +++ b/arch/arm/dts/zynq-zc702.dts @@ -64,19 +64,6 @@ }; }; -&amba { - ocm: sram@fffc0000 { - compatible = "mmio-sram"; - reg = <0xfffc0000 0x10000>; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0xfffc0000 0x10000>; - ocm-sram@0 { - reg = <0x0 0x10000>; - }; - }; -}; - &can0 { status = "okay"; pinctrl-names = "default"; diff --git a/arch/arm/dts/zynqmp-clk-ccf.dtsi b/arch/arm/dts/zynqmp-clk-ccf.dtsi index 7b09d75151..b99eb07b00 100644 --- a/arch/arm/dts/zynqmp-clk-ccf.dtsi +++ b/arch/arm/dts/zynqmp-clk-ccf.dtsi @@ -260,11 +260,19 @@ assigned-clocks = <&zynqmp_clk USB0_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>; }; +&dwc3_0 { + clocks = <&zynqmp_clk USB3_DUAL_REF>; +}; + &usb1 { clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>; assigned-clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>; }; +&dwc3_1 { + clocks = <&zynqmp_clk USB3_DUAL_REF>; +}; + &watchdog0 { clocks = <&zynqmp_clk WDT>; }; diff --git a/arch/arm/dts/zynqmp-e-a2197-00-revA.dts b/arch/arm/dts/zynqmp-e-a2197-00-revA.dts index 37c56181c9..3fa18f560c 100644 --- a/arch/arm/dts/zynqmp-e-a2197-00-revA.dts +++ b/arch/arm/dts/zynqmp-e-a2197-00-revA.dts @@ -155,8 +155,12 @@ phy-handle = <&phy0>; phy-mode = "sgmii"; is-internal-pcspma; - phy0: ethernet-phy@0 { /* u131 M88E1512 */ - reg = <0>; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@0 { /* u131 M88E1512 */ + reg = <0>; + }; }; }; @@ -203,6 +207,18 @@ &i2c0 { /* MIO 34-35 - can't stay here */ status = "okay"; clock-frequency = <400000>; + + tca6416_u233: gpio@20 { /* u233 */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "MAX6643_OT_B", "MAX6643_FANFAIL_B", "", "", /* 0 - 3 */ + "PMBUS2_INA226_ALERT", "", "", "MAX6643_FULLSPD", /* 4 - 7 */ + "FMCP1_FMC_PRSNT_M2C_B", "FMCP2_FMC_PRSNT_M2C_B", "FMCP1_FMCP_PRSNT_M2C_B", "FMCP2_FMCP_PRSNT_M2C_B", /* 10 - 13 */ + "VCCINT_VRHOT_B", "8A34001_EXP_RST_B", "PMBUS_ALERT", "PMBUS1_INA226_ALERT"; /* 14 - 17 */ + }; + i2c-mux@74 { /* u33 */ compatible = "nxp,pca9548"; #address-cells = <1>; diff --git a/arch/arm/dts/zynqmp-sm-k26-revA.dts b/arch/arm/dts/zynqmp-sm-k26-revA.dts index ac349a9dcc..bae24aabdb 100644 --- a/arch/arm/dts/zynqmp-sm-k26-revA.dts +++ b/arch/arm/dts/zynqmp-sm-k26-revA.dts @@ -214,13 +214,17 @@ }; partition@2240000 { label = "SHA256"; - reg = <0x2240000 0x10000>; /* 256B but 64KB sector */ + reg = <0x2240000 0x40000>; /* 256B but 256KB sector */ read-only; lock; }; - partition@2250000 { + partition@2280000 { + label = "Secure OS Storage"; + reg = <0x2280000 0x20000>; /* 128KB */ + }; + partition@22A0000 { label = "User"; - reg = <0x2250000 0x1db0000>; /* 29.5 MB */ + reg = <0x22A0000 0x1db0000>; /* 29.5 MB */ }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu102-revA.dts b/arch/arm/dts/zynqmp-zcu102-revA.dts index a4e92c8bb1..9d8e551ed2 100644 --- a/arch/arm/dts/zynqmp-zcu102-revA.dts +++ b/arch/arm/dts/zynqmp-zcu102-revA.dts @@ -200,13 +200,19 @@ phy-mode = "rgmii-id"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gem3_default>; - phy0: ethernet-phy@21 { - reg = <21>; - ti,rx-internal-delay = <0x8>; - ti,tx-internal-delay = <0xa>; - ti,fifo-depth = <0x1>; - ti,dp83867-rxctrl-strap-quirk; - /* reset-gpios = <&tca6416_u97 6 GPIO_ACTIVE_LOW>; */ + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@21 { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <21>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u97 6 GPIO_ACTIVE_LOW>; + }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu104-revA.dts b/arch/arm/dts/zynqmp-zcu104-revA.dts index 1418cffb20..b9d82afc51 100644 --- a/arch/arm/dts/zynqmp-zcu104-revA.dts +++ b/arch/arm/dts/zynqmp-zcu104-revA.dts @@ -109,12 +109,19 @@ phy-mode = "rgmii-id"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gem3_default>; - phy0: ethernet-phy@c { - reg = <0xc>; - ti,rx-internal-delay = <0x8>; - ti,tx-internal-delay = <0xa>; - ti,fifo-depth = <0x1>; - ti,dp83867-rxctrl-strap-quirk; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u97 6 GPIO_ACTIVE_LOW>; + }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu104-revC.dts b/arch/arm/dts/zynqmp-zcu104-revC.dts index 7fd19ca3a8..6f24e335a1 100644 --- a/arch/arm/dts/zynqmp-zcu104-revC.dts +++ b/arch/arm/dts/zynqmp-zcu104-revC.dts @@ -114,12 +114,19 @@ phy-mode = "rgmii-id"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gem3_default>; - phy0: ethernet-phy@c { - reg = <0xc>; - ti,rx-internal-delay = <0x8>; - ti,tx-internal-delay = <0xa>; - ti,fifo-depth = <0x1>; - ti,dp83867-rxctrl-strap-quirk; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u97 6 GPIO_ACTIVE_LOW>; + }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu111-revA.dts b/arch/arm/dts/zynqmp-zcu111-revA.dts index e412992ff1..2e95f22c3f 100644 --- a/arch/arm/dts/zynqmp-zcu111-revA.dts +++ b/arch/arm/dts/zynqmp-zcu111-revA.dts @@ -172,12 +172,19 @@ phy-mode = "rgmii-id"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gem3_default>; - phy0: ethernet-phy@c { - reg = <0xc>; - ti,rx-internal-delay = <0x8>; - ti,tx-internal-delay = <0xa>; - ti,fifo-depth = <0x1>; - ti,dp83867-rxctrl-strap-quirk; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u22 6 GPIO_ACTIVE_LOW>; + }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu208-revA.dts b/arch/arm/dts/zynqmp-zcu208-revA.dts index c5cdd58af6..7e7e1577eb 100644 --- a/arch/arm/dts/zynqmp-zcu208-revA.dts +++ b/arch/arm/dts/zynqmp-zcu208-revA.dts @@ -169,12 +169,19 @@ status = "okay"; phy-handle = <&phy0>; phy-mode = "rgmii-id"; - phy0: ethernet-phy@c { - reg = <0xc>; - ti,rx-internal-delay = <0x8>; - ti,tx-internal-delay = <0xa>; - ti,fifo-depth = <0x1>; - ti,dp83867-rxctrl-strap-quirk; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u15 6 GPIO_ACTIVE_LOW>; + }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu216-revA.dts b/arch/arm/dts/zynqmp-zcu216-revA.dts index caae16965d..35a30971cb 100644 --- a/arch/arm/dts/zynqmp-zcu216-revA.dts +++ b/arch/arm/dts/zynqmp-zcu216-revA.dts @@ -176,15 +176,21 @@ status = "okay"; phy-handle = <&phy0>; phy-mode = "rgmii-id"; - phy0: ethernet-phy@c { - reg = <0xc>; - ti,rx-internal-delay = <0x8>; - ti,tx-internal-delay = <0xa>; - ti,fifo-depth = <0x1>; - ti,dp83867-rxctrl-strap-quirk; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u15 6 GPIO_ACTIVE_LOW>; + }; }; }; - &gpio { status = "okay"; gpio-line-names = "QSPI_LWR_CLK", "QSPI_LWR_DQ1", "QSPI_LWR_DQ2", "QSPI_LWR_DQ3", "QSPI_LWR_DQ0", /* 0 - 4 */ diff --git a/arch/arm/dts/zynqmp.dtsi b/arch/arm/dts/zynqmp.dtsi index fbc6e752da..f4184f79a5 100644 --- a/arch/arm/dts/zynqmp.dtsi +++ b/arch/arm/dts/zynqmp.dtsi @@ -529,7 +529,7 @@ }; gem0: ethernet@ff0b0000 { - compatible = "cdns,zynqmp-gem", "cdns,gem"; + compatible = "xlnx,zynqmp-gem", "cdns,zynqmp-gem", "cdns,gem"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 57 4>, <0 57 4>; @@ -543,7 +543,7 @@ }; gem1: ethernet@ff0c0000 { - compatible = "cdns,zynqmp-gem", "cdns,gem"; + compatible = "xlnx,zynqmp-gem", "cdns,zynqmp-gem", "cdns,gem"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 59 4>, <0 59 4>; @@ -557,7 +557,7 @@ }; gem2: ethernet@ff0d0000 { - compatible = "cdns,zynqmp-gem", "cdns,gem"; + compatible = "xlnx,zynqmp-gem", "cdns,zynqmp-gem", "cdns,gem"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 61 4>, <0 61 4>; @@ -571,7 +571,7 @@ }; gem3: ethernet@ff0e0000 { - compatible = "cdns,zynqmp-gem", "cdns,gem"; + compatible = "xlnx,zynqmp-gem", "cdns,zynqmp-gem", "cdns,gem"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 63 4>, <0 63 4>; @@ -869,6 +869,7 @@ iommus = <&smmu 0x860>; snps,quirk-frame-length-adjustment = <0x20>; snps,refclk_fladj; + clock-names = "ref"; snps,enable_guctl1_resume_quirk; snps,enable_guctl1_ipd_quirk; snps,xhci-stream-quirk; @@ -900,6 +901,7 @@ iommus = <&smmu 0x861>; snps,quirk-frame-length-adjustment = <0x20>; snps,refclk_fladj; + clock-names = "ref"; snps,enable_guctl1_resume_quirk; snps,enable_guctl1_ipd_quirk; snps,xhci-stream-quirk; diff --git a/arch/arm/include/asm/arch-stm32f7/stm32.h b/arch/arm/include/asm/arch-stm32f7/stm32.h index 3451e74a3d..57db839e8d 100644 --- a/arch/arm/include/asm/arch-stm32f7/stm32.h +++ b/arch/arm/include/asm/arch-stm32f7/stm32.h @@ -10,9 +10,9 @@ #include static const u32 sect_sz_kb[CONFIG_SYS_MAX_FLASH_SECT] = { - [0 ... 3] = 32 * 1024, - [4] = 128 * 1024, - [5 ... 7] = 256 * 1024 + [0 ... 3] = 32 * 1024, + [4] = 128 * 1024, + [5 ... CONFIG_SYS_MAX_FLASH_SECT - 1] = 256 * 1024 }; #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index b146918586..8d42ef4823 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -58,16 +58,22 @@ #endif /* - * We only support cores that support at least Thumb-1 and thus we use - * 'bx lr' + * Use 'bx lr' everywhere except ARMv4 (without 'T') where only 'mov pc, lr' + * works */ .irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo .macro ret\c, reg + + /* ARMv4- don't know bx lr but the assembler fails to see that */ +#ifdef __ARM_ARCH_4__ + mov\c pc, \reg +#else .ifeqs "\reg", "lr" bx\c \reg .else mov\c pc, \reg .endif +#endif .endm .endr diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 6ee2a76761..cd6112dfcd 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -101,7 +101,7 @@ struct arch_global_data { #include -#if defined(__clang__) || defined(CONFIG_LTO) +#if defined(__clang__) || defined(LTO_ENABLE) #define DECLARE_GLOBAL_DATA_PTR #define gd get_gd() diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index c603fe61bc..62cf80f373 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -33,10 +33,12 @@ obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o -obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o else obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o -obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o +ifdef CONFIG_SPL_FRAMEWORK +obj-$(CONFIG_CMD_BOOTI) += image.o +obj-$(CONFIG_CMD_BOOTZ) += zimage.o +endif obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o endif ifdef CONFIG_ARM64 @@ -46,6 +48,7 @@ else obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMSET) += memset.o obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMCPY) += memcpy.o endif +obj-$(CONFIG_$(SPL_TPL_)SYS_L2_PL310) += cache-pl310.o obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += semihosting.o ifneq ($(filter y,$(CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR) $(CONFIG_SAVE_PREV_BL_FDT_ADDR)),) diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 9f086f3b90..e414ef8267 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -192,10 +192,10 @@ static void do_nonsec_virt_switch(void) } #endif -__weak void board_prep_linux(bootm_headers_t *images) { } +__weak void board_prep_linux(struct bootm_headers *images) { } /* Subcommand: PREP */ -static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { char *commandline = env_get("bootargs"); @@ -288,7 +288,7 @@ static void switch_to_el1(void) #endif /* Subcommand: GO */ -static void boot_jump_linux(bootm_headers_t *images, int flag) +static void boot_jump_linux(struct bootm_headers *images, int flag) { #ifdef CONFIG_ARM64 void (*kernel_entry)(void *fdt_addr, void *res0, void *res1, @@ -379,7 +379,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) * they are called if subcommand is equal 0. */ int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* No need for those on ARM */ if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) @@ -401,7 +401,7 @@ int do_bootm_linux(int flag, int argc, char *const argv[], } #if defined(CONFIG_BOOTM_VXWORKS) -void boot_prep_vxworks(bootm_headers_t *images) +void boot_prep_vxworks(struct bootm_headers *images) { #if defined(CONFIG_OF_LIBFDT) int off; @@ -416,7 +416,8 @@ void boot_prep_vxworks(bootm_headers_t *images) #endif cleanup_before_linux(); } -void boot_jump_vxworks(bootm_headers_t *images) + +void boot_jump_vxworks(struct bootm_headers *images) { #if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI) armv8_setup_psci(); diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S index 700eee5fbb..7ff4446dd6 100644 --- a/arch/arm/lib/lib1funcs.S +++ b/arch/arm/lib/lib1funcs.S @@ -377,7 +377,7 @@ ENTRY(__gnu_thumb1_case_sqi) lsls r1, r1, #1 add lr, lr, r1 pop {r1} - bx lr + ret lr ENDPROC(__gnu_thumb1_case_sqi) .popsection @@ -391,7 +391,7 @@ ENTRY(__gnu_thumb1_case_uqi) lsls r1, r1, #1 add lr, lr, r1 pop {r1} - bx lr + ret lr ENDPROC(__gnu_thumb1_case_uqi) .popsection @@ -406,7 +406,7 @@ ENTRY(__gnu_thumb1_case_shi) lsls r1, r1, #1 add lr, lr, r1 pop {r0, r1} - bx lr + ret lr ENDPROC(__gnu_thumb1_case_shi) .popsection @@ -421,7 +421,7 @@ ENTRY(__gnu_thumb1_case_uhi) lsls r1, r1, #1 add lr, lr, r1 pop {r0, r1} - bx lr + ret lr ENDPROC(__gnu_thumb1_case_uhi) .popsection #endif diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S index eee7a219ce..a1c996f94e 100644 --- a/arch/arm/lib/memcpy.S +++ b/arch/arm/lib/memcpy.S @@ -59,7 +59,7 @@ #endif ENTRY(memcpy) cmp r0, r1 - bxeq lr + reteq lr enter r4, lr @@ -148,7 +148,7 @@ ENTRY(memcpy) str1b r0, ip, cs, abort=21f exit r4, lr - bx lr + ret lr 9: rsb ip, ip, #4 cmp ip, #2 @@ -258,7 +258,7 @@ ENTRY(memcpy) .macro copy_abort_end ldmfd sp!, {r4, lr} - bx lr + ret lr .endm ENDPROC(memcpy) diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S index 5102bfabde..dd6f2e3bd5 100644 --- a/arch/arm/lib/relocate.S +++ b/arch/arm/lib/relocate.S @@ -61,7 +61,7 @@ ENTRY(relocate_vectors) stmia r1!, {r2-r8,r10} #endif #endif - bx lr + ret lr ENDPROC(relocate_vectors) @@ -127,13 +127,7 @@ relocate_done: mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ #endif - /* ARMv4- don't know bx lr but the assembler fails to see that */ - -#ifdef __ARM_ARCH_4__ - mov pc, lr -#else - bx lr -#endif + ret lr ENDPROC(relocate_code) diff --git a/arch/arm/lib/setjmp.S b/arch/arm/lib/setjmp.S index 176a1d5315..2f041aeef0 100644 --- a/arch/arm/lib/setjmp.S +++ b/arch/arm/lib/setjmp.S @@ -17,7 +17,7 @@ ENTRY(setjmp) mov ip, sp stm a1, {v1-v8, ip, lr} mov a1, #0 - bx lr + ret lr ENDPROC(setjmp) .popsection @@ -31,6 +31,6 @@ ENTRY(longjmp) bne 1f mov a1, #1 1: - bx lr + ret lr ENDPROC(longjmp) .popsection diff --git a/arch/arm/mach-aspeed/ast2600/spl.c b/arch/arm/mach-aspeed/ast2600/spl.c index 53c8a15bf9..0952e73a45 100644 --- a/arch/arm/mach-aspeed/ast2600/spl.c +++ b/arch/arm/mach-aspeed/ast2600/spl.c @@ -56,9 +56,9 @@ out: return BOOT_DEVICE_RAM; } -struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { - return (struct image_header *)(CONFIG_SYS_LOAD_ADDR); + return (struct legacy_img_hdr *)(CONFIG_SYS_LOAD_ADDR); } #ifdef CONFIG_SPL_OS_BOOT diff --git a/arch/arm/mach-at91/phy.c b/arch/arm/mach-at91/phy.c index 6101eee358..f4484a77c7 100644 --- a/arch/arm/mach-at91/phy.c +++ b/arch/arm/mach-at91/phy.c @@ -42,7 +42,7 @@ void at91_phy_reset(void) /* Wait for end of hardware reset */ while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL)) { /* avoid shutdown by watchdog */ - WATCHDOG_RESET(); + schedule(); mdelay(10); /* timeout for not getting stuck in an endless loop */ diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 0d1a7766be..c6747b257c 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -589,7 +589,7 @@ static ulong get_image_ivt_offset(ulong img_addr) switch (genimg_get_format(buf)) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: - return (image_get_image_size((image_header_t *)img_addr) + return (image_get_image_size((struct legacy_img_hdr *)img_addr) + 0x1000 - 1) & ~(0x1000 - 1); #endif #if CONFIG_IS_ENABLED(FIT) diff --git a/arch/arm/mach-imx/i2c-mxv7.c b/arch/arm/mach-imx/i2c-mxv7.c index d36347d8e8..85d648b56e 100644 --- a/arch/arm/mach-imx/i2c-mxv7.c +++ b/arch/arm/mach-imx/i2c-mxv7.c @@ -46,7 +46,7 @@ int force_idle_bus(void *priv) scl = gpio_get_value(p->scl.gp); if ((sda & scl) == 1) break; - WATCHDOG_RESET(); + schedule(); elapsed = get_timer(start_time); if (elapsed > (CONFIG_SYS_HZ / 5)) { /* .2 seconds */ ret = -EBUSY; diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 5739546c02..a4863281e3 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -327,7 +327,7 @@ phys_size_t get_effective_memsize(void) } } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { ulong top_addr; diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c index 07bf07beee..aa5d23a6fb 100644 --- a/arch/arm/mach-imx/spl_imx_romapi.c +++ b/arch/arm/mach-imx/spl_imx_romapi.c @@ -72,7 +72,7 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image, int ret; u32 offset; u32 pagesize, size; - struct image_header *header; + struct legacy_img_hdr *header; u32 image_offset; ret = rom_api_query_boot_infor(QUERY_IVT_OFF, &offset); @@ -84,14 +84,14 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image, return -1; } - header = (struct image_header *)(CONFIG_SPL_IMX_ROMAPI_LOADADDR); + header = (struct legacy_img_hdr *)(CONFIG_SPL_IMX_ROMAPI_LOADADDR); printf("image offset 0x%x, pagesize 0x%x, ivt offset 0x%x\n", image_offset, pagesize, offset); offset = spl_romapi_get_uboot_base(image_offset, rom_bt_dev); - size = ALIGN(sizeof(struct image_header), pagesize); + size = ALIGN(sizeof(struct legacy_img_hdr), pagesize); ret = rom_api_download_image((u8 *)header, offset, size); if (ret != ROM_API_OKAY) { diff --git a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c b/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c index c51a75ee94..036fec93d7 100644 --- a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c +++ b/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include #include "pinctrl-snapdragon.h" @@ -110,6 +112,32 @@ static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector, return 0; } +static int msm_pinctrl_bind(struct udevice *dev) +{ + ofnode node = dev_ofnode(dev); + const char *name; + int ret; + + ofnode_get_property(node, "gpio-controller", &ret); + if (ret < 0) + return 0; + + /* Get the name of gpio node */ + name = ofnode_get_name(node); + if (!name) + return -EINVAL; + + /* Bind gpio node */ + ret = device_bind_driver_to_node(dev, "gpio_msm", + name, node, NULL); + if (ret) + return ret; + + dev_dbg(dev, "bind %s\n", name); + + return 0; +} + static struct pinctrl_ops msm_pinctrl_ops = { .get_pins_count = msm_get_pins_count, .get_pin_name = msm_get_pin_name, @@ -123,7 +151,7 @@ static struct pinctrl_ops msm_pinctrl_ops = { }; static const struct udevice_id msm_pinctrl_ids[] = { - { .compatible = "qcom,tlmm-ipq4019", .data = (ulong)&ipq4019_data }, + { .compatible = "qcom,ipq4019-pinctrl", .data = (ulong)&ipq4019_data }, { } }; @@ -134,4 +162,5 @@ U_BOOT_DRIVER(pinctrl_snapdraon) = { .priv_auto = sizeof(struct msm_pinctrl_priv), .ops = &msm_pinctrl_ops, .probe = msm_pinctrl_probe, + .bind = msm_pinctrl_bind, }; diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 3962f2800f..14c37acbce 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -493,7 +493,7 @@ bool soc_is_j7200(void) } #ifdef CONFIG_ARM64 -void board_prep_linux(bootm_headers_t *images) +void board_prep_linux(struct bootm_headers *images) { debug("Linux kernel Image start = 0x%lx end = 0x%lx\n", images->os.start, images->os.end); diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c index b3beeca947..aea640b570 100644 --- a/arch/arm/mach-k3/sysfw-loader.c +++ b/arch/arm/mach-k3/sysfw-loader.c @@ -88,10 +88,10 @@ 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) +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { if (sysfw_loaded) - return (struct image_header *)(CONFIG_SYS_TEXT_BASE + offset); + return (struct legacy_img_hdr *)(CONFIG_SYS_TEXT_BASE + offset); else if (sysfw_load_address) return sysfw_load_address; else @@ -490,7 +490,7 @@ void k3_sysfw_loader(bool rom_loaded_sysfw, sysfw_loaded = true; /* Ensure the SYSFW image is in FIT format */ - if (image_get_magic((const image_header_t *)sysfw_load_address) != + if (image_get_magic((const struct legacy_img_hdr *)sysfw_load_address) != FDT_MAGIC) panic("SYSFW image not in FIT format!\n"); diff --git a/arch/arm/mach-keystone/cmd_mon.c b/arch/arm/mach-keystone/cmd_mon.c index e26296b6da..4734e4c714 100644 --- a/arch/arm/mach-keystone/cmd_mon.c +++ b/arch/arm/mach-keystone/cmd_mon.c @@ -17,7 +17,7 @@ static int do_mon_install(struct cmd_tbl *cmdtp, int flag, int argc, { u32 addr, dpsc_base = 0x1E80000, freq, load_addr, size; int rcode = 0; - struct image_header *header; + struct legacy_img_hdr *header; u32 ecrypt_bm_addr = 0; if (argc < 2) @@ -27,7 +27,7 @@ static int do_mon_install(struct cmd_tbl *cmdtp, int flag, int argc, addr = hextoul(argv[1], NULL); - header = (struct image_header *)addr; + header = (struct legacy_img_hdr *)addr; if (image_get_magic(header) != IH_MAGIC) { printf("## Please update monitor image\n"); @@ -36,7 +36,7 @@ static int do_mon_install(struct cmd_tbl *cmdtp, int flag, int argc, load_addr = image_get_load(header); size = image_get_data_size(header); - memcpy((void *)load_addr, (void *)(addr + sizeof(struct image_header)), + memcpy((void *)load_addr, (void *)(addr + sizeof(struct legacy_img_hdr)), size); if (argc >= 3) diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig index f79a5c62cd..04aa2fd97f 100644 --- a/arch/arm/mach-mediatek/Kconfig +++ b/arch/arm/mach-mediatek/Kconfig @@ -40,6 +40,24 @@ config TARGET_MT7629 including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet, switch, USB3.0, PCIe, UART, SPI, I2C and PWM. +config TARGET_MT7981 + bool "MediaTek MT7981 SoC" + select ARM64 + select CPU + help + The MediaTek MT7981 is a ARM64-based SoC with a dual-core Cortex-A53. + including UART, SPI, USB, NAND, SNFI, PWM, Gigabit Ethernet, I2C, + built-in Wi-Fi, and PCIe. + +config TARGET_MT7986 + bool "MediaTek MT7986 SoC" + select ARM64 + select CPU + help + The MediaTek MT7986 is a ARM64-based SoC with a quad-core Cortex-A53. + including UART, SPI, SPI flash, USB3.0, MMC, NAND, SNFI, PWM, PCIe, + Gigabit Ethernet, I2C, built-in 4x4 Wi-Fi, and PCIe. + config TARGET_MT8183 bool "MediaTek MT8183 SoC" select ARM64 @@ -84,6 +102,8 @@ config SYS_BOARD default "mt7622" if TARGET_MT7622 default "mt7623" if TARGET_MT7623 default "mt7629" if TARGET_MT7629 + default "mt7981" if TARGET_MT7981 + default "mt7986" if TARGET_MT7986 default "mt8183" if TARGET_MT8183 default "mt8512" if TARGET_MT8512 default "mt8516" if TARGET_MT8516 @@ -99,6 +119,8 @@ config SYS_CONFIG_NAME default "mt7622" if TARGET_MT7622 default "mt7623" if TARGET_MT7623 default "mt7629" if TARGET_MT7629 + default "mt7981" if TARGET_MT7981 + default "mt7986" if TARGET_MT7986 default "mt8183" if TARGET_MT8183 default "mt8512" if TARGET_MT8512 default "mt8516" if TARGET_MT8516 @@ -113,6 +135,7 @@ config MTK_BROM_HEADER_INFO string default "media=nor" if TARGET_MT8518 || TARGET_MT8512 || TARGET_MT7629 || TARGET_MT7622 default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8183 + default "media=snand;nandinfo=2k+64" if TARGET_MT7981 || TARGET_MT7986 default "lk=1" if TARGET_MT7623 endif diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile index 0f5b0c16d2..fc85293f71 100644 --- a/arch/arm/mach-mediatek/Makefile +++ b/arch/arm/mach-mediatek/Makefile @@ -7,6 +7,8 @@ obj-$(CONFIG_MT8512) += mt8512/ obj-$(CONFIG_TARGET_MT7622) += mt7622/ obj-$(CONFIG_TARGET_MT7623) += mt7623/ obj-$(CONFIG_TARGET_MT7629) += mt7629/ +obj-$(CONFIG_TARGET_MT7981) += mt7981/ +obj-$(CONFIG_TARGET_MT7986) += mt7986/ obj-$(CONFIG_TARGET_MT8183) += mt8183/ obj-$(CONFIG_TARGET_MT8516) += mt8516/ obj-$(CONFIG_TARGET_MT8518) += mt8518/ diff --git a/arch/arm/mach-mediatek/mt7981/Makefile b/arch/arm/mach-mediatek/mt7981/Makefile new file mode 100644 index 0000000000..007eb4a367 --- /dev/null +++ b/arch/arm/mach-mediatek/mt7981/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += init.o +obj-y += lowlevel_init.o diff --git a/arch/arm/mach-mediatek/mt7981/init.c b/arch/arm/mach-mediatek/mt7981/init.c new file mode 100644 index 0000000000..4f77a3defb --- /dev/null +++ b/arch/arm/mach-mediatek/mt7981/init.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_2G); + + return 0; +} + +void reset_cpu(ulong addr) +{ + psci_system_reset(); +} + +static struct mm_region mt7981_mem_map[] = { + { + /* DDR */ + .virt = 0x40000000UL, + .phys = 0x40000000UL, + .size = 0x80000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE, + }, { + .virt = 0x00000000UL, + .phys = 0x00000000UL, + .size = 0x40000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + 0, + } +}; + +struct mm_region *mem_map = mt7981_mem_map; diff --git a/arch/arm/mach-mediatek/mt7981/lowlevel_init.S b/arch/arm/mach-mediatek/mt7981/lowlevel_init.S new file mode 100644 index 0000000000..85a1cea359 --- /dev/null +++ b/arch/arm/mach-mediatek/mt7981/lowlevel_init.S @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/* + * Switch from AArch64 EL2 to AArch32 EL2 + * @param inputs: + * x0: argument, zero + * x1: machine nr + * x2: fdt address + * x3: input argument + * x4: kernel entry point + * @param outputs for secure firmware: + * x0: function id + * x1: kernel entry point + * x2: machine nr + * x3: fdt address + * + * [1] https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/mediatek/common/mtk_sip_svc.c +*/ + +.global armv8_el2_to_aarch32 +armv8_el2_to_aarch32: + mov x3, x2 + mov x2, x1 + mov x1, x4 + mov x4, #0 + ldr x0, =0x82000200 /* MTK_SIP_KERNEL_BOOT_AARCH32 */ + SMC #0 + ret diff --git a/arch/arm/mach-mediatek/mt7986/Makefile b/arch/arm/mach-mediatek/mt7986/Makefile new file mode 100644 index 0000000000..007eb4a367 --- /dev/null +++ b/arch/arm/mach-mediatek/mt7986/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += init.o +obj-y += lowlevel_init.o diff --git a/arch/arm/mach-mediatek/mt7986/init.c b/arch/arm/mach-mediatek/mt7986/init.c new file mode 100644 index 0000000000..0fd459657d --- /dev/null +++ b/arch/arm/mach-mediatek/mt7986/init.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_2G); + + return 0; +} + +void reset_cpu(ulong addr) +{ + psci_system_reset(); +} + +static struct mm_region mt7986_mem_map[] = { + { + /* DDR */ + .virt = 0x40000000UL, + .phys = 0x40000000UL, + .size = 0x80000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE, + }, { + .virt = 0x00000000UL, + .phys = 0x00000000UL, + .size = 0x40000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + 0, + } +}; + +struct mm_region *mem_map = mt7986_mem_map; diff --git a/arch/arm/mach-mediatek/mt7986/lowlevel_init.S b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S new file mode 100644 index 0000000000..85a1cea359 --- /dev/null +++ b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/* + * Switch from AArch64 EL2 to AArch32 EL2 + * @param inputs: + * x0: argument, zero + * x1: machine nr + * x2: fdt address + * x3: input argument + * x4: kernel entry point + * @param outputs for secure firmware: + * x0: function id + * x1: kernel entry point + * x2: machine nr + * x3: fdt address + * + * [1] https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/mediatek/common/mtk_sip_svc.c +*/ + +.global armv8_el2_to_aarch32 +armv8_el2_to_aarch32: + mov x3, x2 + mov x2, x1 + mov x1, x4 + mov x4, #0 + ldr x0, =0x82000200 /* MTK_SIP_KERNEL_BOOT_AARCH32 */ + SMC #0 + ret diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index a81b8e2b0d..2ebe341ed1 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -14,6 +14,7 @@ config ARMADA_32BIT select SPL_SKIP_LOWLEVEL_INIT if SPL select SPL_SIMPLE_BUS if SPL select SUPPORT_SPL + select SYS_L2_PL310 if !SYS_L2CACHE_OFF select TRANSLATION_OFFSET select SPL_SYS_NO_VECTOR_TABLE if SPL select ARCH_VERY_EARLY_INIT diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index 238edbe6ba..63f6af5fe8 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -30,7 +30,7 @@ DECLARE_GLOBAL_DATA_PTR; */ #define USABLE_RAM_SIZE 0x80000000ULL -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { unsigned long top = CONFIG_SYS_SDRAM_BASE + min(gd->ram_size, USABLE_RAM_SIZE); diff --git a/arch/arm/mach-mvebu/include/mach/config.h b/arch/arm/mach-mvebu/include/mach/config.h index 4add0d9e10..2e06f2bdae 100644 --- a/arch/arm/mach-mvebu/include/mach/config.h +++ b/arch/arm/mach-mvebu/include/mach/config.h @@ -25,8 +25,6 @@ #define MV88F78X60 /* for the DDR training bin_hdr code */ #endif -#define CONFIG_SYS_L2_PL310 - #define MV_UART_CONSOLE_BASE MVEBU_UART0_BASE /* Needed for SPI NOR booting in SPL */ @@ -41,9 +39,4 @@ #endif #endif -/* Use common timer */ -#define CONFIG_SYS_TIMER_COUNTS_DOWN -#define CONFIG_SYS_TIMER_COUNTER (MVEBU_TIMER_BASE + 0x14) -#define CONFIG_SYS_TIMER_RATE 25000000 - #endif /* __MVEBU_CONFIG_H */ diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 914d43b049..78317e474d 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -96,6 +96,7 @@ config TI816X config AM43XX bool "AM43XX SoC" select SPECIFY_CONSOLE_INDEX + select SYS_L2_PL310 if !SYS_L2CACHE_OFF imply NAND_OMAP_ELM imply NAND_OMAP_GPMC imply SPL_DM diff --git a/arch/arm/mach-rockchip/sdram.c b/arch/arm/mach-rockchip/sdram.c index 705ec7ba64..12f1d7ee56 100644 --- a/arch/arm/mach-rockchip/sdram.c +++ b/arch/arm/mach-rockchip/sdram.c @@ -205,7 +205,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { unsigned long top = CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE; diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile index 0d31f10f68..cbaaf23f6b 100644 --- a/arch/arm/mach-snapdragon/Makefile +++ b/arch/arm/mach-snapdragon/Makefile @@ -16,6 +16,6 @@ obj-y += pinctrl-snapdragon.o obj-y += pinctrl-apq8016.o obj-y += pinctrl-apq8096.o obj-y += pinctrl-qcs404.o -obj-$(CONFIG_SDM845) += pinctrl-sdm845.o +obj-y += pinctrl-sdm845.o obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o obj-$(CONFIG_TARGET_QCS404EVB) += sysmap-qcs404.o diff --git a/arch/arm/mach-snapdragon/clock-apq8016.c b/arch/arm/mach-snapdragon/clock-apq8016.c index 6e4a0ccb90..23a37a1714 100644 --- a/arch/arm/mach-snapdragon/clock-apq8016.c +++ b/arch/arm/mach-snapdragon/clock-apq8016.c @@ -111,3 +111,8 @@ ulong msm_set_rate(struct clk *clk, ulong rate) return 0; } } + +int msm_enable(struct clk *clk) +{ + return 0; +} diff --git a/arch/arm/mach-snapdragon/clock-apq8096.c b/arch/arm/mach-snapdragon/clock-apq8096.c index e5011be8f2..66184596d5 100644 --- a/arch/arm/mach-snapdragon/clock-apq8096.c +++ b/arch/arm/mach-snapdragon/clock-apq8096.c @@ -93,3 +93,8 @@ ulong msm_set_rate(struct clk *clk, ulong rate) return 0; } } + +int msm_enable(struct clk *clk) +{ + return 0; +} diff --git a/arch/arm/mach-snapdragon/clock-qcs404.c b/arch/arm/mach-snapdragon/clock-qcs404.c index bb8a6fe067..6fe92afe8d 100644 --- a/arch/arm/mach-snapdragon/clock-qcs404.c +++ b/arch/arm/mach-snapdragon/clock-qcs404.c @@ -47,6 +47,14 @@ static struct pll_vote_clk gpll0_vote_clk = { .vote_bit = BIT(0), }; +static const struct bcr_regs usb30_master_regs = { + .cfg_rcgr = USB30_MASTER_CFG_RCGR, + .cmd_rcgr = USB30_MASTER_CMD_RCGR, + .M = USB30_MASTER_M, + .N = USB30_MASTER_N, + .D = USB30_MASTER_D, +}; + ulong msm_set_rate(struct clk *clk, ulong rate) { struct msm_clk_priv *priv = dev_get_priv(clk->dev); @@ -77,3 +85,35 @@ ulong msm_set_rate(struct clk *clk, ulong rate) return 0; } + +int msm_enable(struct clk *clk) +{ + struct msm_clk_priv *priv = dev_get_priv(clk->dev); + + switch (clk->id) { + case GCC_USB30_MASTER_CLK: + clk_enable_cbc(priv->base + USB30_MASTER_CBCR); + clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 4, 0, 0, + CFG_CLK_SRC_GPLL0); + break; + case GCC_SYS_NOC_USB3_CLK: + clk_enable_cbc(priv->base + SYS_NOC_USB3_CBCR); + break; + case GCC_USB30_SLEEP_CLK: + clk_enable_cbc(priv->base + USB30_SLEEP_CBCR); + break; + case GCC_USB30_MOCK_UTMI_CLK: + clk_enable_cbc(priv->base + USB30_MOCK_UTMI_CBCR); + break; + case GCC_USB_HS_PHY_CFG_AHB_CLK: + clk_enable_cbc(priv->base + USB_HS_PHY_CFG_AHB_CBCR); + break; + case GCC_USB2A_PHY_SLEEP_CLK: + clk_enable_cbc(priv->base + USB_HS_PHY_CFG_AHB_CBCR); + break; + default: + return 0; + } + + return 0; +} diff --git a/arch/arm/mach-snapdragon/clock-sdm845.c b/arch/arm/mach-snapdragon/clock-sdm845.c index f69be80898..d6df0365af 100644 --- a/arch/arm/mach-snapdragon/clock-sdm845.c +++ b/arch/arm/mach-snapdragon/clock-sdm845.c @@ -91,3 +91,8 @@ ulong msm_set_rate(struct clk *clk, ulong rate) return 0; } } + +int msm_enable(struct clk *clk) +{ + return 0; +} diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/arch/arm/mach-snapdragon/clock-snapdragon.c index 5652d2fa36..fda7098274 100644 --- a/arch/arm/mach-snapdragon/clock-snapdragon.c +++ b/arch/arm/mach-snapdragon/clock-snapdragon.c @@ -20,6 +20,7 @@ #define CBCR_BRANCH_OFF_BIT BIT(31) extern ulong msm_set_rate(struct clk *clk, ulong rate); +extern int msm_enable(struct clk *clk); /* Enable clock controlled by CBC soft macro */ void clk_enable_cbc(phys_addr_t cbcr) @@ -126,8 +127,14 @@ static ulong msm_clk_set_rate(struct clk *clk, ulong rate) return msm_set_rate(clk, rate); } +static int msm_clk_enable(struct clk *clk) +{ + return msm_enable(clk); +} + static struct clk_ops msm_clk_ops = { .set_rate = msm_clk_set_rate, + .enable = msm_clk_enable, }; static const struct udevice_id msm_clk_ids[] = { diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h b/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h index 4dc96b9fbc..e448faad2d 100644 --- a/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h +++ b/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h @@ -37,4 +37,21 @@ #define SDCC_APPS_CBCR(n) (((n) * 0x1000) + 0x41018) #define SDCC_AHB_CBCR(n) (((n) * 0x1000) + 0x4101C) +/* USB-3.0 controller clock control registers */ +#define SYS_NOC_USB3_CBCR (0x26014) +#define USB30_BCR (0x39000) +#define USB3PHY_BCR (0x39008) +#define USB30_MASTER_CBCR (0x3900C) +#define USB30_SLEEP_CBCR (0x39010) +#define USB30_MOCK_UTMI_CBCR (0x39014) +#define USB30_MOCK_UTMI_CMD_RCGR (0x3901C) +#define USB30_MOCK_UTMI_CFG_RCGR (0x39020) +#define USB30_MASTER_CMD_RCGR (0x39028) +#define USB30_MASTER_CFG_RCGR (0x3902C) +#define USB30_MASTER_M (0x39030) +#define USB30_MASTER_N (0x39034) +#define USB30_MASTER_D (0x39038) +#define USB2A_PHY_SLEEP_CBCR (0x4102C) +#define USB_HS_PHY_CFG_AHB_CBCR (0x41030) + #endif diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c index c2148a5d0a..ab884ab6bf 100644 --- a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c +++ b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include "pinctrl-snapdragon.h" @@ -113,13 +115,37 @@ static struct pinctrl_ops msm_pinctrl_ops = { .get_function_name = msm_get_function_name, }; +static int msm_pinctrl_bind(struct udevice *dev) +{ + ofnode node = dev_ofnode(dev); + const char *name; + int ret; + + ofnode_get_property(node, "gpio-controller", &ret); + if (ret < 0) + return 0; + + /* Get the name of gpio node */ + name = ofnode_get_name(node); + if (!name) + return -EINVAL; + + /* Bind gpio node */ + ret = device_bind_driver_to_node(dev, "gpio_msm", + name, node, NULL); + if (ret) + return ret; + + dev_dbg(dev, "bind %s\n", name); + + return 0; +} + static const struct udevice_id msm_pinctrl_ids[] = { - { .compatible = "qcom,tlmm-apq8016", .data = (ulong)&apq8016_data }, - { .compatible = "qcom,tlmm-apq8096", .data = (ulong)&apq8096_data }, -#ifdef CONFIG_SDM845 - { .compatible = "qcom,tlmm-sdm845", .data = (ulong)&sdm845_data }, -#endif - { .compatible = "qcom,tlmm-qcs404", .data = (ulong)&qcs404_data }, + { .compatible = "qcom,msm8916-pinctrl", .data = (ulong)&apq8016_data }, + { .compatible = "qcom,msm8996-pinctrl", .data = (ulong)&apq8096_data }, + { .compatible = "qcom,sdm845-pinctrl", .data = (ulong)&sdm845_data }, + { .compatible = "qcom,qcs404-pinctrl", .data = (ulong)&qcs404_data }, { } }; @@ -130,4 +156,5 @@ U_BOOT_DRIVER(pinctrl_snapdraon) = { .priv_auto = sizeof(struct msm_pinctrl_priv), .ops = &msm_pinctrl_ops, .probe = msm_pinctrl_probe, + .bind = msm_pinctrl_bind, }; diff --git a/arch/arm/mach-socfpga/board.c b/arch/arm/mach-socfpga/board.c index 7267163222..b49006c6c8 100644 --- a/arch/arm/mach-socfpga/board.c +++ b/arch/arm/mach-socfpga/board.c @@ -114,7 +114,7 @@ void board_fit_image_post_process(const void *fit, int node, void **p_image, #endif #if !IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_FIT) -void board_prep_linux(bootm_headers_t *images) +void board_prep_linux(struct bootm_headers *images) { if (!images->fit_uname_cfg) { if (IS_ENABLED(CONFIG_SOCFPGA_SECURE_VAB_AUTH) && diff --git a/arch/arm/mach-socfpga/spl_a10.c b/arch/arm/mach-socfpga/spl_a10.c index ec67a5b0eb..2c567edd50 100644 --- a/arch/arm/mach-socfpga/spl_a10.c +++ b/arch/arm/mach-socfpga/spl_a10.c @@ -117,7 +117,7 @@ void spl_board_init(void) /* enable console uart printing */ preloader_console_init(); - WATCHDOG_RESET(); + schedule(); arch_early_init_r(); @@ -203,7 +203,7 @@ void spl_board_init(void) */ set_regular_boot(true); - WATCHDOG_RESET(); + schedule(); reset_cpu(); } @@ -268,11 +268,11 @@ void board_init_f(ulong dummy) /* reconfigure and enable the watchdog */ hw_watchdog_init(); - WATCHDOG_RESET(); + schedule(); #endif /* CONFIG_HW_WATCHDOG */ config_dedicated_pins(gd->fdt_blob); - WATCHDOG_RESET(); + schedule(); } /* board specific function prior loading SSBL / U-Boot proper */ diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index 68f28922d1..278253e472 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -11,13 +11,81 @@ #include #include -/* Closed device : bit 6 of OPT0*/ +/* + * Closed device: OTP0 + * STM32MP15x: bit 6 of OPT0 + * STM32MP13x: 0b111111 = 0x3F for OTP_SECURED closed device + */ #define STM32_OTP_CLOSE_ID 0 -#define STM32_OTP_CLOSE_MASK BIT(6) +#define STM32_OTP_STM32MP13x_CLOSE_MASK 0x3F +#define STM32_OTP_STM32MP15x_CLOSE_MASK BIT(6) -/* HASH of key: 8 OTPs, starting with OTP24) */ -#define STM32_OTP_HASH_KEY_START 24 -#define STM32_OTP_HASH_KEY_SIZE 8 +/* PKH is the first element of the key list */ +#define STM32KEY_PKH 0 + +struct stm32key { + char *name; + char *desc; + u8 start; + u8 size; +}; + +const struct stm32key stm32mp13_list[] = { + [STM32KEY_PKH] = { + .name = "PKHTH", + .desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm)", + .start = 24, + .size = 8, + }, + { + .name = "EDMK", + .desc = "Encryption/Decryption Master Key", + .start = 92, + .size = 4, + } +}; + +const struct stm32key stm32mp15_list[] = { + [STM32KEY_PKH] = { + .name = "PKH", + .desc = "Hash of the ECC Public Key (ECDSA is the authentication algorithm)", + .start = 24, + .size = 8, + } +}; + +/* index of current selected key in stm32key list, 0 = PKH by default */ +static u8 stm32key_index; + +static u8 get_key_nb(void) +{ + if (IS_ENABLED(CONFIG_STM32MP13x)) + return ARRAY_SIZE(stm32mp13_list); + + if (IS_ENABLED(CONFIG_STM32MP15x)) + return ARRAY_SIZE(stm32mp15_list); +} + +static const struct stm32key *get_key(u8 index) +{ + if (IS_ENABLED(CONFIG_STM32MP13x)) + return &stm32mp13_list[index]; + + if (IS_ENABLED(CONFIG_STM32MP15x)) + return &stm32mp15_list[index]; +} + +static u32 get_otp_close_mask(void) +{ + if (IS_ENABLED(CONFIG_STM32MP13x)) + return STM32_OTP_STM32MP13x_CLOSE_MASK; + + if (IS_ENABLED(CONFIG_STM32MP15x)) + return STM32_OTP_STM32MP15x_CLOSE_MASK; +} + +#define BSEC_LOCK_ERROR (-1) +#define BSEC_LOCK_PERM BIT(0) static int get_misc_dev(struct udevice **dev) { @@ -30,108 +98,115 @@ static int get_misc_dev(struct udevice **dev) return ret; } -static void read_hash_value(u32 addr) +static void read_key_value(const struct stm32key *key, u32 addr) { int i; - printf("Read KEY at 0x%x\n", addr); - for (i = 0; i < STM32_OTP_HASH_KEY_SIZE; i++) { - printf("OTP value %i: %x\n", STM32_OTP_HASH_KEY_START + i, - __be32_to_cpu(*(u32 *)addr)); + for (i = 0; i < key->size; i++) { + printf("%s OTP %i: [%08x] %08x\n", key->name, key->start + i, + addr, __be32_to_cpu(*(u32 *)addr)); addr += 4; } } -static int read_hash_otp(bool print, bool *locked, bool *closed) +static int read_key_otp(struct udevice *dev, const struct stm32key *key, bool print, bool *locked) { - struct udevice *dev; int i, word, ret; - int nb_invalid = 0, nb_zero = 0, nb_lock = 0; + int nb_invalid = 0, nb_zero = 0, nb_lock = 0, nb_lock_err = 0; u32 val, lock; bool status; - ret = get_misc_dev(&dev); - if (ret) - return ret; - - for (i = 0, word = STM32_OTP_HASH_KEY_START; i < STM32_OTP_HASH_KEY_SIZE; i++, word++) { + for (i = 0, word = key->start; i < key->size; i++, word++) { ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4); if (ret != 4) val = ~0x0; ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4); if (ret != 4) - lock = -1; + lock = BSEC_LOCK_ERROR; if (print) - printf("OTP HASH %i: %x lock : %d\n", word, val, lock); + printf("%s OTP %i: %08x lock : %08x\n", key->name, word, val, lock); if (val == ~0x0) nb_invalid++; else if (val == 0x0) nb_zero++; - if (lock == 1) + if (lock & BSEC_LOCK_PERM) nb_lock++; + if (lock & BSEC_LOCK_ERROR) + nb_lock_err++; } - word = STM32_OTP_CLOSE_ID; - ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4); - if (ret != 4) - val = 0x0; - ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4); - if (ret != 4) - lock = -1; - - status = (val & STM32_OTP_CLOSE_MASK) == STM32_OTP_CLOSE_MASK; - if (closed) - *closed = status; - if (print) - printf("OTP %d: closed status: %d lock : %d\n", word, status, lock); - - status = (nb_lock == STM32_OTP_HASH_KEY_SIZE); + status = nb_lock_err || (nb_lock == key->size); if (locked) *locked = status; - if (!status && print) - printf("Hash of key is not locked!\n"); + if (nb_lock_err && print) + printf("%s lock is invalid!\n", key->name); + else if (!status && print) + printf("%s is not locked!\n", key->name); - if (nb_invalid == STM32_OTP_HASH_KEY_SIZE) { + if (nb_invalid == key->size) { if (print) - printf("Hash of key is invalid!\n"); + printf("%s is invalid!\n", key->name); return -EINVAL; } - if (nb_zero == STM32_OTP_HASH_KEY_SIZE) { + if (nb_zero == key->size) { if (print) - printf("Hash of key is free!\n"); + printf("%s is free!\n", key->name); return -ENOENT; } return 0; } -static int fuse_hash_value(u32 addr, bool print) +static int read_close_status(struct udevice *dev, bool print, bool *closed) +{ + int word, ret, result; + u32 val, lock, mask; + bool status; + + result = 0; + word = STM32_OTP_CLOSE_ID; + ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4); + if (ret < 0) + result = ret; + if (ret != 4) + val = 0x0; + + ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4); + if (ret < 0) + result = ret; + if (ret != 4) + lock = BSEC_LOCK_ERROR; + + mask = get_otp_close_mask(); + status = (val & mask) == mask; + if (closed) + *closed = status; + if (print) + printf("OTP %d: closed status: %d lock : %08x\n", word, status, lock); + + return result; +} + +static int fuse_key_value(struct udevice *dev, const struct stm32key *key, u32 addr, bool print) { - struct udevice *dev; u32 word, val; int i, ret; - ret = get_misc_dev(&dev); - if (ret) - return ret; - - for (i = 0, word = STM32_OTP_HASH_KEY_START; - i < STM32_OTP_HASH_KEY_SIZE; - i++, word++, addr += 4) { + for (i = 0, word = key->start; i < key->size; i++, word++, addr += 4) { val = __be32_to_cpu(*(u32 *)addr); if (print) - printf("Fuse OTP %i : %x\n", word, val); + printf("Fuse %s OTP %i : %08x\n", key->name, word, val); ret = misc_write(dev, STM32_BSEC_OTP(word), &val, 4); if (ret != 4) { - log_err("Fuse OTP %i failed\n", word); + log_err("Fuse %s OTP %i failed\n", key->name, word); return ret; } - /* on success, lock the OTP for HASH key */ - val = 1; + /* on success, lock the OTP for the key */ + val = BSEC_LOCK_PERM; ret = misc_write(dev, STM32_BSEC_LOCK(word), &val, 4); if (ret != 4) { - log_err("Lock OTP %i failed\n", word); + log_err("Lock %s OTP %i failed\n", key->name, word); return ret; } } @@ -153,28 +228,103 @@ static int confirm_prog(void) return 0; } -static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +static void display_key_info(const struct stm32key *key) { - u32 addr; + printf("%s : %s\n", key->name, key->desc); + printf("\tOTP%d..%d\n", key->start, key->start + key->size); +} + +static int do_stm32key_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + int i; + + for (i = 0; i < get_key_nb(); i++) + display_key_info(get_key(i)); + + return CMD_RET_SUCCESS; +} + +static int do_stm32key_select(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + const struct stm32key *key; + int i; if (argc == 1) { - read_hash_otp(true, NULL, NULL); + printf("Selected key:\n"); + key = get_key(stm32key_index); + display_key_info(key); return CMD_RET_SUCCESS; } + for (i = 0; i < get_key_nb(); i++) { + key = get_key(i); + if (!strcmp(key->name, argv[1])) { + printf("%s selected\n", key->name); + stm32key_index = i; + return CMD_RET_SUCCESS; + } + } + + printf("Unknown key %s\n", argv[1]); + + return CMD_RET_FAILURE; +} + +static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + const struct stm32key *key; + struct udevice *dev; + u32 addr; + int ret, i; + int result; + + ret = get_misc_dev(&dev); + + if (argc == 1) { + if (ret) + return CMD_RET_FAILURE; + key = get_key(stm32key_index); + ret = read_key_otp(dev, key, true, NULL); + if (ret != -ENOENT) + return CMD_RET_FAILURE; + return CMD_RET_SUCCESS; + } + + if (!strcmp("-a", argv[1])) { + if (ret) + return CMD_RET_FAILURE; + result = CMD_RET_SUCCESS; + for (i = 0; i < get_key_nb(); i++) { + key = get_key(i); + ret = read_key_otp(dev, key, true, NULL); + if (ret != -ENOENT) + result = CMD_RET_FAILURE; + } + ret = read_close_status(dev, true, NULL); + if (ret) + result = CMD_RET_FAILURE; + + return result; + } + addr = hextoul(argv[1], NULL); if (!addr) return CMD_RET_USAGE; - read_hash_value(addr); + key = get_key(stm32key_index); + printf("Read %s at 0x%08x\n", key->name, addr); + read_key_value(key, addr); return CMD_RET_SUCCESS; } static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + const struct stm32key *key = get_key(stm32key_index); + struct udevice *dev; u32 addr; - bool yes = false, lock, closed; + int ret; + bool yes = false, lock; if (argc < 2) return CMD_RET_USAGE; @@ -189,29 +339,38 @@ static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *con if (!addr) return CMD_RET_USAGE; - if (read_hash_otp(!yes, &lock, &closed) != -ENOENT) { + ret = get_misc_dev(&dev); + if (ret) + return CMD_RET_FAILURE; + + if (read_key_otp(dev, key, !yes, &lock) != -ENOENT) { printf("Error: can't fuse again the OTP\n"); return CMD_RET_FAILURE; } - - if (lock || closed) { - printf("Error: invalid OTP configuration (lock=%d, closed=%d)\n", lock, closed); + if (lock) { + printf("Error: %s is locked\n", key->name); return CMD_RET_FAILURE; } + if (!yes) { + printf("Writing %s with\n", key->name); + read_key_value(key, addr); + } + if (!yes && !confirm_prog()) return CMD_RET_FAILURE; - if (fuse_hash_value(addr, !yes)) + if (fuse_key_value(dev, key, addr, !yes)) return CMD_RET_FAILURE; - printf("Hash key updated !\n"); + printf("%s updated !\n", key->name); return CMD_RET_SUCCESS; } static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + const struct stm32key *key; bool yes, lock, closed; struct udevice *dev; u32 val; @@ -224,32 +383,36 @@ static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *co yes = true; } - ret = read_hash_otp(!yes, &lock, &closed); - if (ret) { - if (ret == -ENOENT) - printf("Error: OTP not programmed!\n"); + ret = get_misc_dev(&dev); + if (ret) + return CMD_RET_FAILURE; + + if (read_close_status(dev, !yes, &closed)) return CMD_RET_FAILURE; - } if (closed) { printf("Error: already closed!\n"); return CMD_RET_FAILURE; } + /* check PKH status before to close */ + key = get_key(STM32KEY_PKH); + ret = read_key_otp(dev, key, !yes, &lock); + if (ret) { + if (ret == -ENOENT) + printf("Error: %s not programmed!\n", key->name); + return CMD_RET_FAILURE; + } if (!lock) - printf("Warning: OTP not locked!\n"); + printf("Warning: %s not locked!\n", key->name); if (!yes && !confirm_prog()) return CMD_RET_FAILURE; - ret = get_misc_dev(&dev); - if (ret) - return CMD_RET_FAILURE; - - val = STM32_OTP_CLOSE_MASK; + val = get_otp_close_mask(); ret = misc_write(dev, STM32_BSEC_OTP(STM32_OTP_CLOSE_ID), &val, 4); if (ret != 4) { - printf("Error: can't update OTP\n"); + printf("Error: can't update OTP %d\n", STM32_OTP_CLOSE_ID); return CMD_RET_FAILURE; } @@ -259,11 +422,15 @@ static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *co } static char stm32key_help_text[] = - "read []: Read the hash stored at addr in memory or in OTP\n" - "stm32key fuse [-y] : Fuse hash stored at addr in OTP\n" - "stm32key close [-y] : Close the device, the hash stored in OTP\n"; + "list : list the supported key with description\n" + "stm32key select [] : Select the key identified by or display the key used for read/fuse command\n" + "stm32key read [ | -a ] : Read the curent key at or current / all (-a) key in OTP\n" + "stm32key fuse [-y] : Fuse the current key at addr in OTP\n" + "stm32key close [-y] : Close the device\n"; -U_BOOT_CMD_WITH_SUBCMDS(stm32key, "Fuse ST Hash key", stm32key_help_text, +U_BOOT_CMD_WITH_SUBCMDS(stm32key, "Manage key on STM32", stm32key_help_text, + U_BOOT_SUBCMD_MKENT(list, 1, 0, do_stm32key_list), + U_BOOT_SUBCMD_MKENT(select, 2, 0, do_stm32key_select), U_BOOT_SUBCMD_MKENT(read, 2, 0, do_stm32key_read), U_BOOT_SUBCMD_MKENT(fuse, 3, 0, do_stm32key_fuse), U_BOOT_SUBCMD_MKENT(close, 2, 0, do_stm32key_close)); diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index f59414e716..d2666b9775 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -61,7 +61,7 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, dev = (int)dectoul(argv[2], NULL); - addr = STM32_DDR_BASE; + addr = CONFIG_SYS_LOAD_ADDR; size = 0; if (argc > 3) { addr = hextoul(argv[3], NULL); @@ -126,21 +126,21 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, char *bootm_argv[5] = { "bootm", boot_addr_start, "-", dtb_addr, NULL }; - u32 uimage = data->uimage; - u32 dtb = data->dtb; - u32 initrd = data->initrd; + const void *uimage = (void *)data->uimage; + const void *dtb = (void *)data->dtb; + const void *initrd = (void *)data->initrd; if (!dtb) bootm_argv[3] = env_get("fdtcontroladdr"); else snprintf(dtb_addr, sizeof(dtb_addr) - 1, - "0x%x", dtb); + "0x%p", dtb); snprintf(boot_addr_start, sizeof(boot_addr_start) - 1, - "0x%x", uimage); + "0x%p", uimage); if (initrd) { - snprintf(initrd_addr, sizeof(initrd_addr) - 1, "0x%x:0x%x", + snprintf(initrd_addr, sizeof(initrd_addr) - 1, "0x%p:0x%zx", initrd, data->initrd_size); bootm_argv[2] = initrd_addr; } @@ -148,7 +148,7 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, printf("Booting kernel at %s %s %s...\n\n\n", boot_addr_start, bootm_argv[2], bootm_argv[3]); /* Try bootm for legacy and FIT format image */ - if (genimg_get_format((void *)uimage) != IMAGE_FORMAT_INVALID) + if (genimg_get_format(uimage) != IMAGE_FORMAT_INVALID) do_bootm(cmdtp, 0, 4, bootm_argv); else if (CONFIG_IS_ENABLED(CMD_BOOTZ)) do_bootz(cmdtp, 0, 4, bootm_argv); diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index c391b6c7ab..89552d2ad1 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -322,7 +322,7 @@ void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header) header->image_length = 0x0; } -static u32 stm32prog_header_checksum(u32 addr, struct image_header_s *header) +static u32 stm32prog_header_checksum(uintptr_t addr, struct image_header_s *header) { u32 i, checksum; u8 *payload; @@ -398,7 +398,7 @@ static int parse_name(struct stm32prog_data *data, if (strlen(p) < sizeof(part->name)) { strcpy(part->name, p); } else { - stm32prog_err("Layout line %d: partition name too long [%d]: %s", + stm32prog_err("Layout line %d: partition name too long [%zd]: %s", i, strlen(p), p); result = -EINVAL; } @@ -537,7 +537,7 @@ int (* const parse[COL_NB_STM32])(struct stm32prog_data *data, int i, char *p, }; static int parse_flash_layout(struct stm32prog_data *data, - ulong addr, + uintptr_t addr, ulong size) { int column = 0, part_nb = 0, ret; @@ -1090,7 +1090,6 @@ static int create_gpt_partitions(struct stm32prog_data *data) if (!buf) return -ENOMEM; - puts("partitions : "); /* initialize the selected device */ for (i = 0; i < data->dev_nb; i++) { /* create gpt partition support only for full update on MMC */ @@ -1098,6 +1097,7 @@ static int create_gpt_partitions(struct stm32prog_data *data) !data->dev[i].full_update) continue; + printf("partitions on mmc%d: ", data->dev[i].dev_id); offset = 0; rootfs_found = false; memset(buf, 0, buflen); @@ -1197,8 +1197,8 @@ static int create_gpt_partitions(struct stm32prog_data *data) sprintf(buf, "part list mmc %d", data->dev[i].dev_id); run_command(buf, 0); #endif + puts("done\n"); } - puts("done\n"); #ifdef DEBUG run_command("mtd list", 0); @@ -1342,10 +1342,22 @@ static int dfu_init_entities(struct stm32prog_data *data) struct stm32prog_part_t *part; struct dfu_entity *dfu; int alt_nb; + u32 otp_size = 0; alt_nb = 1; /* number of virtual = CMD*/ - if (IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) - alt_nb++; /* OTP*/ + + if (IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { + /* OTP_SIZE_SMC = 0 if SMC is not supported */ + otp_size = OTP_SIZE_SMC; + /* check if PTA BSEC is supported */ + ret = optee_ta_open(data); + log_debug("optee_ta_open(PTA_NVMEM) result %d\n", ret); + if (!ret && data->tee) + otp_size = OTP_SIZE_TA; + if (otp_size) + alt_nb++; /* OTP*/ + } + if (CONFIG_IS_ENABLED(DM_PMIC)) alt_nb++; /* PMIC NVMEM*/ @@ -1363,6 +1375,7 @@ static int dfu_init_entities(struct stm32prog_data *data) puts("DFU alt info setting: "); if (data->part_nb) { alt_id = 0; + ret = 0; for (phase = 1; (phase <= PHASE_LAST_USER) && (alt_id < alt_nb) && !ret; @@ -1388,7 +1401,7 @@ static int dfu_init_entities(struct stm32prog_data *data) char buf[ALT_BUF_LEN]; sprintf(buf, "@FlashLayout/0x%02x/1*256Ke ram %x 40000", - PHASE_FLASHLAYOUT, STM32_DDR_BASE); + PHASE_FLASHLAYOUT, CONFIG_SYS_LOAD_ADDR); ret = dfu_alt_add(dfu, "ram", NULL, buf); log_debug("dfu_alt_add(ram, NULL,%s) result %d\n", buf, ret); } @@ -1396,12 +1409,8 @@ static int dfu_init_entities(struct stm32prog_data *data) if (!ret) ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, CMD_SIZE); - if (!ret && IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { - ret = optee_ta_open(data); - log_debug("optee_ta result %d\n", ret); - ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, - data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC); - } + if (!ret && IS_ENABLED(CONFIG_CMD_STM32PROG_OTP) && otp_size) + ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, otp_size); if (!ret && CONFIG_IS_ENABLED(DM_PMIC)) ret = stm32prog_alt_add_virt(dfu, "PMIC", PHASE_PMIC, PMIC_SIZE); @@ -1440,7 +1449,7 @@ int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, if (offset + *size > otp_size) *size = otp_size - offset; - memcpy((void *)((u32)data->otp_part + offset), buffer, *size); + memcpy((void *)((uintptr_t)data->otp_part + offset), buffer, *size); return 0; } @@ -1479,7 +1488,7 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, data->otp_part, OTP_SIZE_TA); else if (IS_ENABLED(CONFIG_ARM_SMCCC)) result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL, - (u32)data->otp_part, 0); + (unsigned long)data->otp_part, 0); if (result) goto end_otp_read; } @@ -1491,7 +1500,7 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, if (offset + *size > otp_size) *size = otp_size - offset; - memcpy(buffer, (void *)((u32)data->otp_part + offset), *size); + memcpy(buffer, (void *)((uintptr_t)data->otp_part + offset), *size); end_otp_read: log_debug("%s: result %i\n", __func__, result); @@ -1521,7 +1530,7 @@ int stm32prog_otp_start(struct stm32prog_data *data) data->otp_part, OTP_SIZE_TA); } else if (IS_ENABLED(CONFIG_ARM_SMCCC)) { arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, - (u32)data->otp_part, 0, 0, 0, 0, 0, &res); + (uintptr_t)data->otp_part, 0, 0, 0, 0, 0, &res); if (!res.a0) { switch (res.a1) { @@ -1699,15 +1708,15 @@ static void stm32prog_end_phase(struct stm32prog_data *data, u64 offset) { if (data->phase == PHASE_FLASHLAYOUT) { #if defined(CONFIG_LEGACY_IMAGE_FORMAT) - if (genimg_get_format((void *)STM32_DDR_BASE) == IMAGE_FORMAT_LEGACY) { - data->script = STM32_DDR_BASE; + if (genimg_get_format((void *)CONFIG_SYS_LOAD_ADDR) == IMAGE_FORMAT_LEGACY) { + data->script = CONFIG_SYS_LOAD_ADDR; data->phase = PHASE_END; log_notice("U-Boot script received\n"); return; } #endif log_notice("\nFlashLayout received, size = %lld\n", offset); - if (parse_flash_layout(data, STM32_DDR_BASE, offset)) + if (parse_flash_layout(data, CONFIG_SYS_LOAD_ADDR, offset)) stm32prog_err("Layout: invalid FlashLayout"); return; } @@ -1823,7 +1832,7 @@ static int part_delete(struct stm32prog_data *data, * need to switch to associated hwpart 1 or 2 */ if (part->part_id < 0) - if (blk_select_hwpart_devnum(IF_TYPE_MMC, + if (blk_select_hwpart_devnum(UCLASS_MMC, part->dev->dev_id, -part->part_id)) return -1; @@ -1832,7 +1841,7 @@ static int part_delete(struct stm32prog_data *data, /* return to user partition */ if (part->part_id < 0) - blk_select_hwpart_devnum(IF_TYPE_MMC, + blk_select_hwpart_devnum(UCLASS_MMC, part->dev->dev_id, 0); if (blks != blks_size) { ret = -1; @@ -1884,6 +1893,10 @@ static void stm32prog_devices_init(struct stm32prog_data *data) if (ret) goto error; + /* empty flashlayout */ + if (!data->dev_nb) + return; + /* initialize the selected device */ for (i = 0; i < data->dev_nb; i++) { ret = init_device(data, &data->dev[i]); @@ -1947,7 +1960,7 @@ int stm32prog_dfu_init(struct stm32prog_data *data) return dfu_init_entities(data); } -int stm32prog_init(struct stm32prog_data *data, ulong addr, ulong size) +int stm32prog_init(struct stm32prog_data *data, uintptr_t addr, ulong size) { memset(data, 0x0, sizeof(*data)); data->read_phase = PHASE_RESET; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index ac300768ca..58f4b96fa7 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -20,7 +20,12 @@ #define DEFAULT_ADDRESS 0xFFFFFFFF #define CMD_SIZE 512 +/* SMC is only supported in SPMIN for STM32MP15x */ +#ifdef CONFIG_STM32MP15x #define OTP_SIZE_SMC 1024 +#else +#define OTP_SIZE_SMC 0 +#endif #define OTP_SIZE_TA 776 #define PMIC_SIZE 8 @@ -154,7 +159,7 @@ struct stm32prog_data { u32 offset; char error[255]; struct stm32prog_part_t *cur_part; - u32 *otp_part; + void *otp_part; u8 pmic_part[PMIC_SIZE]; /* SERIAL information */ @@ -165,12 +170,12 @@ struct stm32prog_data { u8 read_phase; /* bootm information */ - u32 uimage; - u32 dtb; - u32 initrd; - u32 initrd_size; + uintptr_t uimage; + uintptr_t dtb; + uintptr_t initrd; + size_t initrd_size; - u32 script; + uintptr_t script; /* OPTEE PTA NVMEM */ struct udevice *tee; @@ -209,7 +214,7 @@ char *stm32prog_get_error(struct stm32prog_data *data); } /* Main function */ -int stm32prog_init(struct stm32prog_data *data, ulong addr, ulong size); +int stm32prog_init(struct stm32prog_data *data, uintptr_t addr, ulong size); void stm32prog_clean(struct stm32prog_data *data); #ifdef CONFIG_CMD_STM32PROG_SERIAL diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c index 2932eae757..f1bed7d1a3 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c @@ -247,7 +247,7 @@ static int stm32prog_serial_getc_err(void) err = ops->getc(down_serial_dev); if (err == -EAGAIN) { ctrlc(); - WATCHDOG_RESET(); + schedule(); } } while ((err == -EAGAIN) && (!had_ctrlc())); @@ -276,7 +276,7 @@ static bool stm32prog_serial_get_buffer(u8 *buffer, u32 *count) *count -= 1; } else if (err == -EAGAIN) { ctrlc(); - WATCHDOG_RESET(); + schedule(); if (get_timer(start) > TIMEOUT_SERIAL_BUFFER) { err = -ETIMEDOUT; break; @@ -300,7 +300,7 @@ static void stm32prog_serial_putc(u8 w_byte) } /* Helper function ************************************************/ -static u8 stm32prog_start(struct stm32prog_data *data, u32 address) +static u8 stm32prog_start(struct stm32prog_data *data, uintptr_t address) { u8 ret = 0; struct dfu_entity *dfu_entity; @@ -353,7 +353,7 @@ static u8 stm32prog_start(struct stm32prog_data *data, u32 address) } else { void (*entry)(void) = (void *)address; - printf("## Starting application at 0x%x ...\n", address); + printf("## Starting application at 0x%p ...\n", (void *)address); (*entry)(); printf("## Application terminated\n"); ret = -ENOEXEC; @@ -368,9 +368,9 @@ static u8 stm32prog_start(struct stm32prog_data *data, u32 address) * @tmp_xor: Current xor value to update * Return: The address area */ -static u32 get_address(u8 *tmp_xor) +static uintptr_t get_address(u8 *tmp_xor) { - u32 address = 0x0; + uintptr_t address = 0x0; u8 data; data = stm32prog_serial_getc(); @@ -462,7 +462,7 @@ static void get_phase_command(struct stm32prog_data *data) length = strlen(err_msg); } if (phase == PHASE_FLASHLAYOUT) - destination = STM32_DDR_BASE; + destination = CONFIG_SYS_LOAD_ADDR; stm32prog_serial_putc(length + 5); /* Total length */ stm32prog_serial_putc(phase & 0xFF); /* partition ID */ @@ -487,7 +487,7 @@ static void get_phase_command(struct stm32prog_data *data) */ static void read_memory_command(struct stm32prog_data *data) { - u32 address = 0x0; + uintptr_t address = 0x0; u8 rcv_data = 0x0, tmp_xor = 0x0; u32 counter = 0x0; @@ -532,7 +532,7 @@ static void read_memory_command(struct stm32prog_data *data) */ static void start_command(struct stm32prog_data *data) { - u32 address = 0; + uintptr_t address = 0; u8 tmp_xor = 0x0; u8 ret, rcv_data; @@ -546,8 +546,7 @@ static void start_command(struct stm32prog_data *data) return; } /* validate partition */ - ret = stm32prog_start(data, - address); + ret = stm32prog_start(data, address); if (ret) stm32prog_serial_result(ABORT_BYTE); @@ -852,7 +851,7 @@ bool stm32prog_serial_loop(struct stm32prog_data *data) stm32prog_serial_result(ACK_BYTE); cmd_func[counter](data); } - WATCHDOG_RESET(); + schedule(); } /* clean device */ diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c index a8b57c4d8f..be38ff239b 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c @@ -41,7 +41,7 @@ static int stm32prog_set_phase(struct stm32prog_data *data, u8 phase, static int stm32prog_cmd_write(u64 offset, void *buf, long *len) { u8 phase; - u32 address; + uintptr_t address; u8 *pt = buf; void (*entry)(void); int ret; @@ -58,7 +58,7 @@ static int stm32prog_cmd_write(u64 offset, void *buf, long *len) address = (pt[1] << 24) | (pt[2] << 16) | (pt[3] << 8) | pt[4]; if (phase == PHASE_RESET) { entry = (void *)address; - printf("## Starting application at 0x%x ...\n", address); + printf("## Starting application at 0x%p ...\n", entry); (*entry)(); printf("## Application terminated\n"); return 0; @@ -90,7 +90,7 @@ static int stm32prog_cmd_read(u64 offset, void *buf, long *len) } phase = stm32prog_data->phase; if (phase == PHASE_FLASHLAYOUT) - destination = STM32_DDR_BASE; + destination = CONFIG_SYS_LOAD_ADDR; dfu_offset = stm32prog_data->offset; /* mandatory header, size = PHASE_MIN_SIZE */ diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c index 920b99bb68..9346fa8546 100644 --- a/arch/arm/mach-stm32mp/dram_init.c +++ b/arch/arm/mach-stm32mp/dram_init.c @@ -40,7 +40,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { phys_size_t size; phys_addr_t reg; diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 8f7c894286..62bb40b8c8 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -65,7 +65,7 @@ static struct mm_region sunxi_mem_map[] = { }; struct mm_region *mem_map = sunxi_mem_map; -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { /* Some devices (like the EMAC) have a 32-bit DMA limit. */ if (gd->ram_top > (1ULL << 32)) diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c index de9aa68c4a..925bf85f2d 100644 --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c @@ -335,10 +335,10 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { int ret = 0; - struct image_header *header; - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); + struct legacy_img_hdr *header; uint32_t load_offset = sunxi_get_spl_size(); + header = (struct legacy_img_hdr *)CONFIG_SYS_TEXT_BASE; load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS); spi0_init(); diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c index 8950e678a6..1994db0e15 100644 --- a/arch/arm/mach-tegra/board2.c +++ b/arch/arm/mach-tegra/board2.c @@ -401,7 +401,7 @@ int dram_init_banksize(void) * This function is called before dram_init_banksize(), so we can't simply * return gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { ulong ram_top; diff --git a/arch/arm/mach-tegra/xusb-padctl-common.c b/arch/arm/mach-tegra/xusb-padctl-common.c index 8bdd44ad7a..388ec49968 100644 --- a/arch/arm/mach-tegra/xusb-padctl-common.c +++ b/arch/arm/mach-tegra/xusb-padctl-common.c @@ -282,7 +282,7 @@ int tegra_xusb_process_nodes(ofnode nodes[], unsigned int count, debug("%s: count=%d\n", __func__, count); for (i = 0; i < count; i++) { debug("%s: i=%d, node=%p\n", __func__, i, nodes[i].np); - if (!ofnode_is_available(nodes[i])) + if (!ofnode_is_enabled(nodes[i])) continue; padctl.socdata = socdata; diff --git a/arch/arm/mach-versal-net/Kconfig b/arch/arm/mach-versal-net/Kconfig new file mode 100644 index 0000000000..62825e189f --- /dev/null +++ b/arch/arm/mach-versal-net/Kconfig @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: GPL-2.0 + +if ARCH_VERSAL_NET + +config SYS_BOARD + string "Board name" + default "versal-net" + +config SYS_VENDOR + string "Vendor name" + default "xilinx" + +config SYS_SOC + default "versal-net" + +config SYS_CONFIG_NAME + string "Board configuration name" + default "xilinx_versal_net" + help + This option contains information about board configuration name. + Based on this option include/configs/.h header + will be used for board configuration. + +config SYS_MEM_RSVD_FOR_MMU + bool "Reserve memory for MMU Table" + help + If defined this option is used to setup different space for + MMU table than the one which will be allocated during + relocation. + +config GICV3 + def_bool y + +config SYS_MALLOC_LEN + default 0x2000000 + +config ZYNQ_SDHCI_MAX_FREQ + default 200000000 + +source "board/xilinx/Kconfig" +source "board/xilinx/versal-net/Kconfig" + +endif diff --git a/arch/arm/mach-versal-net/Makefile b/arch/arm/mach-versal-net/Makefile new file mode 100644 index 0000000000..e12c4c0e67 --- /dev/null +++ b/arch/arm/mach-versal-net/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2021 - 2022, Xilinx, Inc. +# Copyright (C) 2022, Advanced Micro Devices, Inc. +# +# Michal Simek +# + +obj-y += clk.o +obj-y += cpu.o diff --git a/arch/arm/mach-versal-net/clk.c b/arch/arm/mach-versal-net/clk.c new file mode 100644 index 0000000000..d097de7afa --- /dev/null +++ b/arch/arm/mach-versal-net/clk.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2016 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_CLOCKS +/** + * set_cpu_clk_info - Initialize clock framework + * + * Return: 0 always. + * + * This function is called from common code after relocation and sets up the + * clock framework. The framework must not be used before this function had been + * called. + */ +int set_cpu_clk_info(void) +{ + gd->cpu_clk = get_tbclk(); + + gd->bd->bi_arm_freq = gd->cpu_clk / 1000000; + gd->bd->bi_dsp_freq = 0; + + return 0; +} +#endif diff --git a/arch/arm/mach-versal-net/cpu.c b/arch/arm/mach-versal-net/cpu.c new file mode 100644 index 0000000000..4c9b15411d --- /dev/null +++ b/arch/arm/mach-versal-net/cpu.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define VERSAL_NET_MEM_MAP_USED 5 + +#define DRAM_BANKS CONFIG_NR_DRAM_BANKS + +/* +1 is end of list which needs to be empty */ +#define VERSAL_NET_MEM_MAP_MAX (VERSAL_NET_MEM_MAP_USED + DRAM_BANKS + 1) + +static struct mm_region versal_mem_map[VERSAL_NET_MEM_MAP_MAX] = { + { + .virt = 0x80000000UL, + .phys = 0x80000000UL, + .size = 0x70000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .virt = 0xf0000000UL, + .phys = 0xf0000000UL, + .size = 0x0fe00000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .virt = 0x400000000UL, + .phys = 0x400000000UL, + .size = 0x200000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .virt = 0x600000000UL, + .phys = 0x600000000UL, + .size = 0x800000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + .virt = 0xe00000000UL, + .phys = 0xe00000000UL, + .size = 0xf200000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + } +}; + +void mem_map_fill(void) +{ + int banks = VERSAL_NET_MEM_MAP_USED; + + for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + /* Zero size means no more DDR that's this is end */ + if (!gd->bd->bi_dram[i].size) + break; + + versal_mem_map[banks].virt = gd->bd->bi_dram[i].start; + versal_mem_map[banks].phys = gd->bd->bi_dram[i].start; + versal_mem_map[banks].size = gd->bd->bi_dram[i].size; + versal_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE; + banks = banks + 1; + } +} + +struct mm_region *mem_map = versal_mem_map; + +u64 get_page_table_size(void) +{ + return 0x14000; +} diff --git a/arch/arm/mach-versal-net/include/mach/hardware.h b/arch/arm/mach-versal-net/include/mach/hardware.h new file mode 100644 index 0000000000..808ce48fd1 --- /dev/null +++ b/arch/arm/mach-versal-net/include/mach/hardware.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2016 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + */ + +#ifndef __ASSEMBLY__ +#include +#endif + +#define PMC_TAP 0xF11A0000 + +#define PMC_TAP_IDCODE (PMC_TAP + 0) +#define PMC_TAP_VERSION (PMC_TAP + 0x4) +# define PMC_VERSION_MASK GENMASK(7, 0) +# define PS_VERSION_MASK GENMASK(15, 8) +# define RTL_VERSION_MASK GENMASK(23, 16) +# define PLATFORM_MASK GENMASK(27, 24) +# define PLATFORM_VERSION_MASK GENMASK(31, 28) +#define PMC_TAP_USERCODE (PMC_TAP + 0x8) + +enum versal_net_platform { + VERSAL_NET_SILICON = 0, + VERSAL_NET_SPP = 1, + VERSAL_NET_EMU = 2, + VERSAL_NET_QEMU = 3, +}; + +#define VERSAL_SLCR_BASEADDR 0xF1060000 +#define VERSAL_AXI_MUX_SEL (VERSAL_SLCR_BASEADDR + 0x504) +#define VERSAL_OSPI_LINEAR_MODE BIT(1) diff --git a/arch/arm/mach-versal-net/include/mach/sys_proto.h b/arch/arm/mach-versal-net/include/mach/sys_proto.h new file mode 100644 index 0000000000..5bba9030f2 --- /dev/null +++ b/arch/arm/mach-versal-net/include/mach/sys_proto.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2021 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + */ + +#include + +void mem_map_fill(void); + +static inline int zynqmp_mmio_write(const u32 address, const u32 mask, + const u32 value) +{ + BUILD_BUG(); + return -EINVAL; +} diff --git a/arch/arm/mach-versal/include/mach/sys_proto.h b/arch/arm/mach-versal/include/mach/sys_proto.h index 05934c28d6..8e5712e0c9 100644 --- a/arch/arm/mach-versal/include/mach/sys_proto.h +++ b/arch/arm/mach-versal/include/mach/sys_proto.h @@ -3,6 +3,8 @@ * Copyright 2016 - 2018 Xilinx, Inc. */ +#include + enum { TCM_LOCK, TCM_SPLIT, @@ -10,3 +12,9 @@ enum { void tcm_init(u8 mode); void mem_map_fill(void); + +static inline int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value) +{ + BUILD_BUG(); + return -EINVAL; +} diff --git a/arch/arm/mach-zynq/Makefile b/arch/arm/mach-zynq/Makefile index 8737f434d9..d9b2b999e1 100644 --- a/arch/arm/mach-zynq/Makefile +++ b/arch/arm/mach-zynq/Makefile @@ -6,7 +6,6 @@ # (C) Copyright 2008 # Guennadi Liakhovetki, DENX Software Engineering, -obj-y := timer.o obj-y += cpu.o obj-y += ddrc.o obj-y += slcr.o diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c index 27f6bf2183..1945f60e08 100644 --- a/arch/arm/mach-zynq/clk.c +++ b/arch/arm/mach-zynq/clk.c @@ -52,10 +52,12 @@ int set_cpu_clk_info(void) return ret; rate = clk_get_rate(&clk) / 1000000; - if (i) + if (i) { gd->bd->bi_ddr_freq = rate; - else + } else { gd->bd->bi_arm_freq = rate; + gd->cpu_clk = clk_get_rate(&clk); + } clk_free(&clk); } diff --git a/arch/arm/mach-zynq/timer.c b/arch/arm/mach-zynq/timer.c deleted file mode 100644 index a51822a530..0000000000 --- a/arch/arm/mach-zynq/timer.c +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2017 Weidmüller Interface GmbH & Co. KG - * Stefan Herbrechtsmeier - * - * Copyright (C) 2012 Michal Simek - * Copyright (C) 2011-2017 Xilinx, Inc. All rights reserved. - * - * (C) Copyright 2008 - * Guennadi Liakhovetki, DENX Software Engineering, - * - * (C) Copyright 2004 - * Philippe Robin, ARM Ltd. - * - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2003 - * Texas Instruments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -struct scu_timer { - u32 load; /* Timer Load Register */ - u32 counter; /* Timer Counter Register */ - u32 control; /* Timer Control Register */ -}; - -static struct scu_timer *timer_base = - (struct scu_timer *)ZYNQ_SCUTIMER_BASEADDR; - -#define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */ -#define SCUTIMER_CONTROL_PRESCALER_SHIFT 8 -#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002 /* Auto-reload */ -#define SCUTIMER_CONTROL_ENABLE_MASK 0x00000001 /* Timer enable */ - -#define TIMER_LOAD_VAL 0xFFFFFFFF -#define TIMER_PRESCALE 255 - -int timer_init(void) -{ - const u32 emask = SCUTIMER_CONTROL_AUTO_RELOAD_MASK | - (TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) | - SCUTIMER_CONTROL_ENABLE_MASK; - - struct udevice *dev; - struct clk clk; - int ret; - - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(zynq_clk), &dev); - if (ret) - return ret; - - clk.id = cpu_6or4x_clk; - ret = clk_request(dev, &clk); - if (ret < 0) - return ret; - - gd->cpu_clk = clk_get_rate(&clk); - - clk_free(&clk); - - gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / (TIMER_PRESCALE + 1); - - /* Load the timer counter register */ - writel(0xFFFFFFFF, &timer_base->load); - - /* - * Start the A9Timer device - * Enable Auto reload mode, Clear prescaler control bits - * Set prescaler value, Enable the decrementer - */ - clrsetbits_le32(&timer_base->control, SCUTIMER_CONTROL_PRESCALER_MASK, - emask); - - /* Reset time */ - gd->arch.lastinc = readl(&timer_base->counter) / - (gd->arch.timer_rate_hz / CONFIG_SYS_HZ); - gd->arch.tbl = 0; - - return 0; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return gd->arch.timer_rate_hz; -} diff --git a/arch/arm/mach-zynq/u-boot.lds b/arch/arm/mach-zynq/u-boot.lds index a5169fd915..3b7c9d515f 100644 --- a/arch/arm/mach-zynq/u-boot.lds +++ b/arch/arm/mach-zynq/u-boot.lds @@ -75,7 +75,7 @@ SECTIONS *(.__efi_runtime_rel_stop) } - . = ALIGN(4); + . = ALIGN(8); .image_copy_end : { *(.__image_copy_end) @@ -114,7 +114,7 @@ SECTIONS .bss __bss_base (OVERLAY) : { *(.bss*) - . = ALIGN(4); + . = ALIGN(8); __bss_limit = .; } diff --git a/arch/m68k/lib/bootm.c b/arch/m68k/lib/bootm.c index 9cade92954..c1c9bdceb5 100644 --- a/arch/m68k/lib/bootm.c +++ b/arch/m68k/lib/bootm.c @@ -36,7 +36,7 @@ void arch_lmb_reserve(struct lmb *lmb) } int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int ret; struct bd_info *kbd; diff --git a/arch/m68k/lib/time.c b/arch/m68k/lib/time.c index ebb2ac54db..cd7437b3e2 100644 --- a/arch/m68k/lib/time.c +++ b/arch/m68k/lib/time.c @@ -72,7 +72,7 @@ void dtimer_interrupt(void *not_used) #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG) if (CONFIG_SYS_WATCHDOG_FREQ && (timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0) { - WATCHDOG_RESET (); + schedule(); } #endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ return; diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile index 05f447abba..dfd8135f4f 100644 --- a/arch/microblaze/lib/Makefile +++ b/arch/microblaze/lib/Makefile @@ -4,4 +4,5 @@ # Wolfgang Denk, DENX Software Engineering, wd@denx.de. obj-$(CONFIG_CMD_BOOTM) += bootm.o +obj-$(CONFIG_CMD_BDI) += bdinfo.o obj-y += muldi3.o diff --git a/arch/microblaze/lib/bdinfo.c b/arch/microblaze/lib/bdinfo.c new file mode 100644 index 0000000000..41b7a216a4 --- /dev/null +++ b/arch/microblaze/lib/bdinfo.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022, Ovidiu Panait + */ +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +void arch_print_bdinfo(void) +{ + struct microblaze_cpuinfo *ci = gd_cpuinfo(); + + if (ci->icache_size) { + bdinfo_print_size("icache", ci->icache_size); + bdinfo_print_size("icache line", ci->icache_line_length); + } + + if (ci->dcache_size) { + bdinfo_print_size("dcache", ci->dcache_size); + bdinfo_print_size("dcache line", ci->dcache_line_length); + } +} diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 31b6659cdf..4a5421497e 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -37,7 +37,7 @@ void arch_lmb_reserve(struct lmb *lmb) arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096); } -static void boot_jump_linux(bootm_headers_t *images, int flag) +static void boot_jump_linux(struct bootm_headers *images, int flag) { void (*thekernel)(char *cmdline, ulong rd, ulong dt); ulong dt = (ulong)images->ft_addr; @@ -71,7 +71,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) } } -static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { if (CONFIG_IS_ENABLED(OF_LIBFDT) && CONFIG_IS_ENABLED(LMB) && images->ft_len) { debug("using: FDT\n"); @@ -83,7 +83,7 @@ static void boot_prep_linux(bootm_headers_t *images) } int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { images->cmdline_start = (ulong)env_get("bootargs"); diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index cab8da4860..5fda914e6b 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -71,7 +71,7 @@ static void linux_cmdline_dump(void) debug(" arg %03d: %s\n", i, linux_argv[i]); } -static void linux_cmdline_legacy(bootm_headers_t *images) +static void linux_cmdline_legacy(struct bootm_headers *images) { const char *bootargs, *next, *quote; @@ -111,7 +111,7 @@ static void linux_cmdline_legacy(bootm_headers_t *images) } } -static void linux_cmdline_append(bootm_headers_t *images) +static void linux_cmdline_append(struct bootm_headers *images) { char buf[24]; ulong mem, rd_start, rd_size; @@ -164,7 +164,7 @@ static void linux_env_set(const char *env_name, const char *env_val) } } -static void linux_env_legacy(bootm_headers_t *images) +static void linux_env_legacy(struct bootm_headers *images) { char env_buf[12]; const char *cp; @@ -213,7 +213,7 @@ static void linux_env_legacy(bootm_headers_t *images) } } -static int boot_reloc_fdt(bootm_headers_t *images) +static int boot_reloc_fdt(struct bootm_headers *images) { /* * In case of legacy uImage's, relocation of FDT is already done @@ -243,7 +243,7 @@ int arch_fixup_fdt(void *blob) } #endif -static int boot_setup_fdt(bootm_headers_t *images) +static int boot_setup_fdt(struct bootm_headers *images) { images->initrd_start = virt_to_phys((void *)images->initrd_start); images->initrd_end = virt_to_phys((void *)images->initrd_end); @@ -251,7 +251,7 @@ static int boot_setup_fdt(bootm_headers_t *images) &images->lmb); } -static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { if (CONFIG_IS_ENABLED(MIPS_BOOT_FDT) && images->ft_len) { boot_reloc_fdt(images); @@ -271,7 +271,7 @@ static void boot_prep_linux(bootm_headers_t *images) } } -static void boot_jump_linux(bootm_headers_t *images) +static void boot_jump_linux(struct bootm_headers *images) { typedef void __noreturn (*kernel_entry_t)(int, ulong, ulong, ulong); kernel_entry_t kernel = (kernel_entry_t) images->ep; @@ -302,7 +302,7 @@ static void boot_jump_linux(bootm_headers_t *images) } int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* No need for those on MIPS */ if (flag & BOOTM_STATE_OS_BD_T) diff --git a/arch/mips/mach-jz47xx/jz4780/jz4780.c b/arch/mips/mach-jz47xx/jz4780/jz4780.c index fefba12873..4c40bd86fd 100644 --- a/arch/mips/mach-jz47xx/jz4780/jz4780.c +++ b/arch/mips/mach-jz47xx/jz4780/jz4780.c @@ -30,7 +30,7 @@ void board_init_f(ulong dummy) typedef void __noreturn (*image_entry_noargs_t)(void); struct mmc *mmc; unsigned long count; - struct image_header *header; + struct legacy_img_hdr *header; int ret; /* Set global data pointer */ @@ -58,8 +58,8 @@ void board_init_f(ulong dummy) if (ret) hang(); - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - - sizeof(struct image_header)); + header = (struct legacy_img_hdr *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct legacy_img_hdr)); count = blk_dread(mmc_get_blk_desc(mmc), CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, @@ -76,7 +76,7 @@ void board_init_f(ulong dummy) } #endif /* CONFIG_SPL_BUILD */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return CONFIG_SYS_SDRAM_BASE + (256 * 1024 * 1024); } diff --git a/arch/mips/mach-mtmips/mt7621/spl/spl.c b/arch/mips/mach-mtmips/mt7621/spl/spl.c index 91eebc6c1f..aa5b267bb9 100644 --- a/arch/mips/mach-mtmips/mt7621/spl/spl.c +++ b/arch/mips/mach-mtmips/mt7621/spl/spl.c @@ -64,7 +64,7 @@ void board_boot_order(u32 *spl_boot_list) unsigned long spl_nor_get_uboot_base(void) { const struct tpl_info *tpli; - const image_header_t *hdr; + const struct legacy_img_hdr *hdr; u32 addr; addr = FLASH_MMAP_BASE + TPL_INFO_OFFSET; @@ -72,7 +72,7 @@ unsigned long spl_nor_get_uboot_base(void) if (tpli->magic == TPL_INFO_MAGIC) { addr = FLASH_MMAP_BASE + tpli->size; - hdr = (const image_header_t *)KSEG1ADDR(addr); + hdr = (const struct legacy_img_hdr *)KSEG1ADDR(addr); if (image_get_magic(hdr) == IH_MAGIC) { addr += sizeof(*hdr) + image_get_size(hdr); diff --git a/arch/mips/mach-mtmips/mt7621/tpl/tpl.c b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c index 2a828907a3..d77592da5f 100644 --- a/arch/mips/mach-mtmips/mt7621/tpl/tpl.c +++ b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c @@ -116,7 +116,7 @@ static void mt7621_cache_init(void) void __noreturn tpl_main(void) { - const image_header_t *hdr = (const image_header_t *)__image_copy_end; + const struct legacy_img_hdr *hdr = (const struct legacy_img_hdr *)__image_copy_end; image_entry_noargs_t image_entry; u32 loadaddr, size; uintptr_t data; @@ -132,7 +132,7 @@ void __noreturn tpl_main(void) image_entry = (image_entry_noargs_t)image_get_ep(hdr); /* Load TPL image to L2 cache */ - data = (uintptr_t)__image_copy_end + sizeof(struct image_header); + data = (uintptr_t)__image_copy_end + sizeof(struct legacy_img_hdr); fill_lock_l2cache(data, loadaddr, size); /* Jump to SPL */ diff --git a/arch/mips/mach-octeon/dram.c b/arch/mips/mach-octeon/dram.c index 4679260f17..9c5789b1c8 100644 --- a/arch/mips/mach-octeon/dram.c +++ b/arch/mips/mach-octeon/dram.c @@ -77,7 +77,7 @@ phys_size_t get_effective_memsize(void) return UBOOT_RAM_SIZE_MAX; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { if (IS_ENABLED(CONFIG_RAM_OCTEON)) { /* Map a maximum of 256MiB - return not size but address */ diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c index 3cb59bd977..06c094d0f1 100644 --- a/arch/nios2/lib/bootm.c +++ b/arch/nios2/lib/bootm.c @@ -17,7 +17,7 @@ DECLARE_GLOBAL_DATA_PTR; #define NIOS_MAGIC 0x534f494e /* enable command line and initrd passing */ int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*kernel)(int, int, int, char *) = (void *)images->ep; char *commandline = env_get("bootargs"); diff --git a/arch/powerpc/cpu/mpc85xx/tlb.c b/arch/powerpc/cpu/mpc85xx/tlb.c index ab616497fa..e39fe14382 100644 --- a/arch/powerpc/cpu/mpc85xx/tlb.c +++ b/arch/powerpc/cpu/mpc85xx/tlb.c @@ -312,7 +312,10 @@ unsigned int setup_ddr_tlbs_phys(phys_addr_t p_addr, if (size || memsize > CONFIG_MAX_MEM_MAPPED) { print_size(memsize > CONFIG_MAX_MEM_MAPPED ? memsize - CONFIG_MAX_MEM_MAPPED + size : size, - " left unmapped\n"); + " of DDR memory left unmapped in U-Boot\n"); +#ifndef CONFIG_SPL_BUILD + puts(" "); +#endif } return memsize_in_meg; diff --git a/arch/powerpc/cpu/mpc8xx/cpu_init.c b/arch/powerpc/cpu/mpc8xx/cpu_init.c index c8d06b0508..86b08a6174 100644 --- a/arch/powerpc/cpu/mpc8xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc8xx/cpu_init.c @@ -31,7 +31,7 @@ void cpu_init_f(immap_t __iomem *immr) out_be32(&immr->im_siu_conf.sc_sypcr, CONFIG_SYS_SYPCR & ~SYPCR_SWE); #endif - WATCHDOG_RESET(); + schedule(); /* SIUMCR - contains debug pin configuration (11-6) */ setbits_be32(&immr->im_siu_conf.sc_siumcr, CONFIG_SYS_SIUMCR); diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index e52aa75703..512787854c 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -45,7 +45,7 @@ static void set_clocks_in_mhz (struct bd_info *kbd); #define CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE (768*1024*1024) #endif -static void boot_jump_linux(bootm_headers_t *images) +static void boot_jump_linux(struct bootm_headers *images) { void (*kernel)(struct bd_info *, ulong r4, ulong r5, ulong r6, ulong r7, ulong r8, ulong r9); @@ -84,7 +84,7 @@ static void boot_jump_linux(bootm_headers_t *images) * r9: 0 */ debug(" Booting using OF flat tree...\n"); - WATCHDOG_RESET (); + schedule(); (*kernel) ((struct bd_info *)of_flat_tree, 0, 0, EPAPR_MAGIC, env_get_bootm_mapsize(), 0, 0); /* does not return */ @@ -108,7 +108,7 @@ static void boot_jump_linux(bootm_headers_t *images) struct bd_info *kbd = images->kbd; debug(" Booting using board info...\n"); - WATCHDOG_RESET (); + schedule(); (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end, 0, 0); /* does not return */ @@ -151,7 +151,7 @@ void arch_lmb_reserve(struct lmb *lmb) return ; } -static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { #ifdef CONFIG_MP /* @@ -163,7 +163,7 @@ static void boot_prep_linux(bootm_headers_t *images) #endif } -static int boot_cmdline_linux(bootm_headers_t *images) +static int boot_cmdline_linux(struct bootm_headers *images) { ulong of_size = images->ft_len; struct lmb *lmb = &images->lmb; @@ -184,7 +184,7 @@ static int boot_cmdline_linux(bootm_headers_t *images) return ret; } -static int boot_bd_t_linux(bootm_headers_t *images) +static int boot_bd_t_linux(struct bootm_headers *images) { ulong of_size = images->ft_len; struct lmb *lmb = &images->lmb; @@ -205,7 +205,7 @@ static int boot_bd_t_linux(bootm_headers_t *images) return ret; } -static int boot_body_linux(bootm_headers_t *images) +static int boot_body_linux(struct bootm_headers *images) { int ret; @@ -224,7 +224,7 @@ static int boot_body_linux(bootm_headers_t *images) } noinline int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int ret; @@ -273,7 +273,7 @@ static void set_clocks_in_mhz (struct bd_info *kbd) } #if defined(CONFIG_BOOTM_VXWORKS) -void boot_prep_vxworks(bootm_headers_t *images) +void boot_prep_vxworks(struct bootm_headers *images) { #if defined(CONFIG_OF_LIBFDT) int off; @@ -305,7 +305,7 @@ void boot_prep_vxworks(bootm_headers_t *images) #endif } -void boot_jump_vxworks(bootm_headers_t *images) +void boot_jump_vxworks(struct bootm_headers *images) { /* PowerPC VxWorks boot interface conforms to the ePAPR standard * general purpuse registers: @@ -319,7 +319,7 @@ void boot_jump_vxworks(bootm_headers_t *images) * r9: 0 * TCR: WRC = 0, no watchdog timer reset will occur */ - WATCHDOG_RESET(); + schedule(); ((void (*)(void *, ulong, ulong, ulong, ulong, ulong, ulong))images->ep)(images->ft_addr, diff --git a/arch/powerpc/lib/cache.c b/arch/powerpc/lib/cache.c index 19162511ce..c4c5c2d451 100644 --- a/arch/powerpc/lib/cache.c +++ b/arch/powerpc/lib/cache.c @@ -13,7 +13,7 @@ static ulong maybe_watchdog_reset(ulong flushed) { flushed += CONFIG_SYS_CACHELINE_SIZE; if (flushed >= CONFIG_CACHE_FLUSH_WATCHDOG_THRESHOLD) { - WATCHDOG_RESET(); + schedule(); flushed = 0; } return flushed; diff --git a/arch/powerpc/lib/interrupts.c b/arch/powerpc/lib/interrupts.c index 5ba4cd0c13..bdb8030c27 100644 --- a/arch/powerpc/lib/interrupts.c +++ b/arch/powerpc/lib/interrupts.c @@ -81,7 +81,7 @@ void timer_interrupt(struct pt_regs *regs) #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG) if (CONFIG_SYS_WATCHDOG_FREQ && (timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0) - WATCHDOG_RESET (); + schedule(); #endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ #ifdef CONFIG_LED_STATUS diff --git a/arch/powerpc/lib/ticks.S b/arch/powerpc/lib/ticks.S index c487f938fa..8647d77cc9 100644 --- a/arch/powerpc/lib/ticks.S +++ b/arch/powerpc/lib/ticks.S @@ -9,7 +9,6 @@ #include #include #include -#include /* * unsigned long long get_ticks(void); @@ -42,7 +41,9 @@ wait_ticks: addc r14, r4, r14 /* Compute end time lower */ addze r15, r3 /* and end time upper */ - WATCHDOG_RESET /* Trigger watchdog, if needed */ +#if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG) + bl schedule /* Trigger watchdog, if needed */ +#endif 1: bl get_ticks /* Get current time */ subfc r4, r4, r14 /* Subtract current time from end time */ subfe. r3, r3, r15 diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 78e964db12..32a90b83b5 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -269,6 +269,20 @@ config XIP from a NOR flash memory without copying the code to ram. Say yes here if U-Boot boots from flash directly. +config SPL_XIP + bool "Enable XIP mode for SPL" + help + If SPL starts in read-only memory (XIP for example) then we shouldn't + rely on lock variables (for example hart_lottery and available_harts_lock), + this affects only SPL, other stages should proceed as non-XIP. + +config AVAILABLE_HARTS + bool "Send IPI by available harts" + default y + help + By default, IPI sending mechanism will depend on available_harts. + If disable this, it will send IPI by CPUs node numbers of device tree. + config SHOW_REGS bool "Show registers on unhandled exception" diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 3ffcbbd23f..52ab02519f 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -19,15 +19,17 @@ * The variables here must be stored in the data section since they are used * before the bss section is available. */ -#ifndef CONFIG_XIP +#if !CONFIG_IS_ENABLED(XIP) u32 hart_lottery __section(".data") = 0; +#ifdef CONFIG_AVAILABLE_HARTS /* * The main hart running U-Boot has acquired available_harts_lock until it has * finished initialization of global data. */ u32 available_harts_lock = 1; #endif +#endif static inline bool supports_extension(char ext) { diff --git a/arch/riscv/cpu/fu540/dram.c b/arch/riscv/cpu/fu540/dram.c index 1fdc7837b8..44e11bd56c 100644 --- a/arch/riscv/cpu/fu540/dram.c +++ b/arch/riscv/cpu/fu540/dram.c @@ -21,7 +21,7 @@ int dram_init_banksize(void) return fdtdec_setup_memory_banksize(); } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { /* * Ensure that we run from first 4GB so that all diff --git a/arch/riscv/cpu/fu740/dram.c b/arch/riscv/cpu/fu740/dram.c index 1dc77efeca..d6d4a41d25 100644 --- a/arch/riscv/cpu/fu740/dram.c +++ b/arch/riscv/cpu/fu740/dram.c @@ -20,7 +20,7 @@ int dram_init_banksize(void) return fdtdec_setup_memory_banksize(); } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { #ifdef CONFIG_64BIT /* diff --git a/arch/riscv/cpu/generic/dram.c b/arch/riscv/cpu/generic/dram.c index 1fdc7837b8..44e11bd56c 100644 --- a/arch/riscv/cpu/generic/dram.c +++ b/arch/riscv/cpu/generic/dram.c @@ -21,7 +21,7 @@ int dram_init_banksize(void) return fdtdec_setup_memory_banksize(); } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { /* * Ensure that we run from first 4GB so that all diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index b7f21ab63e..4687bca3c9 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -122,7 +122,7 @@ call_board_init_f_0: call_harts_early_init: jal harts_early_init -#ifndef CONFIG_XIP +#if !CONFIG_IS_ENABLED(XIP) /* * Pick hart to initialize global data and run U-Boot. The other harts * wait for initialization to complete. @@ -152,22 +152,24 @@ call_harts_early_init: /* save the boot hart id to global_data */ SREG tp, GD_BOOT_HART(gp) -#ifndef CONFIG_XIP +#if !CONFIG_IS_ENABLED(XIP) +#ifdef CONFIG_AVAILABLE_HARTS la t0, available_harts_lock amoswap.w.rl zero, zero, 0(t0) +#endif wait_for_gd_init: - la t0, available_harts_lock - li t1, 1 -1: amoswap.w.aq t1, t1, 0(t0) - bnez t1, 1b - /* * Set the global data pointer only when gd_t has been initialized. * This was already set by arch_setup_gd on the boot hart, but all other * harts' global data pointers gets set here. */ mv gp, s0 +#ifdef CONFIG_AVAILABLE_HARTS + la t0, available_harts_lock + li t1, 1 +1: amoswap.w.aq t1, t1, 0(t0) + bnez t1, 1b /* register available harts in the available_harts mask */ li t1, 1 @@ -177,6 +179,7 @@ wait_for_gd_init: SREG t2, GD_AVAILABLE_HARTS(gp) amoswap.w.rl zero, zero, 0(t0) +#endif /* * Continue on hart lottery winner, others branch to diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h index 095484a635..858594a191 100644 --- a/arch/riscv/include/asm/global_data.h +++ b/arch/riscv/include/asm/global_data.h @@ -27,9 +27,11 @@ struct arch_global_data { #if CONFIG_IS_ENABLED(SMP) struct ipi_data ipi[CONFIG_NR_CPUS]; #endif -#ifndef CONFIG_XIP +#if !CONFIG_IS_ENABLED(XIP) +#ifdef CONFIG_AVAILABLE_HARTS ulong available_harts; #endif +#endif }; #include diff --git a/arch/riscv/lib/andes_plic.c b/arch/riscv/lib/andes_plic.c index 5e113ee8c9..68514758a8 100644 --- a/arch/riscv/lib/andes_plic.c +++ b/arch/riscv/lib/andes_plic.c @@ -71,7 +71,7 @@ int riscv_init_ipi(void) continue; /* skip if hart is marked as not available */ - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue; /* read hart ID of CPU */ diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c index f1fe089b3d..452dfcea97 100644 --- a/arch/riscv/lib/asm-offsets.c +++ b/arch/riscv/lib/asm-offsets.c @@ -16,8 +16,10 @@ int main(void) { DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart)); DEFINE(GD_FIRMWARE_FDT_ADDR, offsetof(gd_t, arch.firmware_fdt_addr)); -#ifndef CONFIG_XIP +#if !CONFIG_IS_ENABLED(XIP) +#ifdef CONFIG_AVAILABLE_HARTS DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts)); +#endif #endif return 0; diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index 670d9c9ebc..f5f8b4c733 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -62,7 +62,7 @@ static void announce_and_cleanup(int fake) cleanup_before_linux(); } -static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { if (CONFIG_IS_ENABLED(OF_LIBFDT) && CONFIG_IS_ENABLED(LMB) && images->ft_len) { debug("using: FDT\n"); @@ -76,7 +76,7 @@ static void boot_prep_linux(bootm_headers_t *images) } } -static void boot_jump_linux(bootm_headers_t *images, int flag) +static void boot_jump_linux(struct bootm_headers *images, int flag) { void (*kernel)(ulong hart, void *dtb); int fake = (flag & BOOTM_STATE_OS_FAKE_GO); @@ -107,7 +107,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) } int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* No need for those on RISC-V */ if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) @@ -129,7 +129,7 @@ int do_bootm_linux(int flag, int argc, char *const argv[], } int do_bootm_vxworks(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { return do_bootm_linux(flag, argc, argv, images); } diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c index ba992100ad..4f073a016f 100644 --- a/arch/riscv/lib/smp.c +++ b/arch/riscv/lib/smp.c @@ -27,7 +27,7 @@ static int send_ipi_many(struct ipi_data *ipi, int wait) ofnode_for_each_subnode(node, cpus) { /* skip if hart is marked as not available in the device tree */ - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue; /* read hart ID of CPU */ @@ -45,10 +45,12 @@ static int send_ipi_many(struct ipi_data *ipi, int wait) continue; } -#ifndef CONFIG_XIP +#if !CONFIG_IS_ENABLED(XIP) +#ifdef CONFIG_AVAILABLE_HARTS /* skip if hart is not available */ if (!(gd->arch.available_harts & (1 << reg))) continue; +#endif #endif gd->arch.ipi[reg].addr = ipi->addr; diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index d077948dd7..636d3545b9 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -3,19 +3,22 @@ * Copyright (c) 2011 The Chromium OS Authors. */ +#define LOG_CATEGORY LOGC_SANDBOX + #include #include #include #include #include -#include -#include -#include #include +#include #include #include #include #include +#include +#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -373,3 +376,28 @@ ulong timer_get_boot_us(void) return (count - base_count) / 1000; } + +int sandbox_load_other_fdt(void **fdtp, int *sizep) +{ + const char *orig; + int ret, size; + void *fdt = *fdtp; + + ret = state_load_other_fdt(&orig, &size); + if (ret) { + log_err("Cannot read other FDT\n"); + return log_msg_ret("ld", ret); + } + + if (!*fdtp) { + fdt = os_malloc(size); + if (!fdt) + return log_msg_ret("mem", -ENOMEM); + *sizep = size; + } + + memcpy(fdt, orig, *sizep); + *fdtp = fdt; + + return 0; +} diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index f937991139..d6170adaf5 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -669,6 +669,11 @@ void os_puts(const char *str) os_putc(*str++); } +void os_flush(void) +{ + fflush(stdout); +} + int os_write_ram_buf(const char *fname) { struct sandbox_state *state = state_get_current(); @@ -1012,8 +1017,24 @@ void *os_find_text_base(void) return base; } +/** + * os_unblock_signals() - unblock all signals + * + * If we are relaunching the sandbox in a signal handler, we have to unblock + * the respective signal before calling execv(). See signal(7) man-page. + */ +static void os_unblock_signals(void) +{ + sigset_t sigs; + + sigfillset(&sigs); + sigprocmask(SIG_UNBLOCK, &sigs, NULL); +} + void os_relaunch(char *argv[]) { + os_unblock_signals(); + execv(argv[0], argv); os_exit(1); } diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c index fe5d44d36e..1d49a9bd10 100644 --- a/arch/sandbox/cpu/spl.c +++ b/arch/sandbox/cpu/spl.c @@ -89,7 +89,7 @@ void spl_board_init(void) int ret; ret = ut_run_list("spl", NULL, tests, count, - state->select_unittests); + state->select_unittests, 1); /* continue execution into U-Boot */ } } diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 90a84e93c7..642be164a3 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -205,21 +205,19 @@ SANDBOX_CMDLINE_OPT_SHORT(default_fdt, 'D', 0, static int sandbox_cmdline_cb_test_fdt(struct sandbox_state *state, const char *arg) { - const char *fmt = "/arch/sandbox/dts/test.dtb"; - char *p; + char buf[256]; char *fname; int len; - len = strlen(state->argv[0]) + strlen(fmt) + 1; + len = state_get_rel_filename("arch/sandbox/dts/test.dtb", buf, + sizeof(buf)); + if (len < 0) + return len; + fname = os_malloc(len); if (!fname) return -ENOMEM; - strcpy(fname, state->argv[0]); - p = strrchr(fname, '/'); - if (!p) - p = fname + strlen(fname); - len -= p - fname; - snprintf(p, len, fmt); + strcpy(fname, buf); state->fdt_fname = fname; return 0; diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index e0d01125bb..fcc4a337e5 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -396,6 +396,54 @@ bool autoboot_set_keyed(bool autoboot_keyed) return old_val; } +int state_get_rel_filename(const char *rel_path, char *buf, int size) +{ + struct sandbox_state *state = state_get_current(); + int rel_len, prog_len; + char *p; + int len; + + rel_len = strlen(rel_path); + p = strrchr(state->argv[0], '/'); + prog_len = p ? p - state->argv[0] : 0; + + /* allow space for a / and a terminator */ + len = prog_len + 1 + rel_len + 1; + if (len > size) + return -ENOSPC; + strncpy(buf, state->argv[0], prog_len); + buf[prog_len] = '/'; + strcpy(buf + prog_len + 1, rel_path); + + return len; +} + +int state_load_other_fdt(const char **bufp, int *sizep) +{ + struct sandbox_state *state = state_get_current(); + char fname[256]; + int len, ret; + + /* load the file if needed */ + if (!state->other_fdt_buf) { + len = state_get_rel_filename("arch/sandbox/dts/other.dtb", + fname, sizeof(fname)); + if (len < 0) + return len; + + ret = os_read_file(fname, &state->other_fdt_buf, + &state->other_size); + if (ret) { + log_err("Cannot read file '%s'\n", fname); + return ret; + } + } + *bufp = state->other_fdt_buf; + *sizep = state->other_size; + + return 0; +} + int state_init(void) { state = &main_state; diff --git a/arch/sandbox/dts/Makefile b/arch/sandbox/dts/Makefile index 6cbc9bbcaa..b6a88479b2 100644 --- a/arch/sandbox/dts/Makefile +++ b/arch/sandbox/dts/Makefile @@ -5,7 +5,7 @@ dtb-$(CONFIG_SANDBOX) += sandbox64.dtb else dtb-$(CONFIG_SANDBOX) += sandbox.dtb endif -dtb-$(CONFIG_UT_DM) += test.dtb +dtb-$(CONFIG_UT_DM) += test.dtb other.dtb dtb-$(CONFIG_CMD_EXTENSION) += overlay0.dtbo overlay1.dtbo include $(srctree)/scripts/Makefile.dts diff --git a/arch/sandbox/dts/other.dts b/arch/sandbox/dts/other.dts new file mode 100644 index 0000000000..395a792322 --- /dev/null +++ b/arch/sandbox/dts/other.dts @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Other devicetree file for running sandbox tests + * + * This used for tests which want to check they can access multiple device + * trees. This one is loaded and checks are made that it is actually visible. + */ + +/dts-v1/; + +/ { + compatible = "sandbox-other"; + #address-cells = <1>; + #size-cells = <1>; + + node { + target = <&target 3 4>; + + subnode { + compatible = "sandbox-other2"; + str-prop = "other"; + }; + + subnode2 { + }; + }; + + target: target { + compatible = "sandbox-other2"; + #gpio-cells = <2>; + str-prop = "other"; + reg = <0x8000 0x100>; + status = "disabled"; + }; +}; diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi index 56e6b38bfa..de7a218f45 100644 --- a/arch/sandbox/dts/sandbox.dtsi +++ b/arch/sandbox/dts/sandbox.dtsi @@ -245,6 +245,10 @@ compatible = "sandbox,sandbox-rng"; }; + scsi { + compatible = "sandbox,scsi"; + }; + sound { compatible = "sandbox,sound"; cpu { diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 2761588f0d..4ee471238e 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -233,6 +233,8 @@ test5-gpios = <&gpio_a 19>; bool-value; + int8-value = /bits/ 8 <0x12>; + int16-value = /bits/ 16 <0x1234>; int-value = <1234>; uint-value = <(-1234)>; int64-value = /bits/ 64 <0x1111222233334444>; @@ -1156,6 +1158,11 @@ backlight = <&backlight 0 100>; }; + scsi { + compatible = "sandbox,scsi"; + sandbox,filepath = "scsi.img"; + }; + smem@0 { compatible = "sandbox,smem"; }; diff --git a/arch/sandbox/include/asm/malloc.h b/arch/sandbox/include/asm/malloc.h index a1467b5ead..8aaaa9cb87 100644 --- a/arch/sandbox/include/asm/malloc.h +++ b/arch/sandbox/include/asm/malloc.h @@ -6,6 +6,7 @@ */ #ifndef __ASM_MALLOC_H +#define __ASM_MALLOC_H void *malloc(size_t size); void free(void *ptr); diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 07c768ae5d..fd42daad51 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -108,6 +108,9 @@ struct sandbox_state { bool hwspinlock; /* Hardware Spinlock status */ bool allow_memio; /* Allow readl() etc. to work */ + void *other_fdt_buf; /* 'other' FDT blob used by tests */ + int other_size; /* size of other FDT blob */ + /* * This struct is getting large. * @@ -265,6 +268,33 @@ void state_reset_for_test(struct sandbox_state *state); */ void state_show(struct sandbox_state *state); +/** + * state_get_rel_filename() - Get a filename relative to the executable + * + * This uses argv[0] to obtain a filename path + * + * @rel_path: Relative path to build, e.g. "arch/sandbox/dts/test.dtb". Must not + * have a trailing / + * @buf: Buffer to use to return the filename + * @size: Size of buffer + * @return length of filename (including terminator), -ENOSPC if @size is too + * small + */ +int state_get_rel_filename(const char *rel_path, char *buf, int size); + +/** + * state_load_other_fdt() - load the 'other' FDT into a buffer + * + * This loads the other.dtb file into a buffer. This is typically used in tests. + * + * @bufp: Place to put allocated buffer pointer. The buffer is read using + * os_read_file() which calls os_malloc(), so does affect U-Boot's own malloc() + * space + * @sizep: Returns the size of the buffer + * @return 0 if OK, -ve on error + */ +int state_load_other_fdt(const char **bufp, int *sizep); + /** * Initialize the test system state */ diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 53a036b3ab..0406085917 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -11,6 +11,8 @@ #include #include +struct unit_test_state; + /* The sandbox driver always permits an I2C device with this address */ #define SANDBOX_I2C_TEST_ADDR 0x59 @@ -315,4 +317,21 @@ int sandbox_sdl_set_bpp(struct udevice *dev, enum video_log2_bpp l2bpp); */ void sandbox_set_fake_efi_mgr_dev(struct udevice *dev, bool fake_dev); +/** + * sandbox_load_other_fdt() - load the 'other' FDT into the test state + * + * This copies the other.dtb file into the test state, so that a fresh version + * can be used for a test that is about to run. + * + * If @uts->other_fdt is NULL, as it is when first set up, this allocates a + * buffer for the other FDT and sets @uts->other_fdt_size to its size. + * + * In any case, the other FDT is copied from the sandbox state into + * @uts->other_fdt ready for use. + * + * @uts: Unit test state + * @return 0 if OK, -ve on error + */ +int sandbox_load_other_fdt(void **fdtp, int *sizep); + #endif diff --git a/arch/sandbox/lib/bootm.c b/arch/sandbox/lib/bootm.c index d1d460b84a..c1742f94de 100644 --- a/arch/sandbox/lib/bootm.c +++ b/arch/sandbox/lib/bootm.c @@ -50,7 +50,7 @@ int bootz_setup(ulong image, ulong *start, ulong *end) return ret; } -int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +int do_bootm_linux(int flag, int argc, char *argv[], struct bootm_headers *images) { if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { bootstage_mark(BOOTSTAGE_ID_RUN_OS); diff --git a/arch/sh/lib/bootm.c b/arch/sh/lib/bootm.c index 7ea04442b8..a5fad6c46c 100644 --- a/arch/sh/lib/bootm.c +++ b/arch/sh/lib/bootm.c @@ -40,7 +40,7 @@ static unsigned long sh_check_cmd_arg(char *cmdline, char *key, int base) } int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* Linux kernel load address */ void (*kernel) (void) = (void (*)(void))images->ep; diff --git a/arch/x86/cpu/broadwell/sdram.c b/arch/x86/cpu/broadwell/sdram.c index c104a849a5..1295121ae5 100644 --- a/arch/x86/cpu/broadwell/sdram.c +++ b/arch/x86/cpu/broadwell/sdram.c @@ -25,7 +25,7 @@ #include #include -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return mrc_common_board_get_usable_ram_top(total_size); } diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c index 4a256bad44..f4ee4cdf5d 100644 --- a/arch/x86/cpu/coreboot/sdram.c +++ b/arch/x86/cpu/coreboot/sdram.c @@ -27,7 +27,7 @@ unsigned int install_e820_map(unsigned int max_entries, * address, and how far U-Boot is moved by relocation are set in the global * data structure. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { uintptr_t dest_addr = 0; int i; diff --git a/arch/x86/cpu/efi/payload.c b/arch/x86/cpu/efi/payload.c index b7778565b1..1c28a43778 100644 --- a/arch/x86/cpu/efi/payload.c +++ b/arch/x86/cpu/efi/payload.c @@ -27,7 +27,7 @@ DECLARE_GLOBAL_DATA_PTR; * the relocation address, and how far U-Boot is moved by relocation are * set in the global data structure. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { struct efi_mem_desc *desc, *end; struct efi_entry_memmap *map; diff --git a/arch/x86/cpu/efi/sdram.c b/arch/x86/cpu/efi/sdram.c index af65982fd0..f3086db42c 100644 --- a/arch/x86/cpu/efi/sdram.c +++ b/arch/x86/cpu/efi/sdram.c @@ -11,7 +11,7 @@ DECLARE_GLOBAL_DATA_PTR; -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return (ulong)efi_get_ram_base() + gd->ram_size; } diff --git a/arch/x86/cpu/intel_common/mrc.c b/arch/x86/cpu/intel_common/mrc.c index a97b0b7ceb..a4918fbad6 100644 --- a/arch/x86/cpu/intel_common/mrc.c +++ b/arch/x86/cpu/intel_common/mrc.c @@ -25,7 +25,7 @@ static const char *const ecc_decoder[] = { "active" }; -ulong mrc_common_board_get_usable_ram_top(ulong total_size) +phys_size_t mrc_common_board_get_usable_ram_top(phys_size_t total_size) { struct memory_info *info = &gd->arch.meminfo; uintptr_t dest_addr = 0; @@ -50,7 +50,7 @@ ulong mrc_common_board_get_usable_ram_top(ulong total_size) dest_addr = largest->start + largest->size; - return (ulong)dest_addr; + return (phys_size_t)dest_addr; } void mrc_common_dram_init_banksize(void) diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c index dd6b8753de..1a0ec433e6 100644 --- a/arch/x86/cpu/ivybridge/sdram.c +++ b/arch/x86/cpu/ivybridge/sdram.c @@ -44,7 +44,7 @@ DECLARE_GLOBAL_DATA_PTR; #define CMOS_OFFSET_MRC_SEED_S3 156 #define CMOS_OFFSET_MRC_SEED_CHK 160 -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return mrc_common_board_get_usable_ram_top(total_size); } diff --git a/arch/x86/cpu/qemu/dram.c b/arch/x86/cpu/qemu/dram.c index c174550129..595c397d4a 100644 --- a/arch/x86/cpu/qemu/dram.c +++ b/arch/x86/cpu/qemu/dram.c @@ -71,7 +71,7 @@ int dram_init_banksize(void) * the relocation address, and how far U-Boot is moved by relocation are * set in the global data structure. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return qemu_get_low_memory_size(); } diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c index 2287dce12b..8b1ee2d5ae 100644 --- a/arch/x86/cpu/quark/dram.c +++ b/arch/x86/cpu/quark/dram.c @@ -184,7 +184,7 @@ int dram_init_banksize(void) * the relocation address, and how far U-Boot is moved by relocation are * set in the global data structure. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return gd->ram_size; } diff --git a/arch/x86/cpu/slimbootloader/sdram.c b/arch/x86/cpu/slimbootloader/sdram.c index c6f10e22e3..d748d5c7d4 100644 --- a/arch/x86/cpu/slimbootloader/sdram.c +++ b/arch/x86/cpu/slimbootloader/sdram.c @@ -48,7 +48,7 @@ static struct sbl_memory_map_info *get_memory_map_info(void) * @total_size: The memory size that u-boot occupies * Return: : The top available memory address lower than 4GB */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { struct sbl_memory_map_info *data; int i; diff --git a/arch/x86/cpu/tangier/sdram.c b/arch/x86/cpu/tangier/sdram.c index afb08476ed..8a4b1c5d2d 100644 --- a/arch/x86/cpu/tangier/sdram.c +++ b/arch/x86/cpu/tangier/sdram.c @@ -204,7 +204,7 @@ unsigned int install_e820_map(unsigned int max_entries, * address, and how far U-Boot is moved by relocation are set in the global * data structure. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { struct sfi_table_simple *sb; struct sfi_mem_entry *mentry; diff --git a/arch/x86/include/asm/mrc_common.h b/arch/x86/include/asm/mrc_common.h index 3d7f00c9f9..a7f260a707 100644 --- a/arch/x86/include/asm/mrc_common.h +++ b/arch/x86/include/asm/mrc_common.h @@ -47,7 +47,7 @@ int mrc_add_memory_area(struct memory_info *info, uint64_t start, * the relocation address, and how far U-Boot is moved by relocation are * set in the global data structure. */ -ulong mrc_common_board_get_usable_ram_top(ulong total_size); +phys_size_t mrc_common_board_get_usable_ram_top(phys_size_t total_size); void mrc_common_dram_init_banksize(void); diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index a1655e1cea..4cf41e9354 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -77,7 +77,7 @@ int x86_cleanup_before_linux(void); void x86_enable_caches(void); void x86_disable_caches(void); int x86_init_cache(void); -ulong board_get_usable_ram_top(ulong total_size); +phys_size_t board_get_usable_ram_top(phys_size_t total_size); int default_print_cpuinfo(void); /* Set up a UART which can be used with printch(), printhex8(), etc. */ diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index 1bcdb3e30d..eafcddfa24 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -69,10 +69,10 @@ int arch_fixup_memory_node(void *blob) #endif /* Subcommand: PREP */ -static int boot_prep_linux(bootm_headers_t *images) +static int boot_prep_linux(struct bootm_headers *images) { char *cmd_line_dest = NULL; - image_header_t *hdr; + struct legacy_img_hdr *hdr; int is_zimage = 0; void *data = NULL; size_t len; @@ -201,7 +201,7 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit) } /* Subcommand: GO */ -static int boot_jump_linux(bootm_headers_t *images) +static int boot_jump_linux(struct bootm_headers *images) { debug("## Transferring control to Linux (at address %08lx, kernel %08lx) ...\n", images->ep, images->os.load); @@ -211,7 +211,7 @@ static int boot_jump_linux(bootm_headers_t *images) } int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* No need for those on x86 */ if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) diff --git a/arch/x86/lib/fsp1/fsp_dram.c b/arch/x86/lib/fsp1/fsp_dram.c index cfd9b9f48c..5825221d1e 100644 --- a/arch/x86/lib/fsp1/fsp_dram.c +++ b/arch/x86/lib/fsp1/fsp_dram.c @@ -34,7 +34,7 @@ int dram_init(void) * the relocation address, and how far U-Boot is moved by relocation are * set in the global data structure. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return fsp_get_usable_lowmem_top(gd->arch.hob_list); } diff --git a/arch/x86/lib/fsp2/fsp_dram.c b/arch/x86/lib/fsp2/fsp_dram.c index 42d3892b76..f9ea1ab3ba 100644 --- a/arch/x86/lib/fsp2/fsp_dram.c +++ b/arch/x86/lib/fsp2/fsp_dram.c @@ -77,7 +77,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { if (!ll_boot_init()) return gd->ram_size; diff --git a/arch/xtensa/lib/bootm.c b/arch/xtensa/lib/bootm.c index 277af18168..fee3392815 100644 --- a/arch/xtensa/lib/bootm.c +++ b/arch/xtensa/lib/bootm.c @@ -134,7 +134,7 @@ static struct bp_tag *setup_fdt_tag(struct bp_tag *params, void *fdt_start) * Boot Linux. */ -int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +int do_bootm_linux(int flag, int argc, char *argv[], struct bootm_headers *images) { struct bp_tag *params, *params_start; ulong initrd_start, initrd_end; diff --git a/board/BuR/brppt1/board.c b/board/BuR/brppt1/board.c index 7df37e4e66..c8dc186cdd 100644 --- a/board/BuR/brppt1/board.c +++ b/board/BuR/brppt1/board.c @@ -151,9 +151,7 @@ int board_init(void) hw_watchdog_init(); #endif gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; -#ifdef CONFIG_MTD_RAW_NAND - gpmc_init(); -#endif + return 0; } diff --git a/board/BuR/brppt1/mux.c b/board/BuR/brppt1/mux.c index b863d37335..5d2c7a201e 100644 --- a/board/BuR/brppt1/mux.c +++ b/board/BuR/brppt1/mux.c @@ -26,6 +26,7 @@ static struct module_pin_mux uart0_pin_mux[] = { {OFFSET(uart0_txd), (MODE(0) | PULLUDEN)}, {-1}, }; + static struct module_pin_mux uart1_pin_mux[] = { /* UART1_RTS as I2C2-SCL */ {OFFSET(uart1_rtsn), (MODE(3) | PULLUDEN | PULLUP_EN | RXACTIVE)}, @@ -37,7 +38,7 @@ static struct module_pin_mux uart1_pin_mux[] = { {OFFSET(uart1_txd), (MODE(0) | PULLUDEN)}, {-1}, }; -#ifdef CONFIG_MMC + static struct module_pin_mux mmc1_pin_mux[] = { {OFFSET(gpmc_ad7), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT7 */ {OFFSET(gpmc_ad6), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT6 */ @@ -54,7 +55,7 @@ static struct module_pin_mux mmc1_pin_mux[] = { {OFFSET(gpmc_advn_ale), (MODE(7) | RXACTIVE | PULLUP_EN)},/* MMC1_CD */ {-1}, }; -#endif + static struct module_pin_mux i2c0_pin_mux[] = { /* I2C_DATA */ {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL)}, @@ -118,26 +119,7 @@ static struct module_pin_mux mii2_pin_mux[] = { {OFFSET(gpmc_be1n), (MODE(1) | RXACTIVE)},/* MII1_COL */ {-1}, }; -#ifdef CONFIG_MTD_RAW_NAND -static struct module_pin_mux nand_pin_mux[] = { - {OFFSET(gpmc_ad0), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD0 */ - {OFFSET(gpmc_ad1), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD1 */ - {OFFSET(gpmc_ad2), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD2 */ - {OFFSET(gpmc_ad3), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD3 */ - {OFFSET(gpmc_ad4), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD4 */ - {OFFSET(gpmc_ad5), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD5 */ - {OFFSET(gpmc_ad6), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD6 */ - {OFFSET(gpmc_ad7), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD7 */ - {OFFSET(gpmc_clk), (MODE(2) | RXACTIVE | PULLUP_EN)}, /* NAND WAIT */ - {OFFSET(gpmc_wpn), (MODE(7) | PULLUP_EN | RXACTIVE)}, /* NAND_WPN */ - {OFFSET(gpmc_csn0), (MODE(0) | PULLUDEN)}, /* NAND_CS0 */ - {OFFSET(gpmc_advn_ale), (MODE(0) | PULLUDEN)}, /* NAND_ADV_ALE */ - {OFFSET(gpmc_oen_ren), (MODE(0) | PULLUDEN)}, /* NAND_OE */ - {OFFSET(gpmc_wen), (MODE(0) | PULLUDEN)}, /* NAND_WEN */ - {OFFSET(gpmc_be0n_cle), (MODE(0) | PULLUDEN)}, /* NAND_BE_CLE */ - {-1}, -}; -#endif + static struct module_pin_mux gpIOs[] = { /* GPIO0_6 (SPI0_CS1) - 3v3_PWR_nEN (Display Power Supply) */ {OFFSET(spi0_cs1), (MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE)}, @@ -180,14 +162,6 @@ static struct module_pin_mux gpIOs[] = { {OFFSET(mcasp0_axr0), (MODE(7) | PULLUDDIS) }, /* GPIO3_17 (MCASP0_AHCLKR) - ETH2_LEDY */ {OFFSET(mcasp0_ahclkr), (MODE(7) | PULLUDDIS) }, -#ifndef CONFIG_MTD_RAW_NAND - /* GPIO2_3 - NAND_OE */ - {OFFSET(gpmc_oen_ren), (MODE(7) | PULLDOWN_EN | RXACTIVE)}, - /* GPIO2_4 - NAND_WEN */ - {OFFSET(gpmc_wen), (MODE(7) | PULLDOWN_EN | RXACTIVE)}, - /* GPIO2_5 - NAND_BE_CLE */ - {OFFSET(gpmc_be0n_cle), (MODE(7) | PULLDOWN_EN | RXACTIVE)}, -#endif {-1}, }; @@ -222,7 +196,6 @@ static struct module_pin_mux lcd_pin_mux[] = { {OFFSET(lcd_hsync), (MODE(0) | PULLUDDIS)}, /* LCD-HSync */ {OFFSET(lcd_ac_bias_en), (MODE(0) | PULLUDDIS)},/* LCD-DE */ {OFFSET(lcd_pclk), (MODE(0) | PULLUDDIS)}, /* LCD-CLK */ - {-1}, }; @@ -241,11 +214,7 @@ void enable_board_pin_mux(void) configure_module_pin_mux(i2c0_pin_mux); configure_module_pin_mux(mii1_pin_mux); configure_module_pin_mux(mii2_pin_mux); -#ifdef CONFIG_MTD_RAW_NAND - configure_module_pin_mux(nand_pin_mux); -#elif defined(CONFIG_MMC) configure_module_pin_mux(mmc1_pin_mux); -#endif configure_module_pin_mux(spi0_pin_mux); configure_module_pin_mux(lcd_pin_mux); configure_module_pin_mux(uart1_pin_mux); diff --git a/board/Marvell/octeon_nic23/board.c b/board/Marvell/octeon_nic23/board.c index 3e2c544443..08b1aa4b6e 100644 --- a/board/Marvell/octeon_nic23/board.c +++ b/board/Marvell/octeon_nic23/board.c @@ -3,8 +3,10 @@ * Copyright (C) 2021-2022 Stefan Roese */ +#include #include #include +#include #include #include @@ -15,11 +17,90 @@ #include #include #include +#include #include "board_ddr.h" +/** + * cvmx_spem#_cfg_rd + * + * This register allows read access to the configuration in the PCIe core. + * + */ +union cvmx_spemx_cfg_rd { + u64 u64; + struct cvmx_spemx_cfg_rd_s { + u64 data : 32; + u64 addr : 32; + } s; + struct cvmx_spemx_cfg_rd_s cn73xx; +}; + +/** + * cvmx_spem#_cfg_wr + * + * This register allows write access to the configuration in the PCIe core. + * + */ +union cvmx_spemx_cfg_wr { + u64 u64; + struct cvmx_spemx_cfg_wr_s { + u64 data : 32; + u64 addr : 32; + } s; + struct cvmx_spemx_cfg_wr_s cn73xx; +}; + +/** + * cvmx_spem#_flr_pf_stopreq + * + * PF function level reset stop outbound requests register. + * Hardware automatically sets the STOPREQ bit for the PF when it enters a + * function level reset (FLR). Software is responsible for clearing the STOPREQ + * bit but must not do so prior to hardware taking down the FLR, which could be + * as long as 100ms. It may be appropriate for software to wait longer before clearing + * STOPREQ, software may need to drain deep DPI queues for example. + * Whenever SPEM receives a PF or child VF request mastered by CNXXXX over S2M (i.e. P or NP), + * when STOPREQ is set for the function, SPEM will discard the outgoing request + * before sending it to the PCIe core. If a NP, SPEM will schedule an immediate + * SWI_RSP_ERROR completion for the request - no timeout is required. + * In both cases, SPEM()_DBG_PF()_INFO[P()_BMD_E] will be set and a error + * interrupt is generated. + * + * STOPREQ mimics the behavior of PCIEEP()_CFG001[ME] for outbound requests that will + * master the PCIe bus (P and NP). + * + * STOPREQ will have no effect on completions returned by CNXXXX over the S2M, + * nor on M2S traffic. + * + * When a PF()_STOPREQ is set, none of the associated + * PEM()_FLR_PF()_VF_STOPREQ[VF_STOPREQ] will be set. + * + * STOPREQ is reset when the MAC is reset, and is not reset after a chip soft reset. + */ +union cvmx_spemx_flr_pf_stopreq { + u64 u64; + struct cvmx_spemx_flr_pf_stopreq_s { + u64 reserved_3_63 : 61; + u64 pf2_stopreq : 1; + u64 pf1_stopreq : 1; + u64 pf0_stopreq : 1; + } s; + struct cvmx_spemx_flr_pf_stopreq_s cn73xx; +}; + +#define CVMX_SPEMX_CFG_WR(offset) 0x00011800C0000028ull +#define CVMX_SPEMX_CFG_RD(offset) 0x00011800C0000030ull +#define CVMX_SPEMX_FLR_PF_STOPREQ(offset) 0x00011800C0000218ull + +#define DTX_SELECT_LTSSM 0x0 +#define DTX_SELECT_LTSSM_ENA 0x3ff +#define LTSSM_L0 0x11 + #define NIC23_DEF_DRAM_FREQ 800 +static u32 pci_cfgspace_reg0[2] = { 0, 0 }; + static u8 octeon_nic23_cfg0_spd_values[512] = { OCTEON_NIC23_CFG0_SPD_VALUES }; @@ -145,8 +226,118 @@ void board_configure_qlms(void) cvmx_qlm_measure_clock(4), cvmx_qlm_measure_clock(5)); } +/** + * If there is a PF FLR then the PCI EEPROM is not re-read. In this case + * we need to re-program the vendor and device ID immediately after hardware + * completes FLR. + * + * PCI spec requires FLR to be completed within 100ms. The user who triggered + * FLR expects hardware to finish FLR within 100ms, otherwise the user will + * end up reading DEVICE_ID incorrectly from the reset value. + * CN23XX exits FLR at any point between 66 and 99ms, so U-Boot has to wait + * 99ms to let hardware finish its part, then finish reprogramming the + * correct device ID before the end of 100ms. + * + * Note: this solution only works properly when there is no other activity + * within U-Boot for 100ms from the time FLR is triggered. + * + * This function gets called every 100usec. If FLR happens during any + * other activity like bootloader/image update then it is possible that + * this function does not get called for more than the FLR period which will + * cause the PF device ID restore to happen after whoever initiated the FLR to + * read the incorrect device ID 0x9700 (reset value) instead of 0x9702 + * (restored value). + */ +static void octeon_board_restore_pf(void *ctx) +{ + union cvmx_spemx_flr_pf_stopreq stopreq; + static bool start_initialized[2] = {false, false}; + bool pf0_flag, pf1_flag; + u64 ltssm_bits; + const u64 pf_flr_wait_usecs = 99700; + u64 elapsed_usecs; + union cvmx_spemx_cfg_wr cfg_wr; + union cvmx_spemx_cfg_rd cfg_rd; + static u64 start_us[2]; + int pf_num; + + csr_wr(CVMX_DTX_SPEM_SELX(0), DTX_SELECT_LTSSM); + csr_rd(CVMX_DTX_SPEM_SELX(0)); + csr_wr(CVMX_DTX_SPEM_ENAX(0), DTX_SELECT_LTSSM_ENA); + csr_rd(CVMX_DTX_SPEM_ENAX(0)); + ltssm_bits = csr_rd(CVMX_DTX_SPEM_DATX(0)); + if (((ltssm_bits >> 3) & 0x3f) != LTSSM_L0) + return; + + stopreq.u64 = csr_rd(CVMX_SPEMX_FLR_PF_STOPREQ(0)); + pf0_flag = stopreq.s.pf0_stopreq; + pf1_flag = stopreq.s.pf1_stopreq; + /* See if PF interrupt happened */ + if (!(pf0_flag || pf1_flag)) + return; + + if (pf0_flag && !start_initialized[0]) { + start_initialized[0] = true; + start_us[0] = get_timer_us(0); + } + + /* Store programmed PCIe DevID SPEM0 PF0 */ + if (pf0_flag && !pci_cfgspace_reg0[0]) { + cfg_rd.s.addr = (0 << 24) | 0x0; + csr_wr(CVMX_SPEMX_CFG_RD(0), cfg_rd.u64); + cfg_rd.u64 = csr_rd(CVMX_SPEMX_CFG_RD(0)); + pci_cfgspace_reg0[0] = cfg_rd.s.data; + } + + if (pf1_flag && !start_initialized[1]) { + start_initialized[1] = true; + start_us[1] = get_timer_us(0); + } + + /* Store programmed PCIe DevID SPEM0 PF1 */ + if (pf1_flag && !pci_cfgspace_reg0[1]) { + cfg_rd.s.addr = (1 << 24) | 0x0; + csr_wr(CVMX_SPEMX_CFG_RD(0), cfg_rd.u64); + cfg_rd.u64 = csr_rd(CVMX_SPEMX_CFG_RD(0)); + pci_cfgspace_reg0[1] = cfg_rd.s.data; + } + + /* For PF, rewrite pci config space reg 0 */ + for (pf_num = 0; pf_num < 2; pf_num++) { + if (!start_initialized[pf_num]) + continue; + + elapsed_usecs = get_timer_us(0) - start_us[pf_num]; + + if (elapsed_usecs > pf_flr_wait_usecs) { + /* Here, our measured FLR duration has passed; + * check if device ID has been reset, + * which indicates FLR completion (per MA team). + */ + cfg_rd.s.addr = (pf_num << 24) | 0x0; + csr_wr(CVMX_SPEMX_CFG_RD(0), cfg_rd.u64); + cfg_rd.u64 = csr_rd(CVMX_SPEMX_CFG_RD(0)); + /* if DevID has NOT been reset, FLR is not yet + * complete + */ + if (cfg_rd.s.data != pci_cfgspace_reg0[pf_num]) { + stopreq.s.pf0_stopreq = (pf_num == 0) ? 1 : 0; + stopreq.s.pf1_stopreq = (pf_num == 1) ? 1 : 0; + csr_wr(CVMX_SPEMX_FLR_PF_STOPREQ(0), stopreq.u64); + + cfg_wr.u64 = 0; + cfg_wr.s.addr = (pf_num << 24) | 0; + cfg_wr.s.data = pci_cfgspace_reg0[pf_num]; + csr_wr(CVMX_SPEMX_CFG_WR(0), cfg_wr.u64); + start_initialized[pf_num] = false; + } + } + } +} + int board_late_init(void) { + struct cyclic_info *cyclic; struct gpio_desc gpio = {}; ofnode node; @@ -164,6 +355,12 @@ int board_late_init(void) board_configure_qlms(); + /* Register cyclic function for PCIe FLR fixup */ + cyclic = cyclic_register(octeon_board_restore_pf, 100, + "pcie_flr_fix", NULL); + if (!cyclic) + printf("Registering of cyclic function failed\n"); + return 0; } diff --git a/board/astro/mcf5373l/fpga.c b/board/astro/mcf5373l/fpga.c index 50a3830b85..f85737432b 100644 --- a/board/astro/mcf5373l/fpga.c +++ b/board/astro/mcf5373l/fpga.c @@ -123,7 +123,7 @@ int altera_write_fn(const void *buf, size_t len, int flush, int cookie) if (bytecount % len_40 == 0) { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK putc('.'); /* let them know we are alive */ @@ -343,7 +343,7 @@ int xilinx_fastwr_config_fn(void *buf, size_t len, int flush, int cookie) } if (bytecount % len_40 == 0) { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK putc('.'); /* let them know we are alive */ diff --git a/board/atmel/sam9x60_curiosity/sam9x60_curiosity.c b/board/atmel/sam9x60_curiosity/sam9x60_curiosity.c index d8f32c93b5..8cf67d148d 100644 --- a/board/atmel/sam9x60_curiosity/sam9x60_curiosity.c +++ b/board/atmel/sam9x60_curiosity/sam9x60_curiosity.c @@ -19,6 +19,8 @@ #include #include +extern void at91_pda_detect(void); + DECLARE_GLOBAL_DATA_PTR; void at91_prepare_cpu_var(void); @@ -27,6 +29,8 @@ int board_late_init(void) { at91_prepare_cpu_var(); + at91_pda_detect(); + return 0; } diff --git a/board/broadcom/bcmns3/ns3.c b/board/broadcom/bcmns3/ns3.c index 88036c16c9..26652e8f77 100644 --- a/board/broadcom/bcmns3/ns3.c +++ b/board/broadcom/bcmns3/ns3.c @@ -183,7 +183,7 @@ int dram_init_banksize(void) } /* Limit RAM used by U-Boot to the DDR first bank End region */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return BCM_NS3_MEM_END; } diff --git a/board/dhelectronics/dh_imx6/dh_imx6_spl.c b/board/dhelectronics/dh_imx6/dh_imx6_spl.c index e49e97724a..20a330cce6 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6_spl.c +++ b/board/dhelectronics/dh_imx6/dh_imx6_spl.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -14,11 +15,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -610,6 +613,20 @@ static void dhcom_spl_dram_init(void) } } +void dram_bank_mmu_setup(int bank) +{ + int i; + + set_section_dcache(ROMCP_ARB_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + set_section_dcache(IRAM_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + + for (i = MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT; + i < ((MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT) + + (SZ_1G >> MMU_SECTION_SHIFT)); + i++) + set_section_dcache(i, DCACHE_DEFAULT_OPTION); +} + void board_init_f(ulong dummy) { /* setup AIPS and disable watchdog */ @@ -636,9 +653,33 @@ void board_init_f(ulong dummy) /* DDR3 initialization */ dhcom_spl_dram_init(); + /* Set up early MMU tables at the beginning of DRAM and start d-cache */ + gd->arch.tlb_addr = MMDC0_ARB_BASE_ADDR + SZ_32M; + gd->arch.tlb_size = PGTABLE_SIZE; + enable_caches(); + /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); /* load/boot image from boot device */ board_init_r(NULL, 0); } + +void spl_board_prepare_for_boot(void) +{ + /* + * Flush and disable dcache. Without it, the following bootstage might fail randomly because + * dirty cache lines may not have been written back to DRAM. + * + * If dcache_disable() would be omitted, the following scenario may occur: + * + * The SPL enables dcache and cachelines get populated with data. Then dcache gets disabled + * in U-Boot proper, but still contains dirty data, i.e. the corresponding DRAM locations + * have not yet been updated. When U-Boot reads these locations, it sees an (incorrect) old + * state of the content. + * + * Furthermore, the DRAM contents have likely been modified by U-Boot while dcache was + * disabled. Thus, U-Boot flushing dcache would corrupt DRAM with stale data. + */ + dcache_disable(); /* implies flush_dcache_all() */ +} diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c index 9188f5381e..2bc0d7b943 100644 --- a/board/dhelectronics/dh_stm32mp1/board.c +++ b/board/dhelectronics/dh_stm32mp1/board.c @@ -423,7 +423,7 @@ static void __maybe_unused led_error_blink(u32 nb_blink) for (i = 0; i < 2 * nb_blink; i++) { led_set_state(led, LEDST_TOGGLE); mdelay(125); - WATCHDOG_RESET(); + schedule(); } } #endif diff --git a/board/imgtec/boston/ddr.c b/board/imgtec/boston/ddr.c index 182f79b918..5b245cb447 100644 --- a/board/imgtec/boston/ddr.c +++ b/board/imgtec/boston/ddr.c @@ -23,7 +23,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { DECLARE_GLOBAL_DATA_PTR; diff --git a/board/liebherr/display5/spl.c b/board/liebherr/display5/spl.c index 5c1af1a772..4219d002fe 100644 --- a/board/liebherr/display5/spl.c +++ b/board/liebherr/display5/spl.c @@ -329,7 +329,7 @@ void board_init_f(ulong dummy) /* Initialize and reset WDT in SPL */ #ifdef CONFIG_SPL_WATCHDOG hw_watchdog_init(); - WATCHDOG_RESET(); + schedule(); #endif /* load/boot image from boot device */ diff --git a/board/mediatek/mt7981/MAINTAINERS b/board/mediatek/mt7981/MAINTAINERS new file mode 100644 index 0000000000..e7592a7a54 --- /dev/null +++ b/board/mediatek/mt7981/MAINTAINERS @@ -0,0 +1,10 @@ +MT7981 +M: Sam Shih +S: Maintained +F: board/mediatek/mt7981 +F: include/configs/mt7981.h +F: configs/mt7981_emmc_rfb_defconfig +F: configs/mt7981_rfb_defconfig +F: configs/mt7981_sd_rfb_defconfig +F: configs/mt7981_spim_nand_rfb_defconfig +F: configs/mt7981_spim_nor_rfb_defconfig diff --git a/board/mediatek/mt7981/Makefile b/board/mediatek/mt7981/Makefile new file mode 100644 index 0000000000..fa5990ffb2 --- /dev/null +++ b/board/mediatek/mt7981/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += mt7981_rfb.o diff --git a/board/mediatek/mt7981/mt7981_rfb.c b/board/mediatek/mt7981/mt7981_rfb.c new file mode 100644 index 0000000000..846c715ca0 --- /dev/null +++ b/board/mediatek/mt7981/mt7981_rfb.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +int board_init(void) +{ + return 0; +} diff --git a/board/mediatek/mt7986/MAINTAINERS b/board/mediatek/mt7986/MAINTAINERS new file mode 100644 index 0000000000..ddc078a567 --- /dev/null +++ b/board/mediatek/mt7986/MAINTAINERS @@ -0,0 +1,12 @@ +MT7986 +M: Sam Shih +S: Maintained +F: board/mediatek/mt7986 +F: include/configs/mt7986.h +F: configs/mt7986_rfb_defconfig +F: configs/mt7986a_bpir3_emmc_defconfig +F: configs/mt7986a_bpir3_sd_defconfig +F: configs/mt7986a_emmc_rfb_defconfig +F: configs/mt7986a_sd_rfb_defconfig +F: configs/mt7986b_emmc_rfb_defconfig +F: configs/mt7986b_sd_rfb_defconfig diff --git a/board/mediatek/mt7986/Makefile b/board/mediatek/mt7986/Makefile new file mode 100644 index 0000000000..7bb84fa2f4 --- /dev/null +++ b/board/mediatek/mt7986/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += mt7986_rfb.o diff --git a/board/mediatek/mt7986/mt7986_rfb.c b/board/mediatek/mt7986/mt7986_rfb.c new file mode 100644 index 0000000000..846c715ca0 --- /dev/null +++ b/board/mediatek/mt7986/mt7986_rfb.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +int board_init(void) +{ + return 0; +} diff --git a/board/menlo/m53menlo/m53menlo.c b/board/menlo/m53menlo/m53menlo.c index 61ab3844b8..4afc5aaa43 100644 --- a/board/menlo/m53menlo/m53menlo.c +++ b/board/menlo/m53menlo/m53menlo.c @@ -42,7 +42,7 @@ DECLARE_GLOBAL_DATA_PTR; static u32 mx53_dram_size[2]; -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { /* * WARNING: We must override get_effective_memsize() function here diff --git a/board/nokia/rx51/lowlevel_init.S b/board/nokia/rx51/lowlevel_init.S index c1785bc3f7..1cf8f8d8b2 100644 --- a/board/nokia/rx51/lowlevel_init.S +++ b/board/nokia/rx51/lowlevel_init.S @@ -46,7 +46,6 @@ save_boot_params: * (CONFIG_SYS_TEXT_BASE). */ -copy_kernel_start: /* r0 - start of kernel before */ adr r0, kernoffs /* r0 - current address of kernoffs section */ ldr r1, kernoffs /* r1 - offset of kernel image from kernoffs section */ @@ -77,7 +76,7 @@ copy_kernel_start: ldr r4, [r0, #36] /* r4 - 4 bytes header of kernel at offset 36 */ ldr r5, z_magic /* r5 - LINUX_ARM_ZIMAGE_MAGIC */ cmp r4, r5 - bne copy_kernel_end /* skip if invalid image */ + bne skip_copy /* skip if invalid image */ copy_kernel_loop: ldmdb r1!, {r3 - r10} @@ -85,12 +84,12 @@ copy_kernel_loop: cmp r1, r0 bhi copy_kernel_loop -copy_kernel_end: - /* remove header in source kernel image */ mov r5, #0 str r5, [r0] /* remove 4 bytes header of kernel uImage */ str r5, [r0, #36] /* remove 4 bytes header of kernel zImage */ +skip_copy: + /* Returns */ b save_boot_params_ret diff --git a/board/nokia/rx51/rx51.c b/board/nokia/rx51/rx51.c index 460d248eaa..9548c3c7be 100644 --- a/board/nokia/rx51/rx51.c +++ b/board/nokia/rx51/rx51.c @@ -722,7 +722,7 @@ static int rx51_kp_getc(struct udevice *dev) { keybuf_head %= KEYBUF_SIZE; while (!rx51_kp_tstc(dev)) - WATCHDOG_RESET(); + schedule(); return keybuf[keybuf_head++]; } diff --git a/board/qualcomm/qcs404-evb/qcs404-evb.c b/board/qualcomm/qcs404-evb/qcs404-evb.c index f1e6e7f7eb..249dca7e72 100644 --- a/board/qualcomm/qcs404-evb/qcs404-evb.c +++ b/board/qualcomm/qcs404-evb/qcs404-evb.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,34 @@ int dram_init(void) int board_init(void) { + struct udevice *pmic_gpio; + struct gpio_desc usb_vbus_boost_pin; + int ret, node; + + ret = uclass_get_device_by_name(UCLASS_GPIO, + "pms405_gpios@c000", + &pmic_gpio); + if (ret < 0) { + printf("Failed to find pms405_gpios@c000 node.\n"); + return ret; + } + + node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pmic_gpio), + "usb_vbus_boost_pin"); + if (node < 0) { + printf("Failed to find usb_hub_reset_pm dt node.\n"); + return node; + } + ret = gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0, + &usb_vbus_boost_pin, 0); + if (ret < 0) { + printf("Failed to request usb_hub_reset_pm gpio.\n"); + return ret; + } + + dm_gpio_set_dir_flags(&usb_vbus_boost_pin, + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + return 0; } diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 17b8108cc8..00afb352bd 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -335,7 +335,7 @@ static void set_fdt_addr(void) /* * Prevent relocation from stomping on a firmware provided FDT blob. */ -unsigned long board_get_usable_ram_top(unsigned long total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { if ((gd->ram_top - fw_dtb_pointer) > SZ_64M) return gd->ram_top; diff --git a/board/st/common/stm32mp_dfu.c b/board/st/common/stm32mp_dfu.c index fa48b2a35e..0096f71dfc 100644 --- a/board/st/common/stm32mp_dfu.c +++ b/board/st/common/stm32mp_dfu.c @@ -37,7 +37,7 @@ static void board_get_alt_info_mmc(struct udevice *dev, char *buf) if (!desc) return; - name = blk_get_if_type_name(desc->if_type); + name = blk_get_uclass_name(desc->uclass_id); devnum = desc->devnum; len = strlen(buf); diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 8c162b42a5..2d98ff41ab 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -289,7 +289,7 @@ static void __maybe_unused led_error_blink(u32 nb_blink) for (i = 0; i < 2 * nb_blink; i++) { led_set_state(led, LEDST_TOGGLE); mdelay(125); - WATCHDOG_RESET(); + schedule(); } led_set_state(led, LEDST_ON); } @@ -898,8 +898,8 @@ int mmc_get_env_dev(void) int ft_board_setup(void *blob, struct bd_info *bd) { static const struct node_info nodes[] = { - { "st,stm32f469-qspi", MTD_DEV_TYPE_NOR, }, - { "st,stm32f469-qspi", MTD_DEV_TYPE_SPINAND}, + { "jedec,spi-nor", MTD_DEV_TYPE_NOR, }, + { "spi-nand", MTD_DEV_TYPE_SPINAND}, { "st,stm32mp15-fmc2", MTD_DEV_TYPE_NAND, }, { "st,stm32mp1-fmc2-nfc", MTD_DEV_TYPE_NAND, }, }; diff --git a/board/synopsys/hsdk/hsdk.c b/board/synopsys/hsdk/hsdk.c index 226fbba629..4308c7e440 100644 --- a/board/synopsys/hsdk/hsdk.c +++ b/board/synopsys/hsdk/hsdk.c @@ -844,7 +844,7 @@ static int hsdk_go_run(u32 cpu_start_reg) return 0; } -int board_prep_linux(bootm_headers_t *images) +int board_prep_linux(struct bootm_headers *images) { int ret, ofst; char mask[15]; diff --git a/board/ti/am65x/evm.c b/board/ti/am65x/evm.c index 8a0a506a3e..34ec3915f3 100644 --- a/board/ti/am65x/evm.c +++ b/board/ti/am65x/evm.c @@ -61,7 +61,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { #ifdef CONFIG_PHYS_64BIT /* Limit RAM used by U-Boot to the DDR low region */ diff --git a/board/ti/j721e/evm.c b/board/ti/j721e/evm.c index 5d090048ce..d6e431ead0 100644 --- a/board/ti/j721e/evm.c +++ b/board/ti/j721e/evm.c @@ -57,7 +57,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { #ifdef CONFIG_PHYS_64BIT /* Limit RAM used by U-Boot to the DDR low region */ diff --git a/board/ti/j721s2/evm.c b/board/ti/j721s2/evm.c index 3c75ecfc0f..e09adc8ad3 100644 --- a/board/ti/j721s2/evm.c +++ b/board/ti/j721s2/evm.c @@ -46,7 +46,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { #ifdef CONFIG_PHYS_64BIT /* Limit RAM used by U-Boot to the DDR low region */ diff --git a/board/ti/ks2_evm/board.c b/board/ti/ks2_evm/board.c index 0c5c2c9146..5ba3aa35a9 100644 --- a/board/ti/ks2_evm/board.c +++ b/board/ti/ks2_evm/board.c @@ -64,9 +64,9 @@ int dram_init(void) return 0; } -struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { - return (struct image_header *)(CONFIG_SYS_TEXT_BASE); + return (struct legacy_img_hdr *)(CONFIG_SYS_TEXT_BASE); } int board_init(void) diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c index 22c67c6e38..11f4d5e14a 100644 --- a/board/toradex/common/tdx-cfg-block.c +++ b/board/toradex/common/tdx-cfg-block.c @@ -211,7 +211,7 @@ static int tdx_cfg_block_mmc_storage(u8 *config_block, int write) return -EINVAL; } if (part != mmc_get_blk_desc(mmc)->hwpart) { - if (blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part)) { + if (blk_select_hwpart_devnum(UCLASS_MMC, dev, part)) { puts("MMC partition switch failed\n"); ret = -ENODEV; goto out; @@ -239,7 +239,7 @@ static int tdx_cfg_block_mmc_storage(u8 *config_block, int write) out: /* Switch back to regular eMMC user partition */ - blk_select_hwpart_devnum(IF_TYPE_MMC, 0, 0); + blk_select_hwpart_devnum(UCLASS_MMC, 0, 0); return ret; } diff --git a/board/xilinx/Kconfig b/board/xilinx/Kconfig index 1788066173..746a2332ad 100644 --- a/board/xilinx/Kconfig +++ b/board/xilinx/Kconfig @@ -42,7 +42,7 @@ endif config XILINX_OF_BOARD_DTB_ADDR hex "Default DTB pickup address" - default 0x1000 if ARCH_VERSAL + default 0x1000 if ARCH_VERSAL || ARCH_VERSAL_NET default 0x8000 if MICROBLAZE default 0x100000 if ARCH_ZYNQ || ARCH_ZYNQMP depends on OF_BOARD || OF_SEPARATE @@ -51,10 +51,10 @@ config XILINX_OF_BOARD_DTB_ADDR config BOOT_SCRIPT_OFFSET hex "Boot script offset" - depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || MICROBLAZE + depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || MICROBLAZE default 0xFC0000 if ARCH_ZYNQ || MICROBLAZE default 0x3E80000 if ARCH_ZYNQMP - default 0x7F80000 if ARCH_VERSAL + default 0x7F80000 if ARCH_VERSAL || ARCH_VERSAL_NET help Specifies distro boot script offset in NAND/QSPI/NOR flash. diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 9b4aded466..391ce4dbd7 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include @@ -583,8 +585,33 @@ bool __maybe_unused __weak board_detection(void) return false; } +bool __maybe_unused __weak soc_detection(void) +{ + return false; +} + +char * __maybe_unused __weak soc_name_decode(void) +{ + return NULL; +} + int embedded_dtb_select(void) { + if (soc_detection()) { + char *soc_local_name; + + soc_local_name = soc_name_decode(); + if (soc_local_name) { + board_name = soc_local_name; + printf("Detected SOC name: %s\n", board_name); + + /* Time to change DTB on fly */ + /* Both ways should work here */ + /* fdtdec_resetup(&rescan); */ + return fdtdec_setup(); + } + } + if (board_detection()) { char *board_local_name; @@ -602,3 +629,30 @@ int embedded_dtb_select(void) return 0; } #endif + +#if defined(CONFIG_LMB) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) +{ + phys_size_t size; + phys_addr_t reg; + struct lmb lmb; + + if (!total_size) + return gd->ram_top; + + if (!IS_ALIGNED((ulong)gd->fdt_blob, 0x8)) + panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob); + + /* found enough not-reserved memory to relocated U-Boot */ + lmb_init(&lmb); + lmb_add(&lmb, gd->ram_base, gd->ram_size); + boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); + size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE); + reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE); + + if (!reg) + reg = gd->ram_top - size; + + return reg + size; +} +#endif diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index f58ecd1590..a427ac94a1 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include @@ -38,25 +36,6 @@ int dram_init(void) return 0; }; -ulong board_get_usable_ram_top(ulong total_size) -{ - phys_size_t size; - phys_addr_t reg; - struct lmb lmb; - - /* found enough not-reserved memory to relocated U-Boot */ - lmb_init(&lmb); - lmb_add(&lmb, gd->ram_base, gd->ram_size); - boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); - size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE); - reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE); - - if (!reg) - reg = gd->ram_top - size; - - return reg + size; -} - int board_late_init(void) { ulong max_size; diff --git a/board/xilinx/versal-net/Kconfig b/board/xilinx/versal-net/Kconfig new file mode 100644 index 0000000000..8f94d2bb39 --- /dev/null +++ b/board/xilinx/versal-net/Kconfig @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2020 - 2022, Xilinx, Inc. +# Copyright (C) 2022, Advanced Micro Devices, Inc. +# + +if ARCH_VERSAL_NET + +endif diff --git a/board/xilinx/versal-net/MAINTAINERS b/board/xilinx/versal-net/MAINTAINERS new file mode 100644 index 0000000000..50120a88d6 --- /dev/null +++ b/board/xilinx/versal-net/MAINTAINERS @@ -0,0 +1,8 @@ +XILINX_VERSAL_NET BOARDS +M: Michal Simek +S: Maintained +T: git https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze.git +F: arch/arm/dts/versal-net* +F: board/xilinx/versal-net/ +F: include/configs/xilinx_versal_net* +F: configs/xilinx_versal_net* diff --git a/board/xilinx/versal-net/Makefile b/board/xilinx/versal-net/Makefile new file mode 100644 index 0000000000..2008d4e231 --- /dev/null +++ b/board/xilinx/versal-net/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2021 - 2022, Xilinx, Inc. +# Copyright (C) 2022, Advanced Micro Devices, Inc. +# +# Michal Simek +# + +obj-y := board.o diff --git a/board/xilinx/versal-net/board.c b/board/xilinx/versal-net/board.c new file mode 100644 index 0000000000..760031927f --- /dev/null +++ b/board/xilinx/versal-net/board.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../common/board.h" + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int board_init(void) +{ + printf("EL Level:\tEL%d\n", current_el()); + + return 0; +} + +static u32 platform_id, platform_version; + +char *soc_name_decode(void) +{ + char *name, *platform_name; + + switch (platform_id) { + case VERSAL_NET_SPP: + platform_name = "ipp"; + break; + case VERSAL_NET_EMU: + platform_name = "emu"; + break; + case VERSAL_NET_QEMU: + platform_name = "qemu"; + break; + default: + return NULL; + } + + /* + * --rev. are 6 chars + * max platform name is qemu which is 4 chars + * platform version number are 1+1 + * Plus 1 char for \n + */ + name = calloc(1, strlen(CONFIG_SYS_BOARD) + 13); + if (!name) + return NULL; + + sprintf(name, "%s-%s-rev%d.%d", CONFIG_SYS_BOARD, + platform_name, platform_version / 10, + platform_version % 10); + + return name; +} + +bool soc_detection(void) +{ + u32 version; + + version = readl(PMC_TAP_VERSION); + platform_id = FIELD_GET(PLATFORM_MASK, version); + + debug("idcode %x, version %x, usercode %x\n", + readl(PMC_TAP_IDCODE), version, + readl(PMC_TAP_USERCODE)); + + debug("pmc_ver %lx, ps version %lx, rtl version %lx\n", + FIELD_GET(PMC_VERSION_MASK, version), + FIELD_GET(PS_VERSION_MASK, version), + FIELD_GET(RTL_VERSION_MASK, version)); + + platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version); + + if (platform_id == VERSAL_NET_SPP || + platform_id == VERSAL_NET_EMU) { + /* + * 9 is diff for + * 0 means 0.9 version + * 1 means 1.0 version + * 2 means 1.1 version + * etc, + */ + platform_version += 9; + } + + debug("Platform id: %d version: %d.%d\n", platform_id, + platform_version / 10, platform_version % 10); + + return true; +} + +int board_early_init_f(void) +{ + if (IS_ENABLED(CONFIG_DEBUG_UART)) { + /* Uart debug for sure */ + debug_uart_init(); + puts("Debug uart enabled\n"); /* or printch() */ + } + + return 0; +} + +int board_early_init_r(void) +{ + return 0; +} + +int board_late_init(void) +{ + if (!(gd->flags & GD_FLG_ENV_DEFAULT)) { + debug("Saved variables - Skipping\n"); + return 0; + } + + if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG)) + return 0; + + return board_late_init_xilinx(); +} + +int dram_init_banksize(void) +{ + int ret; + + ret = fdtdec_setup_memory_banksize(); + if (ret) + return ret; + + mem_map_fill(); + + return 0; +} + +int dram_init(void) +{ + int ret; + + if (CONFIG_IS_ENABLED(SYS_MEM_RSVD_FOR_MMU)) + ret = fdtdec_setup_mem_size_base(); + else + ret = fdtdec_setup_mem_size_base_lowest(); + + if (ret) + return -EINVAL; + + return 0; +} + +void reset_cpu(void) +{ +} diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c index d8f39be56c..f9f5457ed2 100644 --- a/board/xilinx/versal/board.c +++ b/board/xilinx/versal/board.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -270,28 +269,6 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) -{ - phys_size_t size; - phys_addr_t reg; - struct lmb lmb; - - if (!total_size) - return gd->ram_top; - - /* found enough not-reserved memory to relocated U-Boot */ - lmb_init(&lmb); - lmb_add(&lmb, gd->ram_base, gd->ram_size); - boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); - size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE); - reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE); - - if (!reg) - reg = gd->ram_top - size; - - return reg + size; -} - void reset_cpu(void) { } diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 63aff0474b..c96433be69 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -168,8 +168,7 @@ void set_dfu_alt_info(char *interface, char *devstr) { ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); - if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && - env_get("dfu_alt_info")) + if (env_get("dfu_alt_info")) return; memset(buf, 0, sizeof(buf)); @@ -177,13 +176,14 @@ void set_dfu_alt_info(char *interface, char *devstr) switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) { case ZYNQ_BM_SD: snprintf(buf, DFU_ALT_BUF_LEN, - "mmc 0:1=boot.bin fat 0 1;" - "u-boot.img fat 0 1"); + "mmc 0=boot.bin fat 0 1;" + "%s fat 0 1", CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); break; case ZYNQ_BM_QSPI: snprintf(buf, DFU_ALT_BUF_LEN, "sf 0:0=boot.bin raw 0 0x1500000;" - "u-boot.img raw 0x%x 0x500000", + "%s raw 0x%x 0x500000", + CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, CONFIG_SYS_SPI_U_BOOT_OFFS); break; default: diff --git a/board/xilinx/zynqmp/cmds.c b/board/xilinx/zynqmp/cmds.c index 2ab9596248..e20030ecda 100644 --- a/board/xilinx/zynqmp/cmds.c +++ b/board/xilinx/zynqmp/cmds.c @@ -142,9 +142,6 @@ static int do_zynqmp_aes(struct cmd_tbl *cmdtp, int flag, int argc, aes->keysrc = hextoul(argv[6], NULL); aes->dstaddr = hextoul(argv[7], NULL); - flush_dcache_range((ulong)aes, (ulong)(aes) + - roundup(sizeof(struct aes), ARCH_DMA_MINALIGN)); - if (aes->srcaddr && aes->ivaddr && aes->dstaddr) { flush_dcache_range(aes->srcaddr, (aes->srcaddr + @@ -169,6 +166,9 @@ static int do_zynqmp_aes(struct cmd_tbl *cmdtp, int flag, int argc, ARCH_DMA_MINALIGN))); } + flush_dcache_range((ulong)aes, (ulong)(aes) + + roundup(sizeof(struct aes), ARCH_DMA_MINALIGN)); + ret = xilinx_pm_request(PM_SECURE_AES, upper_32_bits((ulong)aes), lower_32_bits((ulong)aes), 0, 0, ret_payload); if (ret || ret_payload[1]) diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 57259b60a0..62537760df 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -12,8 +12,6 @@ #include #include #include -#include -#include #include #include #include @@ -256,33 +254,6 @@ int dram_init(void) return 0; } -#if defined(CONFIG_LMB) -ulong board_get_usable_ram_top(ulong total_size) -{ - phys_size_t size; - phys_addr_t reg; - struct lmb lmb; - - if (!total_size) - return gd->ram_top; - - if (!IS_ALIGNED((ulong)gd->fdt_blob, 0x8)) - panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob); - - /* found enough not-reserved memory to relocated U-Boot */ - lmb_init(&lmb); - lmb_add(&lmb, gd->ram_base, gd->ram_size); - boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); - size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE); - reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE); - - if (!reg) - reg = gd->ram_top - size; - - return reg + size; -} -#endif - #else int dram_init_banksize(void) { @@ -641,8 +612,7 @@ void set_dfu_alt_info(char *interface, char *devstr) ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); - if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && - env_get("dfu_alt_info")) + if (env_get("dfu_alt_info")) return; memset(buf, 0, sizeof(buf)); @@ -662,13 +632,13 @@ void set_dfu_alt_info(char *interface, char *devstr) bootseq = mmc_get_env_dev(); if (!multiboot) snprintf(buf, DFU_ALT_BUF_LEN, - "mmc %d:1=boot.bin fat %d 1;" + "mmc %d=boot.bin fat %d 1;" "%s fat %d 1", bootseq, bootseq, CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, bootseq); else snprintf(buf, DFU_ALT_BUF_LEN, - "mmc %d:1=boot%04d.bin fat %d 1;" + "mmc %d=boot%04d.bin fat %d 1;" "%s fat %d 1", bootseq, multiboot, bootseq, CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, bootseq); diff --git a/boot/boot_fit.c b/boot/boot_fit.c index dfc2a3117d..4a493b3684 100644 --- a/boot/boot_fit.c +++ b/boot/boot_fit.c @@ -57,14 +57,14 @@ static int fdt_offset(const void *fit) void *locate_dtb_in_fit(const void *fit) { - struct image_header *header; + struct legacy_img_hdr *header; int size; int ret; size = fdt_totalsize(fit); size = (size + 3) & ~3; - header = (struct image_header *)fit; + header = (struct legacy_img_hdr *)fit; if (image_get_magic(header) != FDT_MAGIC) { debug("No FIT image appended to U-boot\n"); diff --git a/boot/bootm.c b/boot/bootm.c index e3233fdf89..5b20b418db 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -41,10 +41,10 @@ DECLARE_GLOBAL_DATA_PTR; -bootm_headers_t images; /* pointers to os/initrd/fdt images */ +struct bootm_headers images; /* pointers to os/initrd/fdt images */ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], bootm_headers_t *images, + char *const argv[], struct bootm_headers *images, ulong *os_data, ulong *os_len); __weak void board_quiesce_devices(void) @@ -52,7 +52,7 @@ __weak void board_quiesce_devices(void) } #ifdef CONFIG_LMB -static void boot_start_lmb(bootm_headers_t *images) +static void boot_start_lmb(struct bootm_headers *images) { ulong mem_start; phys_size_t mem_size; @@ -65,7 +65,7 @@ static void boot_start_lmb(bootm_headers_t *images) } #else #define lmb_reserve(lmb, base, size) -static inline void boot_start_lmb(bootm_headers_t *images) { } +static inline void boot_start_lmb(struct bootm_headers *images) { } #endif static int bootm_start(struct cmd_tbl *cmdtp, int flag, int argc, @@ -397,9 +397,9 @@ static int handle_decomp_error(int comp_type, size_t uncomp_size, #endif #ifndef USE_HOSTCC -static int bootm_load_os(bootm_headers_t *images, int boot_progress) +static int bootm_load_os(struct bootm_headers *images, int boot_progress) { - image_info_t os = images->os; + struct image_info os = images->os; ulong load = os.load; ulong load_end; ulong blob_start = os.start; @@ -688,7 +688,7 @@ int bootm_process_cmdline_env(int flags) * unless the image type is standalone. */ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], int states, bootm_headers_t *images, + char *const argv[], int states, struct bootm_headers *images, int boot_progress) { boot_os_fn *boot_fn; @@ -825,9 +825,9 @@ err: * pointer to a legacy image header if valid image was found * otherwise return NULL */ -static image_header_t *image_get_kernel(ulong img_addr, int verify) +static struct legacy_img_hdr *image_get_kernel(ulong img_addr, int verify) { - image_header_t *hdr = (image_header_t *)img_addr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)img_addr; if (!image_check_magic(hdr)) { puts("Bad Magic Number\n"); @@ -878,11 +878,11 @@ static image_header_t *image_get_kernel(ulong img_addr, int verify) * address and length, otherwise NULL */ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], bootm_headers_t *images, + char *const argv[], struct bootm_headers *images, ulong *os_data, ulong *os_len) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - image_header_t *hdr; + struct legacy_img_hdr *hdr; #endif ulong img_addr; const void *buf; @@ -940,7 +940,7 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, * kernel decompression. */ memmove(&images->legacy_hdr_os_copy, hdr, - sizeof(image_header_t)); + sizeof(struct legacy_img_hdr)); /* save pointer to image header */ images->legacy_hdr_os = hdr; @@ -1002,7 +1002,7 @@ static int bootm_host_load_image(const void *fit, int req_image_type, { const char *fit_uname_config = NULL; ulong data, len; - bootm_headers_t images; + struct bootm_headers images; int noffset; ulong load_end, buf_size; uint8_t image_type; diff --git a/boot/bootm_os.c b/boot/bootm_os.c index f31820cd07..99ff0e6c02 100644 --- a/boot/bootm_os.c +++ b/boot/bootm_os.c @@ -24,7 +24,7 @@ DECLARE_GLOBAL_DATA_PTR; static int do_bootm_standalone(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int (*appl)(int, char *const[]); @@ -65,10 +65,11 @@ static void __maybe_unused fit_unsupported_reset(const char *msg) #ifdef CONFIG_BOOTM_NETBSD static int do_bootm_netbsd(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { - void (*loader)(struct bd_info *, image_header_t *, char *, char *); - image_header_t *os_hdr, *hdr; + void (*loader)(struct bd_info *bd, struct legacy_img_hdr *hdr, + char *console, char *cmdline); + struct legacy_img_hdr *os_hdr, *hdr; ulong kernel_data, kernel_len; char *cmdline; @@ -115,7 +116,7 @@ static int do_bootm_netbsd(int flag, int argc, char *const argv[], cmdline = ""; } - loader = (void (*)(struct bd_info *, image_header_t *, char *, char *))images->ep; + loader = (void (*)(struct bd_info *, struct legacy_img_hdr *, char *, char *))images->ep; printf("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n", (ulong)loader); @@ -137,7 +138,7 @@ static int do_bootm_netbsd(int flag, int argc, char *const argv[], #ifdef CONFIG_BOOTM_RTEMS static int do_bootm_rtems(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(struct bd_info *); @@ -170,7 +171,7 @@ static int do_bootm_rtems(int flag, int argc, char *const argv[], #if defined(CONFIG_BOOTM_OSE) static int do_bootm_ose(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(void); @@ -203,7 +204,7 @@ static int do_bootm_ose(int flag, int argc, char *const argv[], #if defined(CONFIG_BOOTM_PLAN9) static int do_bootm_plan9(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(void); char *s; @@ -252,7 +253,7 @@ static int do_bootm_plan9(int flag, int argc, char *const argv[], #if defined(CONFIG_BOOTM_VXWORKS) && \ (defined(CONFIG_PPC) || defined(CONFIG_ARM)) -static void do_bootvx_fdt(bootm_headers_t *images) +static void do_bootvx_fdt(struct bootm_headers *images) { #if defined(CONFIG_OF_LIBFDT) int ret; @@ -303,6 +304,7 @@ static void do_bootvx_fdt(bootm_headers_t *images) #else printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep); #endif + flush(); boot_jump_vxworks(images); @@ -310,7 +312,7 @@ static void do_bootvx_fdt(bootm_headers_t *images) } static int do_bootm_vxworks_legacy(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { if (flag != BOOTM_STATE_OS_GO) return 0; @@ -328,7 +330,7 @@ static int do_bootm_vxworks_legacy(int flag, int argc, char *const argv[], } int do_bootm_vxworks(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { char *bootargs; int pos; @@ -364,7 +366,7 @@ int do_bootm_vxworks(int flag, int argc, char *const argv[], #if defined(CONFIG_CMD_ELF) static int do_bootm_qnxelf(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { char *local_args[2]; char str[16]; @@ -402,7 +404,7 @@ static int do_bootm_qnxelf(int flag, int argc, char *const argv[], #ifdef CONFIG_INTEGRITY static int do_bootm_integrity(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(void); @@ -435,7 +437,7 @@ static int do_bootm_integrity(int flag, int argc, char *const argv[], #ifdef CONFIG_BOOTM_OPENRTOS static int do_bootm_openrtos(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(void); @@ -461,7 +463,7 @@ static int do_bootm_openrtos(int flag, int argc, char *const argv[], #ifdef CONFIG_BOOTM_OPTEE static int do_bootm_tee(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int ret; @@ -489,7 +491,7 @@ static int do_bootm_tee(int flag, int argc, char *const argv[], #ifdef CONFIG_BOOTM_EFI static int do_bootm_efi(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int ret; efi_status_t efi_ret; @@ -588,7 +590,7 @@ __weak void board_preboot_os(void) } int boot_selected_os(int argc, char *const argv[], int state, - bootm_headers_t *images, boot_os_fn *boot_fn) + struct bootm_headers *images, boot_os_fn *boot_fn) { arch_preboot_os(); board_preboot_os(); diff --git a/boot/bootretry.c b/boot/bootretry.c index 2bc9c6866e..8d850df9d4 100644 --- a/boot/bootretry.c +++ b/boot/bootretry.c @@ -44,7 +44,7 @@ int bootretry_tstc_timeout(void) while (!tstc()) { /* while no incoming data */ if (retry_time >= 0 && get_ticks() > endtime) return -ETIMEDOUT; - WATCHDOG_RESET(); + schedule(); } return 0; diff --git a/boot/image-android.c b/boot/image-android.c index 1fbbbba1eb..2628db3741 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -63,7 +63,7 @@ int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, ulong *os_data, ulong *os_len) { u32 kernel_addr = android_image_get_kernel_addr(hdr); - const struct image_header *ihdr = (const struct image_header *) + const struct legacy_img_hdr *ihdr = (const struct legacy_img_hdr *) ((uintptr_t)hdr + hdr->page_size); /* @@ -159,8 +159,8 @@ ulong android_image_get_kcomp(const struct andr_img_hdr *hdr) { const void *p = (void *)((uintptr_t)hdr + hdr->page_size); - if (image_get_magic((image_header_t *)p) == IH_MAGIC) - return image_get_comp((image_header_t *)p); + if (image_get_magic((struct legacy_img_hdr *)p) == IH_MAGIC) + return image_get_comp((struct legacy_img_hdr *)p); else if (get_unaligned_le32(p) == LZ4F_MAGIC) return IH_COMP_LZ4; else diff --git a/boot/image-board.c b/boot/image-board.c index 4e4d1c157d..34d1e5f18b 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -24,7 +25,6 @@ DECLARE_GLOBAL_DATA_PTR; -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) /** * image_get_ramdisk - get and verify ramdisk image * @rd_addr: ramdisk image start address @@ -40,10 +40,10 @@ DECLARE_GLOBAL_DATA_PTR; * pointer to a ramdisk image header, if image was found and valid * otherwise, return NULL */ -static const image_header_t *image_get_ramdisk(ulong rd_addr, u8 arch, - int verify) +static const struct legacy_img_hdr *image_get_ramdisk(ulong rd_addr, u8 arch, + int verify) { - const image_header_t *rd_hdr = (const image_header_t *)rd_addr; + const struct legacy_img_hdr *rd_hdr = (const struct legacy_img_hdr *)rd_addr; if (!image_check_magic(rd_hdr)) { puts("Bad Magic Number\n"); @@ -83,7 +83,6 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, u8 arch, return rd_hdr; } -#endif /*****************************************************************************/ /* Shared dual-format routines */ @@ -174,29 +173,29 @@ void memmove_wd(void *to, void *from, size_t len, ulong chunksz) if (to == from) return; -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - if (to > from) { - from += len; - to += len; - } - while (len > 0) { - size_t tail = (len > chunksz) ? chunksz : len; - - WATCHDOG_RESET(); + if (IS_ENABLED(CONFIG_HW_WATCHDOG) || IS_ENABLED(CONFIG_WATCHDOG)) { if (to > from) { - to -= tail; - from -= tail; + from += len; + to += len; } - memmove(to, from, tail); - if (to < from) { - to += tail; - from += tail; + while (len > 0) { + size_t tail = (len > chunksz) ? chunksz : len; + + schedule(); + if (to > from) { + to -= tail; + from -= tail; + } + memmove(to, from, tail); + if (to < from) { + to += tail; + from += tail; + } + len -= tail; } - len -= tail; + } else { + memmove(to, from, len); } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - memmove(to, from, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ } /** @@ -274,9 +273,9 @@ ulong genimg_get_kernel_addr(char * const img_addr) int genimg_get_format(const void *img_addr) { if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) { - const image_header_t *hdr; + const struct legacy_img_hdr *hdr; - hdr = (const image_header_t *)img_addr; + hdr = (const struct legacy_img_hdr *)img_addr; if (image_check_magic(hdr)) return IMAGE_FORMAT_LEGACY; } @@ -302,7 +301,7 @@ int genimg_get_format(const void *img_addr) * 0, no FIT support or no configuration found * 1, configuration found */ -int genimg_has_config(bootm_headers_t *images) +int genimg_has_config(struct bootm_headers *images) { if (CONFIG_IS_ENABLED(FIT) && images->fit_uname_cfg) return 1; @@ -314,23 +313,27 @@ int genimg_has_config(bootm_headers_t *images) * select_ramdisk() - Select and locate the ramdisk to use * * @images: pointer to the bootm images structure - * @select: name of ramdisk to select, or NULL for any + * @select: name of ramdisk to select, or hex address, NULL for any * @arch: expected ramdisk architecture * @rd_datap: pointer to a ulong variable, will hold ramdisk pointer * @rd_lenp: pointer to a ulong variable, will hold ramdisk length * Return: 0 if OK, -ENOPKG if no ramdisk (but an error should not be reported), * other -ve value on other error */ -static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, +static int select_ramdisk(struct bootm_headers *images, const char *select, u8 arch, ulong *rd_datap, ulong *rd_lenp) { + const char *fit_uname_config; + const char *fit_uname_ramdisk; + bool done_select = !select; + bool done = false; + int rd_noffset; ulong rd_addr; char *buf; -#if CONFIG_IS_ENABLED(FIT) - const char *fit_uname_config = images->fit_uname_cfg; - const char *fit_uname_ramdisk = NULL; - int rd_noffset; + if (CONFIG_IS_ENABLED(FIT)) { + fit_uname_config = images->fit_uname_cfg; + fit_uname_ramdisk = NULL; if (select) { ulong default_addr; @@ -345,49 +348,48 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, else default_addr = image_load_addr; - if (fit_parse_conf(select, default_addr, - &rd_addr, &fit_uname_config)) { + if (fit_parse_conf(select, default_addr, &rd_addr, + &fit_uname_config)) { debug("* ramdisk: config '%s' from image at 0x%08lx\n", fit_uname_config, rd_addr); + done_select = true; } else if (fit_parse_subimage(select, default_addr, &rd_addr, &fit_uname_ramdisk)) { debug("* ramdisk: subimage '%s' from image at 0x%08lx\n", fit_uname_ramdisk, rd_addr); - } else -#endif - { - rd_addr = hextoul(select, NULL); - debug("* ramdisk: cmdline image address = 0x%08lx\n", - rd_addr); + done_select = true; } -#if CONFIG_IS_ENABLED(FIT) - } else { - /* use FIT configuration provided in first bootm - * command argument. If the property is not defined, - * quit silently (with -ENOPKG) - */ - rd_addr = map_to_sysmem(images->fit_hdr_os); - rd_noffset = fit_get_node_from_config(images, - FIT_RAMDISK_PROP, - rd_addr); - if (rd_noffset == -ENOENT) - return -ENOPKG; - else if (rd_noffset < 0) - return rd_noffset; } -#endif - - /* - * Check if there is an initrd image at the - * address provided in the second bootm argument - * check image type, for FIT images get FIT node. + } + if (!done_select) { + rd_addr = hextoul(select, NULL); + debug("* ramdisk: cmdline image address = 0x%08lx\n", rd_addr); + } + if (CONFIG_IS_ENABLED(FIT) && !select) { + /* use FIT configuration provided in first bootm + * command argument. If the property is not defined, + * quit silently (with -ENOPKG) */ - buf = map_sysmem(rd_addr, 0); - switch (genimg_get_format(buf)) { -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - case IMAGE_FORMAT_LEGACY: { - const image_header_t *rd_hdr; + rd_addr = map_to_sysmem(images->fit_hdr_os); + rd_noffset = fit_get_node_from_config(images, FIT_RAMDISK_PROP, + rd_addr); + if (rd_noffset == -ENOENT) + return -ENOPKG; + else if (rd_noffset < 0) + return rd_noffset; + } + + /* + * Check if there is an initrd image at the + * address provided in the second bootm argument + * check image type, for FIT images get FIT node. + */ + buf = map_sysmem(rd_addr, 0); + switch (genimg_get_format(buf)) { + case IMAGE_FORMAT_LEGACY: + if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) { + const struct legacy_img_hdr *rd_hdr; printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n", rd_addr); @@ -401,15 +403,15 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, *rd_datap = image_get_data(rd_hdr); *rd_lenp = image_get_data_size(rd_hdr); - break; + done = true; } -#endif -#if CONFIG_IS_ENABLED(FIT) - case IMAGE_FORMAT_FIT: - rd_noffset = fit_image_load(images, - rd_addr, &fit_uname_ramdisk, - &fit_uname_config, arch, - IH_TYPE_RAMDISK, + break; + case IMAGE_FORMAT_FIT: + if (CONFIG_IS_ENABLED(FIT)) { + rd_noffset = fit_image_load(images, rd_addr, + &fit_uname_ramdisk, + &fit_uname_config, + arch, IH_TYPE_RAMDISK, BOOTSTAGE_ID_FIT_RD_START, FIT_LOAD_OPTIONAL_NON_ZERO, rd_datap, rd_lenp); @@ -419,29 +421,41 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, images->fit_hdr_rd = map_sysmem(rd_addr, 0); images->fit_uname_rd = fit_uname_ramdisk; images->fit_noffset_rd = rd_noffset; - break; -#endif -#ifdef CONFIG_ANDROID_BOOT_IMAGE - case IMAGE_FORMAT_ANDROID: - android_image_get_ramdisk((void *)images->os.start, - rd_datap, rd_lenp); - break; -#endif - default: - if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) { - char *end = NULL; + done = true; + } + break; + case IMAGE_FORMAT_ANDROID: + if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { + void *ptr = map_sysmem(images->os.start, 0); + int ret; - if (select) - end = strchr(select, ':'); - if (end) { - *rd_lenp = hextoul(++end, NULL); - *rd_datap = rd_addr; - break; - } + ret = android_image_get_ramdisk(ptr, rd_datap, rd_lenp); + unmap_sysmem(ptr); + if (ret) + return ret; + done = true; + } + break; + } + + if (!done) { + if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) { + char *end = NULL; + + if (select) + end = strchr(select, ':'); + if (end) { + *rd_lenp = hextoul(++end, NULL); + *rd_datap = rd_addr; + done = true; } + } + + if (!done) { puts("Wrong Ramdisk Image Format\n"); return -EINVAL; } + } return 0; } @@ -468,7 +482,7 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, * 1, if ramdisk image is found but corrupted, or invalid * rd_start and rd_end are set to 0 if no ramdisk exists */ -int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_ramdisk(int argc, char *const argv[], struct bootm_headers *images, u8 arch, ulong *rd_start, ulong *rd_end) { ulong rd_data, rd_len; @@ -538,7 +552,6 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, return 0; } -#if defined(CONFIG_LMB) /** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -632,9 +645,8 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, error: return -1; } -#endif -int boot_get_setup(bootm_headers_t *images, u8 arch, +int boot_get_setup(struct bootm_headers *images, u8 arch, ulong *setup_start, ulong *setup_len) { if (!CONFIG_IS_ENABLED(FIT)) @@ -643,7 +655,7 @@ int boot_get_setup(bootm_headers_t *images, u8 arch, return boot_get_setup_fit(images, arch, setup_start, setup_len); } -int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_fpga(int argc, char *const argv[], struct bootm_headers *images, u8 arch, const ulong *ld_start, ulong * const ld_len) { ulong tmp_img_addr, img_data, img_len; @@ -746,7 +758,7 @@ static void fit_loadable_process(u8 img_type, fit_loadable_handler->handler(img_data, img_len); } -int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_loadable(int argc, char *const argv[], struct bootm_headers *images, u8 arch, const ulong *ld_start, ulong * const ld_len) { /* @@ -826,15 +838,13 @@ int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, return 0; } -#if defined(CONFIG_LMB) -#ifdef CONFIG_SYS_BOOT_GET_CMDLINE /** * boot_get_cmdline - allocate and initialize kernel cmdline * @lmb: pointer to lmb handle, will be used for memory mgmt * @cmd_start: pointer to a ulong variable, will hold cmdline start * @cmd_end: pointer to a ulong variable, will hold cmdline end * - * boot_get_cmdline() allocates space for kernel command line below + * This allocates space for kernel command line below * BOOTMAPSZ + env_get_bootm_low() address. If "bootargs" U-Boot environment * variable is present its contents is copied to allocated kernel * command line. @@ -845,10 +855,19 @@ int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, */ int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) { + int barg; char *cmdline; char *s; - cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf, + /* + * Help the compiler detect that this function is only called when + * CONFIG_SYS_BOOT_GET_CMDLINE is enabled + */ + if (!IS_ENABLED(CONFIG_SYS_BOOT_GET_CMDLINE)) + return 0; + + barg = IF_ENABLED_INT(CONFIG_SYS_BOOT_GET_CMDLINE, CONFIG_SYS_BARGSIZE); + cmdline = (char *)(ulong)lmb_alloc_base(lmb, barg, 0xf, env_get_bootm_mapsize() + env_get_bootm_low()); if (!cmdline) return -1; @@ -894,22 +913,22 @@ int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd) debug("## kernel board info at 0x%08lx\n", (ulong)*kbd); -#if defined(DEBUG) - if (IS_ENABLED(CONFIG_CMD_BDI)) + if (_DEBUG && IS_ENABLED(CONFIG_CMD_BDI)) do_bdinfo(NULL, 0, 0, NULL); -#endif return 0; } -#endif -int image_setup_linux(bootm_headers_t *images) +int image_setup_linux(struct bootm_headers *images) { ulong of_size = images->ft_len; char **of_flat_tree = &images->ft_addr; - struct lmb *lmb = &images->lmb; + struct lmb *lmb = images_lmb(images); int ret; + /* This function cannot be called without lmb support */ + if (!CONFIG_IS_ENABLED(LMB)) + return -EFAULT; if (CONFIG_IS_ENABLED(OF_LIBFDT)) boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); @@ -936,7 +955,6 @@ int image_setup_linux(bootm_headers_t *images) return 0; } -#endif void genimg_print_size(uint32_t size) { diff --git a/boot/image-fdt.c b/boot/image-fdt.c index e75d051c87..884e089f2d 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -37,9 +37,9 @@ static void fdt_error(const char *msg) } #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) -static const image_header_t *image_get_fdt(ulong fdt_addr) +static const struct legacy_img_hdr *image_get_fdt(ulong fdt_addr) { - const image_header_t *fdt_hdr = map_sysmem(fdt_addr, 0); + const struct legacy_img_hdr *fdt_hdr = map_sysmem(fdt_addr, 0); image_print_contents(fdt_hdr); @@ -291,7 +291,7 @@ error: * other -ve value on other error */ -static int select_fdt(bootm_headers_t *images, const char *select, u8 arch, +static int select_fdt(struct bootm_headers *images, const char *select, u8 arch, ulong *fdt_addrp) { const char *buf; @@ -358,7 +358,7 @@ static int select_fdt(bootm_headers_t *images, const char *select, u8 arch, switch (genimg_get_format(buf)) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: { - const image_header_t *fdt_hdr; + const struct legacy_img_hdr *fdt_hdr; ulong load, load_end; ulong image_start, image_data, image_end; @@ -470,7 +470,7 @@ static int select_fdt(bootm_headers_t *images, const char *select, u8 arch, * of_flat_tree and of_size are set to 0 if no fdt exists */ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, - bootm_headers_t *images, char **of_flat_tree, ulong *of_size) + struct bootm_headers *images, char **of_flat_tree, ulong *of_size) { ulong img_addr; ulong fdt_addr; @@ -602,7 +602,7 @@ __weak int arch_fixup_fdt(void *blob) return 0; } -int image_setup_libfdt(bootm_headers_t *images, void *blob, +int image_setup_libfdt(struct bootm_headers *images, void *blob, int of_size, struct lmb *lmb) { ulong *initrd_start = &images->initrd_start; @@ -669,6 +669,7 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob, struct event_ft_fixup fixup; fixup.tree = oftree_default(); + fixup.images = images; ret = event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup)); if (ret) { printf("ERROR: fdt fixup event failed: %d\n", ret); diff --git a/boot/image-fit.c b/boot/image-fit.c index f16eab9df3..6e503f827d 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -1969,8 +1969,8 @@ static int fit_image_select(const void *fit, int rd_noffset, int verify) return 0; } -int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name, - ulong addr) +int fit_get_node_from_config(struct bootm_headers *images, + const char *prop_name, ulong addr) { int cfg_noffset; void *fit_hdr; @@ -2031,7 +2031,7 @@ static const char *fit_get_image_type_property(int type) return "unknown"; } -int fit_image_load(bootm_headers_t *images, ulong addr, +int fit_image_load(struct bootm_headers *images, ulong addr, const char **fit_unamep, const char **fit_uname_configp, int arch, int image_type, int bootstage_id, enum fit_load_op load_op, ulong *datap, ulong *lenp) @@ -2289,8 +2289,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr, return noffset; } -int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, - ulong *setup_start, ulong *setup_len) +int boot_get_setup_fit(struct bootm_headers *images, uint8_t arch, + ulong *setup_start, ulong *setup_len) { int noffset; ulong addr; @@ -2310,9 +2310,9 @@ int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, } #ifndef USE_HOSTCC -int boot_get_fdt_fit(bootm_headers_t *images, ulong addr, - const char **fit_unamep, const char **fit_uname_configp, - int arch, ulong *datap, ulong *lenp) +int boot_get_fdt_fit(struct bootm_headers *images, ulong addr, + const char **fit_unamep, const char **fit_uname_configp, + int arch, ulong *datap, ulong *lenp) { int fdt_noffset, cfg_noffset, count; const void *fit; diff --git a/boot/image.c b/boot/image.c index a0d0cc2403..9f95b3260a 100644 --- a/boot/image.c +++ b/boot/image.c @@ -220,11 +220,11 @@ static const struct table_info table_info[IH_COUNT] = { /*****************************************************************************/ /* Legacy format routines */ /*****************************************************************************/ -int image_check_hcrc(const image_header_t *hdr) +int image_check_hcrc(const struct legacy_img_hdr *hdr) { ulong hcrc; ulong len = image_get_header_size(); - image_header_t header; + struct legacy_img_hdr header; /* Copy header so we can blank CRC field for re-calculation */ memmove(&header, (char *)hdr, image_get_header_size()); @@ -235,7 +235,7 @@ int image_check_hcrc(const image_header_t *hdr) return (hcrc == image_get_hcrc(hdr)); } -int image_check_dcrc(const image_header_t *hdr) +int image_check_dcrc(const struct legacy_img_hdr *hdr) { ulong data = image_get_data(hdr); ulong len = image_get_data_size(hdr); @@ -257,7 +257,7 @@ int image_check_dcrc(const image_header_t *hdr) * returns: * number of components */ -ulong image_multi_count(const image_header_t *hdr) +ulong image_multi_count(const struct legacy_img_hdr *hdr) { ulong i, count = 0; uint32_t *size; @@ -290,7 +290,7 @@ ulong image_multi_count(const image_header_t *hdr) * data address and size of the component, if idx is valid * 0 in data and len, if idx is out of range */ -void image_multi_getimg(const image_header_t *hdr, ulong idx, +void image_multi_getimg(const struct legacy_img_hdr *hdr, ulong idx, ulong *data, ulong *len) { int i; @@ -326,7 +326,7 @@ void image_multi_getimg(const image_header_t *hdr, ulong idx, } } -static void image_print_type(const image_header_t *hdr) +static void image_print_type(const struct legacy_img_hdr *hdr) { const char __maybe_unused *os, *arch, *type, *comp; @@ -352,7 +352,7 @@ static void image_print_type(const image_header_t *hdr) */ void image_print_contents(const void *ptr) { - const image_header_t *hdr = (const image_header_t *)ptr; + const struct legacy_img_hdr *hdr = (const struct legacy_img_hdr *)ptr; const char __maybe_unused *p; p = IMAGE_INDENT_STRING; diff --git a/boot/vbe_simple.c b/boot/vbe_simple.c index 0fc57388f3..61b6322ebe 100644 --- a/boot/vbe_simple.c +++ b/boot/vbe_simple.c @@ -240,7 +240,7 @@ static int bootmeth_vbe_simple_ft_fixup(void *ctx, struct event *event) continue; /* Check if there is a node to fix up */ - node = ofnode_path_root(tree, "/chosen/fwupd"); + node = oftree_path(tree, "/chosen/fwupd"); if (!ofnode_valid(node)) continue; node = ofnode_find_subnode(node, dev->name); diff --git a/cmd/Kconfig b/cmd/Kconfig index 0e0be94f41..bfa12ce12a 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1092,7 +1092,6 @@ config CMD_PWM config CMD_GPT bool "GPT (GUID Partition Table) command" select EFI_PARTITION - select HAVE_BLOCK_DEVICE select PARTITION_UUIDS imply RANDOM_UUID help @@ -1194,6 +1193,13 @@ config CMD_LOADS help Load an S-Record file over serial line +config CMD_LOADXY_TIMEOUT + int "loadxy_timeout" + range 0 2000 + default 90 + help + Initial timeout for loadx and loady commands. Zero means infinity. + config CMD_LSBLK depends on BLK bool "lsblk - list block drivers and devices" @@ -1204,7 +1210,6 @@ config CMD_LSBLK config CMD_MBR bool "MBR (Master Boot Record) command" select DOS_PARTITION - select HAVE_BLOCK_DEVICE help Enable the 'mbr' command to ready and write MBR (Master Boot Record) style partition tables. @@ -1336,7 +1341,6 @@ config CMD_OSD config CMD_PART bool "part" depends on PARTITIONS - select HAVE_BLOCK_DEVICE select PARTITION_UUIDS help Read and display information about the partition table on @@ -1467,7 +1471,6 @@ config CMD_UNIVERSE config CMD_USB bool "usb" depends on USB_HOST - select HAVE_BLOCK_DEVICE help USB support. @@ -1507,7 +1510,6 @@ config CMD_PVBLOCK config CMD_VIRTIO bool "virtio" depends on VIRTIO - depends on HAVE_BLOCK_DEVICE default y if VIRTIO help VirtIO block device support @@ -1928,6 +1930,13 @@ config CMD_EFIDEBUG particularly for managing boot parameters as well as examining various EFI status for debugging. +config CMD_EFICONFIG + bool "eficonfig - provide menu-driven uefi variables maintenance interface" + depends on CMD_BOOTEFI_BOOTMGR + help + Enable the 'eficonfig' command which provides the menu-driven UEFI + variable maintenance interface. + config CMD_EXCEPTION bool "exception - raise exception" depends on ARM || RISCV || SANDBOX || X86 @@ -1971,6 +1980,12 @@ config CMD_GETTIME milliseconds. See also the 'bootstage' command which provides more flexibility for boot timing. +config CMD_PAUSE + bool "pause command" + help + Delay execution waiting for any user input. + Useful to allow the user to read a failure log. + config CMD_RNG bool "rng command" depends on DM_RNG @@ -2505,6 +2520,22 @@ config CMD_CBSYSINFO memory by coreboot before jumping to U-Boot. It can be useful for debugging the beaaviour of coreboot or U-Boot. +config CMD_CYCLIC + bool "cyclic - Show information about cyclic functions" + depends on CYCLIC + default y + help + This enables the 'cyclic' command which provides information about + cyclic execution functions. This infrastructure allows registering + functions to be executed cyclically, e.g. every 100ms. These commands + are supported: + + cyclic list - list cyclic functions + cyclic cyclic demo - register cyclic + demo function + + See doc/develop/cyclic.rst for more details. + config CMD_DIAG bool "diag - Board diagnostics" help diff --git a/cmd/Makefile b/cmd/Makefile index 6e87522b62..cf6ce1bd6f 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -18,7 +18,7 @@ obj-$(CONFIG_CMD_AES) += aes.o obj-$(CONFIG_CMD_AB_SELECT) += ab_select.o obj-$(CONFIG_CMD_ADC) += adc.o obj-$(CONFIG_CMD_ARMFLASH) += armflash.o -obj-$(CONFIG_HAVE_BLOCK_DEVICE) += blk_common.o +obj-$(CONFIG_BLK) += blk_common.o obj-$(CONFIG_CMD_BOOTDEV) += bootdev.o obj-$(CONFIG_CMD_BOOTFLOW) += bootflow.o obj-$(CONFIG_CMD_BOOTMETH) += bootmeth.o @@ -56,6 +56,7 @@ obj-$(CONFIG_CMD_DIAG) += diag.o endif obj-$(CONFIG_CMD_ADTIMG) += adtimg.o obj-$(CONFIG_CMD_ABOOTIMG) += abootimg.o +obj-$(CONFIG_CMD_CYCLIC) += cyclic.o obj-$(CONFIG_CMD_EVENT) += event.o obj-$(CONFIG_CMD_EXTENSION) += extension_board.o obj-$(CONFIG_CMD_ECHO) += echo.o @@ -63,6 +64,7 @@ obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o obj-$(CONFIG_CMD_EEPROM) += eeprom.o obj-$(CONFIG_EFI) += efi.o obj-$(CONFIG_CMD_EFIDEBUG) += efidebug.o +obj-$(CONFIG_CMD_EFICONFIG) += eficonfig.o obj-$(CONFIG_CMD_ELF) += elf.o obj-$(CONFIG_CMD_EROFS) += erofs.o obj-$(CONFIG_HUSH_PARSER) += exit.o @@ -102,6 +104,7 @@ obj-$(CONFIG_CMD_MFSL) += mfsl.o obj-$(CONFIG_CMD_MII) += mii.o obj-$(CONFIG_CMD_MISC) += misc.o obj-$(CONFIG_CMD_MDIO) += mdio.o +obj-$(CONFIG_CMD_PAUSE) += pause.o obj-$(CONFIG_CMD_SLEEP) += sleep.o obj-$(CONFIG_CMD_MMC) += mmc.o obj-$(CONFIG_CMD_OPTEE_RPMB) += optee_rpmb.o diff --git a/cmd/bcb.c b/cmd/bcb.c index 1bbd1fae99..1622a90c97 100644 --- a/cmd/bcb.c +++ b/cmd/bcb.c @@ -122,7 +122,7 @@ static int __bcb_load(int devnum, const char *partp) char *endp; int part, ret; - desc = blk_get_devnum_by_type(IF_TYPE_MMC, devnum); + desc = blk_get_devnum_by_uclass_id(UCLASS_MMC, devnum); if (!desc) { ret = -ENODEV; goto err_read_fail; @@ -287,7 +287,7 @@ static int __bcb_store(void) u64 cnt; int ret; - desc = blk_get_devnum_by_type(IF_TYPE_MMC, bcb_dev); + desc = blk_get_devnum_by_uclass_id(UCLASS_MMC, bcb_dev); if (!desc) { ret = -ENODEV; goto err; diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index 37cd8a57eb..af2e9757db 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -16,9 +16,16 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; +void bdinfo_print_size(const char *name, uint64_t size) +{ + printf("%-12s= ", name); + print_size(size, "\n"); +} + void bdinfo_print_num_l(const char *name, ulong value) { printf("%-12s= 0x%0*lx\n", name, 2 * (int)sizeof(value), value); @@ -123,7 +130,7 @@ int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) #if CONFIG_IS_ENABLED(MULTI_DTB_FIT) bdinfo_print_num_l("multi_dtb_fit", (ulong)gd->multi_dtb_fit); #endif - if (gd->fdt_blob) { + if (IS_ENABLED(CONFIG_LMB) && gd->fdt_blob) { struct lmb lmb; lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); diff --git a/cmd/blk_common.c b/cmd/blk_common.c index 4e442f2918..75a072caf5 100644 --- a/cmd/blk_common.c +++ b/cmd/blk_common.c @@ -12,10 +12,10 @@ #include #include -int blk_common_cmd(int argc, char *const argv[], enum if_type if_type, +int blk_common_cmd(int argc, char *const argv[], enum uclass_id uclass_id, int *cur_devnump) { - const char *if_name = blk_get_if_type_name(if_type); + const char *if_name = blk_get_uclass_name(uclass_id); switch (argc) { case 0: @@ -23,16 +23,16 @@ int blk_common_cmd(int argc, char *const argv[], enum if_type if_type, return CMD_RET_USAGE; case 2: if (strncmp(argv[1], "inf", 3) == 0) { - blk_list_devices(if_type); + blk_list_devices(uclass_id); return 0; } else if (strncmp(argv[1], "dev", 3) == 0) { - if (blk_print_device_num(if_type, *cur_devnump)) { + if (blk_print_device_num(uclass_id, *cur_devnump)) { printf("\nno %s devices available\n", if_name); return CMD_RET_FAILURE; } return 0; } else if (strncmp(argv[1], "part", 4) == 0) { - if (blk_list_part(if_type)) + if (blk_list_part(uclass_id)) printf("\nno %s partition table available\n", if_name); return 0; @@ -42,7 +42,7 @@ int blk_common_cmd(int argc, char *const argv[], enum if_type if_type, if (strncmp(argv[1], "dev", 3) == 0) { int dev = (int)dectoul(argv[2], NULL); - if (!blk_show_device(if_type, dev)) { + if (!blk_show_device(uclass_id, dev)) { *cur_devnump = dev; printf("... is now current device\n"); } else { @@ -52,7 +52,7 @@ int blk_common_cmd(int argc, char *const argv[], enum if_type if_type, } else if (strncmp(argv[1], "part", 4) == 0) { int dev = (int)dectoul(argv[2], NULL); - if (blk_print_part_devnum(if_type, dev)) { + if (blk_print_part_devnum(uclass_id, dev)) { printf("\n%s device %d not available\n", if_name, dev); return CMD_RET_FAILURE; @@ -71,7 +71,7 @@ int blk_common_cmd(int argc, char *const argv[], enum if_type if_type, printf("\n%s read: device %d block # "LBAFU", count %lu ... ", if_name, *cur_devnump, blk, cnt); - n = blk_read_devnum(if_type, *cur_devnump, blk, cnt, + n = blk_read_devnum(uclass_id, *cur_devnump, blk, cnt, (ulong *)addr); printf("%ld blocks read: %s\n", n, @@ -86,7 +86,7 @@ int blk_common_cmd(int argc, char *const argv[], enum if_type if_type, printf("\n%s write: device %d block # "LBAFU", count %lu ... ", if_name, *cur_devnump, blk, cnt); - n = blk_write_devnum(if_type, *cur_devnump, blk, cnt, + n = blk_write_devnum(uclass_id, *cur_devnump, blk, cnt, (ulong *)addr); printf("%ld blocks written: %s\n", n, diff --git a/cmd/boot.c b/cmd/boot.c index be67a5980d..14839c1ced 100644 --- a/cmd/boot.c +++ b/cmd/boot.c @@ -32,6 +32,7 @@ static int do_go(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) addr = hextoul(argv[1], NULL); printf ("## Starting application at 0x%08lX ...\n", addr); + flush(); /* * pass address parameter as argv[0] (aka command name), diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 8ab0ff5a64..3041873afb 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -281,7 +281,7 @@ efi_status_t efi_install_fdt(void *fdt) return EFI_SUCCESS; } #else - bootm_headers_t img = { 0 }; + struct bootm_headers img = { 0 }; efi_status_t ret; if (fdt == EFI_FDT_USE_INTERNAL) { diff --git a/cmd/booti.c b/cmd/booti.c index 397d4b8323..6ac39193db 100644 --- a/cmd/booti.c +++ b/cmd/booti.c @@ -21,7 +21,7 @@ DECLARE_GLOBAL_DATA_PTR; * Image booting support */ static int booti_start(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], bootm_headers_t *images) + char *const argv[], struct bootm_headers *images) { int ret; ulong ld; diff --git a/cmd/bootm.c b/cmd/bootm.c index 9fe8ce4a27..d764a27002 100644 --- a/cmd/bootm.c +++ b/cmd/bootm.c @@ -511,7 +511,7 @@ static int do_imls_nand(void) continue; for (off = 0; off < mtd->size; off += mtd->erasesize) { - const image_header_t *header; + const struct legacy_img_hdr *header; int ret; if (nand_block_isbad(mtd, off)) @@ -529,7 +529,7 @@ static int do_imls_nand(void) switch (genimg_get_format(buffer)) { #if defined(CONFIG_LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: - header = (const image_header_t *)buffer; + header = (const struct legacy_img_hdr *)buffer; len = image_get_image_size(header); nand_imls_legacyimage(mtd, nand_dev, off, len); diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 704d36debe..3340be1632 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -220,7 +220,7 @@ static int prepare_bootmenu_entry(struct bootmenu_data *menu, return 1; } -#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR)) +#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR)) && (CONFIG_IS_ENABLED(CMD_EFICONFIG)) /** * prepare_uefi_bootorder_entry() - generate the uefi bootmenu entries * @@ -340,11 +340,21 @@ static struct bootmenu_data *bootmenu_create(int delay) if (ret < 0) goto cleanup; -#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR)) +#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR)) && (CONFIG_IS_ENABLED(CMD_EFICONFIG)) if (i < MAX_COUNT - 1) { - ret = prepare_uefi_bootorder_entry(menu, &iter, &i); - if (ret < 0 && ret != -ENOENT) - goto cleanup; + efi_status_t efi_ret; + + /* + * UEFI specification requires booting from removal media using + * a architecture-specific default image name such as BOOTAA64.EFI. + */ + efi_ret = eficonfig_generate_media_device_boot_option(); + if (efi_ret != EFI_SUCCESS && efi_ret != EFI_NOT_FOUND) + goto cleanup; + + ret = prepare_uefi_bootorder_entry(menu, &iter, &i); + if (ret < 0 && ret != -ENOENT) + goto cleanup; } #endif diff --git a/cmd/bootz.c b/cmd/bootz.c index 4f024bde5f..f1423573d2 100644 --- a/cmd/bootz.c +++ b/cmd/bootz.c @@ -25,7 +25,7 @@ int __weak bootz_setup(ulong image, ulong *start, ulong *end) * zImage booting support */ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], bootm_headers_t *images) + char *const argv[], struct bootm_headers *images) { int ret; ulong zi_start, zi_end; diff --git a/cmd/cyclic.c b/cmd/cyclic.c new file mode 100644 index 0000000000..c1bc556aad --- /dev/null +++ b/cmd/cyclic.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * A general-purpose cyclic execution infrastructure, to allow "small" + * (run-time wise) functions to be executed at a specified frequency. + * Things like LED blinking or watchdog triggering are examples for such + * tasks. + * + * Copyright (C) 2022 Stefan Roese + */ + +#include +#include +#include +#include +#include +#include + +struct cyclic_demo_info { + uint delay_us; +}; + +static void cyclic_demo(void *ctx) +{ + struct cyclic_demo_info *info = ctx; + + /* Just a small dummy delay here */ + udelay(info->delay_us); +} + +static int do_cyclic_demo(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct cyclic_demo_info *info; + struct cyclic_info *cyclic; + uint time_ms; + + if (argc < 3) + return CMD_RET_USAGE; + + info = malloc(sizeof(struct cyclic_demo_info)); + if (!info) { + printf("out of memory\n"); + return CMD_RET_FAILURE; + } + + time_ms = simple_strtoul(argv[1], NULL, 0); + info->delay_us = simple_strtoul(argv[2], NULL, 0); + + /* Register demo cyclic function */ + cyclic = cyclic_register(cyclic_demo, time_ms * 1000, "cyclic_demo", + info); + if (!cyclic) + printf("Registering of cyclic_demo failed\n"); + + printf("Registered function \"%s\" to be executed all %dms\n", + "cyclic_demo", time_ms); + + return 0; +} + +static int do_cyclic_list(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct cyclic_info *cyclic, *tmp; + u64 cnt, freq; + + list_for_each_entry_safe(cyclic, tmp, cyclic_get_list(), list) { + cnt = cyclic->run_cnt * 1000000ULL * 100ULL; + freq = lldiv(cnt, timer_get_us() - cyclic->start_time_us); + printf("function: %s, cpu-time: %lld us, frequency: %lld.%02d times/s\n", + cyclic->name, cyclic->cpu_time_us, + lldiv(freq, 100), do_div(freq, 100)); + } + + return 0; +} + +static char cyclic_help_text[] = + "cyclic demo - register cyclic demo function\n" + "cyclic list - list cyclic functions\n"; + +U_BOOT_CMD_WITH_SUBCMDS(cyclic, "Cyclic", cyclic_help_text, + U_BOOT_SUBCMD_MKENT(demo, 3, 1, do_cyclic_demo), + U_BOOT_SUBCMD_MKENT(list, 1, 1, do_cyclic_list)); diff --git a/cmd/disk.c b/cmd/disk.c index cb3b990ba3..3d7bc2f601 100644 --- a/cmd/disk.c +++ b/cmd/disk.c @@ -20,7 +20,7 @@ int common_diskboot(struct cmd_tbl *cmdtp, const char *intf, int argc, ulong cnt; struct disk_partition info; #if defined(CONFIG_LEGACY_IMAGE_FORMAT) - image_header_t *hdr; + struct legacy_img_hdr *hdr; #endif struct blk_desc *dev_desc; @@ -68,7 +68,7 @@ int common_diskboot(struct cmd_tbl *cmdtp, const char *intf, int argc, switch (genimg_get_format((void *) addr)) { #if defined(CONFIG_LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *) addr; + hdr = (struct legacy_img_hdr *)addr; bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT); diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c new file mode 100644 index 0000000000..2595dd9563 --- /dev/null +++ b/cmd/eficonfig.c @@ -0,0 +1,2502 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Menu-driven UEFI Variable maintenance + * + * Copyright (c) 2022 Masahisa Kojima, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct efi_simple_text_input_protocol *cin; + +#define EFICONFIG_DESCRIPTION_MAX 32 +#define EFICONFIG_OPTIONAL_DATA_MAX 64 + +/** + * struct eficonfig_filepath_info - structure to be used to store file path + * + * @name: file or directory name + * @list: list structure + */ +struct eficonfig_filepath_info { + char *name; + struct list_head list; +}; + +/** + * struct eficonfig_boot_option - structure to be used for updating UEFI boot option + * + * @file_info: user selected file info + * @initrd_info: user selected initrd file info + * @boot_index: index of the boot option + * @description: pointer to the description string + * @optional_data: pointer to the optional_data + * @edit_completed: flag indicates edit complete + */ +struct eficonfig_boot_option { + struct eficonfig_select_file_info file_info; + struct eficonfig_select_file_info initrd_info; + unsigned int boot_index; + u16 *description; + u16 *optional_data; + bool edit_completed; +}; + +/** + * struct eficonfig_volume_entry_data - structure to be used to store volume info + * + * @file_info: pointer to file info structure + * @v: pointer to the protocol interface + * @dp: pointer to the device path + */ +struct eficonfig_volume_entry_data { + struct eficonfig_select_file_info *file_info; + struct efi_simple_file_system_protocol *v; + struct efi_device_path *dp; +}; + +/** + * struct eficonfig_file_entry_data - structure to be used to store file info + * + * @file_info: pointer to file info structure + * @is_directory: flag to identify the directory or file + * @file_name: name of directory or file + */ +struct eficonfig_file_entry_data { + struct eficonfig_select_file_info *file_info; + bool is_directory; + char *file_name; +}; + +/** + * struct eficonfig_boot_selection_data - structure to be used to select the boot option entry + * + * @boot_index: index of the boot option + * @selected: pointer to store the selected index in the BootOrder variable + */ +struct eficonfig_boot_selection_data { + u16 boot_index; + int *selected; +}; + +/** + * struct eficonfig_boot_order - structure to be used to update BootOrder variable + * + * @num: index in the menu entry + * @description: pointer to the description string + * @boot_index: boot option index + * @active: flag to include the boot option into BootOrder variable + * @list: list structure + */ +struct eficonfig_boot_order { + u32 num; + u16 *description; + u32 boot_index; + bool active; + struct list_head list; +}; + +/** + * eficonfig_print_msg() - print message + * + * display the message to the user, user proceeds the screen + * with any key press. + * + * @items: pointer to the structure of each menu entry + * @count: the number of menu entry + * @menu_header: pointer to the menu header string + * Return: status code + */ +void eficonfig_print_msg(char *msg) +{ + /* Flush input */ + while (tstc()) + getchar(); + + printf(ANSI_CURSOR_HIDE + ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION + "%s\n\n Press any key to continue", 3, 4, msg); + + getchar(); +} + +/** + * eficonfig_print_entry() - print each menu entry + * + * @data: pointer to the data associated with each menu entry + */ +static void eficonfig_print_entry(void *data) +{ + struct eficonfig_entry *entry = data; + int reverse = (entry->efi_menu->active == entry->num); + + /* TODO: support scroll or page for many entries */ + + /* + * Move cursor to line where the entry will be drawn (entry->num) + * First 3 lines(menu header) + 1 empty line + */ + printf(ANSI_CURSOR_POSITION, entry->num + 4, 7); + + if (reverse) + puts(ANSI_COLOR_REVERSE); + + printf("%s", entry->title); + + if (reverse) + puts(ANSI_COLOR_RESET); +} + +/** + * eficonfig_display_statusline() - print status line + * + * @m: pointer to the menu structure + */ +static void eficonfig_display_statusline(struct menu *m) +{ + struct eficonfig_entry *entry; + + if (menu_default_choice(m, (void *)&entry) < 0) + return; + + printf(ANSI_CURSOR_POSITION + "\n%s\n" + ANSI_CURSOR_POSITION ANSI_CLEAR_LINE ANSI_CURSOR_POSITION + " Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit" + ANSI_CLEAR_LINE_TO_END ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, + 1, 1, entry->efi_menu->menu_header, entry->efi_menu->count + 5, 1, + entry->efi_menu->count + 6, 1, entry->efi_menu->count + 7, 1); +} + +/** + * eficonfig_choice_entry() - user key input handler + * + * @data: pointer to the efimenu structure + * Return: key string to identify the selected entry + */ +static char *eficonfig_choice_entry(void *data) +{ + int esc = 0; + struct list_head *pos, *n; + struct eficonfig_entry *entry; + enum bootmenu_key key = KEY_NONE; + struct efimenu *efi_menu = data; + + while (1) { + bootmenu_loop((struct bootmenu_data *)efi_menu, &key, &esc); + + switch (key) { + case KEY_UP: + if (efi_menu->active > 0) + --efi_menu->active; + /* no menu key selected, regenerate menu */ + return NULL; + case KEY_DOWN: + if (efi_menu->active < efi_menu->count - 1) + ++efi_menu->active; + /* no menu key selected, regenerate menu */ + return NULL; + case KEY_SELECT: + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_entry, list); + if (entry->num == efi_menu->active) + return entry->key; + } + break; + case KEY_QUIT: + /* Quit by choosing the last entry */ + entry = list_last_entry(&efi_menu->list, struct eficonfig_entry, list); + return entry->key; + default: + /* Pressed key is not valid, no need to regenerate the menu */ + break; + } + } +} + +/** + * eficonfig_destroy() - destroy efimenu + * + * @efi_menu: pointer to the efimenu structure + */ +void eficonfig_destroy(struct efimenu *efi_menu) +{ + struct list_head *pos, *n; + struct eficonfig_entry *entry; + + if (!efi_menu) + return; + + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_entry, list); + free(entry->title); + list_del(&entry->list); + free(entry); + } + free(efi_menu->menu_header); + free(efi_menu); +} + +/** + * eficonfig_process_quit() - callback function for "Quit" entry + * + * @data: pointer to the data + * Return: status code + */ +efi_status_t eficonfig_process_quit(void *data) +{ + return EFI_ABORTED; +} + +/** + * append_entry() - append menu item + * + * @efi_menu: pointer to the efimenu structure + * @title: pointer to the entry title + * @func: callback of each entry + * @data: pointer to the data to be passed to each entry callback + * Return: status code + */ +static efi_status_t append_entry(struct efimenu *efi_menu, + char *title, eficonfig_entry_func func, void *data) +{ + struct eficonfig_entry *entry; + + if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX) + return EFI_OUT_OF_RESOURCES; + + entry = calloc(1, sizeof(struct eficonfig_entry)); + if (!entry) + return EFI_OUT_OF_RESOURCES; + + entry->title = title; + sprintf(entry->key, "%d", efi_menu->count); + entry->efi_menu = efi_menu; + entry->func = func; + entry->data = data; + entry->num = efi_menu->count++; + list_add_tail(&entry->list, &efi_menu->list); + + return EFI_SUCCESS; +} + +/** + * append_quit_entry() - append quit entry + * + * @efi_menu: pointer to the efimenu structure + * Return: status code + */ +static efi_status_t append_quit_entry(struct efimenu *efi_menu) +{ + char *title; + efi_status_t ret; + + title = strdup("Quit"); + if (!title) + return EFI_OUT_OF_RESOURCES; + + ret = append_entry(efi_menu, title, eficonfig_process_quit, NULL); + if (ret != EFI_SUCCESS) + free(title); + + return ret; +} + +/** + * eficonfig_create_fixed_menu() - create fixed entry menu structure + * + * @items: pointer to the menu entry item + * @count: the number of menu entry + * Return: pointer to the efimenu structure + */ +void *eficonfig_create_fixed_menu(const struct eficonfig_item *items, int count) +{ + u32 i; + char *title; + efi_status_t ret; + struct efimenu *efi_menu; + const struct eficonfig_item *iter = items; + + efi_menu = calloc(1, sizeof(struct efimenu)); + if (!efi_menu) + return NULL; + + INIT_LIST_HEAD(&efi_menu->list); + for (i = 0; i < count; i++, iter++) { + title = strdup(iter->title); + if (!title) + goto out; + + ret = append_entry(efi_menu, title, iter->func, iter->data); + if (ret != EFI_SUCCESS) { + free(title); + goto out; + } + } + + return efi_menu; +out: + eficonfig_destroy(efi_menu); + + return NULL; +} + +/** + * eficonfig_process_common() - main handler for UEFI menu + * + * Construct the structures required to show the menu, then handle + * the user input interacting with u-boot menu functions. + * + * @efi_menu: pointer to the efimenu structure + * @menu_header: pointer to the menu header string + * Return: status code + */ +efi_status_t eficonfig_process_common(struct efimenu *efi_menu, char *menu_header) +{ + struct menu *menu; + void *choice = NULL; + struct list_head *pos, *n; + struct eficonfig_entry *entry; + efi_status_t ret = EFI_SUCCESS; + + if (efi_menu->count > EFICONFIG_ENTRY_NUM_MAX) + return EFI_OUT_OF_RESOURCES; + + efi_menu->delay = -1; + efi_menu->active = 0; + + if (menu_header) { + efi_menu->menu_header = strdup(menu_header); + if (!efi_menu->menu_header) + return EFI_OUT_OF_RESOURCES; + } + + menu = menu_create(NULL, 0, 1, eficonfig_display_statusline, + eficonfig_print_entry, eficonfig_choice_entry, + efi_menu); + if (!menu) + return EFI_INVALID_PARAMETER; + + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_entry, list); + if (!menu_item_add(menu, entry->key, entry)) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + } + + entry = list_first_entry_or_null(&efi_menu->list, struct eficonfig_entry, list); + if (entry) + menu_default_set(menu, entry->key); + + printf(ANSI_CURSOR_HIDE + ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION, 1, 1); + + if (menu_get_choice(menu, &choice)) { + entry = choice; + if (entry->func) + ret = entry->func(entry->data); + } +out: + menu_destroy(menu); + + printf(ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION + ANSI_CURSOR_SHOW, 1, 1); + + return ret; +} + +/** + * eficonfig_volume_selected() - handler of volume selection + * + * @data: pointer to the data of selected entry + * Return: status code + */ +static efi_status_t eficonfig_volume_selected(void *data) +{ + struct eficonfig_volume_entry_data *info = data; + + if (info) { + info->file_info->current_volume = info->v; + info->file_info->dp_volume = info->dp; + } + + return EFI_SUCCESS; +} + +/** + * create_selected_device_path() - create device path + * + * @file_info: pointer to the selected file information + * Return: + * device path or NULL. Caller must free the returned value + */ +static +struct efi_device_path *create_selected_device_path(struct eficonfig_select_file_info *file_info) +{ + char *p; + void *buf; + efi_uintn_t fp_size; + struct efi_device_path *dp; + struct efi_device_path_file_path *fp; + + fp_size = sizeof(struct efi_device_path) + + ((u16_strlen(file_info->current_path) + 1) * sizeof(u16)); + buf = calloc(1, fp_size + sizeof(END)); + if (!buf) + return NULL; + + fp = buf; + fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE, + fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH, + fp->dp.length = (u16)fp_size; + u16_strcpy(fp->str, file_info->current_path); + + p = buf; + p += fp_size; + *((struct efi_device_path *)p) = END; + + dp = efi_dp_append(file_info->dp_volume, (struct efi_device_path *)buf); + free(buf); + + return dp; +} + +/** + * eficonfig_file_selected() - handler of file selection + * + * @data: pointer to the data of selected entry + * Return: status code + */ +static efi_status_t eficonfig_file_selected(void *data) +{ + u16 *tmp; + struct eficonfig_file_entry_data *info = data; + + if (!info) + return EFI_INVALID_PARAMETER; + + if (!strcmp(info->file_name, "..")) { + struct eficonfig_filepath_info *iter; + struct list_head *pos, *n; + int is_last; + char *filepath; + tmp = info->file_info->current_path; + + memset(info->file_info->current_path, 0, EFICONFIG_FILE_PATH_BUF_SIZE); + filepath = calloc(1, EFICONFIG_FILE_PATH_MAX); + if (!filepath) + return EFI_OUT_OF_RESOURCES; + + list_for_each_safe(pos, n, &info->file_info->filepath_list) { + iter = list_entry(pos, struct eficonfig_filepath_info, list); + + is_last = list_is_last(&iter->list, &info->file_info->filepath_list); + if (is_last) { + list_del(&iter->list); + free(iter->name); + free(iter); + break; + } + strlcat(filepath, iter->name, EFICONFIG_FILE_PATH_MAX); + } + utf8_utf16_strcpy(&tmp, filepath); + } else { + size_t new_len; + struct eficonfig_filepath_info *filepath_info; + + new_len = u16_strlen(info->file_info->current_path) + + strlen(info->file_name); + if (new_len >= EFICONFIG_FILE_PATH_MAX) { + eficonfig_print_msg("File path is too long!"); + return EFI_INVALID_PARAMETER; + } + tmp = &info->file_info->current_path[u16_strlen(info->file_info->current_path)]; + utf8_utf16_strcpy(&tmp, info->file_name); + + filepath_info = calloc(1, sizeof(struct eficonfig_filepath_info)); + if (!filepath_info) + return EFI_OUT_OF_RESOURCES; + + filepath_info->name = strdup(info->file_name); + if (!filepath_info->name) { + free(filepath_info); + return EFI_OUT_OF_RESOURCES; + } + list_add_tail(&filepath_info->list, &info->file_info->filepath_list); + + if (!info->is_directory) + info->file_info->file_selected = true; + } + + return EFI_SUCCESS; +} + +/** + * eficonfig_select_volume() - construct the volume selection menu + * + * @file_info: pointer to the file selection structure + * Return: status code + */ +static efi_status_t eficonfig_select_volume(struct eficonfig_select_file_info *file_info) +{ + u32 i; + efi_status_t ret; + efi_uintn_t count; + struct efimenu *efi_menu; + struct list_head *pos, *n; + struct efi_handler *handler; + struct eficonfig_entry *entry; + struct efi_device_path *device_path; + efi_handle_t *volume_handles = NULL; + struct efi_simple_file_system_protocol *v; + + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, &efi_simple_file_system_protocol_guid, + NULL, &count, (efi_handle_t **)&volume_handles); + if (ret != EFI_SUCCESS) { + eficonfig_print_msg("No block device found!"); + return ret; + } + + efi_menu = calloc(1, sizeof(struct efimenu)); + if (!efi_menu) + return EFI_OUT_OF_RESOURCES; + + INIT_LIST_HEAD(&efi_menu->list); + for (i = 0; i < count; i++) { + char *devname; + struct efi_block_io *block_io; + struct eficonfig_volume_entry_data *info; + + if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX - 1) + break; + + ret = efi_search_protocol(volume_handles[i], + &efi_simple_file_system_protocol_guid, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&v, efi_root, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + ret = efi_search_protocol(volume_handles[i], &efi_guid_device_path, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&device_path, + efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + ret = efi_search_protocol(volume_handles[i], &efi_block_io_guid, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&block_io, + efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + info = calloc(1, sizeof(struct eficonfig_volume_entry_data)); + if (!info) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + devname = calloc(1, BOOTMENU_DEVICE_NAME_MAX); + if (!devname) { + free(info); + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + ret = efi_disk_get_device_name(volume_handles[i], devname, + BOOTMENU_DEVICE_NAME_MAX); + if (ret != EFI_SUCCESS) { + free(info); + goto out; + } + + info->v = v; + info->dp = device_path; + info->file_info = file_info; + ret = append_entry(efi_menu, devname, eficonfig_volume_selected, info); + if (ret != EFI_SUCCESS) { + free(info); + goto out; + } + } + + ret = append_quit_entry(efi_menu); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_process_common(efi_menu, " ** Select Volume **"); +out: + efi_free_pool(volume_handles); + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_entry, list); + free(entry->data); + } + eficonfig_destroy(efi_menu); + + return ret; +} + +/** + * sort_file() - sort the file name in ascii order + * + * @data1: pointer to the file entry data + * @data2: pointer to the file entry data + * Return: -1 if the data1 file name is less than data2 file name, + * 0 if both file name match, + * 1 if the data1 file name is greater thant data2 file name. + */ +static int sort_file(const void *arg1, const void *arg2) +{ + const struct eficonfig_file_entry_data *data1, *data2; + + data1 = *((const struct eficonfig_file_entry_data **)arg1); + data2 = *((const struct eficonfig_file_entry_data **)arg2); + + return strcasecmp(data1->file_name, data2->file_name); +} + +/** + * eficonfig_create_file_entry() - construct the file menu entry + * + * @efi_menu: pointer to the efimenu structure + * @count: number of the directory and file + * @tmp_infos: pointer to the entry data array + * @f: pointer to the file handle + * @buf: pointer to the buffer to store the directory information + * @file_info: pointer to the file selection structure + * Return: status code + */ +static efi_status_t +eficonfig_create_file_entry(struct efimenu *efi_menu, u32 count, + struct eficonfig_file_entry_data **tmp_infos, + struct efi_file_handle *f, struct efi_file_info *buf, + struct eficonfig_select_file_info *file_info) +{ + char *name, *p; + efi_uintn_t len; + efi_status_t ret; + u32 i, entry_num = 0; + struct eficonfig_file_entry_data *info; + + efi_file_setpos_int(f, 0); + /* Read directory and construct menu structure */ + for (i = 0; i < count; i++) { + if (entry_num >= EFICONFIG_ENTRY_NUM_MAX - 1) + break; + + len = sizeof(struct efi_file_info) + EFICONFIG_FILE_PATH_BUF_SIZE; + ret = efi_file_read_int(f, &len, buf); + if (ret != EFI_SUCCESS || len == 0) + break; + + info = calloc(1, sizeof(struct eficonfig_file_entry_data)); + if (!info) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + /* append '\\' at the end of directory name */ + name = calloc(1, utf16_utf8_strlen(buf->file_name) + 2); + if (!name) { + ret = EFI_OUT_OF_RESOURCES; + free(info); + goto out; + } + p = name; + utf16_utf8_strcpy(&p, buf->file_name); + if (buf->attribute & EFI_FILE_DIRECTORY) { + /* filter out u'.' */ + if (!u16_strcmp(buf->file_name, u".")) { + free(info); + free(name); + continue; + } + name[u16_strlen(buf->file_name)] = '\\'; + info->is_directory = true; + } + + info->file_name = name; + info->file_info = file_info; + tmp_infos[entry_num++] = info; + } + + qsort(tmp_infos, entry_num, sizeof(*tmp_infos), + (int (*)(const void *, const void *))sort_file); + + for (i = 0; i < entry_num; i++) { + ret = append_entry(efi_menu, tmp_infos[i]->file_name, + eficonfig_file_selected, tmp_infos[i]); + if (ret != EFI_SUCCESS) + goto out; + } + +out: + return ret; +} + +/** + * eficonfig_select_file() - construct the file selection menu + * + * @file_info: pointer to the file selection structure + * @root: pointer to the file handle + * Return: status code + */ +static efi_status_t eficonfig_select_file(struct eficonfig_select_file_info *file_info, + struct efi_file_handle *root) +{ + u32 count = 0, i; + efi_uintn_t len; + efi_status_t ret; + struct efimenu *efi_menu; + struct efi_file_handle *f; + struct efi_file_info *buf; + struct eficonfig_file_entry_data **tmp_infos; + + buf = calloc(1, sizeof(struct efi_file_info) + EFICONFIG_FILE_PATH_BUF_SIZE); + if (!buf) + return EFI_OUT_OF_RESOURCES; + + while (!file_info->file_selected) { + efi_menu = calloc(1, sizeof(struct efimenu)); + if (!efi_menu) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + INIT_LIST_HEAD(&efi_menu->list); + + ret = efi_file_open_int(root, &f, file_info->current_path, EFI_FILE_MODE_READ, 0); + if (ret != EFI_SUCCESS) { + eficonfig_print_msg("Reading volume failed!"); + free(efi_menu); + ret = EFI_ABORTED; + goto out; + } + + /* Count the number of directory entries */ + for (;;) { + len = sizeof(struct efi_file_info) + EFICONFIG_FILE_PATH_BUF_SIZE; + ret = efi_file_read_int(f, &len, buf); + if (ret != EFI_SUCCESS || len == 0) + break; + + count++; + } + + /* allocate array to sort the entry */ + tmp_infos = calloc(count, sizeof(*tmp_infos)); + if (!tmp_infos) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + + ret = eficonfig_create_file_entry(efi_menu, count, tmp_infos, + f, buf, file_info); + if (ret != EFI_SUCCESS) + goto err; + + ret = append_quit_entry(efi_menu); + if (ret != EFI_SUCCESS) + goto err; + + ret = eficonfig_process_common(efi_menu, " ** Select File **"); +err: + efi_file_close_int(f); + eficonfig_destroy(efi_menu); + + if (tmp_infos) { + for (i = 0; i < count; i++) + free(tmp_infos[i]); + } + + free(tmp_infos); + + if (ret != EFI_SUCCESS) + break; + } + +out: + free(buf); + + return ret; +} + +/** + * handle_user_input() - handle user input + * + * @buf: pointer to the buffer + * @buf_size: size of the buffer + * @cursor_col: cursor column for user input + * @msg: pointer to the string to display + * Return: status code + */ +static efi_status_t handle_user_input(u16 *buf, int buf_size, + int cursor_col, char *msg) +{ + u16 *tmp; + efi_status_t ret; + + printf(ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION + "%s" + ANSI_CURSOR_POSITION + " Press ENTER to complete, ESC/CTRL+C to quit", + 0, 1, msg, 8, 1); + + /* tmp is used to accept user cancel */ + tmp = calloc(1, buf_size * sizeof(u16)); + if (!tmp) + return EFI_OUT_OF_RESOURCES; + + ret = efi_console_get_u16_string(cin, tmp, buf_size, NULL, 4, cursor_col); + if (ret == EFI_SUCCESS) + u16_strcpy(buf, tmp); + + free(tmp); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + +/** + * eficonfig_boot_add_enter_description() - handle user input for description + * + * @data: pointer to the internal boot option structure + * Return: status code + */ +static efi_status_t eficonfig_boot_add_enter_description(void *data) +{ + struct eficonfig_boot_option *bo = data; + + return handle_user_input(bo->description, EFICONFIG_DESCRIPTION_MAX, 22, + "\n ** Edit Description **\n" + "\n" + " enter description: "); +} + +/** + * eficonfig_boot_add_optional_data() - handle user input for optional data + * + * @data: pointer to the internal boot option structure + * Return: status code + */ +static efi_status_t eficonfig_boot_add_optional_data(void *data) +{ + struct eficonfig_boot_option *bo = data; + + return handle_user_input(bo->optional_data, EFICONFIG_OPTIONAL_DATA_MAX, 24, + "\n ** Edit Optional Data **\n" + "\n" + " enter optional data:"); +} + +/** + * eficonfig_boot_edit_save() - handler to save the boot option + * + * @data: pointer to the internal boot option structure + * Return: status code + */ +static efi_status_t eficonfig_boot_edit_save(void *data) +{ + struct eficonfig_boot_option *bo = data; + + if (u16_strlen(bo->description) == 0) { + eficonfig_print_msg("Boot Description is empty!"); + bo->edit_completed = false; + return EFI_NOT_READY; + } + if (u16_strlen(bo->file_info.current_path) == 0) { + eficonfig_print_msg("File is not selected!"); + bo->edit_completed = false; + return EFI_NOT_READY; + } + + bo->edit_completed = true; + + return EFI_SUCCESS; +} + +/** + * eficonfig_process_select_file() - callback function for "Select File" entry + * + * @data: pointer to the data + * Return: status code + */ +efi_status_t eficonfig_process_select_file(void *data) +{ + return EFI_SUCCESS; +} + +/** + * eficonfig_process_clear_file_selection() - callback function for "Clear" entry + * + * @data: pointer to the data + * Return: status code + */ +efi_status_t eficonfig_process_clear_file_selection(void *data) +{ + struct eficonfig_select_file_info *file_info = data; + + /* clear the existing file information */ + file_info->current_volume = NULL; + file_info->current_path[0] = u'\0'; + file_info->dp_volume = NULL; + + return EFI_ABORTED; +} + +static struct eficonfig_item select_file_menu_items[] = { + {"Select File", eficonfig_process_select_file}, + {"Clear", eficonfig_process_clear_file_selection}, + {"Quit", eficonfig_process_quit}, +}; + + +/** + * eficonfig_display_select_file_option() - display select file option + * + * @file_info: pointer to the file information structure + * Return: status code + */ +efi_status_t eficonfig_display_select_file_option(struct eficonfig_select_file_info *file_info) +{ + efi_status_t ret; + struct efimenu *efi_menu; + + select_file_menu_items[1].data = file_info; + efi_menu = eficonfig_create_fixed_menu(select_file_menu_items, + ARRAY_SIZE(select_file_menu_items)); + if (!efi_menu) + return EFI_OUT_OF_RESOURCES; + + ret = eficonfig_process_common(efi_menu, " ** Update File **"); + if (ret != EFI_SUCCESS) /* User selects "Clear" or "Quit" */ + ret = EFI_NOT_READY; + + eficonfig_destroy(efi_menu); + + return ret; +} + +/** + * eficonfig_select_file_handler() - handle user file selection + * + * @data: pointer to the data + * Return: status code + */ +efi_status_t eficonfig_select_file_handler(void *data) +{ + size_t len; + efi_status_t ret; + struct list_head *pos, *n; + struct efi_file_handle *root; + struct eficonfig_filepath_info *item; + struct eficonfig_select_file_info *tmp = NULL; + struct eficonfig_select_file_info *file_info = data; + + ret = eficonfig_display_select_file_option(file_info); + if (ret != EFI_SUCCESS) + return ret; + + tmp = calloc(1, sizeof(struct eficonfig_select_file_info)); + if (!tmp) + return EFI_OUT_OF_RESOURCES; + + tmp->current_path = calloc(1, EFICONFIG_FILE_PATH_BUF_SIZE); + if (!tmp->current_path) { + free(tmp); + return EFI_OUT_OF_RESOURCES; + } + INIT_LIST_HEAD(&tmp->filepath_list); + + while (!tmp->file_selected) { + tmp->current_volume = NULL; + memset(tmp->current_path, 0, EFICONFIG_FILE_PATH_BUF_SIZE); + + ret = eficonfig_select_volume(tmp); + if (ret != EFI_SUCCESS) + goto out; + + if (!tmp->current_volume) + return EFI_INVALID_PARAMETER; + + ret = efi_open_volume_int(tmp->current_volume, &root); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_select_file(tmp, root); + if (ret == EFI_ABORTED) + continue; + if (ret != EFI_SUCCESS) + goto out; + } + +out: + if (ret == EFI_SUCCESS) { + len = u16_strlen(tmp->current_path); + len = (len >= EFICONFIG_FILE_PATH_MAX) ? (EFICONFIG_FILE_PATH_MAX - 1) : len; + memcpy(file_info->current_path, tmp->current_path, len * sizeof(u16)); + file_info->current_path[len] = u'\0'; + file_info->current_volume = tmp->current_volume; + file_info->dp_volume = tmp->dp_volume; + } + + list_for_each_safe(pos, n, &tmp->filepath_list) { + item = list_entry(pos, struct eficonfig_filepath_info, list); + list_del(&item->list); + free(item->name); + free(item); + } + free(tmp->current_path); + free(tmp); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + +/** + * eficonfig_get_unused_bootoption() - get unused "Boot####" index + * + * @buf: pointer to the buffer to store boot option variable name + * @buf_size: buffer size + * @index: pointer to store the index in the BootOrder variable + * Return: status code + */ +efi_status_t eficonfig_get_unused_bootoption(u16 *buf, efi_uintn_t buf_size, + unsigned int *index) +{ + u32 i; + efi_status_t ret; + efi_uintn_t size; + + if (buf_size < u16_strsize(u"Boot####")) + return EFI_BUFFER_TOO_SMALL; + + for (i = 0; i <= 0xFFFF; i++) { + size = 0; + efi_create_indexed_name(buf, buf_size, "Boot", i); + ret = efi_get_variable_int(buf, &efi_global_variable_guid, + NULL, &size, NULL, NULL); + if (ret == EFI_BUFFER_TOO_SMALL) + continue; + else + break; + } + + if (i > 0xFFFF) + return EFI_OUT_OF_RESOURCES; + + *index = i; + + return EFI_SUCCESS; +} + +/** + * eficonfig_set_boot_option() - set boot option + * + * @varname: pointer to variable name + * @dp: pointer to device path + * @label: pointer to label string + * @optional_data: pointer to optional data + * Return: status code + */ +static efi_status_t eficonfig_set_boot_option(u16 *varname, struct efi_device_path *dp, + efi_uintn_t dp_size, u16 *label, char *optional_data) +{ + void *p = NULL; + efi_status_t ret; + efi_uintn_t size; + struct efi_load_option lo; + + lo.file_path = dp; + lo.file_path_length = dp_size; + lo.attributes = LOAD_OPTION_ACTIVE; + lo.optional_data = optional_data; + lo.label = label; + + size = efi_serialize_load_option(&lo, (u8 **)&p); + if (!size) + return EFI_INVALID_PARAMETER; + + ret = efi_set_variable_int(varname, &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, p, false); + free(p); + + return ret; +} + +/** + * eficonfig_append_bootorder() - append new boot option in BootOrder variable + * + * @index: "Boot####" index to append to BootOrder variable + * Return: status code + */ +efi_status_t eficonfig_append_bootorder(u16 index) +{ + u16 *bootorder; + efi_status_t ret; + u16 *new_bootorder = NULL; + efi_uintn_t last, size, new_size; + + /* append new boot option */ + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + last = size / sizeof(u16); + new_size = size + sizeof(u16); + new_bootorder = calloc(1, new_size); + if (!new_bootorder) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + memcpy(new_bootorder, bootorder, size); + new_bootorder[last] = index; + + ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + new_size, new_bootorder, false); + if (ret != EFI_SUCCESS) + goto out; + +out: + free(bootorder); + free(new_bootorder); + + return ret; +} + +/** + * create_boot_option_entry() - create boot option entry + * + * @efi_menu: pointer to the efimenu structure + * @title: pointer to the entry title + * @val: pointer to boot option label + * @func: callback of each entry + * @data: pointer to the data to be passed to each entry callback + * Return: status code + */ +static efi_status_t create_boot_option_entry(struct efimenu *efi_menu, char *title, u16 *val, + eficonfig_entry_func func, void *data) +{ + u32 len; + char *p, *buf; + + len = strlen(title) + 1; + if (val) + len += utf16_utf8_strlen(val); + buf = calloc(1, len); + if (!buf) + return EFI_OUT_OF_RESOURCES; + + strcpy(buf, title); + if (val) { + p = buf + strlen(title); + utf16_utf8_strcpy(&p, val); + } + + return append_entry(efi_menu, buf, func, data); +} + +/** + * prepare_file_selection_entry() - prepare file selection entry + * + * @efi_menu: pointer to the efimenu structure + * @title: pointer to the title string + * @file_info: pointer to the file info + * Return: status code + */ +static efi_status_t prepare_file_selection_entry(struct efimenu *efi_menu, char *title, + struct eficonfig_select_file_info *file_info) +{ + u32 len; + efi_status_t ret; + u16 *file_name = NULL, *p; + efi_handle_t handle; + char *devname; + + devname = calloc(1, EFICONFIG_VOLUME_PATH_MAX + 1); + if (!devname) + return EFI_OUT_OF_RESOURCES; + + /* get the device name only when the user already selected the file path */ + handle = efi_dp_find_obj(file_info->dp_volume, NULL, NULL); + if (handle) { + ret = efi_disk_get_device_name(handle, devname, EFICONFIG_VOLUME_PATH_MAX); + if (ret != EFI_SUCCESS) + goto out; + } + + /* + * If the preconfigured volume does not exist in the system, display the text + * converted volume device path instead of U-Boot friendly name(e.g. "usb 0:1"). + */ + if (!handle && file_info->dp_volume) { + u16 *dp_str; + char *q = devname; + + dp_str = efi_dp_str(file_info->dp_volume); + if (dp_str) + utf16_utf8_strncpy(&q, dp_str, EFICONFIG_VOLUME_PATH_MAX); + + efi_free_pool(dp_str); + } + + /* append u'/' to devname, it is just for display purpose. */ + if (file_info->current_path[0] != u'\0' && file_info->current_path[0] != u'/') + strlcat(devname, "/", EFICONFIG_VOLUME_PATH_MAX + 1); + + len = strlen(devname); + len += utf16_utf8_strlen(file_info->current_path) + 1; + file_name = calloc(1, len * sizeof(u16)); + if (!file_name) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + p = file_name; + utf8_utf16_strcpy(&p, devname); + u16_strlcat(file_name, file_info->current_path, len); + ret = create_boot_option_entry(efi_menu, title, file_name, + eficonfig_select_file_handler, file_info); +out: + free(devname); + free(file_name); + + return ret; +} + +/** + * eficonfig_show_boot_option() - prepare menu entry for editing boot option + * + * Construct the structures to create edit boot option menu + * + * @bo: pointer to the boot option + * @header_str: pointer to the header string + * Return: status code + */ +static efi_status_t eficonfig_show_boot_option(struct eficonfig_boot_option *bo, + char *header_str) +{ + efi_status_t ret; + struct efimenu *efi_menu; + + efi_menu = calloc(1, sizeof(struct efimenu)); + if (!efi_menu) + return EFI_OUT_OF_RESOURCES; + + INIT_LIST_HEAD(&efi_menu->list); + + ret = create_boot_option_entry(efi_menu, "Description: ", bo->description, + eficonfig_boot_add_enter_description, bo); + if (ret != EFI_SUCCESS) + goto out; + + ret = prepare_file_selection_entry(efi_menu, "File: ", &bo->file_info); + if (ret != EFI_SUCCESS) + goto out; + + ret = prepare_file_selection_entry(efi_menu, "Initrd File: ", &bo->initrd_info); + if (ret != EFI_SUCCESS) + goto out; + + ret = create_boot_option_entry(efi_menu, "Optional Data: ", bo->optional_data, + eficonfig_boot_add_optional_data, bo); + if (ret != EFI_SUCCESS) + goto out; + + ret = create_boot_option_entry(efi_menu, "Save", NULL, + eficonfig_boot_edit_save, bo); + if (ret != EFI_SUCCESS) + goto out; + + ret = create_boot_option_entry(efi_menu, "Quit", NULL, + eficonfig_process_quit, NULL); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_process_common(efi_menu, header_str); +out: + eficonfig_destroy(efi_menu); + + return ret; +} + +/** + * fill_file_info() - fill the file info from efi_device_path structure + * + * @dp: pointer to the device path + * @file_info: pointer to the file info structure + * @device_dp: pointer to the volume device path + */ +static void fill_file_info(struct efi_device_path *dp, + struct eficonfig_select_file_info *file_info, + struct efi_device_path *device_dp) +{ + u16 *file_str, *p; + struct efi_device_path *file_dp = NULL; + + efi_dp_split_file_path(dp, &device_dp, &file_dp); + file_info->dp_volume = device_dp; + + if (file_dp) { + file_str = efi_dp_str(file_dp); + /* + * efi_convert_device_path_to_text() automatically adds u'/' at the + * beginning of file name, remove u'/' before copying to current_path + */ + p = file_str; + if (p[0] == u'/') + p++; + + u16_strcpy(file_info->current_path, p); + efi_free_pool(file_dp); + efi_free_pool(file_str); + } +} + +/** + * eficonfig_edit_boot_option() - prepare boot option structure for editing + * + * Construct the boot option structure and copy the existing value + * + * @varname: pointer to the UEFI variable name + * @bo: pointer to the boot option + * @load_option: pointer to the load option + * @load_option_size: size of the load option + * @header_str: pointer to the header string + * Return : status code + */ +static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_boot_option *bo, + void *load_option, efi_uintn_t load_option_size, + char *header_str) +{ + size_t len; + efi_status_t ret; + char *tmp = NULL, *p; + struct efi_load_option lo = {0}; + efi_uintn_t final_dp_size; + struct efi_device_path *dp = NULL; + efi_uintn_t size = load_option_size; + struct efi_device_path *final_dp = NULL; + struct efi_device_path *device_dp = NULL; + struct efi_device_path *initrd_dp = NULL; + struct efi_device_path *initrd_device_dp = NULL; + + const struct efi_initrd_dp id_dp = { + .vendor = { + { + DEVICE_PATH_TYPE_MEDIA_DEVICE, + DEVICE_PATH_SUB_TYPE_VENDOR_PATH, + sizeof(id_dp.vendor), + }, + EFI_INITRD_MEDIA_GUID, + }, + .end = { + DEVICE_PATH_TYPE_END, + DEVICE_PATH_SUB_TYPE_END, + sizeof(id_dp.end), + } + }; + + bo->file_info.current_path = calloc(1, EFICONFIG_FILE_PATH_BUF_SIZE); + if (!bo->file_info.current_path) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + bo->initrd_info.current_path = calloc(1, EFICONFIG_FILE_PATH_BUF_SIZE); + if (!bo->file_info.current_path) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + bo->description = calloc(1, EFICONFIG_DESCRIPTION_MAX * sizeof(u16)); + if (!bo->description) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + bo->optional_data = calloc(1, EFICONFIG_OPTIONAL_DATA_MAX * sizeof(u16)); + if (!bo->optional_data) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + /* copy the preset value */ + if (load_option) { + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) + goto out; + + if (!lo.label) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + /* truncate the long label string */ + if (u16_strlen(lo.label) >= EFICONFIG_DESCRIPTION_MAX) + lo.label[EFICONFIG_DESCRIPTION_MAX - 1] = u'\0'; + + u16_strcpy(bo->description, lo.label); + + /* EFI image file path is a first instance */ + if (lo.file_path) + fill_file_info(lo.file_path, &bo->file_info, device_dp); + + /* Initrd file path(optional) is placed at second instance. */ + initrd_dp = efi_dp_from_lo(&lo, &efi_lf2_initrd_guid); + if (initrd_dp) { + fill_file_info(initrd_dp, &bo->initrd_info, initrd_device_dp); + efi_free_pool(initrd_dp); + } + + if (size > 0) + memcpy(bo->optional_data, lo.optional_data, size); + } + + while (1) { + ret = eficonfig_show_boot_option(bo, header_str); + if (ret == EFI_SUCCESS && bo->edit_completed) + break; + if (ret == EFI_NOT_READY) + continue; + if (ret != EFI_SUCCESS) + goto out; + } + + if (bo->initrd_info.dp_volume) { + dp = create_selected_device_path(&bo->initrd_info); + if (!dp) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + initrd_dp = efi_dp_append((const struct efi_device_path *)&id_dp, dp); + efi_free_pool(dp); + } + + dp = create_selected_device_path(&bo->file_info); + if (!dp) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + final_dp_size = efi_dp_size(dp) + sizeof(END); + if (initrd_dp) { + final_dp = efi_dp_concat(dp, initrd_dp); + final_dp_size += efi_dp_size(initrd_dp) + sizeof(END); + } else { + final_dp = efi_dp_dup(dp); + } + efi_free_pool(dp); + + if (!final_dp) + goto out; + + if (utf16_utf8_strlen(bo->optional_data)) { + len = utf16_utf8_strlen(bo->optional_data) + 1; + tmp = calloc(1, len); + if (!tmp) + goto out; + p = tmp; + utf16_utf8_strncpy(&p, bo->optional_data, u16_strlen(bo->optional_data)); + } + + ret = eficonfig_set_boot_option(varname, final_dp, final_dp_size, bo->description, tmp); + if (ret != EFI_SUCCESS) + goto out; +out: + free(tmp); + free(bo->optional_data); + free(bo->description); + free(bo->file_info.current_path); + free(bo->initrd_info.current_path); + efi_free_pool(device_dp); + efi_free_pool(initrd_device_dp); + efi_free_pool(initrd_dp); + efi_free_pool(final_dp); + + return ret; +} + +/** + * eficonfig_process_add_boot_option() - handler to add boot option + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_add_boot_option(void *data) +{ + u16 varname[9]; + efi_status_t ret; + struct eficonfig_boot_option *bo = NULL; + + bo = calloc(1, sizeof(struct eficonfig_boot_option)); + if (!bo) + return EFI_OUT_OF_RESOURCES; + + ret = eficonfig_get_unused_bootoption(varname, sizeof(varname), &bo->boot_index); + if (ret != EFI_SUCCESS) + return ret; + + ret = eficonfig_edit_boot_option(varname, bo, NULL, 0, " ** Add Boot Option ** "); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_append_bootorder((u16)bo->boot_index); + if (ret != EFI_SUCCESS) + goto out; + +out: + free(bo); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_SUCCESS : ret; + + return ret; +} + +/** + * eficonfig_process_boot_selected() - handler to select boot option entry + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_boot_selected(void *data) +{ + struct eficonfig_boot_selection_data *info = data; + + if (info) + *info->selected = info->boot_index; + + return EFI_SUCCESS; +} + +/** + * search_bootorder() - search the boot option index in BootOrder + * + * @bootorder: pointer to the BootOrder variable + * @num: number of BootOrder entry + * @target: target boot option index to search + * @index: pointer to store the index of BootOrder variable + * Return: true if exists, false otherwise + */ +static bool search_bootorder(u16 *bootorder, efi_uintn_t num, u32 target, u32 *index) +{ + u32 i; + + for (i = 0; i < num; i++) { + if (target == bootorder[i]) { + if (index) + *index = i; + + return true; + } + } + + return false; +} + +/** + * eficonfig_add_boot_selection_entry() - add boot option menu entry + * + * @efi_menu: pointer to store the efimenu structure + * @boot_index: boot option index to be added + * @selected: pointer to store the selected boot option index + * Return: status code + */ +static efi_status_t eficonfig_add_boot_selection_entry(struct efimenu *efi_menu, + unsigned int boot_index, + unsigned int *selected) +{ + char *buf, *p; + efi_status_t ret; + efi_uintn_t size; + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + struct eficonfig_boot_selection_data *info; + + efi_create_indexed_name(varname, sizeof(varname), "Boot", boot_index); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) + return EFI_SUCCESS; + + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) { + log_warning("Invalid load option for %ls\n", varname); + free(load_option); + return ret; + } + + if (size >= sizeof(efi_guid_t) && + !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated)) { + /* + * auto generated entry has GUID in optional_data, + * skip auto generated entry because it will be generated + * again even if it is edited or deleted. + */ + free(load_option); + return EFI_SUCCESS; + } + + info = calloc(1, sizeof(struct eficonfig_boot_selection_data)); + if (!info) { + free(load_option); + return EFI_OUT_OF_RESOURCES; + } + + buf = calloc(1, utf16_utf8_strlen(lo.label) + 1); + if (!buf) { + free(load_option); + free(info); + return EFI_OUT_OF_RESOURCES; + } + p = buf; + utf16_utf8_strcpy(&p, lo.label); + info->boot_index = boot_index; + info->selected = selected; + ret = append_entry(efi_menu, buf, eficonfig_process_boot_selected, info); + if (ret != EFI_SUCCESS) { + free(load_option); + free(info); + return ret; + } + free(load_option); + + return EFI_SUCCESS; +} + +/** + * eficonfig_show_boot_selection() - construct boot option menu entry + * + * @selected: pointer to store the selected boot option index + * Return: status code + */ +static efi_status_t eficonfig_show_boot_selection(unsigned int *selected) +{ + u32 i; + u16 *bootorder; + efi_status_t ret; + efi_uintn_t num, size; + struct efimenu *efi_menu; + struct list_head *pos, *n; + struct eficonfig_entry *entry; + + efi_menu = calloc(1, sizeof(struct efimenu)); + if (!efi_menu) + return EFI_OUT_OF_RESOURCES; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + + INIT_LIST_HEAD(&efi_menu->list); + num = size / sizeof(u16); + /* list the load option in the order of BootOrder variable */ + for (i = 0; i < num; i++) { + ret = eficonfig_add_boot_selection_entry(efi_menu, bootorder[i], selected); + if (ret != EFI_SUCCESS) + goto out; + + if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX - 1) + break; + } + + /* list the remaining load option not included in the BootOrder */ + for (i = 0; i <= 0xFFFF; i++) { + /* If the index is included in the BootOrder, skip it */ + if (search_bootorder(bootorder, num, i, NULL)) + continue; + + ret = eficonfig_add_boot_selection_entry(efi_menu, i, selected); + if (ret != EFI_SUCCESS) + goto out; + + if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX - 1) + break; + } + + ret = append_quit_entry(efi_menu); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_process_common(efi_menu, " ** Select Boot Option **"); +out: + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_entry, list); + free(entry->data); + } + eficonfig_destroy(efi_menu); + + return ret; +} + +/** + * eficonfig_process_edit_boot_option() - handler to edit boot option + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_edit_boot_option(void *data) +{ + efi_status_t ret; + efi_uintn_t size; + struct eficonfig_boot_option *bo = NULL; + + while (1) { + unsigned int selected; + void *load_option; + u16 varname[] = u"Boot####"; + + ret = eficonfig_show_boot_selection(&selected); + if (ret != EFI_SUCCESS) + break; + + bo = calloc(1, sizeof(struct eficonfig_boot_option)); + if (!bo) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + bo->boot_index = selected; + efi_create_indexed_name(varname, sizeof(varname), "Boot", selected); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) { + free(bo); + ret = EFI_NOT_FOUND; + goto out; + } + + ret = eficonfig_edit_boot_option(varname, bo, load_option, size, + " ** Edit Boot Option ** "); + + free(load_option); + free(bo); + if (ret != EFI_SUCCESS && ret != EFI_ABORTED) + break; + } +out: + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + +/** + * eficonfig_display_change_boot_order() - display the BootOrder list + * + * @efi_menu: pointer to the efimenu structure + * Return: status code + */ +static void eficonfig_display_change_boot_order(struct efimenu *efi_menu) +{ + bool reverse; + struct list_head *pos, *n; + struct eficonfig_boot_order *entry; + + printf(ANSI_CLEAR_CONSOLE ANSI_CURSOR_POSITION + "\n ** Change Boot Order **\n" + ANSI_CURSOR_POSITION + " Press UP/DOWN to move, +/- to change order" + ANSI_CURSOR_POSITION + " Press SPACE to activate or deactivate the entry" + ANSI_CURSOR_POSITION + " Select [Save] to complete, ESC/CTRL+C to quit" + ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, + 1, 1, efi_menu->count + 5, 1, efi_menu->count + 6, 1, + efi_menu->count + 7, 1, efi_menu->count + 8, 1); + + /* draw boot option list */ + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + reverse = (entry->num == efi_menu->active); + + printf(ANSI_CURSOR_POSITION, entry->num + 4, 7); + + if (reverse) + puts(ANSI_COLOR_REVERSE); + + if (entry->num < efi_menu->count - 2) { + if (entry->active) + printf("[*] "); + else + printf("[ ] "); + } + + printf("%ls", entry->description); + + if (reverse) + puts(ANSI_COLOR_RESET); + } +} + +/** + * eficonfig_choice_change_boot_order() - handle the BootOrder update + * + * @efi_menu: pointer to the efimenu structure + * Return: status code + */ +static efi_status_t eficonfig_choice_change_boot_order(struct efimenu *efi_menu) +{ + int esc = 0; + struct list_head *pos, *n; + struct eficonfig_boot_order *tmp; + enum bootmenu_key key = KEY_NONE; + struct eficonfig_boot_order *entry; + + while (1) { + bootmenu_loop(NULL, &key, &esc); + + switch (key) { + case KEY_PLUS: + if (efi_menu->active > 0) { + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + if (entry->num == efi_menu->active) + break; + } + tmp = list_entry(pos->prev, struct eficonfig_boot_order, list); + entry->num--; + tmp->num++; + list_del(&tmp->list); + list_add(&tmp->list, &entry->list); + } + fallthrough; + case KEY_UP: + if (efi_menu->active > 0) + --efi_menu->active; + return EFI_NOT_READY; + case KEY_MINUS: + if (efi_menu->active < efi_menu->count - 3) { + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + if (entry->num == efi_menu->active) + break; + } + tmp = list_entry(pos->next, struct eficonfig_boot_order, list); + entry->num++; + tmp->num--; + list_del(&entry->list); + list_add(&entry->list, &tmp->list); + + ++efi_menu->active; + } + return EFI_NOT_READY; + case KEY_DOWN: + if (efi_menu->active < efi_menu->count - 1) + ++efi_menu->active; + return EFI_NOT_READY; + case KEY_SELECT: + /* "Save" */ + if (efi_menu->active == efi_menu->count - 2) + return EFI_SUCCESS; + + /* "Quit" */ + if (efi_menu->active == efi_menu->count - 1) + return EFI_ABORTED; + + break; + case KEY_SPACE: + if (efi_menu->active < efi_menu->count - 2) { + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + if (entry->num == efi_menu->active) { + entry->active = entry->active ? false : true; + return EFI_NOT_READY; + } + } + } + break; + case KEY_QUIT: + return EFI_ABORTED; + default: + /* Pressed key is not valid, no need to regenerate the menu */ + break; + } + } +} + +/** + * eficonfig_add_change_boot_order_entry() - add boot order entry + * + * @efi_menu: pointer to the efimenu structure + * @boot_index: boot option index to be added + * @active: flag to include the boot option into BootOrder + * Return: status code + */ +static efi_status_t eficonfig_add_change_boot_order_entry(struct efimenu *efi_menu, + u32 boot_index, bool active) +{ + efi_status_t ret; + efi_uintn_t size; + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + struct eficonfig_boot_order *entry; + + efi_create_indexed_name(varname, sizeof(varname), "Boot", boot_index); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) + return EFI_SUCCESS; + + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) { + free(load_option); + return ret; + } + + entry = calloc(1, sizeof(struct eficonfig_boot_order)); + if (!entry) { + free(load_option); + return EFI_OUT_OF_RESOURCES; + } + + entry->description = u16_strdup(lo.label); + if (!entry->description) { + free(load_option); + free(entry); + return EFI_OUT_OF_RESOURCES; + } + entry->num = efi_menu->count++; + entry->boot_index = boot_index; + entry->active = active; + list_add_tail(&entry->list, &efi_menu->list); + + free(load_option); + + return EFI_SUCCESS; +} + +/** + * eficonfig_create_change_boot_order_entry() - create boot order entry + * + * @efi_menu: pointer to the efimenu structure + * @bootorder: pointer to the BootOrder variable + * @num: number of BootOrder entry + * Return: status code + */ +static efi_status_t eficonfig_create_change_boot_order_entry(struct efimenu *efi_menu, + u16 *bootorder, efi_uintn_t num) +{ + u32 i; + efi_status_t ret; + struct eficonfig_boot_order *entry; + + /* list the load option in the order of BootOrder variable */ + for (i = 0; i < num; i++) { + if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX - 2) + break; + + ret = eficonfig_add_change_boot_order_entry(efi_menu, bootorder[i], true); + if (ret != EFI_SUCCESS) + goto out; + } + + /* list the remaining load option not included in the BootOrder */ + for (i = 0; i < 0xFFFF; i++) { + if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX - 2) + break; + + /* If the index is included in the BootOrder, skip it */ + if (search_bootorder(bootorder, num, i, NULL)) + continue; + + ret = eficonfig_add_change_boot_order_entry(efi_menu, i, false); + if (ret != EFI_SUCCESS) + goto out; + } + + /* add "Save" and "Quit" entries */ + entry = calloc(1, sizeof(struct eficonfig_boot_order)); + if (!entry) + goto out; + + entry->num = efi_menu->count++; + entry->description = u16_strdup(u"Save"); + list_add_tail(&entry->list, &efi_menu->list); + + entry = calloc(1, sizeof(struct eficonfig_boot_order)); + if (!entry) + goto out; + + entry->num = efi_menu->count++; + entry->description = u16_strdup(u"Quit"); + list_add_tail(&entry->list, &efi_menu->list); + + efi_menu->active = 0; + + return EFI_SUCCESS; +out: + return EFI_OUT_OF_RESOURCES; +} + +/** + * eficonfig_process_change_boot_order() - handler to change boot order + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_change_boot_order(void *data) +{ + u32 count; + u16 *bootorder; + efi_status_t ret; + efi_uintn_t num, size; + struct list_head *pos, *n; + struct eficonfig_boot_order *entry; + struct efimenu *efi_menu; + + efi_menu = calloc(1, sizeof(struct efimenu)); + if (!efi_menu) + return EFI_OUT_OF_RESOURCES; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + + INIT_LIST_HEAD(&efi_menu->list); + num = size / sizeof(u16); + ret = eficonfig_create_change_boot_order_entry(efi_menu, bootorder, num); + if (ret != EFI_SUCCESS) + goto out; + + while (1) { + eficonfig_display_change_boot_order(efi_menu); + + ret = eficonfig_choice_change_boot_order(efi_menu); + if (ret == EFI_SUCCESS) { + u16 *new_bootorder; + + new_bootorder = calloc(1, (efi_menu->count - 2) * sizeof(u16)); + if (!new_bootorder) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + /* create new BootOrder */ + count = 0; + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + if (entry->active) + new_bootorder[count++] = entry->boot_index; + } + + size = count * sizeof(u16); + ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, new_bootorder, false); + + free(new_bootorder); + goto out; + } else if (ret == EFI_NOT_READY) { + continue; + } else { + goto out; + } + } +out: + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + list_del(&entry->list); + free(entry->description); + free(entry); + } + + free(bootorder); + free(efi_menu); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + +/** + * delete_boot_option() - delete selected boot option + * + * @boot_index: boot option index to delete + * Return: status code + */ +static efi_status_t delete_boot_option(u16 boot_index) +{ + u16 *bootorder; + u16 varname[9]; + efi_status_t ret; + unsigned int index; + efi_uintn_t num, size; + + efi_create_indexed_name(varname, sizeof(varname), + "Boot", boot_index); + ret = efi_set_variable_int(varname, &efi_global_variable_guid, + 0, 0, NULL, false); + if (ret != EFI_SUCCESS) { + log_err("delete boot option(%ls) failed\n", varname); + return ret; + } + + /* update BootOrder if necessary */ + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + if (!bootorder) + return EFI_SUCCESS; + + num = size / sizeof(u16); + if (!search_bootorder(bootorder, num, boot_index, &index)) + return EFI_SUCCESS; + + memmove(&bootorder[index], &bootorder[index + 1], + (num - index - 1) * sizeof(u16)); + size -= sizeof(u16); + ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, bootorder, false); + + return ret; +} + +/** + * eficonfig_process_delete_boot_option() - handler to delete boot option + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_delete_boot_option(void *data) +{ + efi_status_t ret; + unsigned int selected; + + while (1) { + ret = eficonfig_show_boot_selection(&selected); + if (ret == EFI_SUCCESS) + ret = delete_boot_option(selected); + + if (ret != EFI_SUCCESS) + break; + } + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + +/** + * eficonfig_enumerate_boot_option() - enumerate the possible bootable media + * + * @opt: pointer to the media boot option structure + * @volume_handles: pointer to the efi handles + * @count: number of efi handle + * Return: status code + */ +efi_status_t eficonfig_enumerate_boot_option(struct eficonfig_media_boot_option *opt, + efi_handle_t *volume_handles, efi_status_t count) +{ + u32 i; + struct efi_handler *handler; + efi_status_t ret = EFI_SUCCESS; + + for (i = 0; i < count; i++) { + u16 *p; + u16 dev_name[BOOTMENU_DEVICE_NAME_MAX]; + char *optional_data; + struct efi_load_option lo; + char buf[BOOTMENU_DEVICE_NAME_MAX]; + struct efi_device_path *device_path; + + ret = efi_search_protocol(volume_handles[i], &efi_guid_device_path, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&device_path, + efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + ret = efi_disk_get_device_name(volume_handles[i], buf, BOOTMENU_DEVICE_NAME_MAX); + if (ret != EFI_SUCCESS) + continue; + + p = dev_name; + utf8_utf16_strncpy(&p, buf, strlen(buf)); + + lo.label = dev_name; + lo.attributes = LOAD_OPTION_ACTIVE; + lo.file_path = device_path; + lo.file_path_length = efi_dp_size(device_path) + sizeof(END); + /* + * Set the dedicated guid to optional_data, it is used to identify + * the boot option that automatically generated by the bootmenu. + * efi_serialize_load_option() expects optional_data is null-terminated + * utf8 string, so set the "1234567" string to allocate enough space + * to store guid, instead of realloc the load_option. + */ + lo.optional_data = "1234567"; + opt[i].size = efi_serialize_load_option(&lo, (u8 **)&opt[i].lo); + if (!opt[i].size) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + /* set the guid */ + optional_data = (char *)opt[i].lo + (opt[i].size - u16_strsize(u"1234567")); + memcpy(optional_data, &efi_guid_bootmenu_auto_generated, sizeof(efi_guid_t)); + } + +out: + return ret; +} + +/** + * eficonfig_delete_invalid_boot_option() - delete non-existing boot option + * + * @opt: pointer to the media boot option structure + * @count: number of media boot option structure + * Return: status code + */ +efi_status_t eficonfig_delete_invalid_boot_option(struct eficonfig_media_boot_option *opt, + efi_status_t count) +{ + u32 i, j; + efi_uintn_t size; + efi_status_t ret; + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + + for (i = 0; i <= 0xFFFF; i++) { + efi_uintn_t tmp; + + efi_create_indexed_name(varname, sizeof(varname), "Boot", i); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) + continue; + + tmp = size; + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) + goto next; + + if (size >= sizeof(efi_guid_bootmenu_auto_generated)) { + if (guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated) == 0) { + for (j = 0; j < count; j++) { + if (opt[j].size == tmp && + memcmp(opt[j].lo, load_option, tmp) == 0) { + opt[j].exist = true; + break; + } + } + + if (j == count) { + ret = delete_boot_option(i); + if (ret != EFI_SUCCESS) { + free(load_option); + goto out; + } + } + } + } +next: + free(load_option); + } + +out: + return ret; +} + +/** + * eficonfig_generate_media_device_boot_option() - generate the media device boot option + * + * This function enumerates all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL + * and generate the bootmenu entries. + * This function also provide the BOOT#### variable maintenance for + * the media device entries. + * - Automatically create the BOOT#### variable for the newly detected device, + * this BOOT#### variable is distinguished by the special GUID + * stored in the EFI_LOAD_OPTION.optional_data + * - If the device is not attached to the system, the associated BOOT#### variable + * is automatically deleted. + * + * Return: status code + */ +efi_status_t eficonfig_generate_media_device_boot_option(void) +{ + u32 i; + efi_status_t ret; + efi_uintn_t count; + efi_handle_t *volume_handles = NULL; + struct eficonfig_media_boot_option *opt = NULL; + + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, &efi_simple_file_system_protocol_guid, + NULL, &count, (efi_handle_t **)&volume_handles); + if (ret != EFI_SUCCESS) + return ret; + + opt = calloc(count, sizeof(struct eficonfig_media_boot_option)); + if (!opt) + goto out; + + /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */ + ret = eficonfig_enumerate_boot_option(opt, volume_handles, count); + if (ret != EFI_SUCCESS) + goto out; + + /* + * System hardware configuration may vary depending on the user setup. + * The boot option is automatically added by the bootmenu. + * If the device is not attached to the system, the boot option needs + * to be deleted. + */ + ret = eficonfig_delete_invalid_boot_option(opt, count); + if (ret != EFI_SUCCESS) + goto out; + + /* add non-existent boot option */ + for (i = 0; i < count; i++) { + u32 boot_index; + u16 var_name[9]; + + if (!opt[i].exist) { + ret = eficonfig_get_unused_bootoption(var_name, sizeof(var_name), + &boot_index); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_set_variable_int(var_name, &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + opt[i].size, opt[i].lo, false); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_append_bootorder(boot_index); + if (ret != EFI_SUCCESS) { + efi_set_variable_int(var_name, &efi_global_variable_guid, + 0, 0, NULL, false); + goto out; + } + } + } + +out: + if (opt) { + for (i = 0; i < count; i++) + free(opt[i].lo); + } + free(opt); + efi_free_pool(volume_handles); + + return ret; +} + +/** + * eficonfig_init() - do required initialization for eficonfig command + * + * Return: status code + */ +static efi_status_t eficonfig_init(void) +{ + efi_status_t ret = EFI_SUCCESS; + static bool init; + struct efi_handler *handler; + + if (!init) { + ret = efi_search_protocol(efi_root, &efi_guid_text_input_protocol, &handler); + if (ret != EFI_SUCCESS) + return ret; + + ret = efi_protocol_open(handler, (void **)&cin, efi_root, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + return ret; + } + + init = true; + + return ret; +} + +static const struct eficonfig_item maintenance_menu_items[] = { + {"Add Boot Option", eficonfig_process_add_boot_option}, + {"Edit Boot Option", eficonfig_process_edit_boot_option}, + {"Change Boot Order", eficonfig_process_change_boot_order}, + {"Delete Boot Option", eficonfig_process_delete_boot_option}, + {"Quit", eficonfig_process_quit}, +}; + +/** + * do_eficonfig() - execute `eficonfig` command + * + * @cmdtp: table entry describing command + * @flag: bitmap indicating how the command was invoked + * @argc: number of arguments + * @argv: command line arguments + * Return: status code + */ +static int do_eficonfig(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + efi_status_t ret; + struct efimenu *efi_menu; + + if (argc > 1) + return CMD_RET_USAGE; + + ret = efi_init_obj_list(); + if (ret != EFI_SUCCESS) { + log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n", + ret & ~EFI_ERROR_MASK); + + return CMD_RET_FAILURE; + } + + ret = eficonfig_init(); + if (ret != EFI_SUCCESS) + return CMD_RET_FAILURE; + + ret = eficonfig_generate_media_device_boot_option(); + if (ret != EFI_SUCCESS && ret != EFI_NOT_FOUND) + return ret; + + while (1) { + efi_menu = eficonfig_create_fixed_menu(maintenance_menu_items, + ARRAY_SIZE(maintenance_menu_items)); + if (!efi_menu) + return CMD_RET_FAILURE; + + ret = eficonfig_process_common(efi_menu, " ** UEFI Maintenance Menu **"); + eficonfig_destroy(efi_menu); + + if (ret == EFI_ABORTED) + break; + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + eficonfig, 1, 0, do_eficonfig, + "provide menu-driven UEFI variable maintenance interface", + "" +); diff --git a/cmd/elf.c b/cmd/elf.c index ce40d3f72a..b7b9f506a5 100644 --- a/cmd/elf.c +++ b/cmd/elf.c @@ -72,6 +72,7 @@ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) return rcode; printf("## Starting application at 0x%08lx ...\n", addr); + flush(); /* * pass address parameter as argv[0] (aka command name), @@ -274,6 +275,7 @@ int do_bootvx(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) puts("## Not an ELF image, assuming binary\n"); printf("## Starting vxWorks at 0x%08lx ...\n", addr); + flush(); dcache_disable(); #if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI) diff --git a/cmd/fastboot.c b/cmd/fastboot.c index 033a2c95e8..dd223b1554 100644 --- a/cmd/fastboot.c +++ b/cmd/fastboot.c @@ -76,7 +76,7 @@ static int do_fastboot_usb(int argc, char *const argv[], break; if (ctrlc()) break; - WATCHDOG_RESET(); + schedule(); usb_gadget_handle_interrupts(controller_index); } diff --git a/cmd/fpga.c b/cmd/fpga.c index 9cf7651d8c..8c64e957db 100644 --- a/cmd/fpga.c +++ b/cmd/fpga.c @@ -288,7 +288,7 @@ static int do_fpga_loadmk(struct cmd_tbl *cmdtp, int flag, int argc, #if defined(CONFIG_LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: { - image_header_t *hdr = (image_header_t *)fpga_data; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)fpga_data; ulong data; u8 comp; diff --git a/cmd/ide.c b/cmd/ide.c index b78c38e159..6739f0b12d 100644 --- a/cmd/ide.c +++ b/cmd/ide.c @@ -37,7 +37,7 @@ int do_ide(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) } } - return blk_common_cmd(argc, argv, IF_TYPE_IDE, &curr_device); + return blk_common_cmd(argc, argv, UCLASS_IDE, &curr_device); } int do_diskboot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) diff --git a/cmd/load.c b/cmd/load.c index e44ae0d56b..5c4f34781d 100644 --- a/cmd/load.c +++ b/cmd/load.c @@ -83,6 +83,7 @@ static int do_load_serial(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ENTER ...\n", load_baudrate); udelay(50000); + flush(); gd->baudrate = load_baudrate; serial_setbrg(); udelay(50000); @@ -126,6 +127,7 @@ static int do_load_serial(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ESC ...\n", current_baudrate); udelay(50000); + flush(); gd->baudrate = current_baudrate; serial_setbrg(); udelay(50000); @@ -317,6 +319,7 @@ int do_save_serial(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ESC ...\n", (int)current_baudrate); udelay(50000); + flush(); gd->baudrate = current_baudrate; serial_setbrg(); udelay(50000); @@ -471,6 +474,7 @@ static int do_load_serial_bin(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ENTER ...\n", load_baudrate); udelay(50000); + flush(); gd->baudrate = load_baudrate; serial_setbrg(); udelay(50000); @@ -533,6 +537,7 @@ static int do_load_serial_bin(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ESC ...\n", current_baudrate); udelay(50000); + flush(); gd->baudrate = current_baudrate; serial_setbrg(); udelay(50000); diff --git a/cmd/lsblk.c b/cmd/lsblk.c index 6a1c8f5ef4..d214dafc3b 100644 --- a/cmd/lsblk.c +++ b/cmd/lsblk.c @@ -36,7 +36,7 @@ static int do_lsblk(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv continue; desc = dev_get_uclass_plat(udev); printf("%c %s %u", i ? ',' : ':', - blk_get_if_type_name(desc->if_type), + blk_get_uclass_name(desc->uclass_id), desc->devnum); i++; } diff --git a/cmd/mem.c b/cmd/mem.c index 6a7b4014ed..1e39348195 100644 --- a/cmd/mem.c +++ b/cmd/mem.c @@ -300,7 +300,7 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc, /* reset watchdog from time to time */ if ((ngood % (64 << 10)) == 0) - WATCHDOG_RESET(); + schedule(); } unmap_sysmem(buf1); unmap_sysmem(buf2); @@ -848,7 +848,7 @@ static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr, } } addr[test_offset] = pattern; - WATCHDOG_RESET(); + schedule(); /* * Check for addr bits stuck low or shorted. @@ -890,7 +890,7 @@ static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr, * Fill memory with a known pattern. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { - WATCHDOG_RESET(); + schedule(); addr[offset] = pattern; } @@ -898,7 +898,7 @@ static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr, * Check each location and invert it for the second pass. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { - WATCHDOG_RESET(); + schedule(); temp = addr[offset]; if (temp != pattern) { printf("\nFAILURE (read/write) @ 0x%.8lx:" @@ -918,7 +918,7 @@ static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr, * Check each location for the inverted pattern and zero it. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { - WATCHDOG_RESET(); + schedule(); anti_pattern = ~pattern; temp = addr[offset]; if (temp != anti_pattern) { @@ -972,7 +972,7 @@ static ulong test_bitflip_comparison(volatile unsigned long *bufa, for (k = 0; k < max; k++) { q = 0x00000001L << k; for (j = 0; j < 8; j++) { - WATCHDOG_RESET(); + schedule(); q = ~q; p1 = (volatile unsigned long *)bufa; p2 = (volatile unsigned long *)bufb; @@ -1033,7 +1033,7 @@ static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr, pattern, ""); for (addr = buf, val = pattern; addr < end; addr++) { - WATCHDOG_RESET(); + schedule(); *addr = val; val += incr; } @@ -1041,7 +1041,7 @@ static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr, puts("Reading..."); for (addr = buf, val = pattern; addr < end; addr++) { - WATCHDOG_RESET(); + schedule(); readback = *addr; if (readback != val) { ulong offset = addr - buf; diff --git a/cmd/mmc.c b/cmd/mmc.c index 7bd4cd9e01..c79d940798 100644 --- a/cmd/mmc.c +++ b/cmd/mmc.c @@ -154,7 +154,7 @@ static struct mmc *__init_mmc_device(int dev, bool force_init, #ifdef CONFIG_BLOCK_CACHE struct blk_desc *bd = mmc_get_blk_desc(mmc); - blkcache_invalidate(bd->if_type, bd->devnum); + blkcache_invalidate(bd->uclass_id, bd->devnum); #endif return mmc; @@ -331,13 +331,13 @@ static int do_mmcrpmb(struct cmd_tbl *cmdtp, int flag, #else original_part = mmc_get_blk_desc(mmc)->hwpart; #endif - if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, MMC_PART_RPMB) != + if (blk_select_hwpart_devnum(UCLASS_MMC, curr_device, MMC_PART_RPMB) != 0) return CMD_RET_FAILURE; ret = cp->cmd(cmdtp, flag, argc, argv); /* Return to original partition */ - if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, original_part) != + if (blk_select_hwpart_devnum(UCLASS_MMC, curr_device, original_part) != 0) return CMD_RET_FAILURE; return ret; @@ -530,7 +530,7 @@ static int do_mmc_part(struct cmd_tbl *cmdtp, int flag, if (!mmc) return CMD_RET_FAILURE; - mmc_dev = blk_get_devnum_by_type(IF_TYPE_MMC, curr_device); + mmc_dev = blk_get_devnum_by_uclass_id(UCLASS_MMC, curr_device); if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) { part_print(mmc_dev); return CMD_RET_SUCCESS; @@ -580,7 +580,7 @@ static int do_mmc_dev(struct cmd_tbl *cmdtp, int flag, if (!mmc) return CMD_RET_FAILURE; - ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part); + ret = blk_select_hwpart_devnum(UCLASS_MMC, dev, part); printf("switch to partitions #%d, %s\n", part, (!ret) ? "OK" : "ERROR"); if (ret) diff --git a/cmd/mvebu/bubt.c b/cmd/mvebu/bubt.c index 7e6e47f40d..1efbe2e607 100644 --- a/cmd/mvebu/bubt.c +++ b/cmd/mvebu/bubt.c @@ -425,7 +425,7 @@ static size_t usb_read_file(const char *file_name) } /* Try to recognize storage devices immediately */ - blk_first_device(IF_TYPE_USB, &dev); + blk_first_device(UCLASS_USB, &dev); if (!dev) { printf("Error: USB storage device not found\n"); return 0; diff --git a/cmd/nand.c b/cmd/nand.c index e730484d0b..5bb43794e9 100644 --- a/cmd/nand.c +++ b/cmd/nand.c @@ -975,7 +975,7 @@ static int nand_load_image(struct cmd_tbl *cmdtp, struct mtd_info *mtd, char *s; size_t cnt; #if defined(CONFIG_LEGACY_IMAGE_FORMAT) - image_header_t *hdr; + struct legacy_img_hdr *hdr; #endif #if defined(CONFIG_FIT) const void *fit_hdr = NULL; @@ -1004,7 +1004,7 @@ static int nand_load_image(struct cmd_tbl *cmdtp, struct mtd_info *mtd, switch (genimg_get_format ((void *)addr)) { #if defined(CONFIG_LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *)addr; + hdr = (struct legacy_img_hdr *)addr; bootstage_mark(BOOTSTAGE_ID_NAND_TYPE); image_print_contents (hdr); diff --git a/cmd/nvme.c b/cmd/nvme.c index e715c570a3..09d5f438fb 100644 --- a/cmd/nvme.c +++ b/cmd/nvme.c @@ -28,7 +28,7 @@ static int do_nvme(struct cmd_tbl *cmdtp, int flag, int argc, if (strncmp(argv[1], "deta", 4) == 0) { struct udevice *udev; - ret = blk_get_device(IF_TYPE_NVME, nvme_curr_dev, + ret = blk_get_device(UCLASS_NVME, nvme_curr_dev, &udev); if (ret < 0) return CMD_RET_FAILURE; @@ -39,7 +39,7 @@ static int do_nvme(struct cmd_tbl *cmdtp, int flag, int argc, } } - return blk_common_cmd(argc, argv, IF_TYPE_NVME, &nvme_curr_dev); + return blk_common_cmd(argc, argv, UCLASS_NVME, &nvme_curr_dev); } U_BOOT_CMD( diff --git a/cmd/pause.c b/cmd/pause.c new file mode 100644 index 0000000000..c97833c0d7 --- /dev/null +++ b/cmd/pause.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2021 + * Samuel Dionne-Riel + */ + +#include +#include + +static int do_pause(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + char *message = "Press any key to continue..."; + + if (argc == 2) + message = argv[1]; + + /* No newline, so it sticks to the bottom of the screen */ + printf("%s", message); + + /* Wait on "any" key... */ + (void) getchar(); + + /* Since there was no newline, we need it now */ + printf("\n"); + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(pause, 2, 1, do_pause, + "delay until user input", + "[prompt] - Wait until users presses any key. [prompt] can be used to customize the message.\n" +); diff --git a/cmd/pvblock.c b/cmd/pvblock.c index 56ce8b18d5..1b604c3737 100644 --- a/cmd/pvblock.c +++ b/cmd/pvblock.c @@ -14,7 +14,7 @@ static int pvblock_curr_device; int do_pvblock(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - return blk_common_cmd(argc, argv, IF_TYPE_PVBLOCK, + return blk_common_cmd(argc, argv, UCLASS_PVBLOCK, &pvblock_curr_device); } diff --git a/cmd/sata.c b/cmd/sata.c index 76da1906b7..9c9fe111d1 100644 --- a/cmd/sata.c +++ b/cmd/sata.c @@ -27,7 +27,7 @@ int sata_remove(int devnum) struct udevice *dev; int rc; - blk_unbind_all(IF_TYPE_SATA); + blk_unbind_all(UCLASS_AHCI); rc = uclass_find_device(UCLASS_AHCI, devnum, &dev); if (!rc && !dev) @@ -111,7 +111,7 @@ static int do_sata(struct cmd_tbl *cmdtp, int flag, int argc, sata_curr_device = 0; } - return blk_common_cmd(argc, argv, IF_TYPE_SATA, &sata_curr_device); + return blk_common_cmd(argc, argv, UCLASS_AHCI, &sata_curr_device); } U_BOOT_CMD( diff --git a/cmd/scsi.c b/cmd/scsi.c index 5f710d2895..4549995ba7 100644 --- a/cmd/scsi.c +++ b/cmd/scsi.c @@ -50,7 +50,7 @@ static int do_scsi(struct cmd_tbl *cmdtp, int flag, int argc, } } - return blk_common_cmd(argc, argv, IF_TYPE_SCSI, &scsi_curr_dev); + return blk_common_cmd(argc, argv, UCLASS_SCSI, &scsi_curr_dev); } U_BOOT_CMD( diff --git a/cmd/source.c b/cmd/source.c index 81e015b64e..698d9f86d9 100644 --- a/cmd/source.c +++ b/cmd/source.c @@ -46,7 +46,7 @@ int image_source_script(ulong addr, const char *fit_uname) { ulong len; #if defined(CONFIG_LEGACY_IMAGE_FORMAT) - const image_header_t *hdr; + const struct legacy_img_hdr *hdr; #endif u32 *data; int verify; diff --git a/cmd/usb.c b/cmd/usb.c index 3d87376525..2ba056982c 100644 --- a/cmd/usb.c +++ b/cmd/usb.c @@ -719,7 +719,7 @@ static int do_usb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (strncmp(argv[1], "stor", 4) == 0) return usb_stor_info(); - return blk_common_cmd(argc, argv, IF_TYPE_USB, &usb_stor_curr_dev); + return blk_common_cmd(argc, argv, UCLASS_USB, &usb_stor_curr_dev); #else return CMD_RET_USAGE; #endif /* CONFIG_USB_STORAGE */ diff --git a/cmd/usb_mass_storage.c b/cmd/usb_mass_storage.c index d4e619b842..b7daaa6e8e 100644 --- a/cmd/usb_mass_storage.c +++ b/cmd/usb_mass_storage.c @@ -231,7 +231,7 @@ static int do_usb_mass_storage(struct cmd_tbl *cmdtp, int flag, goto cleanup_register; } - WATCHDOG_RESET(); + schedule(); } cleanup_register: diff --git a/cmd/virtio.c b/cmd/virtio.c index ea3ed2e631..ec87d4f02c 100644 --- a/cmd/virtio.c +++ b/cmd/virtio.c @@ -40,7 +40,7 @@ static int do_virtio(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_SUCCESS; } - return blk_common_cmd(argc, argv, IF_TYPE_VIRTIO, &virtio_curr_dev); + return blk_common_cmd(argc, argv, UCLASS_VIRTIO, &virtio_curr_dev); } U_BOOT_CMD( diff --git a/cmd/ximg.c b/cmd/ximg.c index f84141ff45..1c40fd27a0 100644 --- a/cmd/ximg.c +++ b/cmd/ximg.c @@ -42,7 +42,7 @@ do_imgextract(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int part = 0; #if defined(CONFIG_LEGACY_IMAGE_FORMAT) ulong count; - image_header_t *hdr = NULL; + struct legacy_img_hdr *hdr = NULL; #endif #if defined(CONFIG_FIT) const char *uname = NULL; @@ -78,7 +78,7 @@ do_imgextract(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) printf("## Copying part %d from legacy image " "at %08lx ...\n", part, addr); - hdr = (image_header_t *)addr; + hdr = (struct legacy_img_hdr *)addr; if (!image_check_magic(hdr)) { printf("Bad Magic Number\n"); return 1; @@ -197,7 +197,7 @@ do_imgextract(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) while (l > 0) { tail = (l > CHUNKSZ) ? CHUNKSZ : l; - WATCHDOG_RESET(); + schedule(); memmove(to, from, tail); to += tail; from += tail; diff --git a/common/Kconfig b/common/Kconfig index ebee856e56..6608a4f0fc 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -186,6 +186,12 @@ config PRE_CON_BUF_ADDR We should consider removing this option and allocating the memory in board_init_f_init_reserve() instead. +config CONSOLE_FLUSH_SUPPORT + bool "Enable console flush support" + default y + help + This enables compilation of flush() function for console flush support. + config CONSOLE_MUX bool "Enable console multiplexing" default y if DM_VIDEO || VIDEO || LCD @@ -545,13 +551,33 @@ config DISPLAY_BOARDINFO_LATE menu "Start-up hooks" +config CYCLIC + bool "General-purpose cyclic execution mechanism" + help + This enables a general-purpose cyclic execution infrastructure, + to allow "small" (run-time wise) functions to be executed at + a specified frequency. Things like LED blinking or watchdog + triggering are examples for such tasks. + +if CYCLIC + +config CYCLIC_MAX_CPU_TIME_US + int "Sets the max allowed time for a cyclic function in us" + default 1000 + help + The max allowed time for a cyclic function in us. If a functions + takes longer than this duration this function will get unregistered + automatically. + +endif # CYCLIC + config EVENT bool "General-purpose event-handling mechanism" default y if SANDBOX help This enables sending and processing of events, to allow interested parties to be alerted when something happens. This is an attempt to - step the flow of weak functions, hooks, functions in board_f.c + stem the flow of weak functions, hooks, functions in board_f.c and board_r.c and the Kconfig options below. See doc/develop/event.rst for more information. @@ -671,6 +697,27 @@ config ID_EEPROM A number of different systems and vendors enable a vendor-specified EEPROM that contains various identifying features. +config SYS_EEPROM_BUS_NUM + int "I2C bus number of the system identifier EEPROM" + depends on ID_EEPROM + default 0 + +choice + prompt "EEPROM starts with 'CCID' or 'NXID'" + depends on ID_EEPROM && (PPC || ARCH_LS1021A || FSL_LAYERSCAPE) + default SYS_I2C_EEPROM_NXID + help + Specify if the Freescale / NXP ID EEPROM starts with 'CCID' or 'NXID' + ASCII literal string. + +config SYS_I2C_EEPROM_CCID + bool "EEPROM starts with 'CCID'" + +config SYS_I2C_EEPROM_NXID + bool "EEPROM starts with 'NXID'" + +endchoice + config PCI_INIT_R bool "Enumerate PCI buses during init" depends on PCI diff --git a/common/Makefile b/common/Makefile index 2ed8672c3a..1d56c9f289 100644 --- a/common/Makefile +++ b/common/Makefile @@ -84,6 +84,7 @@ obj-y += malloc_simple.o endif endif +obj-$(CONFIG_CYCLIC) += cyclic.o obj-$(CONFIG_$(SPL_TPL_)EVENT) += event.o obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o diff --git a/common/board_f.c b/common/board_f.c index 18e2246733..3df4efeeff 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +57,7 @@ #include #include #include +#include /* * Pointer to initial global data area @@ -113,14 +115,14 @@ static int init_func_watchdog_init(void) hw_watchdog_init(); puts(" Watchdog enabled\n"); # endif - WATCHDOG_RESET(); + schedule(); return 0; } int init_func_watchdog_reset(void) { - WATCHDOG_RESET(); + schedule(); return 0; } @@ -215,6 +217,36 @@ static int announce_dram_init(void) return 0; } +/* + * From input size calculate its nearest rounded unit scale (multiply of 2^10) + * and value in calculated unit scale multiplied by 10 (as fractional fixed + * point number with one decimal digit), which is human natural format, + * same what uses print_size() function for displaying. Mathematically it is: + * round_nearest(val * 2^scale) = size * 10; where: 10 <= val < 10240. + * + * For example for size=87654321 we calculate scale=20 and val=836 which means + * that input has natural human format 83.6 M (mega = 2^20). + */ +#define compute_size_scale_val(size, scale, val) do { \ + scale = ilog2(size) / 10 * 10; \ + val = (10 * size + ((1ULL << scale) >> 1)) >> scale; \ + if (val == 10240) { val = 10; scale += 10; } \ +} while (0) + +/* + * Check if the sizes in their natural units written in decimal format with + * one fraction number are same. + */ +static int sizes_near(unsigned long long size1, unsigned long long size2) +{ + unsigned int size1_scale, size1_val, size2_scale, size2_val; + + compute_size_scale_val(size1, size1_scale, size1_val); + compute_size_scale_val(size2, size2_scale, size2_val); + + return size1_scale == size2_scale && size1_val == size2_val; +} + static int show_dram_config(void) { unsigned long long size; @@ -231,7 +263,11 @@ static int show_dram_config(void) } debug("\nDRAM: "); - print_size(size, ""); + print_size(gd->ram_size, ""); + if (!sizes_near(gd->ram_size, size)) { + printf(" (effective "); + print_size(size, ")"); + } board_add_ram_info(0); putc('\n'); @@ -304,7 +340,7 @@ __weak int mach_cpu_init(void) } /* Get the top of usable RAM */ -__weak ulong board_get_usable_ram_top(ulong total_size) +__weak phys_size_t board_get_usable_ram_top(phys_size_t total_size) { #if defined(CONFIG_SYS_SDRAM_BASE) && CONFIG_SYS_SDRAM_BASE > 0 /* @@ -327,7 +363,7 @@ static int setup_dest_addr(void) /* * Ram is setup, size stored in gd !! */ - debug("Ram size: %08lX\n", (ulong)gd->ram_size); + debug("Ram size: %08llX\n", (unsigned long long)gd->ram_size); #if CONFIG_VAL(SYS_MEM_TOP_HIDE) /* * Subtract specified amount of memory to hide so that it won't @@ -347,7 +383,7 @@ static int setup_dest_addr(void) gd->ram_top = gd->ram_base + get_effective_memsize(); gd->ram_top = board_get_usable_ram_top(gd->mon_len); gd->relocaddr = gd->ram_top; - debug("Ram top: %08lX\n", (ulong)gd->ram_top); + debug("Ram top: %08llX\n", (unsigned long long)gd->ram_top); #if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) /* * We need to make sure the location we intend to put secondary core @@ -828,6 +864,7 @@ static const init_fnc_t init_sequence_f[] = { initf_malloc, log_init, initf_bootstage, /* uses its own timer, so does not need DM */ + cyclic_init, event_init, #ifdef CONFIG_BLOBLIST bloblist_init, diff --git a/common/board_r.c b/common/board_r.c index 00926dcb1e..92ca2066ee 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_MTD_NOR_FLASH @@ -233,6 +234,8 @@ static int initr_dm(void) { int ret; + oftree_reset(); + /* Save the pre-reloc driver model and start a new one */ gd->dm_root_f = gd->dm_root; gd->dm_root = NULL; @@ -340,7 +343,7 @@ static int initr_flash(void) /* * Compute and print flash CRC if flashchecksum is set to 'y' * - * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX + * NOTE: Maybe we should add some schedule()? XXX */ if (env_get_yesno("flashchecksum") == 1) { const uchar *flash_base = (const uchar *)CONFIG_SYS_FLASH_BASE; @@ -611,6 +614,7 @@ static init_fnc_t init_sequence_r[] = { #endif initr_barrier, initr_malloc, + cyclic_init, log_init, initr_bootstage, /* Needs malloc() but has its own timer */ #if defined(CONFIG_CONSOLE_RECORD) diff --git a/common/cli_readline.c b/common/cli_readline.c index e86ee73faf..f6e2bcdece 100644 --- a/common/cli_readline.c +++ b/common/cli_readline.c @@ -72,8 +72,13 @@ static char *delete_char (char *buffer, char *p, int *colp, int *np, int plen) #define getcmd_getch() getchar() #define getcmd_cbeep() getcmd_putch('\a') +#ifdef CONFIG_SPL_BUILD +#define HIST_MAX 3 +#define HIST_SIZE 32 +#else #define HIST_MAX 20 #define HIST_SIZE CONFIG_SYS_CBSIZE +#endif static int hist_max; static int hist_add_idx; @@ -269,7 +274,7 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len, while (!tstc()) { /* while no incoming data */ if (get_ticks() >= etime) return -2; /* timed out */ - WATCHDOG_RESET(); + schedule(); } first = 0; } @@ -590,7 +595,7 @@ int cli_readline_into_buffer(const char *const prompt, char *buffer, for (;;) { if (bootretry_tstc_timeout()) return -2; /* timed out */ - WATCHDOG_RESET(); /* Trigger watchdog, if needed */ + schedule(); /* Trigger watchdog, if needed */ c = getchar(); diff --git a/common/console.c b/common/console.c index e783f309bf..0c9bf66c3f 100644 --- a/common/console.c +++ b/common/console.c @@ -199,6 +199,7 @@ static int console_setfile(int file, struct stdio_dev * dev) case stdout: gd->jt->putc = putc; gd->jt->puts = puts; + STDIO_DEV_ASSIGN_FLUSH(gd->jt, flush); gd->jt->printf = printf; break; } @@ -364,6 +365,19 @@ static void console_puts(int file, const char *s) } } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void console_flush(int file) +{ + int i; + struct stdio_dev *dev; + + for_each_console_dev(i, file, dev) { + if (dev->flush != NULL) + dev->flush(dev); + } +} +#endif + #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) static inline void console_doenv(int file, struct stdio_dev *dev) { @@ -413,6 +427,14 @@ static inline void console_puts(int file, const char *s) stdio_devices[file]->puts(stdio_devices[file], s); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static inline void console_flush(int file) +{ + if (stdio_devices[file]->flush) + stdio_devices[file]->flush(stdio_devices[file]); +} +#endif + #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) static inline void console_doenv(int file, struct stdio_dev *dev) { @@ -480,7 +502,7 @@ int fgetc(int file) * Effectively poll for input wherever it may be available. */ for (;;) { - WATCHDOG_RESET(); + schedule(); if (CONFIG_IS_ENABLED(CONSOLE_MUX)) { /* * Upper layer may have already called tstc() so @@ -526,6 +548,14 @@ void fputs(int file, const char *s) console_puts(file, s); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void fflush(int file) +{ + if (file < MAX_FILES) + console_flush(file); +} +#endif + int fprintf(int file, const char *fmt, ...) { va_list args; @@ -740,6 +770,40 @@ void puts(const char *s) } } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void flush(void) +{ + if (!gd) + return; + + /* sandbox can send characters to stdout before it has a console */ + if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) { + os_flush(); + return; + } + + if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) + return; + + if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) + return; + + if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) + return; + + if (!gd->have_console) + return; + + if (gd->flags & GD_FLG_DEVINIT) { + /* Send to the standard output */ + fflush(stdout); + } else { + /* Send directly to the handler */ + serial_flush(); + } +} +#endif + #ifdef CONFIG_CONSOLE_RECORD int console_record_init(void) { diff --git a/common/cyclic.c b/common/cyclic.c new file mode 100644 index 0000000000..b3c180bd1a --- /dev/null +++ b/common/cyclic.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * A general-purpose cyclic execution infrastructure, to allow "small" + * (run-time wise) functions to be executed at a specified frequency. + * Things like LED blinking or watchdog triggering are examples for such + * tasks. + * + * Copyright (C) 2022 Stefan Roese + */ + +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +void hw_watchdog_reset(void); + +struct list_head *cyclic_get_list(void) +{ + return &gd->cyclic->cyclic_list; +} + +struct cyclic_info *cyclic_register(cyclic_func_t func, uint64_t delay_us, + const char *name, void *ctx) +{ + struct cyclic_info *cyclic; + + if (!gd->cyclic->cyclic_ready) { + pr_debug("Cyclic IF not ready yet\n"); + return NULL; + } + + cyclic = calloc(1, sizeof(struct cyclic_info)); + if (!cyclic) { + pr_debug("Memory allocation error\n"); + return NULL; + } + + /* Store values in struct */ + cyclic->func = func; + cyclic->ctx = ctx; + cyclic->name = strdup(name); + cyclic->delay_us = delay_us; + cyclic->start_time_us = timer_get_us(); + list_add_tail(&cyclic->list, &gd->cyclic->cyclic_list); + + return cyclic; +} + +int cyclic_unregister(struct cyclic_info *cyclic) +{ + list_del(&cyclic->list); + free(cyclic); + + return 0; +} + +void cyclic_run(void) +{ + struct cyclic_info *cyclic, *tmp; + uint64_t now, cpu_time; + + /* Prevent recursion */ + if (gd->cyclic->cyclic_running) + return; + + gd->cyclic->cyclic_running = true; + list_for_each_entry_safe(cyclic, tmp, &gd->cyclic->cyclic_list, list) { + /* + * Check if this cyclic function needs to get called, e.g. + * do not call the cyclic func too often + */ + now = timer_get_us(); + if (time_after_eq64(now, cyclic->next_call)) { + /* Call cyclic function and account it's cpu-time */ + cyclic->next_call = now + cyclic->delay_us; + cyclic->func(cyclic->ctx); + cyclic->run_cnt++; + cpu_time = timer_get_us() - now; + cyclic->cpu_time_us += cpu_time; + + /* Check if cpu-time exceeds max allowed time */ + if (cpu_time > CONFIG_CYCLIC_MAX_CPU_TIME_US) { + pr_err("cyclic function %s took too long: %lldus vs %dus max, disabling\n", + cyclic->name, cpu_time, + CONFIG_CYCLIC_MAX_CPU_TIME_US); + + /* Unregister this cyclic function */ + cyclic_unregister(cyclic); + } + } + } + gd->cyclic->cyclic_running = false; +} + +void schedule(void) +{ + /* The HW watchdog is not integrated into the cyclic IF (yet) */ + if (IS_ENABLED(CONFIG_HW_WATCHDOG)) + hw_watchdog_reset(); + + /* + * schedule() might get called very early before the cyclic IF is + * ready. Make sure to only call cyclic_run() when it's initalized. + */ + if (gd && gd->cyclic && gd->cyclic->cyclic_ready) + cyclic_run(); +} + +int cyclic_uninit(void) +{ + struct cyclic_info *cyclic, *tmp; + + list_for_each_entry_safe(cyclic, tmp, &gd->cyclic->cyclic_list, list) + cyclic_unregister(cyclic); + gd->cyclic->cyclic_ready = false; + + return 0; +} + +int cyclic_init(void) +{ + int size = sizeof(struct cyclic_drv); + + gd->cyclic = (struct cyclic_drv *)malloc(size); + if (!gd->cyclic) + return -ENOMEM; + + memset(gd->cyclic, '\0', size); + INIT_LIST_HEAD(&gd->cyclic->cyclic_list); + gd->cyclic->cyclic_ready = true; + + return 0; +} diff --git a/common/dfu.c b/common/dfu.c index 16bd1ba588..96190889ab 100644 --- a/common/dfu.c +++ b/common/dfu.c @@ -101,7 +101,7 @@ int run_usb_dnl_gadget(int usbctrl_index, char *usb_dnl_gadget) if (dfu_reinit_needed) goto exit; - WATCHDOG_RESET(); + schedule(); usb_gadget_handle_interrupts(usbctrl_index); } exit: diff --git a/common/dlmalloc.c b/common/dlmalloc.c index f48cd2a333..41c7230424 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -596,6 +596,9 @@ ulong mem_malloc_start = 0; ulong mem_malloc_end = 0; ulong mem_malloc_brk = 0; +static bool malloc_testing; /* enable test mode */ +static int malloc_max_allocs; /* return NULL after this many calls to malloc() */ + void *sbrk(ptrdiff_t increment) { ulong old = mem_malloc_brk; @@ -1307,6 +1310,11 @@ Void_t* mALLOc(bytes) size_t bytes; return malloc_simple(bytes); #endif + if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) { + if (--malloc_max_allocs < 0) + return NULL; + } + /* check if mem_malloc_init() was run */ if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) { /* not initialized yet */ @@ -2470,6 +2478,17 @@ int initf_malloc(void) return 0; } +void malloc_enable_testing(int max_allocs) +{ + malloc_testing = true; + malloc_max_allocs = max_allocs; +} + +void malloc_disable_testing(void) +{ + malloc_testing = false; +} + /* History: diff --git a/common/lcd.c b/common/lcd.c index 0898bc025d..a462b22a47 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -294,9 +294,9 @@ void lcd_logo_plot(int x, int y) BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS); if (bpix < 12) { - WATCHDOG_RESET(); + schedule(); lcd_logo_set_cmap(); - WATCHDOG_RESET(); + schedule(); for (i = 0; i < BMP_LOGO_HEIGHT; ++i) { memcpy(fb, bmap, BMP_LOGO_WIDTH); @@ -320,7 +320,7 @@ void lcd_logo_plot(int x, int y) } } - WATCHDOG_RESET(); + schedule(); lcd_sync(); } #else @@ -459,7 +459,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) byte_width = width * 2; for (i = 0; i < height; ++i) { - WATCHDOG_RESET(); + schedule(); for (j = 0; j < width; j++) { if (bpix != 16) { fb_put_byte(&fb, &bmap); @@ -488,7 +488,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) #if defined(CONFIG_BMP_16BPP) case 16: for (i = 0; i < height; ++i) { - WATCHDOG_RESET(); + schedule(); for (j = 0; j < width; j++) fb_put_word(&fb, &bmap); diff --git a/common/memsize.c b/common/memsize.c index d5d13d51bf..3c80ad2c83 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -94,11 +94,23 @@ long get_ram_size(long *base, long maxsize) phys_size_t __weak get_effective_memsize(void) { -#ifndef CONFIG_VERY_BIG_RAM - return gd->ram_size; + phys_size_t ram_size = gd->ram_size; + + /* + * Check for overflow and limit ram size to some representable value. + * It is required that ram_base + ram_size must be representable by + * phys_size_t type and must be aligned by direct access, therefore + * calculate it from last 4kB sector which should work as alignment + * on any platform. + */ + if (gd->ram_base + ram_size < gd->ram_base) + ram_size = ((phys_size_t)~0xfffULL) - gd->ram_base; + +#ifndef CONFIG_MAX_MEM_MAPPED + return ram_size; #else /* limit stack to what we can reasonable map */ - return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ? - CONFIG_MAX_MEM_MAPPED : gd->ram_size); + return ((ram_size > CONFIG_MAX_MEM_MAPPED) ? + CONFIG_MAX_MEM_MAPPED : ram_size); #endif } diff --git a/common/menu.c b/common/menu.c index 3e876b55b3..8fe00965c0 100644 --- a/common/menu.c +++ b/common/menu.c @@ -435,7 +435,7 @@ void bootmenu_autoboot_loop(struct bootmenu_data *menu, printf("Hit any key to stop autoboot: %d ", menu->delay); for (i = 0; i < 100; ++i) { if (!tstc()) { - WATCHDOG_RESET(); + schedule(); mdelay(10); continue; } @@ -483,7 +483,7 @@ void bootmenu_loop(struct bootmenu_data *menu, if (tstc()) { c = getchar(); } else { - WATCHDOG_RESET(); + schedule(); mdelay(10); if (tstc()) c = getchar(); @@ -492,7 +492,7 @@ void bootmenu_loop(struct bootmenu_data *menu, } } else { while (!tstc()) { - WATCHDOG_RESET(); + schedule(); mdelay(10); } c = getchar(); @@ -548,4 +548,13 @@ void bootmenu_loop(struct bootmenu_data *menu, /* ^C was pressed */ if (c == 0x3) *key = KEY_QUIT; + + if (c == '+') + *key = KEY_PLUS; + + if (c == '-') + *key = KEY_MINUS; + + if (c == ' ') + *key = KEY_SPACE; } diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 70d97815f0..f2422d28f9 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -40,6 +40,7 @@ config SPL_SIZE_LIMIT hex "Maximum size of SPL image" default 0x11000 if ARCH_MX6 && !MX6_OCRAM_256KB default 0x31000 if ARCH_MX6 && MX6_OCRAM_256KB + default 0x30000 if ARCH_MVEBU && ARMADA_32BIT default 0x0 help Specifies the maximum length of the U-Boot SPL image. @@ -792,7 +793,6 @@ config SPL_DM_MAILBOX config SPL_MMC bool "Support MMC" depends on MMC - select HAVE_BLOCK_DEVICE help Enable support for MMC (Multimedia Card) within SPL. This enables the MMC protocol implementation and allows any enabled drivers to @@ -1318,7 +1318,6 @@ config SPL_THERMAL config SPL_USB_HOST bool "Support USB host drivers" - select HAVE_BLOCK_DEVICE help Enable access to USB (Universal Serial Bus) host devices so that SPL can load U-Boot from a connected USB peripheral, such as a USB diff --git a/common/spl/spl.c b/common/spl/spl.c index 29e0898f03..752b5b247c 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -116,6 +116,11 @@ int __weak bootz_setup(ulong image, ulong *start, ulong *end) { return 1; } + +int __weak booti_setup(ulong image, ulong *relocated_addr, ulong *size, bool force_reloc) +{ + return 1; +} #endif /* Weak default function for arch/board-specific fixups to the spl_image_info */ @@ -222,7 +227,7 @@ __weak void spl_board_prepare_for_boot(void) /* Nothing to do! */ } -__weak struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +__weak struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { return map_sysmem(CONFIG_SYS_TEXT_BASE + offset, 0); } @@ -253,9 +258,9 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image) #if CONFIG_IS_ENABLED(LOAD_FIT_FULL) /* Parse and load full fitImage in SPL */ static int spl_load_fit_image(struct spl_image_info *spl_image, - const struct image_header *header) + const struct legacy_img_hdr *header) { - bootm_headers_t images; + struct bootm_headers images; const char *fit_uname_config = NULL; uintptr_t fdt_hack; const char *uname; @@ -354,7 +359,7 @@ __weak int spl_parse_board_header(struct spl_image_info *spl_image, } __weak int spl_parse_legacy_header(struct spl_image_info *spl_image, - const struct image_header *header) + const struct legacy_img_hdr *header) { /* LEGACY image not supported */ debug("Legacy boot image support not enabled, proceeding to other boot methods\n"); @@ -363,7 +368,7 @@ __weak int spl_parse_legacy_header(struct spl_image_info *spl_image, int spl_parse_image_header(struct spl_image_info *spl_image, const struct spl_boot_device *bootdev, - const struct image_header *header) + const struct legacy_img_hdr *header) { #if CONFIG_IS_ENABLED(LOAD_FIT_FULL) int ret = spl_load_fit_image(spl_image, header); @@ -391,6 +396,21 @@ int spl_parse_image_header(struct spl_image_info *spl_image, #endif #if CONFIG_IS_ENABLED(OS_BOOT) +#if defined(CMD_BOOTI) + ulong start, size; + + if (!booti_setup((ulong)header, &start, &size, 0)) { + spl_image->name = "Linux"; + spl_image->os = IH_OS_LINUX; + spl_image->load_addr = start; + spl_image->entry_point = start; + spl_image->size = size; + debug(SPL_TPL_PROMPT + "payload Image, load addr: 0x%lx size: %d\n", + spl_image->load_addr, spl_image->size); + return 0; + } +#elif defined(CMD_BOOTZ) ulong start, end; if (!bootz_setup((ulong)header, &start, &end)) { @@ -404,6 +424,7 @@ int spl_parse_image_header(struct spl_image_info *spl_image, spl_image->load_addr, spl_image->size); return 0; } +#endif #endif if (!spl_parse_board_header(spl_image, bootdev, (const void *)header, sizeof(*header))) diff --git a/common/spl/spl_ext.c b/common/spl/spl_ext.c index ebd914c492..f117c630bf 100644 --- a/common/spl/spl_ext.c +++ b/common/spl/spl_ext.c @@ -15,7 +15,7 @@ int spl_load_image_ext(struct spl_image_info *spl_image, const char *filename) { s32 err; - struct image_header *header; + struct legacy_img_hdr *header; loff_t filelen, actlen; struct disk_partition part_info = {}; @@ -41,7 +41,7 @@ int spl_load_image_ext(struct spl_image_info *spl_image, puts("spl: ext4fs_open failed\n"); goto end; } - err = ext4fs_read((char *)header, 0, sizeof(struct image_header), &actlen); + err = ext4fs_read((char *)header, 0, sizeof(struct legacy_img_hdr), &actlen); if (err < 0) { puts("spl: ext4fs_read failed\n"); goto end; diff --git a/common/spl/spl_fat.c b/common/spl/spl_fat.c index 5b270541fc..f8a5b80a3b 100644 --- a/common/spl/spl_fat.c +++ b/common/spl/spl_fat.c @@ -60,7 +60,7 @@ int spl_load_image_fat(struct spl_image_info *spl_image, const char *filename) { int err; - struct image_header *header; + struct legacy_img_hdr *header; err = spl_register_fat_device(block_dev, partition); if (err) @@ -68,7 +68,7 @@ int spl_load_image_fat(struct spl_image_info *spl_image, header = spl_get_load_buffer(-sizeof(*header), sizeof(*header)); - err = file_fat_read(filename, header, sizeof(struct image_header)); + err = file_fat_read(filename, header, sizeof(struct legacy_img_hdr)); if (err <= 0) goto end; @@ -78,7 +78,7 @@ int spl_load_image_fat(struct spl_image_info *spl_image, if (err <= 0) goto end; err = spl_parse_image_header(spl_image, bootdev, - (struct image_header *)CONFIG_SYS_LOAD_ADDR); + (struct legacy_img_hdr *)CONFIG_SYS_LOAD_ADDR); if (err == -EAGAIN) return err; if (err == 0) diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index a35be52965..c1ed31e367 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -429,7 +429,9 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image, * depending on how the overlay is stored, so * don't fail yet if the allocation failed. */ - tmpbuffer = malloc(CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ); + size_t size = CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ; + + tmpbuffer = malloc_cache_aligned(size); if (!tmpbuffer) debug("%s: unable to allocate space for overlays\n", __func__); @@ -537,7 +539,7 @@ static void *spl_get_fit_load_buffer(size_t size) { void *buf; - buf = malloc(size); + buf = malloc_cache_aligned(size); if (!buf) { pr_err("Could not get FIT buffer of %lu bytes\n", (ulong)size); pr_err("\tcheck CONFIG_SYS_SPL_MALLOC_SIZE\n"); diff --git a/common/spl/spl_legacy.c b/common/spl/spl_legacy.c index ae8731c782..b3624dfbb7 100644 --- a/common/spl/spl_legacy.c +++ b/common/spl/spl_legacy.c @@ -16,9 +16,9 @@ #define LZMA_LEN (1 << 20) int spl_parse_legacy_header(struct spl_image_info *spl_image, - const struct image_header *header) + const struct legacy_img_hdr *header) { - u32 header_size = sizeof(struct image_header); + u32 header_size = sizeof(struct legacy_img_hdr); /* check uImage header CRC */ if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK) && @@ -67,7 +67,7 @@ int spl_parse_legacy_header(struct spl_image_info *spl_image, * following switch/case statement in spl_load_legacy_img() away due to * Dead Code Elimination. */ -static inline int spl_image_get_comp(const struct image_header *hdr) +static inline int spl_image_get_comp(const struct legacy_img_hdr *hdr) { if (IS_ENABLED(CONFIG_SPL_LZMA)) return image_get_comp(hdr); @@ -81,7 +81,7 @@ int spl_load_legacy_img(struct spl_image_info *spl_image, { __maybe_unused SizeT lzma_len; __maybe_unused void *src; - struct image_header hdr; + struct legacy_img_hdr hdr; ulong dataptr; int ret; diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 23a395e63d..e4135b2048 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -20,7 +20,7 @@ static int mmc_load_legacy(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, struct mmc *mmc, - ulong sector, struct image_header *header) + ulong sector, struct legacy_img_hdr *header) { u32 image_offset_sectors; u32 image_size_sectors; @@ -83,7 +83,7 @@ int mmc_load_image_raw_sector(struct spl_image_info *spl_image, struct mmc *mmc, unsigned long sector) { unsigned long count; - struct image_header *header; + struct legacy_img_hdr *header; struct blk_desc *bd = mmc_get_blk_desc(mmc); int ret = 0; diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c index 7b7579a2df..a16738818c 100644 --- a/common/spl/spl_nand.c +++ b/common/spl/spl_nand.c @@ -78,7 +78,7 @@ struct mtd_info * __weak nand_get_mtd(void) static int spl_nand_load_element(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, - int offset, struct image_header *header) + int offset, struct legacy_img_hdr *header) { struct mtd_info *mtd = nand_get_mtd(); int bl_len = mtd ? mtd->writesize : 1; @@ -133,7 +133,7 @@ static int spl_nand_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { int err; - struct image_header *header; + struct legacy_img_hdr *header; int *src __attribute__((unused)); int *dst __attribute__((unused)); diff --git a/common/spl/spl_net.c b/common/spl/spl_net.c index a853e6aead..b2c901b554 100644 --- a/common/spl/spl_net.c +++ b/common/spl/spl_net.c @@ -28,7 +28,7 @@ static ulong spl_net_load_read(struct spl_load_info *load, ulong sector, static int spl_net_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct image_header *header = (struct image_header *)image_load_addr; + struct legacy_img_hdr *header = (struct legacy_img_hdr *)image_load_addr; int rv; env_init(); diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c index 7986e930d2..281c6136f5 100644 --- a/common/spl/spl_nor.c +++ b/common/spl/spl_nor.c @@ -26,7 +26,7 @@ unsigned long __weak spl_nor_get_uboot_base(void) static int spl_nor_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - __maybe_unused const struct image_header *header; + __maybe_unused const struct legacy_img_hdr *header; __maybe_unused struct spl_load_info load; /* @@ -41,7 +41,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, * Load Linux from its location in NOR flash to its defined * location in SDRAM */ - header = (const struct image_header *)CONFIG_SYS_OS_BASE; + header = (const struct legacy_img_hdr *)CONFIG_SYS_OS_BASE; #ifdef CONFIG_SPL_LOAD_FIT if (image_get_magic(header) == FDT_MAGIC) { int ret; @@ -72,7 +72,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, memcpy((void *)spl_image->load_addr, (void *)(CONFIG_SYS_OS_BASE + - sizeof(struct image_header)), + sizeof(struct legacy_img_hdr)), spl_image->size); #ifdef CONFIG_SYS_SPL_ARGS_ADDR spl_image->arg = (void *)CONFIG_SYS_SPL_ARGS_ADDR; @@ -92,7 +92,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, * defined location in SDRAM */ #ifdef CONFIG_SPL_LOAD_FIT - header = (const struct image_header *)spl_nor_get_uboot_base(); + header = (const struct legacy_img_hdr *)spl_nor_get_uboot_base(); if (image_get_magic(header) == FDT_MAGIC) { debug("Found FIT format U-Boot\n"); load.bl_len = 1; diff --git a/common/spl/spl_onenand.c b/common/spl/spl_onenand.c index f80769a027..53a8c6de89 100644 --- a/common/spl/spl_onenand.c +++ b/common/spl/spl_onenand.c @@ -18,7 +18,7 @@ static int spl_onenand_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct image_header *header; + struct legacy_img_hdr *header; int ret; debug("spl: onenand\n"); diff --git a/common/spl/spl_ram.c b/common/spl/spl_ram.c index d64710878c..2b1ac19152 100644 --- a/common/spl/spl_ram.c +++ b/common/spl/spl_ram.c @@ -41,9 +41,9 @@ static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector, static int spl_ram_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct image_header *header; + struct legacy_img_hdr *header; - header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS; + header = (struct legacy_img_hdr *)CONFIG_SPL_LOAD_FIT_ADDRESS; if (CONFIG_IS_ENABLED(IMAGE_PRE_LOAD)) { unsigned long addr = (unsigned long)header; @@ -53,7 +53,7 @@ static int spl_ram_load_image(struct spl_image_info *spl_image, return ret; addr += image_load_offset; - header = (struct image_header *)addr; + header = (struct legacy_img_hdr *)addr; } #if CONFIG_IS_ENABLED(DFU) @@ -87,7 +87,7 @@ static int spl_ram_load_image(struct spl_image_info *spl_image, u_boot_pos = (ulong)spl_get_load_buffer(-sizeof(*header), sizeof(*header)); } - header = (struct image_header *)map_sysmem(u_boot_pos, 0); + header = (struct legacy_img_hdr *)map_sysmem(u_boot_pos, 0); spl_parse_image_header(spl_image, bootdev, header); } diff --git a/common/spl/spl_sata.c b/common/spl/spl_sata.c index 1351d78612..9ae0273068 100644 --- a/common/spl/spl_sata.c +++ b/common/spl/spl_sata.c @@ -30,7 +30,7 @@ static int spl_sata_load_image_raw(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, struct blk_desc *stor_dev, unsigned long sector) { - struct image_header *header; + struct legacy_img_hdr *header; unsigned long count; u32 image_size_sectors; u32 image_offset_sectors; @@ -71,7 +71,7 @@ static int spl_sata_load_image(struct spl_image_info *spl_image, /* try to recognize storage devices immediately */ scsi_scan(false); - stor_dev = blk_get_devnum_by_type(IF_TYPE_SCSI, 0); + stor_dev = blk_get_devnum_by_uclass_id(UCLASS_SCSI, 0); if (!stor_dev) return -ENODEV; diff --git a/common/spl/spl_semihosting.c b/common/spl/spl_semihosting.c index df6aeb2951..5b5e842a11 100644 --- a/common/spl/spl_semihosting.c +++ b/common/spl/spl_semihosting.c @@ -27,7 +27,7 @@ static int spl_smh_load_image(struct spl_image_info *spl_image, const char *filename = CONFIG_SPL_FS_LOAD_PAYLOAD_NAME; int ret; long fd, len; - struct image_header *header = + struct legacy_img_hdr *header = spl_get_load_buffer(-sizeof(*header), sizeof(*header)); fd = smh_open(filename, MODE_READ | MODE_BINARY); @@ -43,7 +43,7 @@ static int spl_smh_load_image(struct spl_image_info *spl_image, } len = ret; - ret = smh_read_full(fd, header, sizeof(struct image_header)); + ret = smh_read_full(fd, header, sizeof(struct legacy_img_hdr)); if (ret) { log_debug("could not read image header: %d\n", ret); goto out; diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c index d959ad1145..da6742416e 100644 --- a/common/spl/spl_spi.c +++ b/common/spl/spl_spi.c @@ -26,7 +26,7 @@ static int spi_load_image_os(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, struct spi_flash *flash, - struct image_header *header) + struct legacy_img_hdr *header) { int err; @@ -92,7 +92,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, int err = 0; unsigned int payload_offs; struct spi_flash *flash; - struct image_header *header; + struct legacy_img_hdr *header; unsigned int sf_bus = spl_spi_boot_bus(); unsigned int sf_cs = spl_spi_boot_cs(); @@ -139,7 +139,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, if (err) return err; err = spl_parse_image_header(spl_image, bootdev, - (struct image_header *)CONFIG_SYS_LOAD_ADDR); + (struct legacy_img_hdr *)CONFIG_SYS_LOAD_ADDR); } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) { struct spl_load_info load; diff --git a/common/spl/spl_ubi.c b/common/spl/spl_ubi.c index bdf5cc4c38..fb804f0208 100644 --- a/common/spl/spl_ubi.c +++ b/common/spl/spl_ubi.c @@ -15,7 +15,7 @@ int spl_ubi_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct image_header *header; + struct legacy_img_hdr *header; struct ubispl_info info; struct ubispl_load volumes[2]; int ret = 1; @@ -54,7 +54,7 @@ int spl_ubi_load_image(struct spl_image_info *spl_image, ret = ubispl_load_volumes(&info, volumes, 2); if (!ret) { - header = (struct image_header *)volumes[0].load_addr; + header = (struct legacy_img_hdr *)volumes[0].load_addr; spl_parse_image_header(spl_image, bootdev, header); puts("Linux loaded.\n"); goto out; diff --git a/common/spl/spl_usb.c b/common/spl/spl_usb.c index ccf01c8276..479e2dc182 100644 --- a/common/spl/spl_usb.c +++ b/common/spl/spl_usb.c @@ -41,7 +41,7 @@ int spl_usb_load(struct spl_image_info *spl_image, /* try to recognize storage devices immediately */ usb_stor_curr_dev = usb_stor_scan(1); - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, usb_stor_curr_dev); + stor_dev = blk_get_devnum_by_uclass_id(UCLASS_USB, usb_stor_curr_dev); if (!stor_dev) return -ENODEV; diff --git a/common/spl/spl_xip.c b/common/spl/spl_xip.c index e9a40b0ec7..1258d85e63 100644 --- a/common/spl/spl_xip.c +++ b/common/spl/spl_xip.c @@ -25,6 +25,6 @@ static int spl_xip(struct spl_image_info *spl_image, } #endif return(spl_parse_image_header(spl_image, bootdev, - (const struct image_header *)CONFIG_SYS_UBOOT_BASE)); + (const struct legacy_img_hdr *)CONFIG_SYS_UBOOT_BASE)); } SPL_LOAD_IMAGE_METHOD("XIP", 0, BOOT_DEVICE_XIP, spl_xip); diff --git a/common/spl/spl_ymodem.c b/common/spl/spl_ymodem.c index fdd5261042..038b443845 100644 --- a/common/spl/spl_ymodem.c +++ b/common/spl/spl_ymodem.c @@ -96,7 +96,7 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, int ret; connection_info_t info; char buf[BUF_SIZE]; - struct image_header *ih = NULL; + struct legacy_img_hdr *ih = NULL; ulong addr = 0; info.mode = xyzModem_ymodem; @@ -111,9 +111,9 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, goto end_stream; if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL) && - image_get_magic((struct image_header *)buf) == FDT_MAGIC) { + image_get_magic((struct legacy_img_hdr *)buf) == FDT_MAGIC) { addr = CONFIG_SYS_LOAD_ADDR; - ih = (struct image_header *)addr; + ih = (struct legacy_img_hdr *)addr; memcpy((void *)addr, buf, res); size += res; @@ -129,7 +129,7 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, if (ret) return ret; } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic((struct image_header *)buf) == FDT_MAGIC) { + image_get_magic((struct legacy_img_hdr *)buf) == FDT_MAGIC) { struct spl_load_info load; struct ymodem_fit_info info; @@ -147,7 +147,7 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) size += res; } else { - ih = (struct image_header *)buf; + ih = (struct legacy_img_hdr *)buf; ret = spl_parse_image_header(spl_image, bootdev, ih); if (ret) goto end_stream; @@ -158,7 +158,7 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, #endif addr = spl_image->load_addr; memcpy((void *)addr, buf, res); - ih = (struct image_header *)addr; + ih = (struct legacy_img_hdr *)addr; size += res; addr += res; @@ -177,7 +177,7 @@ end_stream: #ifdef CONFIG_SPL_GZIP if (!(IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic((struct image_header *)buf) == FDT_MAGIC) && + image_get_magic((struct legacy_img_hdr *)buf) == FDT_MAGIC) && (ih->ih_comp == IH_COMP_GZIP)) { if (gunzip((void *)(spl_image->load_addr + sizeof(*ih)), CONFIG_SYS_BOOTM_LEN, diff --git a/common/splash_source.c b/common/splash_source.c index 2c03cbdf92..87e55a54f8 100644 --- a/common/splash_source.c +++ b/common/splash_source.c @@ -327,17 +327,17 @@ static int splash_load_fit(struct splash_location *location, u32 bmp_load_addr) int external_splash_addr; int external_splash_size; bool is_splash_external = false; - struct image_header *img_header; + struct legacy_img_hdr *img_header; const u32 *fit_header; u32 fit_size; - const size_t header_size = sizeof(struct image_header); + const size_t header_size = sizeof(struct legacy_img_hdr); /* Read in image header */ res = splash_storage_read_raw(location, bmp_load_addr, header_size); if (res < 0) return res; - img_header = (struct image_header *)bmp_load_addr; + img_header = (struct legacy_img_hdr *)bmp_load_addr; if (image_get_magic(img_header) != FDT_MAGIC) { printf("Could not find FDT magic\n"); return -EINVAL; diff --git a/common/stdio.c b/common/stdio.c index 92161a0df8..13083842cb 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -87,6 +87,13 @@ static void stdio_serial_puts(struct stdio_dev *dev, const char *s) serial_puts(s); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void stdio_serial_flush(struct stdio_dev *dev) +{ + serial_flush(); +} +#endif + static int stdio_serial_getc(struct stdio_dev *dev) { return serial_getc(); @@ -112,6 +119,7 @@ static void drv_system_init (void) dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; dev.putc = stdio_serial_putc; dev.puts = stdio_serial_puts; + STDIO_DEV_ASSIGN_FLUSH(&dev, stdio_serial_flush); dev.getc = stdio_serial_getc; dev.tstc = stdio_serial_tstc; stdio_register (&dev); diff --git a/common/usb_kbd.c b/common/usb_kbd.c index d385bea532..4cbc9acb73 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -446,7 +446,7 @@ static int usb_kbd_getc(struct stdio_dev *sdev) data = usb_kbd_dev->privptr; while (data->usb_in_pointer == data->usb_out_pointer) { - WATCHDOG_RESET(); + schedule(); usb_kbd_poll_for_event(usb_kbd_dev); } diff --git a/common/usb_storage.c b/common/usb_storage.c index eaa31374ef..e59c819bac 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -144,7 +144,7 @@ int usb_stor_info(void) #if CONFIG_IS_ENABLED(BLK) struct udevice *dev; - for (blk_first_device(IF_TYPE_USB, &dev); + for (blk_first_device(UCLASS_USB, &dev); dev; blk_next_device(&dev)) { struct blk_desc *desc = dev_get_uclass_plat(dev); @@ -219,7 +219,7 @@ static int usb_stor_probe_device(struct usb_device *udev) snprintf(str, sizeof(str), "lun%d", lun); ret = blk_create_devicef(udev->dev, "usb_storage_blk", str, - IF_TYPE_USB, usb_max_devs, 512, 0, + UCLASS_USB, usb_max_devs, 512, 0, &dev); if (ret) { debug("Cannot bind driver\n"); @@ -279,7 +279,7 @@ static int usb_stor_probe_device(struct usb_device *udev) blkdev = &usb_dev_desc[usb_max_devs]; memset(blkdev, '\0', sizeof(struct blk_desc)); - blkdev->if_type = IF_TYPE_USB; + blkdev->uclass_id = UCLASS_USB; blkdev->devnum = usb_max_devs; blkdev->part_type = PART_TYPE_UNKNOWN; blkdev->target = 0xff; @@ -1577,8 +1577,8 @@ U_BOOT_DRIVER(usb_storage_blk) = { }; #else U_BOOT_LEGACY_BLK(usb) = { - .if_typename = "usb", - .if_type = IF_TYPE_USB, + .uclass_idname = "usb", + .uclass_id = UCLASS_USB, .max_devs = USB_MAX_STOR_DEV, .desc = usb_dev_desc, }; diff --git a/common/xyzModem.c b/common/xyzModem.c index ece25acb18..fb319f7119 100644 --- a/common/xyzModem.c +++ b/common/xyzModem.c @@ -26,6 +26,7 @@ #include #include #include +#include /* Assumption - run xyzModem protocol over the console port */ @@ -50,6 +51,8 @@ static struct int len, mode, total_retries; int total_SOH, total_STX, total_CAN; bool crc_mode, at_eof, tx_ack; + bool first_xmodem_packet; + ulong initial_time, timeout; unsigned long file_length, read_length; } xyz; @@ -65,7 +68,7 @@ CYGACC_COMM_IF_GETC_TIMEOUT (char chan, char *c) { ulong now = get_timer(0); - WATCHDOG_RESET(); + schedule(); while (!tstc ()) { if (get_timer(now) > xyzModem_CHAR_TIMEOUT) @@ -409,6 +412,19 @@ xyzModem_get_hdr (void) return 0; } +static +ulong +xyzModem_get_initial_timeout (void) +{ + /* timeout is in seconds, non-positive timeout value is infinity */ +#if CONFIG_IS_ENABLED(ENV_SUPPORT) + const char *timeout_str = env_get("loadxy_timeout"); + if (timeout_str) + return 1000 * simple_strtol(timeout_str, NULL, 10); +#endif + return 1000 * CONFIG_CMD_LOADXY_TIMEOUT; +} + int xyzModem_stream_open (connection_info_t * info, int *err) { @@ -439,18 +455,28 @@ xyzModem_stream_open (connection_info_t * info, int *err) xyz.total_CAN = 0; xyz.read_length = 0; xyz.file_length = 0; + xyz.first_xmodem_packet = false; + xyz.initial_time = get_timer(0); + xyz.timeout = xyzModem_get_initial_timeout(); CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); if (xyz.mode == xyzModem_xmodem) { /* X-modem doesn't have an information header - exit here */ + xyz.first_xmodem_packet = true; xyz.next_blk = 1; return 0; } - while (retries-- > 0) + while (!(xyz.timeout && get_timer(xyz.initial_time) > xyz.timeout)) { + if (--retries <= 0) + { + retries = xyzModem_MAX_RETRIES; + crc_retries = xyzModem_MAX_RETRIES_WITH_CRC; + xyz.crc_mode = true; + } stat = xyzModem_get_hdr (); if (stat == 0) { @@ -503,9 +529,19 @@ xyzModem_stream_read (char *buf, int size, int *err) retries = xyzModem_MAX_RETRIES; while (retries-- > 0) { + if (xyz.first_xmodem_packet && xyz.timeout && + get_timer(xyz.initial_time) > xyz.timeout) + { + *err = xyzModem_timeout; + xyz.len = -1; + return total; + } + stat = xyzModem_get_hdr (); if (stat == 0) { + if (xyz.mode == xyzModem_xmodem && xyz.first_xmodem_packet) + xyz.first_xmodem_packet = false; if (xyz.blk == xyz.next_blk) { xyz.tx_ack = true; @@ -583,7 +619,7 @@ xyzModem_stream_read (char *buf, int size, int *err) xyz.total_retries++; ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__)); } - if (stat < 0) + if (stat < 0 && (!xyz.first_xmodem_packet || stat != xyzModem_timeout)) { *err = stat; xyz.len = -1; diff --git a/configs/M5253DEMO_defconfig b/configs/M5253DEMO_defconfig index 79382eb0fe..a73aca082c 100644 --- a/configs/M5253DEMO_defconfig +++ b/configs/M5253DEMO_defconfig @@ -25,6 +25,7 @@ CONFIG_CMD_EXT2=y CONFIG_CMD_FAT=y CONFIG_MAC_PARTITION=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y +# CONFIG_BLOCK_CACHE is not set CONFIG_SYS_IDE_MAXBUS=1 CONFIG_SYS_ATA_STRIDE=4 CONFIG_SYS_ATA_DATA_OFFSET=0xA0 diff --git a/configs/MPC8548CDS_36BIT_defconfig b/configs/MPC8548CDS_36BIT_defconfig index def5d6fdf4..feb0be5a49 100644 --- a/configs/MPC8548CDS_36BIT_defconfig +++ b/configs/MPC8548CDS_36BIT_defconfig @@ -21,6 +21,7 @@ CONFIG_USE_BOOTCOMMAND=y CONFIG_BOOTCOMMAND="setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off console=$consoledev,$baudrate $othbootargs;tftp $loadaddr $bootfile;tftp $fdtaddr $fdtfile;bootm $loadaddr - $fdtaddr" # CONFIG_MISC_INIT_R is not set CONFIG_ID_EEPROM=y +CONFIG_SYS_I2C_EEPROM_CCID=y CONFIG_HUSH_PARSER=y CONFIG_SYS_PBSIZE=276 CONFIG_CMD_IMLS=y diff --git a/configs/MPC8548CDS_defconfig b/configs/MPC8548CDS_defconfig index 881fca912b..945347941b 100644 --- a/configs/MPC8548CDS_defconfig +++ b/configs/MPC8548CDS_defconfig @@ -20,6 +20,7 @@ CONFIG_USE_BOOTCOMMAND=y CONFIG_BOOTCOMMAND="setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off console=$consoledev,$baudrate $othbootargs;tftp $loadaddr $bootfile;tftp $fdtaddr $fdtfile;bootm $loadaddr - $fdtaddr" # CONFIG_MISC_INIT_R is not set CONFIG_ID_EEPROM=y +CONFIG_SYS_I2C_EEPROM_CCID=y CONFIG_HUSH_PARSER=y CONFIG_SYS_PBSIZE=276 CONFIG_CMD_IMLS=y diff --git a/configs/MPC8548CDS_legacy_defconfig b/configs/MPC8548CDS_legacy_defconfig index 99a63300af..f069451697 100644 --- a/configs/MPC8548CDS_legacy_defconfig +++ b/configs/MPC8548CDS_legacy_defconfig @@ -21,6 +21,7 @@ CONFIG_USE_BOOTCOMMAND=y CONFIG_BOOTCOMMAND="setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off console=$consoledev,$baudrate $othbootargs;tftp $loadaddr $bootfile;tftp $fdtaddr $fdtfile;bootm $loadaddr - $fdtaddr" # CONFIG_MISC_INIT_R is not set CONFIG_ID_EEPROM=y +CONFIG_SYS_I2C_EEPROM_CCID=y CONFIG_HUSH_PARSER=y CONFIG_SYS_PBSIZE=276 CONFIG_CMD_IMLS=y diff --git a/configs/ae350_rv32_spl_defconfig b/configs/ae350_rv32_spl_defconfig index 9b79cc41b5..1cc98a2653 100644 --- a/configs/ae350_rv32_spl_defconfig +++ b/configs/ae350_rv32_spl_defconfig @@ -48,3 +48,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_ATCSPI200_SPI=y # CONFIG_BINMAN_FDT is not set +# CONFIG_AVAILABLE_HARTS is not set diff --git a/configs/ae350_rv32_spl_xip_defconfig b/configs/ae350_rv32_spl_xip_defconfig index c7b6ea4730..67c1e35c55 100644 --- a/configs/ae350_rv32_spl_xip_defconfig +++ b/configs/ae350_rv32_spl_xip_defconfig @@ -11,7 +11,7 @@ CONFIG_SPL=y CONFIG_SYS_LOAD_ADDR=0x100000 CONFIG_TARGET_AX25_AE350=y CONFIG_RISCV_SMODE=y -CONFIG_XIP=y +CONFIG_SPL_XIP=y CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xffff00 diff --git a/configs/ae350_rv64_spl_defconfig b/configs/ae350_rv64_spl_defconfig index 4c33ca2383..4318300300 100644 --- a/configs/ae350_rv64_spl_defconfig +++ b/configs/ae350_rv64_spl_defconfig @@ -49,3 +49,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_ATCSPI200_SPI=y # CONFIG_BINMAN_FDT is not set +# CONFIG_AVAILABLE_HARTS is not set diff --git a/configs/ae350_rv64_spl_xip_defconfig b/configs/ae350_rv64_spl_xip_defconfig index a197c97736..baee9bfe4a 100644 --- a/configs/ae350_rv64_spl_xip_defconfig +++ b/configs/ae350_rv64_spl_xip_defconfig @@ -12,7 +12,7 @@ CONFIG_SYS_LOAD_ADDR=0x100000 CONFIG_TARGET_AX25_AE350=y CONFIG_ARCH_RV64I=y CONFIG_RISCV_SMODE=y -CONFIG_XIP=y +CONFIG_SPL_XIP=y CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xfffe70 diff --git a/configs/axm_defconfig b/configs/axm_defconfig index dc262c95a3..dd5efbca86 100644 --- a/configs/axm_defconfig +++ b/configs/axm_defconfig @@ -79,8 +79,6 @@ CONFIG_ENV_IS_IN_NAND=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SPL_DM=y -CONFIG_BLK=y -CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_CLK=y CONFIG_CLK_AT91=y CONFIG_AT91_GPIO=y diff --git a/configs/bcm963158_ram_defconfig b/configs/bcm963158_ram_defconfig index 424eca7946..c0fda57ff7 100644 --- a/configs/bcm963158_ram_defconfig +++ b/configs/bcm963158_ram_defconfig @@ -38,7 +38,6 @@ CONFIG_ISO_PARTITION=y CONFIG_EFI_PARTITION=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set -CONFIG_BLK=y CONFIG_CLK=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y @@ -64,4 +63,3 @@ CONFIG_BCM63XX_HSSPI=y CONFIG_SYSRESET=y CONFIG_SYSRESET_WATCHDOG=y CONFIG_WDT_BCM6345=y -# CONFIG_GENERATE_SMBIOS_TABLE is not set diff --git a/configs/bcm968360bg_ram_defconfig b/configs/bcm968360bg_ram_defconfig index 7f9093c6f6..a83d4efd55 100644 --- a/configs/bcm968360bg_ram_defconfig +++ b/configs/bcm968360bg_ram_defconfig @@ -34,7 +34,6 @@ CONFIG_ISO_PARTITION=y CONFIG_EFI_PARTITION=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set -CONFIG_BLK=y CONFIG_CLK=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y diff --git a/configs/bcm968380gerg_ram_defconfig b/configs/bcm968380gerg_ram_defconfig index a0924689e4..284fa2fdef 100644 --- a/configs/bcm968380gerg_ram_defconfig +++ b/configs/bcm968380gerg_ram_defconfig @@ -42,7 +42,6 @@ CONFIG_CMD_NAND=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set # CONFIG_DM_DEVICE_REMOVE is not set -CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y CONFIG_LED_BCM6328=y diff --git a/configs/bcm968580xref_ram_defconfig b/configs/bcm968580xref_ram_defconfig index a8c7ffa748..4320739809 100644 --- a/configs/bcm968580xref_ram_defconfig +++ b/configs/bcm968580xref_ram_defconfig @@ -34,7 +34,6 @@ CONFIG_ISO_PARTITION=y CONFIG_EFI_PARTITION=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set -CONFIG_BLK=y CONFIG_CLK=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y @@ -61,4 +60,3 @@ CONFIG_BCM63XX_HSSPI=y CONFIG_SYSRESET=y CONFIG_SYSRESET_WATCHDOG=y CONFIG_WDT_BCM6345=y -# CONFIG_GENERATE_SMBIOS_TABLE is not set diff --git a/configs/brppt1_mmc_defconfig b/configs/brppt1_mmc_defconfig index b1ed2bcd68..a45604de16 100644 --- a/configs/brppt1_mmc_defconfig +++ b/configs/brppt1_mmc_defconfig @@ -17,6 +17,8 @@ CONFIG_SPL_SERIAL=y CONFIG_SPL=y CONFIG_ENV_OFFSET_REDUND=0x50000 CONFIG_SYS_LOAD_ADDR=0x80000000 +CONFIG_LOCALVERSION="-2.0.0" +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x4030ff00 # CONFIG_EXPERT is not set @@ -26,7 +28,7 @@ CONFIG_BOOTDELAY=0 CONFIG_USE_BOOTCOMMAND=y CONFIG_BOOTCOMMAND="run b_default" CONFIG_USE_PREBOOT=y -CONFIG_PREBOOT="run cfgscr; run brdefaultip" +CONFIG_PREBOOT="mw ${cfgaddr} 0; mw ${dtbaddr} 0; run cfgscr; run brdefaultip" CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y CONFIG_SYS_CONSOLE_INFO_QUIET=y @@ -90,7 +92,7 @@ CONFIG_NETCONSOLE=y CONFIG_DM=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y -# CONFIG_OF_TRANSLATE is not set +CONFIG_SPL_OF_TRANSLATE=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_DM_I2C=y CONFIG_I2C_SET_DEFAULT_BUS_NUM=y diff --git a/configs/brppt1_nand_defconfig b/configs/brppt1_nand_defconfig deleted file mode 100644 index c5981bad49..0000000000 --- a/configs/brppt1_nand_defconfig +++ /dev/null @@ -1,122 +0,0 @@ -CONFIG_ARM=y -CONFIG_ARCH_OMAP2PLUS=y -CONFIG_SYS_MALLOC_LEN=0x500000 -CONFIG_SPL_GPIO=y -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=1 -CONFIG_ENV_SIZE=0x10000 -CONFIG_ENV_OFFSET=0x60000 -CONFIG_DM_GPIO=y -CONFIG_DEFAULT_DEVICE_TREE="am335x-brppt1-nand" -CONFIG_AM33XX=y -CONFIG_TARGET_BRPPT1=y -CONFIG_SPL_SERIAL=y -CONFIG_SPL=y -CONFIG_SYS_LOAD_ADDR=0x80000000 -CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x4030ff00 -# CONFIG_EXPERT is not set -# CONFIG_FIT is not set -CONFIG_OF_BOARD_SETUP=y -CONFIG_BOOTDELAY=0 -CONFIG_USE_BOOTCOMMAND=y -CONFIG_BOOTCOMMAND="run b_default" -CONFIG_USE_PREBOOT=y -CONFIG_PREBOOT="run cfgscr; run brdefaultip" -CONFIG_SYS_CONSOLE_IS_IN_ENV=y -CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y -CONFIG_SYS_CONSOLE_INFO_QUIET=y -# CONFIG_DISPLAY_CPUINFO is not set -# CONFIG_DISPLAY_BOARDINFO is not set -CONFIG_ARCH_MISC_INIT=y -CONFIG_SPL_SYS_MALLOC_SIMPLE=y -CONFIG_SYS_SPL_MALLOC=y -CONFIG_SYS_SPL_MALLOC_SIZE=0x500000 -# CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set -CONFIG_SPL_I2C=y -CONFIG_SPL_NAND_DRIVERS=y -CONFIG_SPL_NAND_ECC=y -CONFIG_SPL_NAND_BASE=y -CONFIG_SPL_POWER=y -CONFIG_SPL_WATCHDOG=y -CONFIG_SPL_YMODEM_SUPPORT=y -CONFIG_HUSH_PARSER=y -CONFIG_SYS_MAXARGS=64 -CONFIG_SYS_CBSIZE=512 -CONFIG_SYS_PBSIZE=532 -CONFIG_CMD_BOOTZ=y -CONFIG_SYS_BOOTM_LEN=0x2000000 -# CONFIG_CMD_IMI is not set -# CONFIG_CMD_XIMG is not set -# CONFIG_CMD_EDITENV is not set -# CONFIG_CMD_CRC32 is not set -# CONFIG_CMD_FLASH is not set -CONFIG_CMD_GPIO=y -CONFIG_CMD_I2C=y -# CONFIG_CMD_LOADS is not set -CONFIG_CMD_NAND=y -CONFIG_CMD_PART=y -CONFIG_CMD_USB=y -# CONFIG_CMD_ITEST is not set -CONFIG_CMD_DHCP=y -CONFIG_BOOTP_MAY_FAIL=y -# CONFIG_CMD_NFS is not set -CONFIG_SYS_DISABLE_AUTOLOAD=y -CONFIG_CMD_MII=y -CONFIG_CMD_PING=y -CONFIG_CMD_BOOTCOUNT=y -CONFIG_CMD_CACHE=y -CONFIG_CMD_TIME=y -CONFIG_CMD_EXT4=y -CONFIG_CMD_EXT4_WRITE=y -CONFIG_CMD_FAT=y -CONFIG_CMD_FS_GENERIC=y -CONFIG_CMD_MTDPARTS=y -CONFIG_MTDIDS_DEFAULT="nand0=omap2-nand.0" -CONFIG_MTDPARTS_DEFAULT="mtdparts=omap2-nand.0:128k(MLO),128k(cfgscr),128k(dtb),128k(u-boot-env),512k(u-boot),4m(kernel),128m(rootfs),-(user)" -# CONFIG_SPL_DOS_PARTITION is not set -CONFIG_OF_CONTROL=y -CONFIG_SPL_OF_CONTROL=y -CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clocks clock-names interrupt-parent interrupt-controller interrupt-cells dma-names dmas " -CONFIG_ENV_OVERWRITE=y -CONFIG_ENV_IS_IN_NAND=y -CONFIG_SYS_RELOC_GD_ENV_ADDR=y -CONFIG_VERSION_VARIABLE=y -CONFIG_NET_RETRY_COUNT=10 -CONFIG_BOOTP_SEND_HOSTNAME=y -CONFIG_NET_RANDOM_ETHADDR=y -CONFIG_NETCONSOLE=y -CONFIG_DM=y -CONFIG_SPL_DM=y -CONFIG_SPL_DM_SEQ_ALIAS=y -# CONFIG_OF_TRANSLATE is not set -CONFIG_BOOTCOUNT_LIMIT=y -CONFIG_DM_I2C=y -CONFIG_I2C_SET_DEFAULT_BUS_NUM=y -CONFIG_MISC=y -# CONFIG_MMC is not set -CONFIG_MTD=y -CONFIG_MTD_RAW_NAND=y -CONFIG_SYS_NAND_BLOCK_SIZE=0x20000 -CONFIG_SYS_NAND_PAGE_COUNT=0x40 -CONFIG_SYS_NAND_PAGE_SIZE=0x800 -CONFIG_SYS_NAND_OOBSIZE=0x40 -CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y -CONFIG_SYS_NAND_U_BOOT_OFFS=0x80000 -CONFIG_PHY_NATSEMI=y -CONFIG_DRIVER_TI_CPSW=y -CONFIG_DM_PMIC=y -# CONFIG_SPL_DM_PMIC is not set -CONFIG_PMIC_TPS65217=y -CONFIG_DM_SERIAL=y -CONFIG_USB=y -CONFIG_USB_MUSB_HOST=y -CONFIG_USB_MUSB_GADGET=y -CONFIG_USB_MUSB_TI=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_FAT_WRITE=y -CONFIG_LZO=y -# CONFIG_OF_LIBFDT_OVERLAY is not set -# CONFIG_EFI_LOADER is not set diff --git a/configs/brppt1_spi_defconfig b/configs/brppt1_spi_defconfig deleted file mode 100644 index fa6b840d9e..0000000000 --- a/configs/brppt1_spi_defconfig +++ /dev/null @@ -1,130 +0,0 @@ -CONFIG_ARM=y -CONFIG_ARCH_OMAP2PLUS=y -CONFIG_SYS_MALLOC_LEN=0x500000 -CONFIG_SYS_MALLOC_F_LEN=0x4000 -CONFIG_SPL_GPIO=y -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=1 -CONFIG_ENV_SIZE=0x10000 -CONFIG_ENV_OFFSET=0x20000 -CONFIG_ENV_SECT_SIZE=0x10000 -CONFIG_DM_GPIO=y -CONFIG_SPL_DM_SPI=y -CONFIG_DEFAULT_DEVICE_TREE="am335x-brppt1-spi" -CONFIG_AM33XX=y -CONFIG_TARGET_BRPPT1=y -CONFIG_SPL_SERIAL=y -CONFIG_SPL=y -CONFIG_ENV_OFFSET_REDUND=0x30000 -CONFIG_SPL_SPI_FLASH_SUPPORT=y -CONFIG_SPL_SPI=y -CONFIG_SYS_LOAD_ADDR=0x80000000 -CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x4030ff00 -# CONFIG_EXPERT is not set -# CONFIG_FIT is not set -CONFIG_OF_BOARD_SETUP=y -CONFIG_SPI_BOOT=y -CONFIG_BOOTDELAY=0 -CONFIG_USE_BOOTCOMMAND=y -CONFIG_BOOTCOMMAND="run b_default" -CONFIG_USE_PREBOOT=y -CONFIG_PREBOOT="run cfgscr; run brdefaultip" -CONFIG_SYS_CONSOLE_IS_IN_ENV=y -CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y -CONFIG_SYS_CONSOLE_INFO_QUIET=y -# CONFIG_DISPLAY_CPUINFO is not set -# CONFIG_DISPLAY_BOARDINFO is not set -CONFIG_ARCH_MISC_INIT=y -CONFIG_SPL_SYS_MALLOC_SIMPLE=y -CONFIG_SYS_SPL_MALLOC=y -CONFIG_SYS_SPL_MALLOC_SIZE=0x500000 -# CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set -CONFIG_SPL_I2C=y -# CONFIG_SPL_NAND_SUPPORT is not set -CONFIG_SPL_DM_SPI_FLASH=y -CONFIG_SPL_POWER=y -CONFIG_SPL_SPI_LOAD=y -CONFIG_SYS_SPI_U_BOOT_OFFS=0x40000 -CONFIG_SPL_WATCHDOG=y -CONFIG_SPL_YMODEM_SUPPORT=y -CONFIG_HUSH_PARSER=y -CONFIG_SYS_MAXARGS=64 -CONFIG_SYS_CBSIZE=512 -CONFIG_SYS_PBSIZE=532 -CONFIG_CMD_BOOTZ=y -CONFIG_SYS_BOOTM_LEN=0x2000000 -# CONFIG_CMD_IMI is not set -# CONFIG_CMD_XIMG is not set -# CONFIG_CMD_EDITENV is not set -# CONFIG_CMD_CRC32 is not set -# CONFIG_CMD_FLASH is not set -CONFIG_CMD_GPIO=y -CONFIG_CMD_I2C=y -# CONFIG_CMD_LOADS is not set -CONFIG_CMD_MMC=y -CONFIG_CMD_BKOPS_ENABLE=y -CONFIG_CMD_PART=y -CONFIG_CMD_USB=y -# CONFIG_CMD_ITEST is not set -CONFIG_CMD_DHCP=y -CONFIG_BOOTP_MAY_FAIL=y -# CONFIG_CMD_NFS is not set -CONFIG_SYS_DISABLE_AUTOLOAD=y -CONFIG_CMD_MII=y -CONFIG_CMD_PING=y -CONFIG_CMD_BOOTCOUNT=y -CONFIG_CMD_CACHE=y -CONFIG_CMD_TIME=y -CONFIG_CMD_EXT4=y -CONFIG_CMD_EXT4_WRITE=y -CONFIG_CMD_FAT=y -CONFIG_CMD_FS_GENERIC=y -# CONFIG_SPL_DOS_PARTITION is not set -CONFIG_OF_CONTROL=y -CONFIG_SPL_OF_CONTROL=y -CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clocks clock-names interrupt-parent interrupt-controller interrupt-cells dma-names dmas " -CONFIG_ENV_OVERWRITE=y -CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_SYS_REDUNDAND_ENVIRONMENT=y -CONFIG_SYS_RELOC_GD_ENV_ADDR=y -CONFIG_VERSION_VARIABLE=y -CONFIG_NET_RETRY_COUNT=10 -CONFIG_BOOTP_SEND_HOSTNAME=y -CONFIG_NET_RANDOM_ETHADDR=y -CONFIG_NETCONSOLE=y -CONFIG_DM=y -CONFIG_SPL_DM=y -CONFIG_SPL_DM_SEQ_ALIAS=y -# CONFIG_OF_TRANSLATE is not set -CONFIG_BOOTCOUNT_LIMIT=y -CONFIG_DM_I2C=y -CONFIG_I2C_SET_DEFAULT_BUS_NUM=y -CONFIG_MISC=y -CONFIG_MMC_OMAP_HS=y -CONFIG_MTD=y -CONFIG_DM_SPI_FLASH=y -CONFIG_SF_DEFAULT_SPEED=24000000 -CONFIG_SPI_FLASH_STMICRO=y -CONFIG_SPI_FLASH_WINBOND=y -# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set -CONFIG_PHY_NATSEMI=y -CONFIG_DRIVER_TI_CPSW=y -CONFIG_DM_PMIC=y -# CONFIG_SPL_DM_PMIC is not set -CONFIG_PMIC_TPS65217=y -CONFIG_DM_SERIAL=y -CONFIG_SPI=y -CONFIG_DM_SPI=y -CONFIG_OMAP3_SPI=y -CONFIG_USB=y -CONFIG_USB_MUSB_HOST=y -CONFIG_USB_MUSB_GADGET=y -CONFIG_USB_MUSB_TI=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_FAT_WRITE=y -CONFIG_LZO=y -# CONFIG_OF_LIBFDT_OVERLAY is not set -# CONFIG_EFI_LOADER is not set diff --git a/configs/crs305-1g-4s-bit_defconfig b/configs/crs305-1g-4s-bit_defconfig index 1b46ab4bf9..463f474a8f 100644 --- a/configs/crs305-1g-4s-bit_defconfig +++ b/configs/crs305-1g-4s-bit_defconfig @@ -37,7 +37,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ARP_TIMEOUT=200 CONFIG_NET_RETRY_COUNT=50 -CONFIG_BLK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_ENV=y # CONFIG_MMC is not set @@ -51,4 +50,3 @@ CONFIG_PCI=y CONFIG_PCI_MVEBU=y CONFIG_SYS_NS16550=y CONFIG_KIRKWOOD_SPI=y -# CONFIG_EFI_LOADER is not set diff --git a/configs/crs305-1g-4s_defconfig b/configs/crs305-1g-4s_defconfig index a7a3ffe481..84d23a24cc 100644 --- a/configs/crs305-1g-4s_defconfig +++ b/configs/crs305-1g-4s_defconfig @@ -38,7 +38,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ARP_TIMEOUT=200 CONFIG_NET_RETRY_COUNT=50 -CONFIG_BLK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_ENV=y # CONFIG_MMC is not set @@ -52,4 +51,3 @@ CONFIG_PCI=y CONFIG_PCI_MVEBU=y CONFIG_SYS_NS16550=y CONFIG_KIRKWOOD_SPI=y -# CONFIG_EFI_LOADER is not set diff --git a/configs/crs326-24g-2s-bit_defconfig b/configs/crs326-24g-2s-bit_defconfig index 70f71de6ae..1eb70e5a32 100644 --- a/configs/crs326-24g-2s-bit_defconfig +++ b/configs/crs326-24g-2s-bit_defconfig @@ -37,7 +37,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ARP_TIMEOUT=200 CONFIG_NET_RETRY_COUNT=50 -CONFIG_BLK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_ENV=y # CONFIG_MMC is not set @@ -51,4 +50,3 @@ CONFIG_PCI=y CONFIG_PCI_MVEBU=y CONFIG_SYS_NS16550=y CONFIG_KIRKWOOD_SPI=y -# CONFIG_EFI_LOADER is not set diff --git a/configs/crs326-24g-2s_defconfig b/configs/crs326-24g-2s_defconfig index 5991b62923..44cb0b0663 100644 --- a/configs/crs326-24g-2s_defconfig +++ b/configs/crs326-24g-2s_defconfig @@ -37,7 +37,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ARP_TIMEOUT=200 CONFIG_NET_RETRY_COUNT=50 -CONFIG_BLK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_ENV=y # CONFIG_MMC is not set @@ -51,4 +50,3 @@ CONFIG_PCI=y CONFIG_PCI_MVEBU=y CONFIG_SYS_NS16550=y CONFIG_KIRKWOOD_SPI=y -# CONFIG_EFI_LOADER is not set diff --git a/configs/crs328-4c-20s-4s-bit_defconfig b/configs/crs328-4c-20s-4s-bit_defconfig index 434e9fb90f..95008cf1cb 100644 --- a/configs/crs328-4c-20s-4s-bit_defconfig +++ b/configs/crs328-4c-20s-4s-bit_defconfig @@ -37,7 +37,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ARP_TIMEOUT=200 CONFIG_NET_RETRY_COUNT=50 -CONFIG_BLK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_ENV=y # CONFIG_MMC is not set @@ -51,4 +50,3 @@ CONFIG_PCI=y CONFIG_PCI_MVEBU=y CONFIG_SYS_NS16550=y CONFIG_KIRKWOOD_SPI=y -# CONFIG_EFI_LOADER is not set diff --git a/configs/crs328-4c-20s-4s_defconfig b/configs/crs328-4c-20s-4s_defconfig index 8e08cceaac..2f6cade9bd 100644 --- a/configs/crs328-4c-20s-4s_defconfig +++ b/configs/crs328-4c-20s-4s_defconfig @@ -37,7 +37,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ARP_TIMEOUT=200 CONFIG_NET_RETRY_COUNT=50 -CONFIG_BLK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_ENV=y # CONFIG_MMC is not set @@ -51,4 +50,3 @@ CONFIG_PCI=y CONFIG_PCI_MVEBU=y CONFIG_SYS_NS16550=y CONFIG_KIRKWOOD_SPI=y -# CONFIG_EFI_LOADER is not set diff --git a/configs/dh_imx6_defconfig b/configs/dh_imx6_defconfig index 4b6776ea9c..c7fb2c67a7 100644 --- a/configs/dh_imx6_defconfig +++ b/configs/dh_imx6_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SPL_SYS_L2_PL310=y CONFIG_ARCH_MX6=y CONFIG_SYS_TEXT_BASE=0x17800000 CONFIG_SYS_MALLOC_F_LEN=0x1000 diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig index 4de32099ed..e5e70a2ada 100644 --- a/configs/dragonboard410c_defconfig +++ b/configs/dragonboard410c_defconfig @@ -43,7 +43,7 @@ CONFIG_FASTBOOT_BUF_ADDR=0x91000000 CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_MSM_GPIO=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_LED=y CONFIG_LED_GPIO=y CONFIG_MMC_SDHCI=y @@ -52,7 +52,7 @@ CONFIG_PHY=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_DM_PMIC=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_MSM_SERIAL=y CONFIG_SPMI_MSM=y CONFIG_USB=y diff --git a/configs/dragonboard820c_defconfig b/configs/dragonboard820c_defconfig index 855f628213..e2e2e627ae 100644 --- a/configs/dragonboard820c_defconfig +++ b/configs/dragonboard820c_defconfig @@ -36,12 +36,12 @@ CONFIG_ENV_EXT4_INTERFACE="mmc" CONFIG_ENV_EXT4_DEVICE_AND_PART="0:1" CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_CLK=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_MSM=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_DM_PMIC=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_MSM_SERIAL=y CONFIG_SPMI_MSM=y diff --git a/configs/dragonboard845c_defconfig b/configs/dragonboard845c_defconfig index cf1a1d25cf..a69d82761a 100644 --- a/configs/dragonboard845c_defconfig +++ b/configs/dragonboard845c_defconfig @@ -20,10 +20,10 @@ CONFIG_CMD_GPIO=y # CONFIG_NET is not set CONFIG_CLK=y CONFIG_MSM_GPIO=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_PINCTRL=y CONFIG_DM_PMIC=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_MSM_GENI_SERIAL=y CONFIG_SPMI_MSM=y CONFIG_LMB_MAX_REGIONS=64 diff --git a/configs/durian_defconfig b/configs/durian_defconfig index d9e3768bb0..4d2ccab8a0 100644 --- a/configs/durian_defconfig +++ b/configs/durian_defconfig @@ -32,7 +32,6 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM=y CONFIG_SCSI_AHCI=y CONFIG_AHCI_PCI=y -CONFIG_BLK=y # CONFIG_MMC is not set CONFIG_PCI=y CONFIG_PCI_PHYTIUM=y diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig index 0bef043ea6..3061cbec41 100644 --- a/configs/evb-ast2500_defconfig +++ b/configs/evb-ast2500_defconfig @@ -39,6 +39,16 @@ CONFIG_SYS_I2C_ASPEED=y CONFIG_I2C_EEPROM=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ASPEED=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_ISSI=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_SST=y +CONFIG_SPI_FLASH_WINBOND=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set CONFIG_PHY_REALTEK=y CONFIG_FTGMAC100=y CONFIG_PHY=y @@ -47,6 +57,10 @@ CONFIG_RAM=y CONFIG_DM_RESET=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_SPI_DIRMAP=y +CONFIG_SPI_ASPEED_SMC=y CONFIG_SYSRESET=y CONFIG_TIMER=y CONFIG_WDT=y diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig index 1284d51918..1981f895d6 100644 --- a/configs/evb-ast2600_defconfig +++ b/configs/evb-ast2600_defconfig @@ -87,6 +87,16 @@ CONFIG_SYS_I2C_ASPEED=y CONFIG_I2C_EEPROM=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ASPEED=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_ISSI=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_SST=y +CONFIG_SPI_FLASH_WINBOND=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set CONFIG_PHY_REALTEK=y CONFIG_DM_MDIO=y CONFIG_FTGMAC100=y @@ -98,6 +108,10 @@ CONFIG_SPL_RAM=y CONFIG_DM_RESET=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_SPI_DIRMAP=y +CONFIG_SPI_ASPEED_SMC=y CONFIG_SYSRESET=y CONFIG_SPL_SYSRESET=y CONFIG_WDT=y diff --git a/configs/gardena-smart-gateway-at91sam_defconfig b/configs/gardena-smart-gateway-at91sam_defconfig index 8de93e49ff..5574b9d17f 100644 --- a/configs/gardena-smart-gateway-at91sam_defconfig +++ b/configs/gardena-smart-gateway-at91sam_defconfig @@ -89,7 +89,6 @@ CONFIG_VERSION_VARIABLE=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y CONFIG_SPL_DM=y -CONFIG_BLK=y CONFIG_CLK=y CONFIG_CLK_AT91=y CONFIG_AT91_GPIO=y diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index b9ee281be9..992e850999 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -78,7 +78,6 @@ CONFIG_VERSION_VARIABLE=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM=y # CONFIG_DM_DEVICE_REMOVE is not set -CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_LED=y CONFIG_LED_BLINK=y diff --git a/configs/imx8mn_bsh_smm_s2_defconfig b/configs/imx8mn_bsh_smm_s2_defconfig index 2603aa35e7..588597f92b 100644 --- a/configs/imx8mn_bsh_smm_s2_defconfig +++ b/configs/imx8mn_bsh_smm_s2_defconfig @@ -45,6 +45,8 @@ CONFIG_SPL_DMA=y CONFIG_SPL_I2C=y CONFIG_SPL_MTD_SUPPORT=y CONFIG_SPL_NAND_SUPPORT=y +CONFIG_SPL_NAND_BASE=y +CONFIG_SPL_NAND_IDENT=y CONFIG_SPL_POWER=y CONFIG_SPL_WATCHDOG=y CONFIG_SYS_MAXARGS=64 diff --git a/configs/j7200_hs_evm_a72_defconfig b/configs/j7200_hs_evm_a72_defconfig new file mode 100644 index 0000000000..7c95b00af5 --- /dev/null +++ b/configs/j7200_hs_evm_a72_defconfig @@ -0,0 +1,205 @@ +CONFIG_ARM=y +CONFIG_ARCH_K3=y +CONFIG_TI_SECURE_DEVICE=y +CONFIG_SYS_MALLOC_LEN=0x2000000 +CONFIG_SYS_MALLOC_F_LEN=0x8000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 +CONFIG_SOC_K3_J721E=y +CONFIG_TARGET_J7200_A72_EVM=y +CONFIG_ENV_SIZE=0x20000 +CONFIG_ENV_OFFSET=0x680000 +CONFIG_DM_GPIO=y +CONFIG_SPL_DM_SPI=y +CONFIG_DEFAULT_DEVICE_TREE="k3-j7200-common-proc-board" +CONFIG_SPL_TEXT_BASE=0x80080000 +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_ENV_OFFSET_REDUND=0x6A0000 +CONFIG_SPL_FS_FAT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI=y +# CONFIG_PSCI_RESET is not set +CONFIG_DISTRO_DEFAULTS=y +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80480000 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000 +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_OF_BOARD_SETUP=y +CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_fit_${boot}; run get_overlaystring; run run_fit" +CONFIG_LOGLEVEL=7 +CONFIG_SPL_MAX_SIZE=0xc0000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x80a00000 +CONFIG_SPL_BSS_MAX_SIZE=0x80000 +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_STACK_R=y +CONFIG_SYS_SPL_MALLOC=y +CONFIG_SYS_SPL_MALLOC_SIZE=0x800000 +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400 +CONFIG_SPL_DMA=y +CONFIG_SPL_ENV_SUPPORT=y +CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img" +CONFIG_SPL_I2C=y +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y +CONFIG_SPL_NOR_SUPPORT=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_RAM_SUPPORT=y +CONFIG_SPL_RAM_DEVICE=y +# CONFIG_SPL_SPI_FLASH_TINY is not set +CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000 +CONFIG_SPL_USB_GADGET=y +CONFIG_SPL_DFU=y +CONFIG_SPL_YMODEM_SUPPORT=y +CONFIG_SYS_MAXARGS=64 +CONFIG_CMD_ASKENV=y +CONFIG_CMD_DFU=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y +CONFIG_CMD_REMOTEPROC=y +CONFIG_CMD_UFS=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0,nor0=47034000.hyperbus" +CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),128k(ospi.env),128k(ospi.env.backup),1m(ospi.sysfw),-@8m(ospi.rootfs);47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),1m(hbmc.sysfw),-@8m(hbmc.rootfs)" +CONFIG_CMD_UBI=y +# CONFIG_ISO_PARTITION is not set +# CONFIG_SPL_EFI_PARTITION is not set +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_SPL_MULTI_DTB_FIT=y +CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_REDUNDAND_ENVIRONMENT=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=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_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_CLK_CCF=y +CONFIG_CLK_TI_SCI=y +CONFIG_DFU_MMC=y +CONFIG_DFU_RAM=y +CONFIG_DFU_SF=y +CONFIG_SYS_DFU_DATA_BUF_SIZE=0x40000 +CONFIG_SYS_DFU_MAX_FILE_SIZE=0x800000 +CONFIG_DMA_CHANNELS=y +CONFIG_TI_K3_NAVSS_UDMA=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x82000000 +CONFIG_FASTBOOT_BUF_SIZE=0x2F000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_FASTBOOT_CMD_OEM_FORMAT=y +CONFIG_TI_SCI_PROTOCOL=y +CONFIG_DA8XX_GPIO=y +CONFIG_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_DM_I2C_GPIO=y +CONFIG_SYS_I2C_OMAP24XX=y +CONFIG_DM_MAILBOX=y +CONFIG_K3_SEC_PROXY=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_MMC_UHS_SUPPORT=y +CONFIG_MMC_HS400_SUPPORT=y +CONFIG_SPL_MMC_HS400_SUPPORT=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ADMA=y +CONFIG_SPL_MMC_SDHCI_ADMA=y +CONFIG_MMC_SDHCI_AM654=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_FLASH_CFI_MTD=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_HBMC_AM654=y +CONFIG_SYS_MAX_FLASH_BANKS_DETECT=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_STMICRO=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_SPI_FLASH_MTD=y +CONFIG_MULTIPLEXER=y +CONFIG_MUX_MMIO=y +CONFIG_PHY_FIXED=y +CONFIG_TI_AM65_CPSW_NUSS=y +CONFIG_PHY=y +CONFIG_SPL_PHY=y +CONFIG_PHY_CADENCE_TORRENT=y +CONFIG_PHY_J721E_WIZ=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_GENERIC is not set +CONFIG_PINCTRL_SINGLE=y +CONFIG_POWER_DOMAIN=y +CONFIG_TI_SCI_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_REMOTEPROC_TI_K3_R5F=y +CONFIG_DM_RESET=y +CONFIG_RESET_TI_SCI=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y +CONFIG_DM_SERIAL=y +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y +CONFIG_SOC_TI=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_HAS_CQSPI_REF_CLK=y +CONFIG_CQSPI_REF_CLK=133333333 +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_SYSRESET_TI_SCI=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_SPL_DM_USB_GADGET=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +CONFIG_USB_CDNS3_HOST=y +CONFIG_SPL_USB_CDNS3_GADGET=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" +CONFIG_USB_GADGET_VENDOR_NUM=0x0451 +CONFIG_USB_GADGET_PRODUCT_NUM=0x6164 +CONFIG_UFS=y +CONFIG_CADENCE_UFS=y +CONFIG_TI_J721E_UFS=y +CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/configs/j7200_hs_evm_r5_defconfig b/configs/j7200_hs_evm_r5_defconfig new file mode 100644 index 0000000000..0cf9c688e4 --- /dev/null +++ b/configs/j7200_hs_evm_r5_defconfig @@ -0,0 +1,171 @@ +CONFIG_ARM=y +CONFIG_ARCH_K3=y +CONFIG_TI_SECURE_DEVICE=y +CONFIG_SYS_MALLOC_LEN=0x2000000 +CONFIG_SYS_MALLOC_F_LEN=0x70000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SOC_K3_J721E=y +CONFIG_K3_EARLY_CONS=y +CONFIG_TARGET_J7200_R5_EVM=y +CONFIG_ENV_SIZE=0x20000 +CONFIG_DM_GPIO=y +CONFIG_SPL_DM_SPI=y +CONFIG_DEFAULT_DEVICE_TREE="k3-j7200-r5-common-proc-board" +CONFIG_SPL_TEXT_BASE=0x41c00000 +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_SPL_FS_FAT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI=y +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x41cf5bfc +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_LOAD_FIT_ADDRESS=0x80080000 +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_USE_BOOTCOMMAND=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_SPL_MAX_SIZE=0xc0000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x41cf5bfc +CONFIG_SPL_BSS_MAX_SIZE=0xa000 +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_STACK_R=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SYS_SPL_MALLOC=y +CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y +CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x84000000 +CONFIG_SYS_SPL_MALLOC_SIZE=0x1000000 +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_DMA=y +CONFIG_SPL_ENV_SUPPORT=y +CONFIG_SPL_FS_EXT4=y +CONFIG_SPL_I2C=y +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y +CONFIG_SPL_NOR_SUPPORT=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_RAM_SUPPORT=y +CONFIG_SPL_RAM_DEVICE=y +CONFIG_SPL_REMOTEPROC=y +# CONFIG_SPL_SPI_FLASH_TINY is not set +CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000 +CONFIG_SPL_USB_GADGET=y +CONFIG_SPL_DFU=y +CONFIG_SPL_YMODEM_SUPPORT=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_MAXARGS=64 +CONFIG_SYS_BOOTM_LEN=0x4000000 +CONFIG_CMD_DFU=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPT=y +CONFIG_CMD_MMC=y +CONFIG_CMD_REMOTEPROC=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_CMD_FAT=y +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_SPL_CLK_CCF=y +CONFIG_SPL_CLK_K3_PLL=y +CONFIG_SPL_CLK_K3=y +CONFIG_SYS_DFU_DATA_BUF_SIZE=0x40000 +CONFIG_DMA_CHANNELS=y +CONFIG_TI_K3_NAVSS_UDMA=y +CONFIG_TI_SCI_PROTOCOL=y +CONFIG_DA8XX_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_FS_LOADER=y +CONFIG_SPL_FS_LOADER=y +CONFIG_K3_AVS0=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_SPL_MMC_HS400_SUPPORT=y +CONFIG_MMC_SDHCI=y +CONFIG_SPL_MMC_SDHCI_ADMA=y +CONFIG_MMC_SDHCI_AM654=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_FLASH_CFI_MTD=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_HBMC_AM654=y +CONFIG_SYS_MAX_FLASH_BANKS_DETECT=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_GENERIC is not set +CONFIG_PINCTRL_SINGLE=y +CONFIG_POWER_DOMAIN=y +CONFIG_TI_SCI_POWER_DOMAIN=y +CONFIG_TI_POWER_DOMAIN=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_TPS65941=y +CONFIG_DM_REGULATOR=y +CONFIG_SPL_DM_REGULATOR=y +CONFIG_DM_REGULATOR_TPS65941=y +CONFIG_K3_SYSTEM_CONTROLLER=y +CONFIG_REMOTEPROC_TI_K3_ARM64=y +CONFIG_DM_RESET=y +CONFIG_RESET_TI_SCI=y +CONFIG_DM_SERIAL=y +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y +CONFIG_SOC_TI=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_HAS_CQSPI_REF_CLK=y +CONFIG_CQSPI_REF_CLK=133333333 +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_SYSRESET_TI_SCI=y +CONFIG_TIMER=y +CONFIG_SPL_TIMER=y +CONFIG_OMAP_TIMER=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_SPL_DM_USB_GADGET=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +CONFIG_SPL_USB_CDNS3_GADGET=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" +CONFIG_USB_GADGET_VENDOR_NUM=0x0451 +CONFIG_USB_GADGET_PRODUCT_NUM=0x6164 +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_FS_EXT4=y +CONFIG_FS_FAT_MAX_CLUSTSIZE=16384 +CONFIG_LIB_RATIONAL=y +CONFIG_SPL_LIB_RATIONAL=y diff --git a/configs/j721s2_evm_a72_defconfig b/configs/j721s2_evm_a72_defconfig index 671fce6268..a06312f4f5 100644 --- a/configs/j721s2_evm_a72_defconfig +++ b/configs/j721s2_evm_a72_defconfig @@ -32,7 +32,7 @@ CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000 # CONFIG_USE_SPL_FIT_GENERATOR is not set CONFIG_OF_BOARD_SETUP=y -CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run main_cpsw0_qsgmii_phyinit; run boot_rprocs; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern" +CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern" CONFIG_LOGLEVEL=7 CONFIG_SPL_MAX_SIZE=0xc0000 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y diff --git a/configs/j721s2_hs_evm_a72_defconfig b/configs/j721s2_hs_evm_a72_defconfig new file mode 100644 index 0000000000..7ae0c3ba7b --- /dev/null +++ b/configs/j721s2_hs_evm_a72_defconfig @@ -0,0 +1,214 @@ +CONFIG_ARM=y +CONFIG_ARCH_K3=y +CONFIG_TI_SECURE_DEVICE=y +CONFIG_SYS_MALLOC_LEN=0x2000000 +CONFIG_SYS_MALLOC_F_LEN=0x8000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 +CONFIG_SOC_K3_J721S2=y +CONFIG_TARGET_J721S2_A72_EVM=y +CONFIG_ENV_SIZE=0x20000 +CONFIG_ENV_OFFSET=0x680000 +CONFIG_DM_GPIO=y +CONFIG_SPL_DM_SPI=y +CONFIG_DEFAULT_DEVICE_TREE="k3-j721s2-common-proc-board" +CONFIG_SPL_TEXT_BASE=0x80080000 +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_ENV_OFFSET_REDUND=0x6A0000 +CONFIG_SPL_FS_FAT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI=y +# CONFIG_PSCI_RESET is not set +CONFIG_DISTRO_DEFAULTS=y +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80480000 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000 +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_OF_BOARD_SETUP=y +CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_fit_${boot}; run get_overlaystring; run run_fit" +CONFIG_LOGLEVEL=7 +CONFIG_SPL_MAX_SIZE=0xc0000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x80a00000 +CONFIG_SPL_BSS_MAX_SIZE=0x80000 +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_STACK_R=y +CONFIG_SYS_SPL_MALLOC=y +CONFIG_SYS_SPL_MALLOC_SIZE=0x800000 +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400 +CONFIG_SPL_DMA=y +CONFIG_SPL_ENV_SUPPORT=y +CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img" +CONFIG_SPL_I2C=y +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y +CONFIG_SPL_NOR_SUPPORT=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_RAM_SUPPORT=y +CONFIG_SPL_RAM_DEVICE=y +# CONFIG_SPL_SPI_FLASH_TINY is not set +CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000 +CONFIG_SPL_THERMAL=y +CONFIG_SPL_USB_GADGET=y +CONFIG_SPL_DFU=y +CONFIG_SPL_YMODEM_SUPPORT=y +CONFIG_SYS_MAXARGS=64 +CONFIG_CMD_ASKENV=y +CONFIG_CMD_DFU=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y +CONFIG_CMD_REMOTEPROC=y +CONFIG_CMD_UFS=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0,nor0=47034000.hyperbus" +CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),256k(ospi.env),256k(ospi.env.backup),57088k@8m(ospi.rootfs),256k(ospi.phypattern);47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),-@8m(hbmc.rootfs)" +CONFIG_CMD_UBI=y +# CONFIG_ISO_PARTITION is not set +# CONFIG_SPL_EFI_PARTITION is not set +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_SPL_MULTI_DTB_FIT=y +CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_REDUNDAND_ENVIRONMENT=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=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_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_CLK_CCF=y +CONFIG_CLK_TI_SCI=y +CONFIG_DFU_MMC=y +CONFIG_DFU_RAM=y +CONFIG_DFU_SF=y +CONFIG_SYS_DFU_DATA_BUF_SIZE=0x40000 +CONFIG_SYS_DFU_MAX_FILE_SIZE=0x800000 +CONFIG_DMA_CHANNELS=y +CONFIG_TI_K3_NAVSS_UDMA=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x82000000 +CONFIG_FASTBOOT_BUF_SIZE=0x2F000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_FASTBOOT_CMD_OEM_FORMAT=y +CONFIG_TI_SCI_PROTOCOL=y +CONFIG_DA8XX_GPIO=y +CONFIG_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_DM_I2C_GPIO=y +CONFIG_SYS_I2C_OMAP24XX=y +CONFIG_DM_MAILBOX=y +CONFIG_K3_SEC_PROXY=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_MMC_UHS_SUPPORT=y +CONFIG_MMC_HS400_SUPPORT=y +CONFIG_SPL_MMC_HS400_SUPPORT=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ADMA=y +CONFIG_SPL_MMC_SDHCI_ADMA=y +CONFIG_MMC_SDHCI_AM654=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_FLASH_CFI_MTD=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_SYS_MAX_FLASH_BANKS_DETECT=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_SOFT_RESET=y +CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_S28HS512T=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_MT35XU=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_SPI_FLASH_MTD=y +CONFIG_MULTIPLEXER=y +CONFIG_MUX_MMIO=y +CONFIG_PHY_TI_DP83867=y +CONFIG_PHY_FIXED=y +CONFIG_TI_AM65_CPSW_NUSS=y +CONFIG_PHY=y +CONFIG_SPL_PHY=y +CONFIG_PHY_CADENCE_TORRENT=y +CONFIG_PHY_J721E_WIZ=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_GENERIC is not set +CONFIG_PINCTRL_SINGLE=y +CONFIG_POWER_DOMAIN=y +CONFIG_TI_SCI_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_REMOTEPROC_TI_K3_DSP=y +CONFIG_REMOTEPROC_TI_K3_R5F=y +CONFIG_DM_RESET=y +CONFIG_RESET_TI_SCI=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y +CONFIG_DM_SERIAL=y +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y +CONFIG_SOC_TI=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_HAS_CQSPI_REF_CLK=y +CONFIG_CQSPI_REF_CLK=133333333 +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_SYSRESET_TI_SCI=y +CONFIG_DM_THERMAL=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_SPL_DM_USB_GADGET=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +CONFIG_USB_CDNS3_HOST=y +CONFIG_SPL_USB_CDNS3_GADGET=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" +CONFIG_USB_GADGET_VENDOR_NUM=0x0451 +CONFIG_USB_GADGET_PRODUCT_NUM=0x6168 +CONFIG_UFS=y +CONFIG_CADENCE_UFS=y +CONFIG_TI_J721E_UFS=y +CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/configs/j721s2_hs_evm_r5_defconfig b/configs/j721s2_hs_evm_r5_defconfig new file mode 100644 index 0000000000..8df968c65c --- /dev/null +++ b/configs/j721s2_hs_evm_r5_defconfig @@ -0,0 +1,177 @@ +CONFIG_ARM=y +CONFIG_ARCH_K3=y +CONFIG_TI_SECURE_DEVICE=y +CONFIG_SYS_MALLOC_LEN=0x2000000 +CONFIG_SYS_MALLOC_F_LEN=0x10000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SOC_K3_J721S2=y +CONFIG_K3_EARLY_CONS=y +CONFIG_TARGET_J721S2_R5_EVM=y +CONFIG_ENV_SIZE=0x20000 +CONFIG_DM_GPIO=y +CONFIG_SPL_DM_SPI=y +CONFIG_DEFAULT_DEVICE_TREE="k3-j721s2-r5-common-proc-board" +CONFIG_SPL_TEXT_BASE=0x41c00000 +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_SPL_SIZE_LIMIT=0x80000 +CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK=0x4000 +CONFIG_SPL_FS_FAT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI=y +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x41c76000 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_LOAD_FIT_ADDRESS=0x80080000 +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_USE_BOOTCOMMAND=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_SPL_SIZE_LIMIT_SUBTRACT_GD=y +CONFIG_SPL_SIZE_LIMIT_SUBTRACT_MALLOC=y +CONFIG_SPL_MAX_SIZE=0xc0000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x41c76000 +CONFIG_SPL_BSS_MAX_SIZE=0xa000 +CONFIG_SPL_SYS_REPORT_STACK_F_USAGE=y +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_STACK_R=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SYS_SPL_MALLOC=y +CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y +CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x84000000 +CONFIG_SYS_SPL_MALLOC_SIZE=0x1000000 +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_DMA=y +CONFIG_SPL_ENV_SUPPORT=y +CONFIG_SPL_FS_EXT4=y +CONFIG_SPL_I2C=y +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y +CONFIG_SPL_NOR_SUPPORT=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_RAM_SUPPORT=y +CONFIG_SPL_RAM_DEVICE=y +CONFIG_SPL_REMOTEPROC=y +# CONFIG_SPL_SPI_FLASH_TINY is not set +CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000 +CONFIG_SPL_THERMAL=y +CONFIG_SPL_USB_GADGET=y +CONFIG_SPL_DFU=y +CONFIG_SPL_YMODEM_SUPPORT=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_MAXARGS=64 +CONFIG_SYS_BOOTM_LEN=0x4000000 +CONFIG_CMD_DFU=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPT=y +CONFIG_CMD_MMC=y +CONFIG_CMD_REMOTEPROC=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_CMD_FAT=y +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_SPL_CLK_CCF=y +CONFIG_SPL_CLK_K3_PLL=y +CONFIG_SPL_CLK_K3=y +CONFIG_SYS_DFU_DATA_BUF_SIZE=0x40000 +CONFIG_DMA_CHANNELS=y +CONFIG_TI_K3_NAVSS_UDMA=y +CONFIG_TI_SCI_PROTOCOL=y +CONFIG_DA8XX_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_FS_LOADER=y +CONFIG_SPL_FS_LOADER=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_SPL_MMC_HS400_SUPPORT=y +CONFIG_MMC_SDHCI=y +CONFIG_SPL_MMC_SDHCI_ADMA=y +CONFIG_MMC_SDHCI_AM654=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_FLASH_CFI_MTD=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_SYS_MAX_FLASH_BANKS_DETECT=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_SOFT_RESET=y +CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_S28HS512T=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_MT35XU=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_GENERIC is not set +CONFIG_PINCTRL_SINGLE=y +CONFIG_POWER_DOMAIN=y +CONFIG_TI_POWER_DOMAIN=y +CONFIG_K3_SYSTEM_CONTROLLER=y +CONFIG_REMOTEPROC_TI_K3_ARM64=y +CONFIG_DM_RESET=y +CONFIG_RESET_TI_SCI=y +CONFIG_DM_SERIAL=y +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y +CONFIG_SOC_TI=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_HAS_CQSPI_REF_CLK=y +CONFIG_CQSPI_REF_CLK=133333333 +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_SYSRESET_TI_SCI=y +CONFIG_DM_THERMAL=y +CONFIG_TIMER=y +CONFIG_SPL_TIMER=y +CONFIG_OMAP_TIMER=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_SPL_DM_USB_GADGET=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +CONFIG_SPL_USB_CDNS3_GADGET=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" +CONFIG_USB_GADGET_VENDOR_NUM=0x0451 +CONFIG_USB_GADGET_PRODUCT_NUM=0x6168 +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_FS_EXT4=y +CONFIG_FS_FAT_MAX_CLUSTSIZE=16384 +CONFIG_PANIC_HANG=y +CONFIG_LIB_RATIONAL=y +CONFIG_SPL_LIB_RATIONAL=y diff --git a/configs/ls1021atwr_nor_SECURE_BOOT_defconfig b/configs/ls1021atwr_nor_SECURE_BOOT_defconfig index e385ea47aa..f66aacc991 100644 --- a/configs/ls1021atwr_nor_SECURE_BOOT_defconfig +++ b/configs/ls1021atwr_nor_SECURE_BOOT_defconfig @@ -33,6 +33,7 @@ CONFIG_SILENT_CONSOLE=y CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 CONFIG_SYS_BOOTM_LEN=0x4000000 diff --git a/configs/ls1021atwr_nor_defconfig b/configs/ls1021atwr_nor_defconfig index 1d4e57c6ed..110cf5d3d2 100644 --- a/configs/ls1021atwr_nor_defconfig +++ b/configs/ls1021atwr_nor_defconfig @@ -34,6 +34,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_ARCH_MISC_INIT=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 CONFIG_SYS_BOOTM_LEN=0x4000000 diff --git a/configs/ls1021atwr_nor_lpuart_defconfig b/configs/ls1021atwr_nor_lpuart_defconfig index 391f46459f..9d8dbbf043 100644 --- a/configs/ls1021atwr_nor_lpuart_defconfig +++ b/configs/ls1021atwr_nor_lpuart_defconfig @@ -34,6 +34,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_ARCH_MISC_INIT=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 CONFIG_SYS_BOOTM_LEN=0x4000000 diff --git a/configs/ls1021atwr_qspi_defconfig b/configs/ls1021atwr_qspi_defconfig index 3b37641c6a..039c9842e9 100644 --- a/configs/ls1021atwr_qspi_defconfig +++ b/configs/ls1021atwr_qspi_defconfig @@ -35,6 +35,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_ARCH_MISC_INIT=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 CONFIG_SYS_BOOTM_LEN=0x4000000 diff --git a/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig b/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig index 38c074d158..a916959d57 100644 --- a/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig +++ b/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig @@ -43,6 +43,7 @@ CONFIG_SILENT_CONSOLE=y CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SPL_MAX_SIZE=0x1a000 CONFIG_SPL_PAD_TO=0x1c000 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y diff --git a/configs/ls1021atwr_sdcard_ifc_defconfig b/configs/ls1021atwr_sdcard_ifc_defconfig index 3dd0871213..65f033aed9 100644 --- a/configs/ls1021atwr_sdcard_ifc_defconfig +++ b/configs/ls1021atwr_sdcard_ifc_defconfig @@ -44,6 +44,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_ARCH_MISC_INIT=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SPL_MAX_SIZE=0x1a000 CONFIG_SPL_PAD_TO=0x1c000 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y diff --git a/configs/ls1021atwr_sdcard_qspi_defconfig b/configs/ls1021atwr_sdcard_qspi_defconfig index 84722b01e8..45c9179727 100644 --- a/configs/ls1021atwr_sdcard_qspi_defconfig +++ b/configs/ls1021atwr_sdcard_qspi_defconfig @@ -45,6 +45,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_ARCH_MISC_INIT=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SPL_MAX_SIZE=0x1a000 CONFIG_SPL_PAD_TO=0x1c000 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y diff --git a/configs/lschlv2_defconfig b/configs/lschlv2_defconfig index cfccfdcfc4..441cd8ef24 100644 --- a/configs/lschlv2_defconfig +++ b/configs/lschlv2_defconfig @@ -70,7 +70,5 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_KIRKWOOD_SPI=y -CONFIG_TIMER=y -CONFIG_ORION_TIMER=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/lsxhl_defconfig b/configs/lsxhl_defconfig index 1945b72450..f350f8ff42 100644 --- a/configs/lsxhl_defconfig +++ b/configs/lsxhl_defconfig @@ -71,7 +71,5 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_KIRKWOOD_SPI=y -CONFIG_TIMER=y -CONFIG_ORION_TIMER=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index b5c5efe596..01c93d5c4e 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -43,9 +43,9 @@ CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_CMD_IMLS=y CONFIG_CMD_SPL=y CONFIG_CMD_ASKENV=y +CONFIG_CMD_GREPENV=y CONFIG_CMD_GPIO=y CONFIG_CMD_SAVES=y -# CONFIG_CMD_SETEXPR is not set CONFIG_BOOTP_BOOTFILESIZE=y CONFIG_CMD_TFTPPUT=y CONFIG_CMD_CACHE=y diff --git a/configs/mt7981_emmc_rfb_defconfig b/configs/mt7981_emmc_rfb_defconfig new file mode 100644 index 0000000000..5f9f6d8582 --- /dev/null +++ b/configs/mt7981_emmc_rfb_defconfig @@ -0,0 +1,64 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_SYS_TEXT_BASE=0x41e00000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x80000 +CONFIG_ENV_OFFSET=0x300000 +CONFIG_DEFAULT_DEVICE_TREE="mt7981-emmc-rfb" +CONFIG_TARGET_MT7981=y +CONFIG_DEBUG_UART_BASE=0x11002000 +CONFIG_DEBUG_UART_CLOCK=40000000 +CONFIG_SYS_LOAD_ADDR=0x46000000 +CONFIG_DEBUG_UART=y +# CONFIG_AUTOBOOT is not set +CONFIG_DEFAULT_FDT_FILE="mt7981-emmc-rfb" +CONFIG_LOGLEVEL=7 +CONFIG_LOG=y +CONFIG_SYS_PROMPT="MT7981> " +CONFIG_SYS_CBSIZE=512 +CONFIG_SYS_PBSIZE=1049 +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_UNLZ4 is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_GPT_RENAME=y +CONFIG_CMD_LSBLK=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y +CONFIG_CMD_READ=y +CONFIG_CMD_PING=y +CONFIG_CMD_SMC=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_CLK=y +CONFIG_MMC_HS200_SUPPORT=y +CONFIG_MMC_MTK=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7981=y +CONFIG_POWER_DOMAIN=y +CONFIG_MTK_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_SERIAL=y +CONFIG_MTK_SERIAL=y +CONFIG_FAT_WRITE=y +CONFIG_HEXDUMP=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/mt7981_rfb_defconfig b/configs/mt7981_rfb_defconfig new file mode 100644 index 0000000000..88299e3e51 --- /dev/null +++ b/configs/mt7981_rfb_defconfig @@ -0,0 +1,69 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_SYS_TEXT_BASE=0x41e00000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_DEFAULT_DEVICE_TREE="mt7981-rfb" +CONFIG_TARGET_MT7981=y +CONFIG_DEBUG_UART_BASE=0x11002000 +CONFIG_DEBUG_UART_CLOCK=40000000 +CONFIG_SYS_LOAD_ADDR=0x46000000 +CONFIG_DEBUG_UART=y +# CONFIG_AUTOBOOT is not set +CONFIG_DEFAULT_FDT_FILE="mt7981-rfb" +CONFIG_LOGLEVEL=7 +CONFIG_LOG=y +CONFIG_SYS_PROMPT="MT7981> " +CONFIG_SYS_CBSIZE=512 +CONFIG_SYS_PBSIZE=1049 +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_UNLZ4 is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_MTD=y +CONFIG_CMD_SF_TEST=y +CONFIG_CMD_PING=y +CONFIG_CMD_SMC=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_BLK=y +CONFIG_HAVE_BLOCK_DEVICE=y +CONFIG_CLK=y +# CONFIG_MMC is not set +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_SPI_NAND=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_EON=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_ISSI=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_XMC=y +CONFIG_SPI_FLASH_XTX=y +CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7981=y +CONFIG_POWER_DOMAIN=y +CONFIG_MTK_POWER_DOMAIN=y +CONFIG_DM_SERIAL=y +CONFIG_MTK_SERIAL=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_MTK_SPIM=y +CONFIG_HEXDUMP=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/mt7981_sd_rfb_defconfig b/configs/mt7981_sd_rfb_defconfig new file mode 100644 index 0000000000..b5c765bd7c --- /dev/null +++ b/configs/mt7981_sd_rfb_defconfig @@ -0,0 +1,64 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_SYS_TEXT_BASE=0x41e00000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x80000 +CONFIG_ENV_OFFSET=0x300000 +CONFIG_DEFAULT_DEVICE_TREE="mt7981-sd-rfb" +CONFIG_TARGET_MT7981=y +CONFIG_DEBUG_UART_BASE=0x11002000 +CONFIG_DEBUG_UART_CLOCK=40000000 +CONFIG_SYS_LOAD_ADDR=0x46000000 +CONFIG_DEBUG_UART=y +# CONFIG_AUTOBOOT is not set +CONFIG_DEFAULT_FDT_FILE="mt7981-sd-rfb" +CONFIG_LOGLEVEL=7 +CONFIG_LOG=y +CONFIG_SYS_PROMPT="MT7981> " +CONFIG_SYS_CBSIZE=512 +CONFIG_SYS_PBSIZE=1049 +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_UNLZ4 is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_GPT_RENAME=y +CONFIG_CMD_LSBLK=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y +CONFIG_CMD_READ=y +CONFIG_CMD_PING=y +CONFIG_CMD_SMC=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_CLK=y +CONFIG_MMC_HS200_SUPPORT=y +CONFIG_MMC_MTK=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7981=y +CONFIG_POWER_DOMAIN=y +CONFIG_MTK_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_SERIAL=y +CONFIG_MTK_SERIAL=y +CONFIG_FAT_WRITE=y +CONFIG_HEXDUMP=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/mt7986_rfb_defconfig b/configs/mt7986_rfb_defconfig new file mode 100644 index 0000000000..ff1e63b6bd --- /dev/null +++ b/configs/mt7986_rfb_defconfig @@ -0,0 +1,66 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_SYS_TEXT_BASE=0x41e00000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_DEFAULT_DEVICE_TREE="mt7986a-rfb" +CONFIG_TARGET_MT7986=y +CONFIG_DEBUG_UART_BASE=0x11002000 +CONFIG_DEBUG_UART_CLOCK=40000000 +CONFIG_SYS_LOAD_ADDR=0x46000000 +CONFIG_DEBUG_UART=y +# CONFIG_AUTOBOOT is not set +CONFIG_DEFAULT_FDT_FILE="mt7986a-rfb" +CONFIG_LOGLEVEL=7 +CONFIG_LOG=y +CONFIG_SYS_PROMPT="MT7986> " +CONFIG_SYS_CBSIZE=512 +CONFIG_SYS_PBSIZE=1049 +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_UNLZ4 is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_MTD=y +CONFIG_CMD_SF_TEST=y +CONFIG_CMD_PING=y +CONFIG_CMD_SMC=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_CLK=y +# CONFIG_MMC is not set +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_SPI_NAND=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_EON=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_ISSI=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_XMC=y +CONFIG_SPI_FLASH_XTX=y +CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7986=y +CONFIG_POWER_DOMAIN=y +CONFIG_MTK_POWER_DOMAIN=y +CONFIG_DM_SERIAL=y +CONFIG_MTK_SERIAL=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_MTK_SPIM=y +CONFIG_HEXDUMP=y diff --git a/configs/mt7986a_bpir3_emmc_defconfig b/configs/mt7986a_bpir3_emmc_defconfig new file mode 100644 index 0000000000..3e368b68de --- /dev/null +++ b/configs/mt7986a_bpir3_emmc_defconfig @@ -0,0 +1,64 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_SYS_TEXT_BASE=0x41e00000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x80000 +CONFIG_ENV_OFFSET=0x300000 +CONFIG_DEFAULT_DEVICE_TREE="mt7986a-emmc-rfb" +CONFIG_TARGET_MT7986=y +CONFIG_DEBUG_UART_BASE=0x11002000 +CONFIG_DEBUG_UART_CLOCK=40000000 +CONFIG_SYS_LOAD_ADDR=0x46000000 +CONFIG_DEBUG_UART=y +# CONFIG_AUTOBOOT is not set +CONFIG_DEFAULT_FDT_FILE="mt7986a-emmc-rfb" +CONFIG_LOGLEVEL=7 +CONFIG_LOG=y +CONFIG_SYS_PROMPT="MT7986> " +CONFIG_SYS_CBSIZE=512 +CONFIG_SYS_PBSIZE=1049 +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_UNLZ4 is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_GPT_RENAME=y +CONFIG_CMD_LSBLK=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y +CONFIG_CMD_READ=y +CONFIG_CMD_PING=y +CONFIG_CMD_SMC=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_CLK=y +CONFIG_MMC_HS200_SUPPORT=y +CONFIG_MMC_MTK=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7986=y +CONFIG_POWER_DOMAIN=y +CONFIG_MTK_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_SERIAL=y +CONFIG_MTK_SERIAL=y +CONFIG_FAT_WRITE=y +CONFIG_HEXDUMP=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/mt7986a_bpir3_sd_defconfig b/configs/mt7986a_bpir3_sd_defconfig new file mode 100644 index 0000000000..b9a69a3d3d --- /dev/null +++ b/configs/mt7986a_bpir3_sd_defconfig @@ -0,0 +1,64 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_SYS_TEXT_BASE=0x41e00000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x80000 +CONFIG_ENV_OFFSET=0x300000 +CONFIG_DEFAULT_DEVICE_TREE="mt7986a-sd-rfb" +CONFIG_TARGET_MT7986=y +CONFIG_DEBUG_UART_BASE=0x11002000 +CONFIG_DEBUG_UART_CLOCK=40000000 +CONFIG_SYS_LOAD_ADDR=0x46000000 +CONFIG_DEBUG_UART=y +# CONFIG_AUTOBOOT is not set +CONFIG_DEFAULT_FDT_FILE="mt7986a-sd-rfb" +CONFIG_LOGLEVEL=7 +CONFIG_LOG=y +CONFIG_SYS_PROMPT="MT7986> " +CONFIG_SYS_CBSIZE=512 +CONFIG_SYS_PBSIZE=1049 +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_UNLZ4 is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_GPT_RENAME=y +CONFIG_CMD_LSBLK=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y +CONFIG_CMD_READ=y +CONFIG_CMD_PING=y +CONFIG_CMD_SMC=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_CLK=y +CONFIG_MMC_HS200_SUPPORT=y +CONFIG_MMC_MTK=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7986=y +CONFIG_POWER_DOMAIN=y +CONFIG_MTK_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_SERIAL=y +CONFIG_MTK_SERIAL=y +CONFIG_FAT_WRITE=y +CONFIG_HEXDUMP=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/netspace_mini_v2_defconfig b/configs/netspace_mini_v2_defconfig index c48063500a..5ce2fbdb93 100644 --- a/configs/netspace_mini_v2_defconfig +++ b/configs/netspace_mini_v2_defconfig @@ -54,7 +54,6 @@ CONFIG_SYS_FAULT_ECHO_LINK_DOWN=y CONFIG_DM=y CONFIG_SATA_MV=y CONFIG_SYS_SATA_MAX_DEVICE=1 -CONFIG_BLK=y CONFIG_LBA48=y CONFIG_SYS_64BIT_LBA=y CONFIG_KIRKWOOD_GPIO=y diff --git a/configs/nokia_rx51_defconfig b/configs/nokia_rx51_defconfig index 41f8268ec2..6629137d00 100644 --- a/configs/nokia_rx51_defconfig +++ b/configs/nokia_rx51_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_L2CACHE_OFF=y CONFIG_ARCH_OMAP2PLUS=y CONFIG_SYS_MALLOC_LEN=0xc0000 CONFIG_TARGET_NOKIA_RX51=y -CONFIG_SYS_LOAD_ADDR=0x80000000 +CONFIG_SYS_LOAD_ADDR=0x80008000 CONFIG_OPTIMIZE_INLINING=y CONFIG_LTO=y # CONFIG_FIT is not set diff --git a/configs/nsim_hs38_defconfig b/configs/nsim_hs38_defconfig index 8e5e8ea305..9b85dc4141 100644 --- a/configs/nsim_hs38_defconfig +++ b/configs/nsim_hs38_defconfig @@ -29,8 +29,6 @@ CONFIG_OF_EMBED=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_USE_BOOTFILE=y CONFIG_BOOTFILE="uImage" -CONFIG_BLK=y -CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_DM_SERIAL=y CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYS_NS16550=y diff --git a/configs/octeon_nic23_defconfig b/configs/octeon_nic23_defconfig index 95e98c1161..abc7914437 100644 --- a/configs/octeon_nic23_defconfig +++ b/configs/octeon_nic23_defconfig @@ -20,6 +20,8 @@ CONFIG_AHCI=y CONFIG_OF_BOARD_FIXUP=y CONFIG_SYS_CONSOLE_ENV_OVERWRITE=y # CONFIG_SYS_DEVICE_NULLDEV is not set +CONFIG_CYCLIC=y +CONFIG_CYCLIC_MAX_CPU_TIME_US=5000 CONFIG_ARCH_MISC_INIT=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_BOARD_LATE_INIT=y diff --git a/configs/omap4_panda_defconfig b/configs/omap4_panda_defconfig index 3a28adf2ae..814953fae6 100644 --- a/configs/omap4_panda_defconfig +++ b/configs/omap4_panda_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_OMAP2PLUS=y CONFIG_SYS_MALLOC_F_LEN=0x4000 CONFIG_DEFAULT_DEVICE_TREE="omap4-panda" diff --git a/configs/omap4_sdp4430_defconfig b/configs/omap4_sdp4430_defconfig index 6d5de532f3..a2645b9819 100644 --- a/configs/omap4_sdp4430_defconfig +++ b/configs/omap4_sdp4430_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y # CONFIG_SPL_USE_ARCH_MEMCPY is not set # CONFIG_SPL_USE_ARCH_MEMSET is not set CONFIG_ARCH_OMAP2PLUS=y diff --git a/configs/pg_wcom_expu1_defconfig b/configs/pg_wcom_expu1_defconfig index 5dae75f0f9..aa4deac3df 100644 --- a/configs/pg_wcom_expu1_defconfig +++ b/configs/pg_wcom_expu1_defconfig @@ -40,7 +40,6 @@ CONFIG_AUTOBOOT_STOP_STR=" " CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0" CONFIG_SILENT_CONSOLE=y -CONFIG_EVENT=y CONFIG_LAST_STAGE_INIT=y CONFIG_MISC_INIT_R=y CONFIG_SYS_MAXARGS=32 diff --git a/configs/pg_wcom_expu1_update_defconfig b/configs/pg_wcom_expu1_update_defconfig index 68fa48d0da..ba82a4f0d0 100644 --- a/configs/pg_wcom_expu1_update_defconfig +++ b/configs/pg_wcom_expu1_update_defconfig @@ -38,7 +38,6 @@ CONFIG_AUTOBOOT_STOP_STR=" " CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0" CONFIG_SILENT_CONSOLE=y -CONFIG_EVENT=y CONFIG_LAST_STAGE_INIT=y CONFIG_MISC_INIT_R=y CONFIG_SYS_MAXARGS=32 diff --git a/configs/pg_wcom_seli8_defconfig b/configs/pg_wcom_seli8_defconfig index f56f3eb534..c1b60aa516 100644 --- a/configs/pg_wcom_seli8_defconfig +++ b/configs/pg_wcom_seli8_defconfig @@ -40,7 +40,6 @@ CONFIG_AUTOBOOT_STOP_STR=" " CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0" CONFIG_SILENT_CONSOLE=y -CONFIG_EVENT=y CONFIG_LAST_STAGE_INIT=y CONFIG_MISC_INIT_R=y CONFIG_SYS_MAXARGS=32 diff --git a/configs/pg_wcom_seli8_update_defconfig b/configs/pg_wcom_seli8_update_defconfig index 2840266e89..5aef18d586 100644 --- a/configs/pg_wcom_seli8_update_defconfig +++ b/configs/pg_wcom_seli8_update_defconfig @@ -38,7 +38,6 @@ CONFIG_AUTOBOOT_STOP_STR=" " CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0" CONFIG_SILENT_CONSOLE=y -CONFIG_EVENT=y CONFIG_LAST_STAGE_INIT=y CONFIG_MISC_INIT_R=y CONFIG_SYS_MAXARGS=32 diff --git a/configs/pm9261_defconfig b/configs/pm9261_defconfig index 68fb02bd35..cd73fe41f9 100644 --- a/configs/pm9261_defconfig +++ b/configs/pm9261_defconfig @@ -39,7 +39,6 @@ CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_FLASH=y # CONFIG_NET is not set CONFIG_DM=y -CONFIG_BLK=y CONFIG_CLK=y CONFIG_CLK_AT91=y CONFIG_AT91_GPIO=y diff --git a/configs/pm9263_defconfig b/configs/pm9263_defconfig index 470ae9efa8..67fb1b9483 100644 --- a/configs/pm9263_defconfig +++ b/configs/pm9263_defconfig @@ -43,7 +43,6 @@ CONFIG_OF_CONTROL=y CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_FLASH=y CONFIG_DM=y -CONFIG_BLK=y CONFIG_CLK=y CONFIG_CLK_AT91=y CONFIG_AT91_GPIO=y diff --git a/configs/poleg_evb_defconfig b/configs/poleg_evb_defconfig index ba017e327a..597a72eed9 100644 --- a/configs/poleg_evb_defconfig +++ b/configs/poleg_evb_defconfig @@ -1,5 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_CPU_INIT=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_NPCM=y CONFIG_SYS_TEXT_BASE=0x8200 CONFIG_SYS_MALLOC_LEN=0x240000 diff --git a/configs/qcs404evb_defconfig b/configs/qcs404evb_defconfig index d45f6b2348..dae1551411 100644 --- a/configs/qcs404evb_defconfig +++ b/configs/qcs404evb_defconfig @@ -22,6 +22,7 @@ CONFIG_CMD_GPIO=y CONFIG_CMD_GPT=y CONFIG_CMD_MMC=y CONFIG_CMD_PART=y +CONFIG_CMD_USB=y CONFIG_CMD_EXT2=y CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y @@ -29,10 +30,25 @@ CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y # CONFIG_NET is not set CONFIG_CLK=y +CONFIG_QCOM_PMIC_GPIO=y +CONFIG_MISC=y CONFIG_MMC_HS400_SUPPORT=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ADMA=y CONFIG_MMC_SDHCI_MSM=y +CONFIG_PHY=y +CONFIG_PHY_QCOM_USB_HS_28NM=y +CONFIG_PHY_QCOM_USB_SS=y CONFIG_PINCTRL=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_QCOM=y +CONFIG_DM_RESET=y CONFIG_MSM_SERIAL=y +CONFIG_SPMI_MSM=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_USB_STORAGE=y CONFIG_LMB_MAX_REGIONS=64 diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index 36988d3d36..f48564c3f5 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -39,8 +39,6 @@ CONFIG_BOOTFILE="uImage" CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y CONFIG_SIMPLE_BUS_CORRECT_RANGE=y -CONFIG_BLK=y -CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_LBA48=y CONFIG_CHIP_SELECTS_PER_CTRL=0 CONFIG_MPC8XXX_GPIO=y diff --git a/configs/sam9x60_curiosity_mmc_defconfig b/configs/sam9x60_curiosity_mmc_defconfig index 99f61d732a..c8dffa85d1 100644 --- a/configs/sam9x60_curiosity_mmc_defconfig +++ b/configs/sam9x60_curiosity_mmc_defconfig @@ -72,4 +72,8 @@ CONFIG_DEBUG_UART_ANNOUNCE=y CONFIG_ATMEL_USART=y CONFIG_TIMER=y CONFIG_MCHP_PIT64B_TIMER=y +CONFIG_W1=y +CONFIG_W1_GPIO=y +CONFIG_W1_EEPROM=y +CONFIG_W1_EEPROM_DS24XXX=y CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 290d1506c2..b20b181ab1 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -67,6 +67,7 @@ CONFIG_CMD_BMP=y CONFIG_CMD_EFIDEBUG=y CONFIG_CMD_RTC=y CONFIG_CMD_TIME=y +CONFIG_CMD_PAUSE=y CONFIG_CMD_TIMER=y CONFIG_CMD_SOUND=y CONFIG_CMD_QFW=y @@ -103,7 +104,6 @@ CONFIG_DEVRES=y CONFIG_DEBUG_DEVRES=y CONFIG_ADC=y CONFIG_ADC_SANDBOX=y -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_SYS_IDE_MAXBUS=1 @@ -127,7 +127,7 @@ CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_GPIO_HOG=y CONFIG_DM_GPIO_LOOKUP_LABEL=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_SANDBOX_GPIO=y CONFIG_I2C_CROS_EC_TUNNEL=y CONFIG_I2C_CROS_EC_LDO=y @@ -178,7 +178,7 @@ CONFIG_DM_PMIC=y CONFIG_PMIC_ACT8846=y CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_MAX77686=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_PMIC_RK8XX=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_PMIC_SANDBOX=y @@ -202,6 +202,8 @@ CONFIG_DM_RESET=y CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y CONFIG_RTC_RV8803=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y CONFIG_SANDBOX_SERIAL=y CONFIG_SMEM=y CONFIG_SANDBOX_SMEM=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index ab5d3f19bf..df6a28ef24 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -94,8 +94,10 @@ CONFIG_CMD_ETHSW=y CONFIG_CMD_BMP=y CONFIG_CMD_BOOTCOUNT=y CONFIG_CMD_EFIDEBUG=y +CONFIG_CMD_EFICONFIG=y CONFIG_CMD_RTC=y CONFIG_CMD_TIME=y +CONFIG_CMD_PAUSE=y CONFIG_CMD_TIMER=y CONFIG_CMD_SOUND=y CONFIG_CMD_QFW=y @@ -135,7 +137,6 @@ CONFIG_DEBUG_DEVRES=y CONFIG_SIMPLE_PM_BUS=y CONFIG_ADC=y CONFIG_ADC_SANDBOX=y -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_SYS_IDE_MAXBUS=1 @@ -171,7 +172,7 @@ CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_GPIO_HOG=y CONFIG_DM_GPIO_LOOKUP_LABEL=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_SANDBOX_GPIO=y CONFIG_DM_HWSPINLOCK=y CONFIG_HWSPINLOCK_SANDBOX=y @@ -231,7 +232,7 @@ CONFIG_PMIC_ACT8846=y CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_MAX77686=y CONFIG_DM_PMIC_MC34708=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_PMIC_RK8XX=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_PMIC_SANDBOX=y @@ -262,9 +263,7 @@ CONFIG_RESET_SCMI=y CONFIG_DM_RTC=y CONFIG_RTC_RV8803=y CONFIG_SCSI=y -CONFIG_SCSI_AHCI_PLAT=y -CONFIG_SYS_SCSI_MAX_SCSI_ID=8 -CONFIG_SYS_SCSI_MAX_LUN=4 +CONFIG_DM_SCSI=y CONFIG_SANDBOX_SERIAL=y CONFIG_SMEM=y CONFIG_SANDBOX_SMEM=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index a8b439faa9..a2eb7afcf9 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -85,7 +85,6 @@ CONFIG_DEVRES=y CONFIG_DEBUG_DEVRES=y CONFIG_ADC=y CONFIG_ADC_SANDBOX=y -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_CLK=y @@ -100,7 +99,7 @@ CONFIG_DM_DEMO_SHAPE=y CONFIG_DFU_SF=y CONFIG_GPIO_HOG=y CONFIG_DM_GPIO_LOOKUP_LABEL=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_SANDBOX_GPIO=y CONFIG_I2C_CROS_EC_TUNNEL=y CONFIG_I2C_CROS_EC_LDO=y @@ -153,7 +152,7 @@ CONFIG_PMIC_ACT8846=y CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_MAX77686=y CONFIG_DM_PMIC_MC34708=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_PMIC_SANDBOX=y CONFIG_PMIC_S5M8767=y @@ -174,6 +173,8 @@ CONFIG_REMOTEPROC_SANDBOX=y CONFIG_DM_RESET=y CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y CONFIG_SANDBOX_SERIAL=y CONFIG_SOUND=y CONFIG_SOUND_SANDBOX=y diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig index 3d34d81731..8bf10bb3ee 100644 --- a/configs/sandbox_noinst_defconfig +++ b/configs/sandbox_noinst_defconfig @@ -108,7 +108,6 @@ CONFIG_DEBUG_DEVRES=y # CONFIG_SPL_SIMPLE_BUS is not set CONFIG_ADC=y CONFIG_ADC_SANDBOX=y -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_SYS_IDE_MAXBUS=1 @@ -126,7 +125,7 @@ CONFIG_DM_DEMO_SIMPLE=y CONFIG_DM_DEMO_SHAPE=y CONFIG_SPL_FIRMWARE=y CONFIG_GPIO_HOG=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_SANDBOX_GPIO=y CONFIG_I2C_CROS_EC_TUNNEL=y CONFIG_I2C_CROS_EC_LDO=y @@ -176,7 +175,7 @@ CONFIG_PMIC_ACT8846=y CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_MAX77686=y CONFIG_DM_PMIC_MC34708=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_PMIC_RK8XX=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_PMIC_SANDBOX=y @@ -200,6 +199,8 @@ CONFIG_DM_RESET=y CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y CONFIG_SPL_DM_RTC=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y CONFIG_SANDBOX_SERIAL=y CONFIG_SOUND=y CONFIG_SOUND_SANDBOX=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index 76e8acd126..c33f17186d 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -109,7 +109,6 @@ CONFIG_DEBUG_DEVRES=y # CONFIG_SPL_SIMPLE_BUS is not set CONFIG_ADC=y CONFIG_ADC_SANDBOX=y -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_SYS_IDE_MAXBUS=1 @@ -127,7 +126,7 @@ CONFIG_DM_DEMO_SIMPLE=y CONFIG_DM_DEMO_SHAPE=y CONFIG_SPL_FIRMWARE=y CONFIG_GPIO_HOG=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_SANDBOX_GPIO=y CONFIG_I2C_CROS_EC_TUNNEL=y CONFIG_I2C_CROS_EC_LDO=y @@ -179,7 +178,7 @@ CONFIG_PMIC_ACT8846=y CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_MAX77686=y CONFIG_DM_PMIC_MC34708=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_PMIC_RK8XX=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_PMIC_SANDBOX=y @@ -203,6 +202,8 @@ CONFIG_DM_RESET=y CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y CONFIG_SPL_DM_RTC=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y CONFIG_SANDBOX_SERIAL=y CONFIG_SOUND=y CONFIG_SOUND_SANDBOX=y diff --git a/configs/sandbox_vpl_defconfig b/configs/sandbox_vpl_defconfig index 96c9622707..be8186ead3 100644 --- a/configs/sandbox_vpl_defconfig +++ b/configs/sandbox_vpl_defconfig @@ -124,7 +124,6 @@ CONFIG_DEBUG_DEVRES=y # CONFIG_SPL_SIMPLE_BUS is not set CONFIG_ADC=y CONFIG_ADC_SANDBOX=y -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_CLK=y @@ -136,7 +135,7 @@ CONFIG_DM_DEMO_SIMPLE=y CONFIG_DM_DEMO_SHAPE=y CONFIG_SPL_FIRMWARE=y CONFIG_GPIO_HOG=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_SANDBOX_GPIO=y CONFIG_I2C_CROS_EC_TUNNEL=y CONFIG_I2C_CROS_EC_LDO=y @@ -184,7 +183,7 @@ CONFIG_PMIC_ACT8846=y CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_MAX77686=y CONFIG_DM_PMIC_MC34708=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_PMIC_RK8XX=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_PMIC_SANDBOX=y @@ -209,6 +208,8 @@ CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y CONFIG_SPL_DM_RTC=y CONFIG_TPL_DM_RTC=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y CONFIG_SANDBOX_SERIAL=y CONFIG_SOUND=y CONFIG_SOUND_SANDBOX=y diff --git a/configs/socfpga_arria10_defconfig b/configs/socfpga_arria10_defconfig index 3eac3dfa5d..6fe8d55002 100644 --- a/configs/socfpga_arria10_defconfig +++ b/configs/socfpga_arria10_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_arria5_defconfig b/configs/socfpga_arria5_defconfig index dbadb3d49a..2632c0af4e 100644 --- a/configs/socfpga_arria5_defconfig +++ b/configs/socfpga_arria5_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_chameleonv3_defconfig b/configs/socfpga_chameleonv3_defconfig index 2a5a277319..478efc59ea 100644 --- a/configs/socfpga_chameleonv3_defconfig +++ b/configs/socfpga_chameleonv3_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_ENV_SIZE=0x10000 CONFIG_ENV_OFFSET=0x4400 diff --git a/configs/socfpga_cyclone5_defconfig b/configs/socfpga_cyclone5_defconfig index 4fd14d2e2c..451de03e1d 100644 --- a/configs/socfpga_cyclone5_defconfig +++ b/configs/socfpga_cyclone5_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_dbm_soc1_defconfig b/configs/socfpga_dbm_soc1_defconfig index 5c17ccb651..7786843427 100644 --- a/configs/socfpga_dbm_soc1_defconfig +++ b/configs/socfpga_dbm_soc1_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_de0_nano_soc_defconfig b/configs/socfpga_de0_nano_soc_defconfig index 1ef0dd9398..cfc8b50e2b 100644 --- a/configs/socfpga_de0_nano_soc_defconfig +++ b/configs/socfpga_de0_nano_soc_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_de10_nano_defconfig b/configs/socfpga_de10_nano_defconfig index 296128c9fb..53c4ff5ffd 100644 --- a/configs/socfpga_de10_nano_defconfig +++ b/configs/socfpga_de10_nano_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_de10_standard_defconfig b/configs/socfpga_de10_standard_defconfig index 8e6fe0697d..15d4599526 100644 --- a/configs/socfpga_de10_standard_defconfig +++ b/configs/socfpga_de10_standard_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_de1_soc_defconfig b/configs/socfpga_de1_soc_defconfig index 15089fe6d9..2a15936806 100644 --- a/configs/socfpga_de1_soc_defconfig +++ b/configs/socfpga_de1_soc_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_is1_defconfig b/configs/socfpga_is1_defconfig index 832b26f6de..3a21bc77a2 100644 --- a/configs/socfpga_is1_defconfig +++ b/configs/socfpga_is1_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_mcvevk_defconfig b/configs/socfpga_mcvevk_defconfig index 75190c0eb5..35ea73a598 100644 --- a/configs/socfpga_mcvevk_defconfig +++ b/configs/socfpga_mcvevk_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_secu1_defconfig b/configs/socfpga_secu1_defconfig index 400c89b84f..a6106f2a43 100644 --- a/configs/socfpga_secu1_defconfig +++ b/configs/socfpga_secu1_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_SYS_MALLOC_F_LEN=0x800 diff --git a/configs/socfpga_sockit_defconfig b/configs/socfpga_sockit_defconfig index 1e9dc14af0..0539d2937e 100644 --- a/configs/socfpga_sockit_defconfig +++ b/configs/socfpga_sockit_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_socrates_defconfig b/configs/socfpga_socrates_defconfig index dab11f8920..a81f74d329 100644 --- a/configs/socfpga_socrates_defconfig +++ b/configs/socfpga_socrates_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_sr1500_defconfig b/configs/socfpga_sr1500_defconfig index 90ffa9a9c5..59d809ca0e 100644 --- a/configs/socfpga_sr1500_defconfig +++ b/configs/socfpga_sr1500_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x4000 diff --git a/configs/socfpga_vining_fpga_defconfig b/configs/socfpga_vining_fpga_defconfig index 1b88ccd209..3a99667811 100644 --- a/configs/socfpga_vining_fpga_defconfig +++ b/configs/socfpga_vining_fpga_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x4000 diff --git a/configs/starqltechn_defconfig b/configs/starqltechn_defconfig index 2d07767b61..4f84f5f974 100644 --- a/configs/starqltechn_defconfig +++ b/configs/starqltechn_defconfig @@ -23,10 +23,10 @@ CONFIG_CMD_BMP=y # CONFIG_DM_STDIO is not set CONFIG_CLK=y CONFIG_MSM_GPIO=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_PINCTRL=y CONFIG_DM_PMIC=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y # CONFIG_REQUIRE_SERIAL_CONSOLE is not set CONFIG_SPMI_MSM=y CONFIG_DM_VIDEO=y diff --git a/configs/stemmy_defconfig b/configs/stemmy_defconfig index 7fc0a39872..f1d3ef5b12 100644 --- a/configs/stemmy_defconfig +++ b/configs/stemmy_defconfig @@ -1,5 +1,6 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_U8500=y CONFIG_SUPPORT_PASSING_ATAGS=y # CONFIG_SETUP_MEMORY_TAGS is not set diff --git a/configs/stm32746g-eval_defconfig b/configs/stm32746g-eval_defconfig index 58232a7114..7200446d28 100644 --- a/configs/stm32746g-eval_defconfig +++ b/configs/stm32746g-eval_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32746g-eval" diff --git a/configs/stm32746g-eval_spl_defconfig b/configs/stm32746g-eval_spl_defconfig index a3b7146454..ff42952a76 100644 --- a/configs/stm32746g-eval_spl_defconfig +++ b/configs/stm32746g-eval_spl_defconfig @@ -1,8 +1,7 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y -CONFIG_SYS_TEXT_BASE=0x08008000 +CONFIG_SYS_TEXT_BASE=0x08009000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y @@ -13,10 +12,11 @@ CONFIG_SPL_TEXT_BASE=0x8000000 CONFIG_SYS_PROMPT="U-Boot > " CONFIG_SPL_SERIAL=y CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_SIZE_LIMIT=0x9000 CONFIG_STM32F7=y CONFIG_TARGET_STM32F746_DISCO=y CONFIG_SPL=y -CONFIG_SYS_LOAD_ADDR=0x8008000 +CONFIG_SYS_LOAD_ADDR=0x8009000 CONFIG_BUILD_TARGET="u-boot-with-spl.bin" CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y @@ -29,13 +29,13 @@ CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel" # CONFIG_DISPLAY_CPUINFO is not set CONFIG_BOARD_LATE_INIT=y -CONFIG_SPL_PAD_TO=0x8000 +CONFIG_SPL_PAD_TO=0x9000 CONFIG_SPL_NO_BSS_LIMIT=y CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_MTD_SUPPORT=y CONFIG_SPL_XIP_SUPPORT=y -CONFIG_SYS_SPL_ARGS_ADDR=0x81c0000 +CONFIG_SYS_SPL_ARGS_ADDR=0x80c0000 CONFIG_SPL_DM_RESET=y CONFIG_SYS_PBSIZE=1050 CONFIG_CMD_GPT=y diff --git a/configs/stm32f429-discovery_defconfig b/configs/stm32f429-discovery_defconfig index e6e595d495..914ac14641 100644 --- a/configs/stm32f429-discovery_defconfig +++ b/configs/stm32f429-discovery_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x0200000 -CONFIG_SYS_MALLOC_F_LEN=0xF00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_SECT_SIZE=0x20000 diff --git a/configs/stm32f429-evaluation_defconfig b/configs/stm32f429-evaluation_defconfig index 073f27168a..af7a8bf076 100644 --- a/configs/stm32f429-evaluation_defconfig +++ b/configs/stm32f429-evaluation_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xF00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32429i-eval" diff --git a/configs/stm32f469-discovery_defconfig b/configs/stm32f469-discovery_defconfig index bd3693275e..90680fdb05 100644 --- a/configs/stm32f469-discovery_defconfig +++ b/configs/stm32f469-discovery_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xF00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32f469-disco" diff --git a/configs/stm32f746-disco_defconfig b/configs/stm32f746-disco_defconfig index ed537b0578..a8edf11b40 100644 --- a/configs/stm32f746-disco_defconfig +++ b/configs/stm32f746-disco_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32f746-disco" diff --git a/configs/stm32f746-disco_spl_defconfig b/configs/stm32f746-disco_spl_defconfig index e7b1acc433..0e358e86ff 100644 --- a/configs/stm32f746-disco_spl_defconfig +++ b/configs/stm32f746-disco_spl_defconfig @@ -1,8 +1,7 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y -CONFIG_SYS_TEXT_BASE=0x08008000 +CONFIG_SYS_TEXT_BASE=0x08009000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y @@ -13,10 +12,11 @@ CONFIG_SPL_TEXT_BASE=0x8000000 CONFIG_SYS_PROMPT="U-Boot > " CONFIG_SPL_SERIAL=y CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_SIZE_LIMIT=0x9000 CONFIG_STM32F7=y CONFIG_TARGET_STM32F746_DISCO=y CONFIG_SPL=y -CONFIG_SYS_LOAD_ADDR=0x8008000 +CONFIG_SYS_LOAD_ADDR=0x8009000 CONFIG_BUILD_TARGET="u-boot-with-spl.bin" CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y @@ -29,13 +29,13 @@ CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel" # CONFIG_DISPLAY_CPUINFO is not set CONFIG_BOARD_LATE_INIT=y -CONFIG_SPL_PAD_TO=0x8000 +CONFIG_SPL_PAD_TO=0x9000 CONFIG_SPL_NO_BSS_LIMIT=y CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_MTD_SUPPORT=y CONFIG_SPL_XIP_SUPPORT=y -CONFIG_SYS_SPL_ARGS_ADDR=0x81c0000 +CONFIG_SYS_SPL_ARGS_ADDR=0x80c0000 CONFIG_SPL_DM_RESET=y CONFIG_SYS_PBSIZE=1050 CONFIG_CMD_GPT=y diff --git a/configs/stm32f769-disco_defconfig b/configs/stm32f769-disco_defconfig index 423af7446a..3e7b5bd06e 100644 --- a/configs/stm32f769-disco_defconfig +++ b/configs/stm32f769-disco_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32f769-disco" @@ -41,7 +40,7 @@ CONFIG_MTD=y CONFIG_DM_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_STM32_FLASH=y -CONFIG_SYS_MAX_FLASH_SECT=8 +CONFIG_SYS_MAX_FLASH_SECT=12 CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_STMICRO=y diff --git a/configs/stm32f769-disco_spl_defconfig b/configs/stm32f769-disco_spl_defconfig index 19d2c24abb..f0a1b667b8 100644 --- a/configs/stm32f769-disco_spl_defconfig +++ b/configs/stm32f769-disco_spl_defconfig @@ -1,8 +1,7 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y -CONFIG_SYS_TEXT_BASE=0x08008000 +CONFIG_SYS_TEXT_BASE=0x08009000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y @@ -13,10 +12,11 @@ CONFIG_SPL_TEXT_BASE=0x8000000 CONFIG_SYS_PROMPT="U-Boot > " CONFIG_SPL_SERIAL=y CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_SIZE_LIMIT=0x9000 CONFIG_STM32F7=y CONFIG_TARGET_STM32F746_DISCO=y CONFIG_SPL=y -CONFIG_SYS_LOAD_ADDR=0x8008000 +CONFIG_SYS_LOAD_ADDR=0x8009000 CONFIG_BUILD_TARGET="u-boot-with-spl.bin" CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y @@ -28,7 +28,7 @@ CONFIG_AUTOBOOT_STOP_STR=" " CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel" # CONFIG_DISPLAY_CPUINFO is not set -CONFIG_SPL_PAD_TO=0x8000 +CONFIG_SPL_PAD_TO=0x9000 CONFIG_SPL_NO_BSS_LIMIT=y CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y @@ -62,7 +62,7 @@ CONFIG_MTD=y CONFIG_DM_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_STM32_FLASH=y -CONFIG_SYS_MAX_FLASH_SECT=8 +CONFIG_SYS_MAX_FLASH_SECT=12 CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_STMICRO=y diff --git a/configs/stm32h743-disco_defconfig b/configs/stm32h743-disco_defconfig index d33da43065..8c62c70a57 100644 --- a/configs/stm32h743-disco_defconfig +++ b/configs/stm32h743-disco_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xF00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32h743i-disco" diff --git a/configs/stm32h743-eval_defconfig b/configs/stm32h743-eval_defconfig index a72de48690..1ff6b50819 100644 --- a/configs/stm32h743-eval_defconfig +++ b/configs/stm32h743-eval_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xF00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32h743i-eval" diff --git a/configs/stm32h750-art-pi_defconfig b/configs/stm32h750-art-pi_defconfig index b8296a98b4..a5fce5e866 100644 --- a/configs/stm32h750-art-pi_defconfig +++ b/configs/stm32h750-art-pi_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x90000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xF00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32h750i-art-pi" diff --git a/configs/stm32mp13_defconfig b/configs/stm32mp13_defconfig index 26beb73e84..af6b1839d0 100644 --- a/configs/stm32mp13_defconfig +++ b/configs/stm32mp13_defconfig @@ -64,7 +64,6 @@ CONFIG_DM_REGULATOR_GPIO=y CONFIG_DM_REGULATOR_SCMI=y CONFIG_RESET_SCMI=y CONFIG_DM_RNG=y -CONFIG_RNG_OPTEE=y CONFIG_DM_RTC=y CONFIG_RTC_STM32=y CONFIG_SERIAL_RX_BUFFER=y diff --git a/configs/stm32mp15_defconfig b/configs/stm32mp15_defconfig index 0f6b3738ca..ec8fb37110 100644 --- a/configs/stm32mp15_defconfig +++ b/configs/stm32mp15_defconfig @@ -124,7 +124,6 @@ CONFIG_DM_REGULATOR_SCMI=y CONFIG_REMOTEPROC_STM32_COPRO=y CONFIG_RESET_SCMI=y CONFIG_DM_RNG=y -CONFIG_RNG_OPTEE=y CONFIG_RNG_STM32MP1=y CONFIG_DM_RTC=y CONFIG_RTC_STM32=y diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig index 1154eec210..9cfa9a20f3 100644 --- a/configs/stm32mp15_trusted_defconfig +++ b/configs/stm32mp15_trusted_defconfig @@ -124,7 +124,6 @@ CONFIG_DM_REGULATOR_STPMIC1=y CONFIG_REMOTEPROC_STM32_COPRO=y CONFIG_RESET_SCMI=y CONFIG_DM_RNG=y -CONFIG_RNG_OPTEE=y CONFIG_RNG_STM32MP1=y CONFIG_DM_RTC=y CONFIG_RTC_STM32=y diff --git a/configs/theadorable_debug_defconfig b/configs/theadorable_debug_defconfig index 9074ca1620..3d84bf9d57 100644 --- a/configs/theadorable_debug_defconfig +++ b/configs/theadorable_debug_defconfig @@ -22,6 +22,7 @@ CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xff0000 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_FIT=y +# CONFIG_FIT_PRINT is not set CONFIG_BOOTDELAY=3 CONFIG_USE_PREBOOT=y # CONFIG_CONSOLE_MUX is not set @@ -98,3 +99,5 @@ CONFIG_VIDEO_MVEBU=y CONFIG_BMP_16BPP=y CONFIG_BMP_24BPP=y CONFIG_BMP_32BPP=y +CONFIG_FAT_WRITE=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/tools-only_defconfig b/configs/tools-only_defconfig index 211acc7774..2c418f5dbb 100644 --- a/configs/tools-only_defconfig +++ b/configs/tools-only_defconfig @@ -18,7 +18,6 @@ CONFIG_OF_CONTROL=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set # CONFIG_ACPIGEN is not set -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_SANDBOX_GPIO=y diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig index ba635feb44..6698f23135 100644 --- a/configs/turris_omnia_defconfig +++ b/configs/turris_omnia_defconfig @@ -28,6 +28,8 @@ CONFIG_SYS_MEMTEST_END=0x00ffffff CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xff0000 +CONFIG_HAS_BOARD_SIZE_LIMIT=y +CONFIG_BOARD_SIZE_LIMIT=983040 CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_OF_BOARD_SETUP=y diff --git a/configs/xilinx_versal_mini_defconfig b/configs/xilinx_versal_mini_defconfig index a78ee631e4..7a0557a22e 100644 --- a/configs/xilinx_versal_mini_defconfig +++ b/configs/xilinx_versal_mini_defconfig @@ -66,3 +66,4 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_MMC is not set CONFIG_ARM_DCC=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set diff --git a/configs/xilinx_versal_mini_emmc0_defconfig b/configs/xilinx_versal_mini_emmc0_defconfig index ef73579dca..4b626d3465 100644 --- a/configs/xilinx_versal_mini_emmc0_defconfig +++ b/configs/xilinx_versal_mini_emmc0_defconfig @@ -67,3 +67,4 @@ CONFIG_ARM_DCC=y CONFIG_FAT_WRITE=y # CONFIG_GZIP is not set # CONFIG_EFI_LOADER is not set +# CONFIG_LMB is not set diff --git a/configs/xilinx_versal_mini_emmc1_defconfig b/configs/xilinx_versal_mini_emmc1_defconfig index fb7c5cfdbb..6fe2ebf876 100644 --- a/configs/xilinx_versal_mini_emmc1_defconfig +++ b/configs/xilinx_versal_mini_emmc1_defconfig @@ -67,3 +67,4 @@ CONFIG_ARM_DCC=y CONFIG_FAT_WRITE=y # CONFIG_GZIP is not set # CONFIG_EFI_LOADER is not set +# CONFIG_LMB is not set diff --git a/configs/xilinx_versal_net_mini_defconfig b/configs/xilinx_versal_net_mini_defconfig new file mode 100644 index 0000000000..e8fa08e3ef --- /dev/null +++ b/configs/xilinx_versal_net_mini_defconfig @@ -0,0 +1,72 @@ +CONFIG_ARM=y +CONFIG_SYS_CONFIG_NAME="xilinx_versal_net_mini" +CONFIG_SYS_ICACHE_OFF=y +# CONFIG_ARM64_CRC32 is not set +# CONFIG_ARM64_SUPPORT_AARCH32 is not set +CONFIG_ARCH_VERSAL_NET=y +CONFIG_SYS_TEXT_BASE=0xBBF10000 +CONFIG_SYS_MALLOC_LEN=0x20000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=3 +CONFIG_ENV_SIZE=0x80 +CONFIG_DEFAULT_DEVICE_TREE="versal-net-mini" +CONFIG_SYS_PROMPT="Versal NET> " +CONFIG_SYS_MEM_RSVD_FOR_MMU=y +# CONFIG_PSCI_RESET is not set +CONFIG_SYS_LOAD_ADDR=0x8000000 +CONFIG_SYS_MEMTEST_START=0x00000000 +CONFIG_SYS_MEMTEST_END=0x00001000 +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xBBF10000 +# CONFIG_EXPERT is not set +# CONFIG_LEGACY_IMAGE_FORMAT is not set +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +# CONFIG_AUTOBOOT is not set +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_BOARD_EARLY_INIT_R=y +# CONFIG_BOARD_LATE_INIT is not set +# CONFIG_CMDLINE_EDITING is not set +# CONFIG_AUTO_COMPLETE is not set +# CONFIG_SYS_LONGHELP is not set +# CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_BOOTD is not set +# CONFIG_CMD_BOOTM is not set +# CONFIG_CMD_BOOTI is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_FDT is not set +# CONFIG_CMD_GO is not set +# CONFIG_CMD_RUN is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +# CONFIG_CMD_EDITENV is not set +# CONFIG_CMD_SAVEENV is not set +# CONFIG_CMD_ENV_EXISTS is not set +# CONFIG_CMD_CRC32 is not set +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MX_CYCLIC=y +CONFIG_CMD_MEMTEST=y +CONFIG_SYS_ALT_MEMTEST=y +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +# CONFIG_CMD_ECHO is not set +# CONFIG_CMD_ITEST is not set +# CONFIG_CMD_SOURCE is not set +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_CACHE=y +# CONFIG_CMD_SLEEP is not set +CONFIG_OF_EMBED=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +# CONFIG_NET is not set +# CONFIG_DM_WARN is not set +# CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_GPIO is not set +# CONFIG_I2C is not set +# CONFIG_INPUT is not set +# CONFIG_MMC is not set +# CONFIG_POWER is not set +CONFIG_ARM_DCC=y +CONFIG_PL01X_SERIAL=y +# CONFIG_GZIP is not set diff --git a/configs/xilinx_versal_net_virt_defconfig b/configs/xilinx_versal_net_virt_defconfig new file mode 100644 index 0000000000..4a9910b7c4 --- /dev/null +++ b/configs/xilinx_versal_net_virt_defconfig @@ -0,0 +1,131 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_SYS_INIT_SP_BSS_OFFSET=1572864 +CONFIG_ARCH_VERSAL_NET=y +CONFIG_SYS_TEXT_BASE=0x8000000 +CONFIG_SYS_MALLOC_F_LEN=0x100000 +CONFIG_DEFAULT_DEVICE_TREE="xilinx-versal-net-virt" +CONFIG_SYS_PROMPT="Versal NET> " +CONFIG_CMD_FRU=y +CONFIG_SYS_LOAD_ADDR=0x8000000 +CONFIG_SYS_MEMTEST_START=0x00000000 +CONFIG_SYS_MEMTEST_END=0x00001000 +CONFIG_DISTRO_DEFAULTS=y +CONFIG_REMAKE_ELF=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +CONFIG_BOOTDELAY=5 +CONFIG_USE_PREBOOT=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_BOARD_EARLY_INIT_R=y +CONFIG_CLOCKS=y +CONFIG_SYS_MAXARGS=64 +CONFIG_SYS_PBSIZE=2073 +CONFIG_SYS_BOOTM_LEN=0x6400000 +CONFIG_CMD_BOOTMENU=y +CONFIG_CMD_GREPENV=y +CONFIG_CMD_NVEDIT_EFI=y +CONFIG_CMD_MEMTEST=y +CONFIG_SYS_ALT_MEMTEST=y +CONFIG_CMD_CLK=y +CONFIG_CMD_DFU=y +CONFIG_CMD_DM=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y +CONFIG_CMD_SF_TEST=y +CONFIG_CMD_USB=y +CONFIG_BOOTP_MAY_FAIL=y +CONFIG_BOOTP_BOOTFILESIZE=y +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_EFIDEBUG=y +CONFIG_CMD_TIME=y +CONFIG_CMD_TIMER=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_SQUASHFS=y +CONFIG_CMD_MTDPARTS=y +CONFIG_CMD_UBI=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_OF_BOARD=y +CONFIG_DTB_RESELECT=y +CONFIG_MULTI_DTB_FIT=y +CONFIG_SYS_REDUNDAND_ENVIRONMENT=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_NETCONSOLE=y +CONFIG_IP_DEFRAG=y +CONFIG_SYS_FAULT_ECHO_LINK_DOWN=y +CONFIG_TFTP_BLOCKSIZE=4096 +CONFIG_CLK_VERSAL=y +CONFIG_DFU_RAM=y +CONFIG_ZYNQ_GPIO=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_CADENCE=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_DM_MAILBOX=y +CONFIG_ZYNQMP_IPI=y +CONFIG_MISC=y +CONFIG_I2C_EEPROM=y +CONFIG_SYS_I2C_EEPROM_ADDR=0x0 +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_MMC_UHS_SUPPORT=y +CONFIG_MMC_HS400_SUPPORT=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ZYNQ=y +CONFIG_ZYNQ_SDHCI_MIN_FREQ=100000 +CONFIG_MTD=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_ISSI=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_SST=y +CONFIG_SPI_FLASH_WINBOND=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_MARVELL=y +CONFIG_PHY_NATSEMI=y +CONFIG_PHY_REALTEK=y +CONFIG_PHY_TI_DP83867=y +CONFIG_PHY_VITESSE=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH_PHY=y +CONFIG_PHY_GIGE=y +CONFIG_XILINX_AXIEMAC=y +CONFIG_ZYNQ_GEM=y +CONFIG_POWER_DOMAIN=y +CONFIG_ZYNQMP_POWER_DOMAIN=y +CONFIG_DM_RESET=y +CONFIG_RESET_ZYNQMP=y +CONFIG_ARM_DCC=y +CONFIG_PL01X_SERIAL=y +CONFIG_XILINX_UARTLITE=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_CADENCE_OSPI_VERSAL=y +CONFIG_ZYNQ_SPI=y +CONFIG_ZYNQMP_GQSPI=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_USB_ULPI_VIEWPORT=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Xilinx" +CONFIG_USB_GADGET_VENDOR_NUM=0x03FD +CONFIG_USB_GADGET_PRODUCT_NUM=0x0300 +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_USB_FUNCTION_THOR=y +CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index 6e61abd0c6..6afd06798d 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -7,6 +7,7 @@ CONFIG_SYS_TEXT_BASE=0x8000000 CONFIG_SYS_MALLOC_F_LEN=0x100000 CONFIG_DEFAULT_DEVICE_TREE="xilinx-versal-virt" CONFIG_SYS_PROMPT="Versal> " +CONFIG_ENV_OFFSET_REDUND=0x7F00000 CONFIG_CMD_FRU=y CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_SYS_LOAD_ADDR=0x8000000 @@ -25,6 +26,7 @@ CONFIG_SYS_MAXARGS=64 CONFIG_SYS_PBSIZE=2073 CONFIG_SYS_BOOTM_LEN=0x6400000 CONFIG_CMD_BOOTMENU=y +CONFIG_CMD_GREPENV=y CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_MEMTEST=y CONFIG_SYS_ALT_MEMTEST=y @@ -69,6 +71,8 @@ CONFIG_FPGA_XILINX=y CONFIG_FPGA_VERSALPL=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_CADENCE=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y CONFIG_DM_MAILBOX=y CONFIG_ZYNQMP_IPI=y CONFIG_MISC=y @@ -102,6 +106,8 @@ CONFIG_PHY_GIGE=y CONFIG_XILINX_AXIEMAC=y CONFIG_XILINX_AXIMRMAC=y CONFIG_ZYNQ_GEM=y +CONFIG_POWER_DOMAIN=y +CONFIG_ZYNQMP_POWER_DOMAIN=y CONFIG_DM_RESET=y CONFIG_RESET_ZYNQMP=y CONFIG_ARM_DCC=y @@ -111,8 +117,11 @@ CONFIG_SOC_XILINX_VERSAL=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_CADENCE_QSPI=y +CONFIG_HAS_CQSPI_REF_CLK=y +CONFIG_CQSPI_REF_CLK=200000000 CONFIG_CADENCE_OSPI_VERSAL=y CONFIG_ZYNQ_SPI=y +CONFIG_ZYNQMP_GQSPI=y CONFIG_USB=y CONFIG_DM_USB_GADGET=y CONFIG_USB_XHCI_HCD=y diff --git a/configs/xilinx_zynq_virt_defconfig b/configs/xilinx_zynq_virt_defconfig index 7beb5915fc..c12a1cbbc8 100644 --- a/configs/xilinx_zynq_virt_defconfig +++ b/configs/xilinx_zynq_virt_defconfig @@ -8,6 +8,7 @@ CONFIG_DM_GPIO=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc706" CONFIG_SPL_STACK_R_ADDR=0x200000 CONFIG_SPL=y +CONFIG_ENV_OFFSET_REDUND=0xE40000 CONFIG_CMD_FRU=y CONFIG_CMD_ZYNQ_AES=y CONFIG_SYS_LOAD_ADDR=0x0 @@ -50,6 +51,7 @@ CONFIG_SYS_PBSIZE=2071 CONFIG_SYS_BOOTM_LEN=0x3c00000 CONFIG_CMD_IMLS=y CONFIG_CMD_THOR_DOWNLOAD=y +CONFIG_CMD_GREPENV=y CONFIG_CMD_MEMTEST=y CONFIG_SYS_ALT_MEMTEST=y CONFIG_CMD_DFU=y @@ -64,7 +66,6 @@ CONFIG_CMD_MTD=y CONFIG_CMD_NAND_LOCK_UNLOCK=y CONFIG_CMD_SF_TEST=y CONFIG_CMD_USB=y -# CONFIG_CMD_SETEXPR is not set CONFIG_BOOTP_MAY_FAIL=y CONFIG_CMD_TFTPPUT=y CONFIG_CMD_CACHE=y @@ -149,3 +150,4 @@ CONFIG_DISPLAY=y CONFIG_SPL_GZIP=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y +CONFIG_TOOLS_MKEFICAPSULE=y diff --git a/configs/xilinx_zynqmp_mini_nand_defconfig b/configs/xilinx_zynqmp_mini_nand_defconfig index a2405f24ef..e6054fe177 100644 --- a/configs/xilinx_zynqmp_mini_nand_defconfig +++ b/configs/xilinx_zynqmp_mini_nand_defconfig @@ -65,3 +65,4 @@ CONFIG_SYS_NAND_MAX_CHIPS=2 CONFIG_ARM_DCC=y CONFIG_PANIC_HANG=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set diff --git a/configs/xilinx_zynqmp_mini_nand_single_defconfig b/configs/xilinx_zynqmp_mini_nand_single_defconfig index e6ebc12ed7..aa35b48c72 100644 --- a/configs/xilinx_zynqmp_mini_nand_single_defconfig +++ b/configs/xilinx_zynqmp_mini_nand_single_defconfig @@ -64,3 +64,4 @@ CONFIG_SYS_NAND_ONFI_DETECTION=y CONFIG_ARM_DCC=y CONFIG_PANIC_HANG=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig index e6d4308347..d0cc0360d2 100644 --- a/configs/xilinx_zynqmp_mini_qspi_defconfig +++ b/configs/xilinx_zynqmp_mini_qspi_defconfig @@ -3,7 +3,7 @@ CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_qspi" CONFIG_SYS_ICACHE_OFF=y CONFIG_ARCH_ZYNQMP=y CONFIG_SYS_TEXT_BASE=0xFFFC0000 -CONFIG_SYS_MALLOC_LEN=0x1a00 +CONFIG_SYS_MALLOC_LEN=0x1b00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x80 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-qspi" @@ -19,7 +19,9 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xfffe0000 # CONFIG_EXPERT is not set CONFIG_REMAKE_ELF=y # CONFIG_LEGACY_IMAGE_FORMAT is not set +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set # CONFIG_AUTOBOOT is not set +CONFIG_LOGLEVEL=0 # CONFIG_DISPLAY_CPUINFO is not set # CONFIG_BOARD_LATE_INIT is not set CONFIG_CLOCKS=y @@ -62,6 +64,7 @@ CONFIG_SYS_PBSIZE=1049 # CONFIG_CMD_SOURCE is not set # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_SLEEP is not set +# CONFIG_CMD_MP is not set CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y @@ -69,17 +72,24 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_DM_WARN is not set # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_SPL_DM_SEQ_ALIAS=y +# CONFIG_FIRMWARE is not set +# CONFIG_GPIO is not set +# CONFIG_I2C is not set +# CONFIG_INPUT is not set # CONFIG_MMC is not set -CONFIG_SPI_FLASH_BAR=y +# CONFIG_SPI_FLASH_SMART_HWCAPS is not set +# CONFIG_SPI_FLASH_UNLOCK_ALL is not set CONFIG_SPI_FLASH_ISSI=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_WINBOND=y # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +# CONFIG_POWER is not set CONFIG_ARM_DCC=y CONFIG_SPI=y CONFIG_ZYNQMP_GQSPI=y +# CONFIG_FAT_WRITE is not set CONFIG_PANIC_HANG=y # CONFIG_GZIP is not set # CONFIG_LMB is not set diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index e5ac26e038..1591f221b5 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -10,6 +10,7 @@ CONFIG_SPL_STACK_R_ADDR=0x18000000 CONFIG_SPL_SIZE_LIMIT=0x2a000 CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK=0x0 CONFIG_SPL=y +CONFIG_ENV_OFFSET_REDUND=0x1E80000 CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI=y CONFIG_ZYNQ_MAC_IN_EEPROM=y @@ -56,6 +57,7 @@ CONFIG_SYS_PBSIZE=2073 CONFIG_SYS_BOOTM_LEN=0x6400000 CONFIG_CMD_BOOTMENU=y CONFIG_CMD_THOR_DOWNLOAD=y +CONFIG_CMD_GREPENV=y CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_MEMTEST=y CONFIG_SYS_ALT_MEMTEST=y diff --git a/configs/zynq_cse_nand_defconfig b/configs/zynq_cse_nand_defconfig index b69c8b92a4..22f7456d33 100644 --- a/configs/zynq_cse_nand_defconfig +++ b/configs/zynq_cse_nand_defconfig @@ -79,3 +79,4 @@ CONFIG_NAND_ZYNQ=y CONFIG_SYS_NAND_ONFI_DETECTION=y CONFIG_ARM_DCC=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set diff --git a/configs/zynq_cse_nor_defconfig b/configs/zynq_cse_nor_defconfig index 59cd19ef2d..9f2d33782f 100644 --- a/configs/zynq_cse_nor_defconfig +++ b/configs/zynq_cse_nor_defconfig @@ -81,3 +81,4 @@ CONFIG_SYS_FLASH_CFI=y CONFIG_SYS_FLASH_QUIET_TEST=y CONFIG_ARM_DCC=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set diff --git a/configs/zynq_cse_qspi_defconfig b/configs/zynq_cse_qspi_defconfig index 49dd5ad606..a767224795 100644 --- a/configs/zynq_cse_qspi_defconfig +++ b/configs/zynq_cse_qspi_defconfig @@ -91,3 +91,4 @@ CONFIG_SPI_FLASH_WINBOND=y CONFIG_ARM_DCC=y CONFIG_ZYNQ_QSPI=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set diff --git a/disk/Kconfig b/disk/Kconfig index 81d8867ed7..c9b9dbaf1a 100644 --- a/disk/Kconfig +++ b/disk/Kconfig @@ -24,7 +24,7 @@ config SPL_PARTITIONS select SPL_STRTO help Enable this for base partition support in SPL. The required - partition table types shold be enabled separately. This add a + partition table types shold be enabled separately. This adds a small amount of size to SPL, typically 500 bytes. config TPL_PARTITIONS @@ -32,9 +32,9 @@ config TPL_PARTITIONS select TPL_SPRINTF select TPL_STRTO help - Enable this for base partition support in SPL. The required - partition table types shold be enabled separately. This add a - small amount of size to SPL, typically 500 bytes. + Enable this for base partition support in TPL. The required + partition table types shold be enabled separately. This adds a + small amount of size to TPL, typically 500 bytes. config MAC_PARTITION bool "Enable Apple's MacOS partition table" diff --git a/disk/Makefile b/disk/Makefile index ec148832b3..45588cf66e 100644 --- a/disk/Makefile +++ b/disk/Makefile @@ -9,8 +9,12 @@ obj-$(CONFIG_$(SPL_TPL_)PARTITIONS) += part.o ifdef CONFIG_$(SPL_TPL_)BLK obj-$(CONFIG_$(SPL_TPL_)PARTITIONS) += disk-uclass.o endif + +# Must have BLK or SPL_LEGACY_BLOCK to support partitions +ifneq ($(CONFIG_$(SPL_TPL_)BLK),$(CONFIG_SPL_LEGACY_BLOCK),) obj-$(CONFIG_$(SPL_TPL_)MAC_PARTITION) += part_mac.o obj-$(CONFIG_$(SPL_TPL_)DOS_PARTITION) += part_dos.o obj-$(CONFIG_$(SPL_TPL_)ISO_PARTITION) += part_iso.o obj-$(CONFIG_$(SPL_TPL_)AMIGA_PARTITION) += part_amiga.o obj-$(CONFIG_$(SPL_TPL_)EFI_PARTITION) += part_efi.o +endif diff --git a/disk/disk-uclass.c b/disk/disk-uclass.c index f3fb942a6b..551f8b1dca 100644 --- a/disk/disk-uclass.c +++ b/disk/disk-uclass.c @@ -27,8 +27,7 @@ int part_create_block_devices(struct udevice *blk_dev) struct udevice *dev; int ret; - if (!CONFIG_IS_ENABLED(PARTITIONS) || - !CONFIG_IS_ENABLED(HAVE_BLOCK_DEVICE)) + if (!CONFIG_IS_ENABLED(PARTITIONS) || !blk_enabled()) return 0; if (device_get_uclass_id(blk_dev) != UCLASS_BLK) @@ -192,12 +191,12 @@ unsigned long dev_read(struct udevice *dev, lbaint_t start, start_in_disk += part->gpt_part_info.start; } - if (blkcache_read(block_dev->if_type, block_dev->devnum, + if (blkcache_read(block_dev->uclass_id, block_dev->devnum, start_in_disk, blkcnt, block_dev->blksz, buffer)) return blkcnt; blks_read = ops->read(dev, start, blkcnt, buffer); if (blks_read == blkcnt) - blkcache_fill(block_dev->if_type, block_dev->devnum, + blkcache_fill(block_dev->uclass_id, block_dev->devnum, start_in_disk, blkcnt, block_dev->blksz, buffer); return blks_read; @@ -217,7 +216,7 @@ unsigned long dev_write(struct udevice *dev, lbaint_t start, if (!ops->write) return -ENOSYS; - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return ops->write(dev, start, blkcnt, buffer); } @@ -236,7 +235,7 @@ unsigned long dev_erase(struct udevice *dev, lbaint_t start, if (!ops->erase) return -ENOSYS; - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return ops->erase(dev, start, blkcnt); } diff --git a/disk/part.c b/disk/part.c index de1b917e84..f982b30f97 100644 --- a/disk/part.c +++ b/disk/part.c @@ -54,13 +54,14 @@ static struct part_driver *part_driver_lookup_type(struct blk_desc *dev_desc) return NULL; } -#ifdef CONFIG_HAVE_BLOCK_DEVICE static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart) { struct blk_desc *dev_desc; int ret; - dev_desc = blk_get_devnum_by_typename(ifname, dev); + if (!blk_enabled()) + return NULL; + dev_desc = blk_get_devnum_by_uclass_idname(ifname, dev); if (!dev_desc) { debug("%s: No device for iface '%s', dev %d\n", __func__, ifname, dev); @@ -78,21 +79,11 @@ static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart) struct blk_desc *blk_get_dev(const char *ifname, int dev) { + if (!blk_enabled()) + return NULL; + return get_dev_hwpart(ifname, dev, 0); } -#else -struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart) -{ - return NULL; -} - -struct blk_desc *blk_get_dev(const char *ifname, int dev) -{ - return NULL; -} -#endif - -#ifdef CONFIG_HAVE_BLOCK_DEVICE /* ------------------------------------------------------------------------- */ /* @@ -120,7 +111,7 @@ static lba512_t lba512_muldiv(lba512_t block_count, lba512_t mul_by, return bc_quot * mul_by + ((bc_rem * mul_by) >> right_shift); } -void dev_print (struct blk_desc *dev_desc) +void dev_print(struct blk_desc *dev_desc) { lba512_t lba512; /* number of blocks if 512bytes block size */ @@ -129,44 +120,42 @@ void dev_print (struct blk_desc *dev_desc) return; } - switch (dev_desc->if_type) { - case IF_TYPE_SCSI: + switch (dev_desc->uclass_id) { + case UCLASS_SCSI: printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n", dev_desc->target,dev_desc->lun, dev_desc->vendor, dev_desc->product, dev_desc->revision); break; - case IF_TYPE_ATAPI: - case IF_TYPE_IDE: - case IF_TYPE_SATA: + case UCLASS_IDE: + case UCLASS_AHCI: printf ("Model: %s Firm: %s Ser#: %s\n", dev_desc->vendor, dev_desc->revision, dev_desc->product); break; - case IF_TYPE_SD: - case IF_TYPE_MMC: - case IF_TYPE_USB: - case IF_TYPE_NVME: - case IF_TYPE_PVBLOCK: - case IF_TYPE_HOST: + case UCLASS_MMC: + case UCLASS_USB: + case UCLASS_NVME: + case UCLASS_PVBLOCK: + case UCLASS_ROOT: printf ("Vendor: %s Rev: %s Prod: %s\n", dev_desc->vendor, dev_desc->revision, dev_desc->product); break; - case IF_TYPE_VIRTIO: + case UCLASS_VIRTIO: printf("%s VirtIO Block Device\n", dev_desc->vendor); break; - case IF_TYPE_DOC: - puts("device type DOC\n"); - return; - case IF_TYPE_UNKNOWN: + case UCLASS_EFI_MEDIA: + printf("EFI media Block Device %d\n", dev_desc->devnum); + break; + case UCLASS_INVALID: puts("device type unknown\n"); return; default: - printf("Unhandled device type: %i\n", dev_desc->if_type); + printf("Unhandled device type: %i\n", dev_desc->uclass_id); return; } puts (" Type: "); @@ -228,9 +217,6 @@ void dev_print (struct blk_desc *dev_desc) puts (" Capacity: not available\n"); } } -#endif - -#ifdef CONFIG_HAVE_BLOCK_DEVICE void part_init(struct blk_desc *dev_desc) { @@ -239,7 +225,7 @@ void part_init(struct blk_desc *dev_desc) const int n_ents = ll_entry_count(struct part_driver, part_driver); struct part_driver *entry; - blkcache_invalidate(dev_desc->if_type, dev_desc->devnum); + blkcache_invalidate(dev_desc->uclass_id, dev_desc->devnum); dev_desc->part_type = PART_TYPE_UNKNOWN; for (entry = drv; entry != drv + n_ents; entry++) { @@ -262,41 +248,35 @@ static void print_part_header(const char *type, struct blk_desc *dev_desc) CONFIG_IS_ENABLED(AMIGA_PARTITION) || \ CONFIG_IS_ENABLED(EFI_PARTITION) puts ("\nPartition Map for "); - switch (dev_desc->if_type) { - case IF_TYPE_IDE: + switch (dev_desc->uclass_id) { + case UCLASS_IDE: puts ("IDE"); break; - case IF_TYPE_SATA: + case UCLASS_AHCI: puts ("SATA"); break; - case IF_TYPE_SCSI: + case UCLASS_SCSI: puts ("SCSI"); break; - case IF_TYPE_ATAPI: - puts ("ATAPI"); - break; - case IF_TYPE_USB: + case UCLASS_USB: puts ("USB"); break; - case IF_TYPE_DOC: - puts ("DOC"); - break; - case IF_TYPE_MMC: + case UCLASS_MMC: puts ("MMC"); break; - case IF_TYPE_HOST: + case UCLASS_ROOT: puts ("HOST"); break; - case IF_TYPE_NVME: + case UCLASS_NVME: puts ("NVMe"); break; - case IF_TYPE_PVBLOCK: + case UCLASS_PVBLOCK: puts("PV BLOCK"); break; - case IF_TYPE_VIRTIO: + case UCLASS_VIRTIO: puts("VirtIO"); break; - case IF_TYPE_EFI_MEDIA: + case UCLASS_EFI_MEDIA: puts("EFI"); break; default: @@ -325,38 +305,36 @@ void part_print(struct blk_desc *dev_desc) drv->print(dev_desc); } -#endif /* CONFIG_HAVE_BLOCK_DEVICE */ - int part_get_info(struct blk_desc *dev_desc, int part, struct disk_partition *info) { -#ifdef CONFIG_HAVE_BLOCK_DEVICE struct part_driver *drv; + if (blk_enabled()) { #if CONFIG_IS_ENABLED(PARTITION_UUIDS) - /* The common case is no UUID support */ - info->uuid[0] = 0; + /* The common case is no UUID support */ + info->uuid[0] = 0; #endif #ifdef CONFIG_PARTITION_TYPE_GUID - info->type_guid[0] = 0; + info->type_guid[0] = 0; #endif - drv = part_driver_lookup_type(dev_desc); - if (!drv) { - debug("## Unknown partition table type %x\n", - dev_desc->part_type); - return -EPROTONOSUPPORT; + drv = part_driver_lookup_type(dev_desc); + if (!drv) { + debug("## Unknown partition table type %x\n", + dev_desc->part_type); + return -EPROTONOSUPPORT; + } + if (!drv->get_info) { + PRINTF("## Driver %s does not have the get_info() method\n", + drv->name); + return -ENOSYS; + } + if (drv->get_info(dev_desc, part, info) == 0) { + PRINTF("## Valid %s partition found ##\n", drv->name); + return 0; + } } - if (!drv->get_info) { - PRINTF("## Driver %s does not have the get_info() method\n", - drv->name); - return -ENOSYS; - } - if (drv->get_info(dev_desc, part, info) == 0) { - PRINTF("## Valid %s partition found ##\n", drv->name); - return 0; - } -#endif /* CONFIG_HAVE_BLOCK_DEVICE */ return -ENOENT; } @@ -424,15 +402,15 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str, goto cleanup; } -#ifdef CONFIG_HAVE_BLOCK_DEVICE - /* - * Updates the partition table for the specified hw partition. - * Always should be done, otherwise hw partition 0 will return stale - * data after displaying a non-zero hw partition. - */ - if ((*dev_desc)->if_type == IF_TYPE_MMC) - part_init(*dev_desc); -#endif + if (blk_enabled()) { + /* + * Updates the partition table for the specified hw partition. + * Always should be done, otherwise hw partition 0 will return + * stale data after displaying a non-zero hw partition. + */ + if ((*dev_desc)->uclass_id == UCLASS_MMC) + part_init(*dev_desc); + } cleanup: free(dup_str); @@ -784,23 +762,18 @@ void part_set_generic_name(const struct blk_desc *dev_desc, { char *devtype; - switch (dev_desc->if_type) { - case IF_TYPE_IDE: - case IF_TYPE_SATA: - case IF_TYPE_ATAPI: + switch (dev_desc->uclass_id) { + case UCLASS_IDE: + case UCLASS_AHCI: devtype = "hd"; break; - case IF_TYPE_SCSI: + case UCLASS_SCSI: devtype = "sd"; break; - case IF_TYPE_USB: + case UCLASS_USB: devtype = "usbd"; break; - case IF_TYPE_DOC: - devtype = "docd"; - break; - case IF_TYPE_MMC: - case IF_TYPE_SD: + case UCLASS_MMC: devtype = "mmcsd"; break; default: diff --git a/disk/part_amiga.c b/disk/part_amiga.c index ac7ada5478..45d3a70486 100644 --- a/disk/part_amiga.c +++ b/disk/part_amiga.c @@ -11,8 +11,6 @@ #include "part_amiga.h" #include -#ifdef CONFIG_HAVE_BLOCK_DEVICE - #undef AMIGA_DEBUG #ifdef AMIGA_DEBUG @@ -387,5 +385,3 @@ U_BOOT_PART_TYPE(amiga) = { .print = part_print_amiga, .test = part_test_amiga, }; - -#endif diff --git a/disk/part_dos.c b/disk/part_dos.c index 94fae7166d..a94702c5f3 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -23,8 +23,6 @@ #include "part_dos.h" #include -#ifdef CONFIG_HAVE_BLOCK_DEVICE - #define DOS_PART_DEFAULT_SECTOR 512 /* should this be configurable? It looks like it's not very common at all @@ -518,5 +516,3 @@ U_BOOT_PART_TYPE(dos) = { .print = part_print_ptr(part_print_dos), .test = part_test_dos, }; - -#endif diff --git a/disk/part_efi.c b/disk/part_efi.c index 5090efd119..ad94504ed9 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -28,8 +28,6 @@ #include #include -#ifdef CONFIG_HAVE_BLOCK_DEVICE - /* GUID for basic data partitons */ #if CONFIG_IS_ENABLED(EFI_PARTITION) static const efi_guid_t partition_basic_data_guid = PARTITION_BASIC_DATA_GUID; @@ -1204,4 +1202,3 @@ U_BOOT_PART_TYPE(a_efi) = { .print = part_print_ptr(part_print_efi), .test = part_test_efi, }; -#endif /* CONFIG_HAVE_BLOCK_DEVICE */ diff --git a/disk/part_iso.c b/disk/part_iso.c index 1061f341d3..4cd619bf46 100644 --- a/disk/part_iso.c +++ b/disk/part_iso.c @@ -12,8 +12,6 @@ #include #include "part_iso.h" -#ifdef CONFIG_HAVE_BLOCK_DEVICE - /* #define ISO_PART_DEBUG */ #ifdef ISO_PART_DEBUG @@ -241,4 +239,3 @@ U_BOOT_PART_TYPE(iso) = { .print = part_print_iso, .test = part_test_iso, }; -#endif diff --git a/disk/part_mac.c b/disk/part_mac.c index e01ae74566..ae8263f755 100644 --- a/disk/part_mac.c +++ b/disk/part_mac.c @@ -20,8 +20,6 @@ #include "part_mac.h" #include -#ifdef CONFIG_HAVE_BLOCK_DEVICE - /* stdlib.h causes some compatibility problems; should fixe these! -- wd */ #ifndef __ldiv_t_defined typedef struct { @@ -247,4 +245,3 @@ U_BOOT_PART_TYPE(mac) = { .print = part_print_mac, .test = part_test_mac, }; -#endif diff --git a/doc/board/nokia/rx51.rst b/doc/board/nokia/rx51.rst index 061fe7677e..7c6647bce2 100644 --- a/doc/board/nokia/rx51.rst +++ b/doc/board/nokia/rx51.rst @@ -158,8 +158,7 @@ UBIFS support add following lines into file ``configs/nokia_rx51_defconfig``:: CONFIG_CMD_UBI=y CONFIG_CMD_UBIFS=y - CONFIG_MTD_UBI_FASTMAP=y - CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT=1 + CONFIG_MTD_UBI_BEB_LIMIT=10 Run in QEMU ----------- diff --git a/doc/build/gcc.rst b/doc/build/gcc.rst index ee544ad87e..a71f860a48 100644 --- a/doc/build/gcc.rst +++ b/doc/build/gcc.rst @@ -152,6 +152,23 @@ of dtc is new enough. It also makes sure that pylibfdt is present, if needed Note that the :doc:`tools` are always built with the included version of libfdt so it is not possible to build U-Boot tools with a system libfdt, at present. +Link-time optimisation (LTO) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +U-Boot supports link-time optimisation which can reduce the size of the final +U-Boot binaries, particularly with SPL. + +At present this can be enabled by ARM boards by adding `CONFIG_LTO=y` into the +defconfig file. Other architectures are not supported. LTO is enabled by default +for sandbox. + +This does incur a link-time penalty of several seconds. For faster incremental +builds during development, you can disable it by setting `NO_LTO` to `1`. + +.. code-block:: bash + + NO_LTO=1 make + Other build targets ~~~~~~~~~~~~~~~~~~~ diff --git a/doc/develop/cyclic.rst b/doc/develop/cyclic.rst new file mode 100644 index 0000000000..43bedacb9f --- /dev/null +++ b/doc/develop/cyclic.rst @@ -0,0 +1,50 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Cyclic functions +================ + +The cyclic function execution infrastruture provides a way to periodically +execute code, e.g. every 100ms. Examples for such functions might be LED +blinking etc. The functions that are hooked into this cyclic list should +be small timewise as otherwise the execution of the other code that relies +on a high frequent polling (e.g. UART rx char ready check) might be +delayed too much. To detect cyclic functions with a too long execution +time, the Kconfig option `CONFIG_CYCLIC_MAX_CPU_TIME_US` is introduced, +which configures the max allowed time for such a cyclic function. If it's +execution time exceeds this time, this cyclic function will get removed +from the cyclic list. + +Registering a cyclic function +----------------------------- + +To register a cyclic function, use something like this:: + + static void cyclic_demo(void *ctx) + { + /* Just a small dummy delay here */ + udelay(10); + } + + int board_init(void) + { + struct cyclic_info *cyclic; + + /* Register demo cyclic function */ + cyclic = cyclic_register(cyclic_demo, 10 * 1000, "cyclic_demo", NULL); + if (!cyclic) + printf("Registering of cyclic_demo failed\n"); + + return 0; + } + +This will register the function `cyclic_demo()` to be periodically +executed all 10ms. + +How is this cyclic functionality integrated / executed? +-------------------------------------------------------- + +The cyclic infrastructure integrates the main function responsible for +calling all registered cyclic functions cyclic_run() into the common +WATCHDOG_RESET macro. This guarantees that cyclic_run() is executed +very often, which is necessary for the cyclic functions to get scheduled +and executed at their configured periods. diff --git a/doc/develop/driver-model/livetree.rst b/doc/develop/driver-model/livetree.rst index faf3eb5b5f..55aa3eac92 100644 --- a/doc/develop/driver-model/livetree.rst +++ b/doc/develop/driver-model/livetree.rst @@ -235,20 +235,9 @@ tree either present or absent. This is to make sure that the flat tree functions work correctly even with OF_LIVE is enabled. But if a test modifies the flat device tree, then the live tree can become invalid. Any live tree tests that run after that point will use a corrupted tree, e.g. with an incorrect property name -or worse. To deal with this we use a flag UT_TESTF_LIVE_OR_FLAT then ensures -that tests which write to the flat tree are not run if OF_LIVE is enabled. Only -the live tree version of the test is run, when OF_LIVE is enabled, with -sandbox_flattree running the flat tree version. - -This is of course a work-around, even if a reasonable one. One solution to this -problem would be to make a copy of the flat tree before the test and restore it -afterwards, in the same memory location, so that the live tree pointers work -again. Another would be to regenerate the live tree if a test modified the flat -tree. - -Neither of these solutions is currently implemented, since the situation that -causes the problem can only occur in sandbox tests, is somewhat esoteric and -the UT_TESTF_LIVE_OR_FLAT flag deals with it in a reasonable way. +or worse. To deal with this we take a copy of the device tree and restore it +after any test that modifies it. Note that this copy is not made on other +boards, only sandbox. Multiple livetrees @@ -261,11 +250,14 @@ a flat tree. It would be helpful to use livetree for fixups, since adding a lot of nodes and properties would involve less memory copying and be more efficient. As a step towards this, an `oftree` type has been introduced. It is normally set to -oftree_default() but can be set to other values. Eventually this should allow -the use of FDT fixups using the ofnode interface, instead of the low-level -libfdt one. +oftree_default() but can be set to other values using oftree_from_fdt(). +So long as OF_LIVE is disabled, it is possible to do fixups using the ofnode +interface. The OF_LIVE support required addition of the flattening step at the +end. -See dm_test_ofnode_root() for some examples. +See dm_test_ofnode_root() for some examples. The ofnode_path_root() function +causes a flat device tree to be 'registered' such that it can be used by the +ofnode interface. Internal implementation @@ -329,10 +321,9 @@ Adding a new function for device-tree access involves the following steps: Future work ----------- -Live tree support was introduced in U-Boot 2017.07. There is still quite a bit -of work to do to flesh this out: +Live tree support was introduced in U-Boot 2017.07. Some possible enhancements +are: -- tests for all access functions -- more support for livetree modification -- addition of more access functions as needed - support for livetree in SPL and before relocation (if desired) +- freeing leaked memory caused by writing new nodes / property values to the + livetree (ofnode_write_prop()) diff --git a/doc/develop/driver-model/migration.rst b/doc/develop/driver-model/migration.rst index 5a60436925..742fea5515 100644 --- a/doc/develop/driver-model/migration.rst +++ b/doc/develop/driver-model/migration.rst @@ -57,7 +57,7 @@ In concert with maintainers migrating their block device usage to the appropriate DM driver, CONFIG_BLK needs to be set as well. The final deadline here coincides with the final deadline for migration of the various block subsystems. At this point we will be able to audit and correct the logic in -Kconfig around using CONFIG_PARTITIONS and CONFIG_HAVE_BLOCK_DEVICE and make +Kconfig around using CONFIG_PARTITIONS and CONFIG_SPL_LEGACY_BLOCK and make use of CONFIG_BLK / CONFIG_SPL_BLK as needed. CONFIG_DM_SPI / CONFIG_DM_SPI_FLASH diff --git a/doc/develop/index.rst b/doc/develop/index.rst index 72332f7da6..5934d9ffb1 100644 --- a/doc/develop/index.rst +++ b/doc/develop/index.rst @@ -28,6 +28,7 @@ Implementation ci_testing commands config_binding + cyclic devicetree/index distro driver-model/index diff --git a/doc/develop/py_testing.rst b/doc/develop/py_testing.rst index 06f919609b..92fbd22721 100644 --- a/doc/develop/py_testing.rst +++ b/doc/develop/py_testing.rst @@ -121,31 +121,36 @@ more options. Running tests in parallel ~~~~~~~~~~~~~~~~~~~~~~~~~ -Note: This does not fully work yet and is documented only so you can try to -fix the problems. +Note: Not all tests can run in parallel at present, so the usual approach is +to just run those that can. First install support for parallel tests:: + sudo apt install python3-pytest-xdist + +or::: + pip3 install pytest-xdist -Then build sandbox in a suitable build directory. It is not possible to use -the --build flag with xdist. +Then run the tests in parallel using the -n flag:: -Finally, run the tests in parallel using the -n flag:: + test/py/test.py -B sandbox --build --build-dir /tmp/b/sandbox -q -k \ + 'not slow and not bootstd and not spi_flash' -n16 - # build sandbox first, in a suitable build directory. It is not possible - # to use the --build flag with -n - test/py/test.py -B sandbox --build-dir /tmp/b/sandbox -q -k 'not slow' -n32 +You can also use `make pcheck` to run all tests in parallel. This uses a maximum +of 16 threads, since the setup time is significant and there are under 1000 +tests. -At least the following non-slow tests are known to fail: +Note that the `test-log.html` output does not work correctly at present with +parallel testing. All the threads write to it at once, so it is garbled. -- test_fit_ecdsa -- test_bind_unbind_with_uclass -- ut_dm_spi_flash -- test_gpt_rename_partition -- test_gpt_swap_partitions -- test_pinmux_status -- test_sqfs_load +Note that the `tools/` tests still run each tool's tests once after the other, +although within that, they do run in parallel. So for example, the buildman +tests run in parallel, then the binman tests run in parallel. There would be a +significant advantage to running them all in parallel together, but that would +require a large amount of refactoring, e.g. with more use of pytest fixtures. +The code-coverage tests are omitted since they cannot run in parallel due to a +Python limitation. Testing under a debugger diff --git a/doc/develop/testing.rst b/doc/develop/testing.rst index 1abe4d7f0f..5afeb42f69 100644 --- a/doc/develop/testing.rst +++ b/doc/develop/testing.rst @@ -28,8 +28,12 @@ run. Type this:: make tcheck +You can also run a selection tests in parallel with:: + + make pcheck + All of the above use the test/run script with a paremeter to select which tests -are run. +are run. See :doc:`py_testing` for more information. Sandbox diff --git a/doc/develop/tests_sandbox.rst b/doc/develop/tests_sandbox.rst index 40cf8ecdd7..8e42a32afb 100644 --- a/doc/develop/tests_sandbox.rst +++ b/doc/develop/tests_sandbox.rst @@ -119,6 +119,30 @@ You can easily use gdb on these tests, without needing --gdbserver:: You can then single-step and look at variables as needed. +Running tests multiple times +---------------------------- + +Some tests can have race conditions which are hard to detect on a single +one. It is possible to run each individual test multiple times, before moving +to the next test, with the '-r' flag. + +This is most useful when running a single test, since running all tests +multiple times can take a while. + +For example:: + + => ut dm -r1000 dm_test_rtc_set_get + ... + Test: dm_test_rtc_set_get: rtc.c (flat tree) + Test: dm_test_rtc_set_get: rtc.c + test/dm/rtc.c:257, dm_test_rtc_reset(): old_base_time == base_time: Expected 0x62e7453c (1659323708), got 0x62e7453d (1659323709) + Test: dm_test_rtc_set_get: rtc.c (flat tree) + Test: dm_test_rtc_set_get: rtc.c + Test: dm_test_rtc_set_get: rtc.c (flat tree) + ... + Test dm_test_rtc_reset failed 3 times + + Running sandbox_spl tests directly ---------------------------------- diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index 941e427093..cd84706953 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -748,7 +748,7 @@ UEFI block IO driver The UEFI block IO driver supports devices exposing the EFI_BLOCK_IO_PROTOCOL. When connected it creates a new U-Boot block IO device with interface type -IF_TYPE_EFI_LOADER, adds child controllers mapping the partitions, and installs +UCLASS_EFI_LOADER, adds child controllers mapping the partitions, and installs the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the software iPXE to boot from iSCSI network drives [4]. diff --git a/doc/device-tree-bindings/pmic/pm8916.txt b/doc/device-tree-bindings/pmic/pm8916.txt deleted file mode 100644 index 15c598b8c4..0000000000 --- a/doc/device-tree-bindings/pmic/pm8916.txt +++ /dev/null @@ -1,18 +0,0 @@ -Qualcomm pm8916 PMIC - -This PMIC is connected using SPMI bus so should be child of SPMI bus controller. - -Required properties: -- compatible: "qcom,spmi-pmic"; -- reg: SPMI Slave ID, size (ignored) -- #address-cells: 0x1 (peripheral ID) -- #size-cells: 0x1 (size of peripheral register space) - -Example: - -pm8916@0 { - compatible = "qcom,spmi-pmic"; - reg = <0x0 0x1>; - #address-cells = <0x1>; - #size-cells = <0x1>; -}; diff --git a/doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt b/doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt new file mode 100644 index 0000000000..eb78e3ae77 --- /dev/null +++ b/doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt @@ -0,0 +1,94 @@ + Qualcomm SPMI PMICs multi-function device bindings + +The Qualcomm SPMI series presently includes PM8941, PM8841 and PMA8084 +PMICs. These PMICs use a QPNP scheme through SPMI interface. +QPNP is effectively a partitioning scheme for dividing the SPMI extended +register space up into logical pieces, and set of fixed register +locations/definitions within these regions, with some of these regions +specifically used for interrupt handling. + +The QPNP PMICs are used with the Qualcomm Snapdragon series SoCs, and are +interfaced to the chip via the SPMI (System Power Management Interface) bus. +Support for multiple independent functions are implemented by splitting the +16-bit SPMI slave address space into 256 smaller fixed-size regions, 256 bytes +each. A function can consume one or more of these fixed-size register regions. + +Required properties: +- compatible: Should contain one of: + "qcom,pm660", + "qcom,pm660l", + "qcom,pm7325", + "qcom,pm8004", + "qcom,pm8005", + "qcom,pm8019", + "qcom,pm8028", + "qcom,pm8110", + "qcom,pm8150", + "qcom,pm8150b", + "qcom,pm8150c", + "qcom,pm8150l", + "qcom,pm8226", + "qcom,pm8350c", + "qcom,pm8841", + "qcom,pm8901", + "qcom,pm8909", + "qcom,pm8916", + "qcom,pm8941", + "qcom,pm8950", + "qcom,pm8953", + "qcom,pm8994", + "qcom,pm8998", + "qcom,pma8084", + "qcom,pmd9635", + "qcom,pmi8950", + "qcom,pmi8962", + "qcom,pmi8994", + "qcom,pmi8998", + "qcom,pmk8002", + "qcom,pmk8350", + "qcom,pmr735a", + "qcom,smb2351", + or generalized "qcom,spmi-pmic". +- reg: Specifies the SPMI USID slave address for this device. + For more information see: + Documentation/devicetree/bindings/spmi/spmi.yaml + +Required properties for peripheral child nodes: +- compatible: Should contain "qcom,xxx", where "xxx" is a peripheral name. + +Optional properties for peripheral child nodes: +- interrupts: Interrupts are specified as a 4-tuple. For more information + see: + Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml +- interrupt-names: Corresponding interrupt name to the interrupts property + +Each child node of SPMI slave id represents a function of the PMIC. In the +example below the rtc device node represents a peripheral of pm8941 +SID = 0. The regulator device node represents a peripheral of pm8941 SID = 1. + +Example: + + spmi { + compatible = "qcom,spmi-pmic-arb"; + + pm8941@0 { + compatible = "qcom,pm8941", "qcom,spmi-pmic"; + reg = <0x0 SPMI_USID>; + + rtc { + compatible = "qcom,rtc"; + interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "alarm"; + }; + }; + + pm8941@1 { + compatible = "qcom,pm8941", "qcom,spmi-pmic"; + reg = <0x1 SPMI_USID>; + + regulator { + compatible = "qcom,regulator"; + regulator-name = "8941_boost"; + }; + }; + }; diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt index 6870111840..0a03c942bd 100644 --- a/doc/uImage.FIT/source_file_format.txt +++ b/doc/uImage.FIT/source_file_format.txt @@ -23,7 +23,7 @@ in the system memory and passed to bootm as a arguments. Some of them may be missing: FDT is not present for legacy platforms, ramdisk is always optional. Additionally, old uImage format has been extended to support multi sub-images but the support is limited by simple format of the legacy uImage structure. -Single binary header 'struct image_header' is not flexible enough to cover all +Single binary header 'struct legacy_img_hdr' is not flexible enough to cover all possible scenarios. All those factors combined clearly show that there is a need for new, more diff --git a/doc/usage/cmd/bootmenu.rst b/doc/usage/cmd/bootmenu.rst index 9430f8c9aa..cb3c8d2f93 100644 --- a/doc/usage/cmd/bootmenu.rst +++ b/doc/usage/cmd/bootmenu.rst @@ -4,6 +4,15 @@ bootmenu command ================ +Synopsis +-------- +:: + + bootmenu [delay] + +Description +----------- + The "bootmenu" command uses U-Boot menu interfaces and provides a simple mechanism for creating menus with different boot items. The cursor keys "Up" and "Down" are used for navigation through @@ -79,6 +88,55 @@ The above example will be rendered as below:: The selected menu entry will be highlighted - it will have inverted background and text colors. +UEFI boot variable enumeration +'''''''''''''''''''''''''''''' +If enabled, the bootmenu command will automatically generate and add +UEFI-related boot menu entries for the following items. + + * possible bootable media with default file names + * user-defined UEFI boot options + +The bootmenu automatically enumerates the possible bootable +media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. +This auto generated entry is named as " :" format. +(e.g. "usb 0:1") + +The bootmenu displays the UEFI-related menu entries in order of "BootOrder". +When the user selects the UEFI boot menu entry, the bootmenu sets +the selected boot variable index to "BootNext" without non-volatile attribute, +then call the uefi boot manager with the command "bootefi bootmgr". + +Example bootmenu is as below:: + + *** U-Boot Boot Menu *** + + mmc 0:1 + mmc 0:2 + debian + nvme 0:1 + ubuntu + nvme 0:2 + usb 0:2 + U-Boot console + +Default behavior when user exits from the bootmenu +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +User can exit from bootmenu by selecting the last entry +"U-Boot console"/"Quit" or ESC/CTRL+C key. + +When the CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is disabled, +user exits from the bootmenu and returns to the U-Boot console. + +When the CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is enabled, user can not +enter the U-Boot console. When the user exits from the bootmenu, +the bootmenu invokes the following default behavior. + + * if CONFIG_CMD_BOOTEFI_BOOTMGR is enabled, execute "bootefi bootmgr" command + * "bootefi bootmgr" fails or is not enabled, then execute "run bootcmd" command. + +Configuration +------------- + The "bootmenu" command is enabled by:: CONFIG_CMD_BOOTMENU=y @@ -88,3 +146,19 @@ To run the bootmenu at startup add these additional settings:: CONFIG_AUTOBOOT_KEYED=y CONFIG_BOOTDELAY=30 CONFIG_AUTOBOOT_MENU_SHOW=y + +UEFI boot variable enumeration is enabled by:: + + CONFIG_CMD_BOOTEFI_BOOTMGR=y + +To improve the product security, entering U-Boot console from bootmenu +can be disabled by:: + + CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE=y + +To scan the discoverable devices connected to the buses such as +USB and PCIe prior to bootmenu showing up, CONFIG_PREBOOT can be +used to run the command before showing the bootmenu, i.e.:: + + CONFIG_USE_PREBOOT=y + CONFIG_PREBOOT="pci enum; usb start; scsi scan; nvme scan; virtio scan" diff --git a/doc/usage/cmd/cyclic.rst b/doc/usage/cmd/cyclic.rst new file mode 100644 index 0000000000..3085cc7204 --- /dev/null +++ b/doc/usage/cmd/cyclic.rst @@ -0,0 +1,45 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +cyclic command +============== + +Synopsis +-------- + +:: + + cyclic list + +Description +----------- + +The cyclic list command provides a list of the currently registered +cyclic functions. + +This shows the following information: + +Function + Function name + +cpu-time + Total time spent in this cyclic function. + +Frequency + Frequency of execution of this function, e.g. 100 times/s for a + pediod of 10ms. + + +See :doc:`../../develop/cyclic` for more information on cyclic functions. + +Example +------- + +:: + + => cyclic list + function: cyclic_demo, cpu-time: 52906 us, frequency: 99.20 times/s + +Configuration +------------- + +The cyclic command is only available if CONFIG_CMD_CYCLIC=y. diff --git a/doc/usage/cmd/eficonfig.rst b/doc/usage/cmd/eficonfig.rst new file mode 100644 index 0000000000..340ebc80db --- /dev/null +++ b/doc/usage/cmd/eficonfig.rst @@ -0,0 +1,71 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. (C) Copyright 2022, Masahisa Kojima + +eficonfig command +================= + +Synopsis +-------- +:: + + eficonfig + +Description +----------- + +The "eficonfig" command uses U-Boot menu interface and provides +a menu-driven UEFI variable maintenance feature. +The "eficonfig" has the following menu entries. + +Add Boot Option + Add new UEFI Boot Option. + User can edit description, file path, and optional_data. + +Edit Boot Option + Edit the existing UEFI Boot Option + User can edit description, file path, and optional_data. + +Change Boot Order + Change the order of UEFI BootOrder variable. + +Delete Boot Option + Delete the UEFI Boot Option + +Configuration +------------- + +The "eficonfig" command is enabled by:: + + CONFIG_CMD_EFICONFIG=y + +If CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is enabled, user can not enter +U-Boot console. In this case, bootmenu can be used to invoke "eficonfig":: + + CONFIG_USE_PREBOOT=y + CONFIG_PREBOOT="setenv bootmenu_0 UEFI Maintenance Menu=eficonfig" + +How to boot the system with newly added UEFI Boot Option +'''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +"eficonfig" command is responsible for configuring the UEFI variables, +not directly handle the system boot. +The new Boot Option added by "eficonfig" is appended at the last entry +of UEFI BootOrder variable, user may want to change the boot order +through "Change Boot Order". +If the bootmenu is enabled, CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is enabled, +and "eficonfig" is configured as preboot command, the newly added Boot Options +are enumerated in the bootmenu when user exits from the eficonfig menu. +User may select the entry in the bootmenu to boot the system, or follow +the U-Boot configuration the system already has. + +Auto boot with the UEFI Boot Option +''''''''''''''''''''''''''''''''''' + +To do auto boot according to the UEFI BootOrder variable, +add "bootefi bootmgr" entry as a default or first bootmenu entry:: + + CONFIG_PREBOOT="setenv bootmenu_0 UEFI Boot Manager=bootefi bootmgr; setenv bootmenu_1 UEFI Maintenance Menu=eficonfig" + +See also +-------- +* :doc:`bootmenu` provides a simple mechanism for creating menus with different boot items diff --git a/doc/usage/cmd/loady.rst b/doc/usage/cmd/loady.rst index 2819cc72ae..718af6e128 100644 --- a/doc/usage/cmd/loady.rst +++ b/doc/usage/cmd/loady.rst @@ -61,6 +61,13 @@ Configuration The command is only available if CONFIG_CMD_LOADB=y. +Initial timeout in seconds while waiting for transfer is configured by +config option CMD_LOADXY_TIMEOUT or by env variable $loadxy_timeout. +Setting it to 0 means infinite timeout. + +Transfer can be cancelled by pressing 3 times after two seconds +of inactivity on terminal. + Return value ------------ diff --git a/doc/usage/cmd/pause.rst b/doc/usage/cmd/pause.rst new file mode 100644 index 0000000000..c79e399c02 --- /dev/null +++ b/doc/usage/cmd/pause.rst @@ -0,0 +1,53 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later: + +pause command +============= + +Synopsis +-------- + +:: + + pause [prompt] + + +Description +----------- + +The pause command delays execution waiting for any user input. + +It can accept a single parameter to change the prompt message. + +Examples +-------- + +Using with the default prompt: + +:: + + => pause + Press any key to continue... + + +Using with a custom prompt: + +:: + + => pause 'Prompt for pause...' + Prompt for pause... + +Note that complex prompts require proper quoting: + +:: + + => pause Prompt for pause... + pause - delay until user input + + Usage: + pause [prompt] - Wait until users presses any key. [prompt] can be used to customize the message. + +Return value +------------ + +The return value $? is always set to 0 (true), unless invoked in an invalid +manner. diff --git a/doc/usage/index.rst b/doc/usage/index.rst index f1beeec59c..0fda121026 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -33,8 +33,10 @@ Shell commands cmd/bootz cmd/cbsysinfo cmd/conitrace + cmd/cyclic cmd/dm cmd/echo + cmd/eficonfig cmd/env cmd/event cmd/exception @@ -52,6 +54,7 @@ Shell commands cmd/mbr cmd/md cmd/mmc + cmd/pause cmd/pinmux cmd/printenv cmd/pstore diff --git a/doc/usage/partitions.rst b/doc/usage/partitions.rst index 2c1a12b6bf..628469bbec 100644 --- a/doc/usage/partitions.rst +++ b/doc/usage/partitions.rst @@ -20,7 +20,7 @@ generic syntax. interface The interface used to access the partition's device, like ``mmc`` or ``scsi``. For a full list of supported interfaces, consult the - ``if_typename_str`` array in ``drivers/block/blk-uclass.c`` + ``uclass_idname_str`` array in ``drivers/block/blk-uclass.c`` devnum The device number. This defaults to 0. diff --git a/drivers/Makefile b/drivers/Makefile index eba9940231..9d9f69a3c9 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -59,7 +59,8 @@ obj-$(CONFIG_SPL_WATCHDOG) += watchdog/ obj-$(CONFIG_SPL_USB_HOST) += usb/host/ obj-$(CONFIG_OMAP_USB_PHY) += usb/phy/ obj-$(CONFIG_SPL_SATA) += ata/ scsi/ -obj-$(CONFIG_HAVE_BLOCK_DEVICE) += block/ +obj-$(CONFIG_SPL_LEGACY_BLOCK) += block/ +obj-$(CONFIG_SPL_BLK) += block/ obj-$(CONFIG_SPL_THERMAL) += thermal/ endif diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index cd6060d511..a063b221cd 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -9,8 +9,6 @@ config AHCI config SATA bool "Support SATA controllers" - depends on BLK - select HAVE_BLOCK_DEVICE help This enables support for SATA (Serial Advanced Technology Attachment), a serial bus standard for connecting to hard drives and diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 1a2c3c2fe7..167b5a395f 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -880,7 +880,7 @@ int dwc_ahsata_scan(struct udevice *dev) device_find_first_child(dev, &blk); if (!blk) { ret = blk_create_devicef(dev, "dwc_ahsata_blk", "blk", - IF_TYPE_SATA, -1, 512, 0, &blk); + UCLASS_AHCI, -1, 512, 0, &blk); if (ret) { debug("Can't create device\n"); return ret; diff --git a/drivers/ata/fsl_sata.c b/drivers/ata/fsl_sata.c index 6db4247368..972101b29c 100644 --- a/drivers/ata/fsl_sata.c +++ b/drivers/ata/fsl_sata.c @@ -888,7 +888,7 @@ static int fsl_ata_probe(struct udevice *dev) for (i = 0; i < nr_ports; i++) { snprintf(sata_name, sizeof(sata_name), "fsl_sata%d", i); ret = blk_create_devicef(dev, "sata_fsl_blk", sata_name, - IF_TYPE_SATA, -1, 512, 0, &blk); + UCLASS_AHCI, -1, 512, 0, &blk); if (ret) { debug("Can't create device\n"); return ret; diff --git a/drivers/ata/sata.c b/drivers/ata/sata.c index 0e6c8cdd42..ce3e9b5a40 100644 --- a/drivers/ata/sata.c +++ b/drivers/ata/sata.c @@ -79,7 +79,7 @@ int __sata_initialize(void) for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) { memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc)); - sata_dev_desc[i].if_type = IF_TYPE_SATA; + sata_dev_desc[i].uclass_id = UCLASS_AHCI; sata_dev_desc[i].devnum = i; sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN; sata_dev_desc[i].type = DEV_TYPE_HARDDISK; diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index a187796dfc..18c7a66db1 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1076,7 +1076,7 @@ static int sata_mv_probe(struct udevice *dev) for (i = 0; i < nr_ports; i++) { ret = blk_create_devicef(dev, "sata_mv_blk", "blk", - IF_TYPE_SATA, -1, 512, 0, &blk); + UCLASS_AHCI, -1, 512, 0, &blk); if (ret) { debug("Can't create device\n"); continue; diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 7065154572..b5e150d568 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -730,7 +730,7 @@ static int sil_pci_probe(struct udevice *dev) for (i = sata_info.portbase; i < sata_info.maxport; i++) { snprintf(sata_name, sizeof(sata_name), "sil_sata%d", i); ret = blk_create_devicef(dev, "sata_sil_blk", sata_name, - IF_TYPE_SATA, -1, 512, 0, &blk); + UCLASS_AHCI, -1, 512, 0, &blk); if (ret) { debug("Can't create device\n"); return ret; diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index b5b482086a..707e2bcd23 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -1,7 +1,8 @@ config BLK - bool "Support block devices" + bool # "Support block devices" depends on DM - default y if DM_MMC || DM_USB + default y if MMC || USB || SCSI || NVME || IDE || AHCI || SATA + default y if EFI_MEDIA || VIRTIO_BLK || PVBLOCK help Enable support for block devices, such as SCSI, MMC and USB flash sticks. These provide a block-level interface which permits @@ -10,10 +11,16 @@ config BLK be partitioned into several areas, called 'partitions' in U-Boot. A filesystem can be placed in each partition. -config HAVE_BLOCK_DEVICE - bool "Enable Legacy Block Device" +config SPL_LEGACY_BLOCK + bool # "Enable Legacy Block Device" + depends on SPL && !DM_SPL + default y if SPL_MMC || SPL_USB_STORAGE || SCSI || NVME || IDE + default y if SPL_AHCI_PCI help - Some devices require block support whether or not DM is enabled + Some devices require block support whether or not DM is enabled. This + is only supported in SPL. With this, the blk uclass is not used, but + instead a legacy implementation of block devices is used, with all + devices consisting of 'struct blk_desc' records. config SPL_BLK bool "Support block devices in SPL" @@ -108,7 +115,6 @@ endif # EFI_MEDIA config IDE bool "Support IDE controllers" - select HAVE_BLOCK_DEVICE help Enables support for IDE (Integrated Drive Electronics) hard drives. This allows access to raw blocks and filesystems on an IDE drive @@ -221,7 +227,6 @@ endif # IDE config LBA48 bool "Enable LBA support for disks larger than 137GB" - depends on HAVE_BLOCK_DEVICE help Set this to enable support for disks larger than 137GB. Also look at CONFIG_SYS_64BIT_LBA. Without both of these, LBA48 @@ -230,7 +235,6 @@ config LBA48 config SYS_64BIT_LBA bool "Enable 64bit number of blocks on a block device" - depends on HAVE_BLOCK_DEVICE help Make the block subsystem use 64bit sector addresses, rather than the default of 32bit. diff --git a/drivers/block/Makefile b/drivers/block/Makefile index b221a7c6ee..f48d3e1214 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_$(SPL_)BLK) += blk-uclass.o ifndef CONFIG_$(SPL_)BLK -obj-$(CONFIG_HAVE_BLOCK_DEVICE) += blk_legacy.o +obj-$(CONFIG_SPL_LEGACY_BLOCK) += blk_legacy.o endif ifndef CONFIG_SPL_BUILD diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 21c5209bb6..7d12d5413f 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -17,70 +17,78 @@ #include #include -static const char *if_typename_str[IF_TYPE_COUNT] = { - [IF_TYPE_IDE] = "ide", - [IF_TYPE_SCSI] = "scsi", - [IF_TYPE_ATAPI] = "atapi", - [IF_TYPE_USB] = "usb", - [IF_TYPE_DOC] = "doc", - [IF_TYPE_MMC] = "mmc", - [IF_TYPE_SD] = "sd", - [IF_TYPE_SATA] = "sata", - [IF_TYPE_HOST] = "host", - [IF_TYPE_NVME] = "nvme", - [IF_TYPE_EFI_MEDIA] = "efi", - [IF_TYPE_EFI_LOADER] = "efiloader", - [IF_TYPE_VIRTIO] = "virtio", - [IF_TYPE_PVBLOCK] = "pvblock", +static struct { + enum uclass_id id; + const char *name; +} uclass_idname_str[] = { + { UCLASS_IDE, "ide" }, + { UCLASS_SCSI, "scsi" }, + { UCLASS_USB, "usb" }, + { UCLASS_MMC, "mmc" }, + { UCLASS_AHCI, "sata" }, + { UCLASS_ROOT, "host" }, + { UCLASS_NVME, "nvme" }, + { UCLASS_EFI_MEDIA, "efi" }, + { UCLASS_EFI_LOADER, "efiloader" }, + { UCLASS_VIRTIO, "virtio" }, + { UCLASS_PVBLOCK, "pvblock" }, }; -static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = { - [IF_TYPE_IDE] = UCLASS_IDE, - [IF_TYPE_SCSI] = UCLASS_SCSI, - [IF_TYPE_ATAPI] = UCLASS_INVALID, - [IF_TYPE_USB] = UCLASS_MASS_STORAGE, - [IF_TYPE_DOC] = UCLASS_INVALID, - [IF_TYPE_MMC] = UCLASS_MMC, - [IF_TYPE_SD] = UCLASS_INVALID, - [IF_TYPE_SATA] = UCLASS_AHCI, - [IF_TYPE_HOST] = UCLASS_ROOT, - [IF_TYPE_NVME] = UCLASS_NVME, - [IF_TYPE_EFI_MEDIA] = UCLASS_EFI_MEDIA, - [IF_TYPE_EFI_LOADER] = UCLASS_EFI_LOADER, - [IF_TYPE_VIRTIO] = UCLASS_VIRTIO, - [IF_TYPE_PVBLOCK] = UCLASS_PVBLOCK, -}; - -static enum if_type if_typename_to_iftype(const char *if_typename) +static enum uclass_id uclass_name_to_iftype(const char *uclass_idname) { int i; - for (i = 0; i < IF_TYPE_COUNT; i++) { - if (if_typename_str[i] && - !strcmp(if_typename, if_typename_str[i])) - return i; + for (i = 0; i < ARRAY_SIZE(uclass_idname_str); i++) { + if (!strcmp(uclass_idname, uclass_idname_str[i].name)) + return uclass_idname_str[i].id; } - return IF_TYPE_UNKNOWN; + return UCLASS_INVALID; } -static enum uclass_id if_type_to_uclass_id(enum if_type if_type) +static enum uclass_id conv_uclass_id(enum uclass_id uclass_id) { - return if_type_uclass_id[if_type]; + /* + * This strange adjustment is used because we use UCLASS_MASS_STORAGE + * for USB storage devices, so need to return this as the uclass to + * use for USB. In fact USB_UCLASS is for USB controllers, not + * peripherals. + * + * The name of the UCLASS_MASS_STORAGE uclass driver is + * "usb_mass_storage", but we want to use "usb" in things like the + * 'part list' command and when showing interfaces. + * + * So for now we have this one-way conversion. + * + * The fix for this is possibly to: + * - rename UCLASS_MASS_STORAGE name to "usb" + * - rename UCLASS_USB name to "usb_ctlr" + * - use UCLASS_MASS_STORAGE instead of UCLASS_USB in if_typename_str + */ + if (uclass_id == UCLASS_USB) + return UCLASS_MASS_STORAGE; + return uclass_id; } -const char *blk_get_if_type_name(enum if_type if_type) +const char *blk_get_uclass_name(enum uclass_id uclass_id) { - return if_typename_str[if_type]; + int i; + + for (i = 0; i < ARRAY_SIZE(uclass_idname_str); i++) { + if (uclass_idname_str[i].id == uclass_id) + return uclass_idname_str[i].name; + } + + return "(none)"; } -struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum) +struct blk_desc *blk_get_devnum_by_uclass_id(enum uclass_id uclass_id, int devnum) { struct blk_desc *desc; struct udevice *dev; int ret; - ret = blk_get_device(if_type, devnum, &dev); + ret = blk_get_device(uclass_id, devnum, &dev); if (ret) return NULL; desc = dev_get_uclass_plat(dev); @@ -93,24 +101,24 @@ struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum) * name in a local table. This gives us an interface type which we can match * against the uclass of the block device's parent. */ -struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) +struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname, int devnum) { enum uclass_id uclass_id; - enum if_type if_type; + enum uclass_id type; struct udevice *dev; struct uclass *uc; int ret; - if_type = if_typename_to_iftype(if_typename); - if (if_type == IF_TYPE_UNKNOWN) { + type = uclass_name_to_iftype(uclass_idname); + if (type == UCLASS_INVALID) { debug("%s: Unknown interface type '%s'\n", __func__, - if_typename); + uclass_idname); return NULL; } - uclass_id = if_type_to_uclass_id(if_type); + uclass_id = conv_uclass_id(type); if (uclass_id == UCLASS_INVALID) { debug("%s: Unknown uclass for interface type'\n", - if_typename_str[if_type]); + blk_get_uclass_name(type)); return NULL; } @@ -120,8 +128,8 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) uclass_foreach_dev(dev, uc) { struct blk_desc *desc = dev_get_uclass_plat(dev); - debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__, - if_type, devnum, dev->name, desc->if_type, desc->devnum); + debug("%s: uclass_id=%d, devnum=%d: %s, %d, %d\n", __func__, + type, devnum, dev->name, desc->uclass_id, desc->devnum); if (desc->devnum != devnum) continue; @@ -169,14 +177,14 @@ struct blk_desc *blk_get_by_device(struct udevice *dev) /** * get_desc() - Get the block device descriptor for the given device number * - * @if_type: Interface type + * @uclass_id: Interface type * @devnum: Device number (0 = first) * @descp: Returns block device descriptor on success * Return: 0 on success, -ENODEV if there is no such device and no device * with a higher device number, -ENOENT if there is no such device but there * is one with a higher number, or other -ve on other error. */ -static int get_desc(enum if_type if_type, int devnum, struct blk_desc **descp) +static int get_desc(enum uclass_id uclass_id, int devnum, struct blk_desc **descp) { bool found_more = false; struct udevice *dev; @@ -190,9 +198,9 @@ static int get_desc(enum if_type if_type, int devnum, struct blk_desc **descp) uclass_foreach_dev(dev, uc) { struct blk_desc *desc = dev_get_uclass_plat(dev); - debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__, - if_type, devnum, dev->name, desc->if_type, desc->devnum); - if (desc->if_type == if_type) { + debug("%s: uclass_id=%d, devnum=%d: %s, %d, %d\n", __func__, + uclass_id, devnum, dev->name, desc->uclass_id, desc->devnum); + if (desc->uclass_id == uclass_id) { if (desc->devnum == devnum) { ret = device_probe(dev); if (ret) @@ -209,26 +217,26 @@ static int get_desc(enum if_type if_type, int devnum, struct blk_desc **descp) return found_more ? -ENOENT : -ENODEV; } -int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart) +int blk_select_hwpart_devnum(enum uclass_id uclass_id, int devnum, int hwpart) { struct udevice *dev; int ret; - ret = blk_get_device(if_type, devnum, &dev); + ret = blk_get_device(uclass_id, devnum, &dev); if (ret) return ret; return blk_select_hwpart(dev, hwpart); } -int blk_list_part(enum if_type if_type) +int blk_list_part(enum uclass_id uclass_id) { struct blk_desc *desc; int devnum, ok; int ret; for (ok = 0, devnum = 0;; ++devnum) { - ret = get_desc(if_type, devnum, &desc); + ret = get_desc(uclass_id, devnum, &desc); if (ret == -ENODEV) break; else if (ret) @@ -246,12 +254,12 @@ int blk_list_part(enum if_type if_type) return 0; } -int blk_print_part_devnum(enum if_type if_type, int devnum) +int blk_print_part_devnum(enum uclass_id uclass_id, int devnum) { struct blk_desc *desc; int ret; - ret = get_desc(if_type, devnum, &desc); + ret = get_desc(uclass_id, devnum, &desc); if (ret) return ret; if (desc->type == DEV_TYPE_UNKNOWN) @@ -261,14 +269,14 @@ int blk_print_part_devnum(enum if_type if_type, int devnum) return 0; } -void blk_list_devices(enum if_type if_type) +void blk_list_devices(enum uclass_id uclass_id) { struct blk_desc *desc; int ret; int i; for (i = 0;; ++i) { - ret = get_desc(if_type, i, &desc); + ret = get_desc(uclass_id, i, &desc); if (ret == -ENODEV) break; else if (ret) @@ -280,12 +288,12 @@ void blk_list_devices(enum if_type if_type) } } -int blk_print_device_num(enum if_type if_type, int devnum) +int blk_print_device_num(enum uclass_id uclass_id, int devnum) { struct blk_desc *desc; int ret; - ret = get_desc(if_type, devnum, &desc); + ret = get_desc(uclass_id, devnum, &desc); if (ret) return ret; printf("\nIDE device %d: ", devnum); @@ -294,13 +302,13 @@ int blk_print_device_num(enum if_type if_type, int devnum) return 0; } -int blk_show_device(enum if_type if_type, int devnum) +int blk_show_device(enum uclass_id uclass_id, int devnum) { struct blk_desc *desc; int ret; printf("\nDevice %d: ", devnum); - ret = get_desc(if_type, devnum, &desc); + ret = get_desc(uclass_id, devnum, &desc); if (ret == -ENODEV || ret == -ENOENT) { printf("unknown device\n"); return -ENODEV; @@ -315,14 +323,14 @@ int blk_show_device(enum if_type if_type, int devnum) return 0; } -ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start, +ulong blk_read_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, void *buffer) { struct blk_desc *desc; ulong n; int ret; - ret = get_desc(if_type, devnum, &desc); + ret = get_desc(uclass_id, devnum, &desc); if (ret) return ret; n = blk_dread(desc, start, blkcnt, buffer); @@ -332,13 +340,13 @@ ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start, return n; } -ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start, +ulong blk_write_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, const void *buffer) { struct blk_desc *desc; int ret; - ret = get_desc(if_type, devnum, &desc); + ret = get_desc(uclass_id, devnum, &desc); if (ret) return ret; return blk_dwrite(desc, start, blkcnt, buffer); @@ -361,7 +369,7 @@ int blk_dselect_hwpart(struct blk_desc *desc, int hwpart) return blk_select_hwpart(desc->bdev, hwpart); } -int blk_first_device(int if_type, struct udevice **devp) +int blk_first_device(int uclass_id, struct udevice **devp) { struct blk_desc *desc; int ret; @@ -373,7 +381,7 @@ int blk_first_device(int if_type, struct udevice **devp) return -ENODEV; do { desc = dev_get_uclass_plat(*devp); - if (desc->if_type == if_type) + if (desc->uclass_id == uclass_id) return 0; ret = uclass_find_next_device(devp); if (ret) @@ -386,10 +394,10 @@ int blk_first_device(int if_type, struct udevice **devp) int blk_next_device(struct udevice **devp) { struct blk_desc *desc; - int ret, if_type; + int ret, uclass_id; desc = dev_get_uclass_plat(*devp); - if_type = desc->if_type; + uclass_id = desc->uclass_id; do { ret = uclass_find_next_device(devp); if (ret) @@ -397,12 +405,12 @@ int blk_next_device(struct udevice **devp) if (!*devp) return -ENODEV; desc = dev_get_uclass_plat(*devp); - if (desc->if_type == if_type) + if (desc->uclass_id == uclass_id) return 0; } while (1); } -int blk_find_device(int if_type, int devnum, struct udevice **devp) +int blk_find_device(int uclass_id, int devnum, struct udevice **devp) { struct uclass *uc; struct udevice *dev; @@ -414,9 +422,9 @@ int blk_find_device(int if_type, int devnum, struct udevice **devp) uclass_foreach_dev(dev, uc) { struct blk_desc *desc = dev_get_uclass_plat(dev); - debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__, - if_type, devnum, dev->name, desc->if_type, desc->devnum); - if (desc->if_type == if_type && desc->devnum == devnum) { + debug("%s: uclass_id=%d, devnum=%d: %s, %d, %d\n", __func__, + uclass_id, devnum, dev->name, desc->uclass_id, desc->devnum); + if (desc->uclass_id == uclass_id && desc->devnum == devnum) { *devp = dev; return 0; } @@ -425,11 +433,11 @@ int blk_find_device(int if_type, int devnum, struct udevice **devp) return -ENODEV; } -int blk_get_device(int if_type, int devnum, struct udevice **devp) +int blk_get_device(int uclass_id, int devnum, struct udevice **devp) { int ret; - ret = blk_find_device(if_type, devnum, devp); + ret = blk_find_device(uclass_id, devnum, devp); if (ret) return ret; @@ -446,12 +454,12 @@ unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start, if (!ops->read) return -ENOSYS; - if (blkcache_read(block_dev->if_type, block_dev->devnum, + if (blkcache_read(block_dev->uclass_id, block_dev->devnum, start, blkcnt, block_dev->blksz, buffer)) return blkcnt; blks_read = ops->read(dev, start, blkcnt, buffer); if (blks_read == blkcnt) - blkcache_fill(block_dev->if_type, block_dev->devnum, + blkcache_fill(block_dev->uclass_id, block_dev->devnum, start, blkcnt, block_dev->blksz, buffer); return blks_read; @@ -466,7 +474,7 @@ unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start, if (!ops->write) return -ENOSYS; - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return ops->write(dev, start, blkcnt, buffer); } @@ -479,7 +487,7 @@ unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start, if (!ops->erase) return -ENOSYS; - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return ops->erase(dev, start, blkcnt); } @@ -516,7 +524,7 @@ const char *blk_get_devtype(struct udevice *dev) return uclass_get_name(device_get_uclass_id(parent)); }; -int blk_find_max_devnum(enum if_type if_type) +int blk_find_max_devnum(enum uclass_id uclass_id) { struct udevice *dev; int max_devnum = -ENODEV; @@ -529,18 +537,18 @@ int blk_find_max_devnum(enum if_type if_type) uclass_foreach_dev(dev, uc) { struct blk_desc *desc = dev_get_uclass_plat(dev); - if (desc->if_type == if_type && desc->devnum > max_devnum) + if (desc->uclass_id == uclass_id && desc->devnum > max_devnum) max_devnum = desc->devnum; } return max_devnum; } -int blk_next_free_devnum(enum if_type if_type) +int blk_next_free_devnum(enum uclass_id uclass_id) { int ret; - ret = blk_find_max_devnum(if_type); + ret = blk_find_max_devnum(uclass_id); if (ret == -ENODEV) return 0; if (ret < 0) @@ -622,7 +630,7 @@ int blk_count_devices(enum blk_flag_t flag) return count; } -static int blk_claim_devnum(enum if_type if_type, int devnum) +static int blk_claim_devnum(enum uclass_id uclass_id, int devnum) { struct udevice *dev; struct uclass *uc; @@ -634,8 +642,8 @@ static int blk_claim_devnum(enum if_type if_type, int devnum) uclass_foreach_dev(dev, uc) { struct blk_desc *desc = dev_get_uclass_plat(dev); - if (desc->if_type == if_type && desc->devnum == devnum) { - int next = blk_next_free_devnum(if_type); + if (desc->uclass_id == uclass_id && desc->devnum == devnum) { + int next = blk_next_free_devnum(uclass_id); if (next < 0) return next; @@ -648,7 +656,7 @@ static int blk_claim_devnum(enum if_type if_type, int devnum) } int blk_create_device(struct udevice *parent, const char *drv_name, - const char *name, int if_type, int devnum, int blksz, + const char *name, int uclass_id, int devnum, int blksz, lbaint_t lba, struct udevice **devp) { struct blk_desc *desc; @@ -656,9 +664,9 @@ int blk_create_device(struct udevice *parent, const char *drv_name, int ret; if (devnum == -1) { - devnum = blk_next_free_devnum(if_type); + devnum = blk_next_free_devnum(uclass_id); } else { - ret = blk_claim_devnum(if_type, devnum); + ret = blk_claim_devnum(uclass_id, devnum); if (ret < 0 && ret != -ENOENT) return ret; } @@ -668,7 +676,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name, if (ret) return ret; desc = dev_get_uclass_plat(dev); - desc->if_type = if_type; + desc->uclass_id = uclass_id; desc->blksz = blksz; desc->log2blksz = LOG2(desc->blksz); desc->lba = lba; @@ -681,7 +689,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name, } int blk_create_devicef(struct udevice *parent, const char *drv_name, - const char *name, int if_type, int devnum, int blksz, + const char *name, int uclass_id, int devnum, int blksz, lbaint_t lba, struct udevice **devp) { char dev_name[30], *str; @@ -692,7 +700,7 @@ int blk_create_devicef(struct udevice *parent, const char *drv_name, if (!str) return -ENOMEM; - ret = blk_create_device(parent, drv_name, str, if_type, devnum, + ret = blk_create_device(parent, drv_name, str, uclass_id, devnum, blksz, lba, devp); if (ret) { free(str); @@ -716,7 +724,7 @@ int blk_probe_or_unbind(struct udevice *dev) return ret; } -int blk_unbind_all(int if_type) +int blk_unbind_all(int uclass_id) { struct uclass *uc; struct udevice *dev, *next; @@ -728,7 +736,7 @@ int blk_unbind_all(int if_type) uclass_foreach_dev_safe(dev, next, uc) { struct blk_desc *desc = dev_get_uclass_plat(dev); - if (desc->if_type == if_type) { + if (desc->uclass_id == uclass_id) { ret = device_remove(dev, DM_REMOVE_NORMAL); if (ret) return ret; @@ -743,8 +751,7 @@ int blk_unbind_all(int if_type) static int blk_post_probe(struct udevice *dev) { - if (CONFIG_IS_ENABLED(PARTITIONS) && - IS_ENABLED(CONFIG_HAVE_BLOCK_DEVICE)) { + if (CONFIG_IS_ENABLED(PARTITIONS) && blk_enabled()) { struct blk_desc *desc = dev_get_uclass_plat(dev); part_init(desc); diff --git a/drivers/block/blk_legacy.c b/drivers/block/blk_legacy.c index df9a359754..5bf1d04715 100644 --- a/drivers/block/blk_legacy.c +++ b/drivers/block/blk_legacy.c @@ -9,14 +9,14 @@ #include #include -struct blk_driver *blk_driver_lookup_type(int if_type) +struct blk_driver *blk_driver_lookup_type(int uclass_id) { struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver); const int n_ents = ll_entry_count(struct blk_driver, blk_driver); struct blk_driver *entry; for (entry = drv; entry != drv + n_ents; entry++) { - if (if_type == entry->if_type) + if (uclass_id == entry->uclass_id) return entry; } @@ -24,14 +24,14 @@ struct blk_driver *blk_driver_lookup_type(int if_type) return NULL; } -static struct blk_driver *blk_driver_lookup_typename(const char *if_typename) +static struct blk_driver *blk_driver_lookup_typename(const char *uclass_idname) { struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver); const int n_ents = ll_entry_count(struct blk_driver, blk_driver); struct blk_driver *entry; for (entry = drv; entry != drv + n_ents; entry++) { - if (!strcmp(if_typename, entry->if_typename)) + if (!strcmp(uclass_idname, entry->uclass_idname)) return entry; } @@ -39,11 +39,11 @@ static struct blk_driver *blk_driver_lookup_typename(const char *if_typename) return NULL; } -const char *blk_get_if_type_name(enum if_type if_type) +const char *blk_get_uclass_name(enum uclass_id uclass_id) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); - return drv ? drv->if_typename : NULL; + return drv ? drv->uclass_idname : NULL; } /** @@ -70,15 +70,14 @@ static int get_desc(struct blk_driver *drv, int devnum, struct blk_desc **descp) return drv->get_dev(devnum, descp); } -#ifdef CONFIG_HAVE_BLOCK_DEVICE -int blk_list_part(enum if_type if_type) +int blk_list_part(enum uclass_id uclass_id) { struct blk_driver *drv; struct blk_desc *desc; int devnum, ok; bool first = true; - drv = blk_driver_lookup_type(if_type); + drv = blk_driver_lookup_type(uclass_id); if (!drv) return -ENOSYS; for (ok = 0, devnum = 0; devnum < drv->max_devs; ++devnum) { @@ -98,9 +97,9 @@ int blk_list_part(enum if_type if_type) return 0; } -int blk_print_part_devnum(enum if_type if_type, int devnum) +int blk_print_part_devnum(enum uclass_id uclass_id, int devnum) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; int ret; @@ -116,9 +115,9 @@ int blk_print_part_devnum(enum if_type if_type, int devnum) return 0; } -void blk_list_devices(enum if_type if_type) +void blk_list_devices(enum uclass_id uclass_id) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; int i; @@ -134,9 +133,9 @@ void blk_list_devices(enum if_type if_type) } } -int blk_print_device_num(enum if_type if_type, int devnum) +int blk_print_device_num(enum uclass_id uclass_id, int devnum) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; int ret; @@ -145,15 +144,15 @@ int blk_print_device_num(enum if_type if_type, int devnum) ret = get_desc(drv, devnum, &desc); if (ret) return ret; - printf("\n%s device %d: ", drv->if_typename, devnum); + printf("\n%s device %d: ", drv->uclass_idname, devnum); dev_print(desc); return 0; } -int blk_show_device(enum if_type if_type, int devnum) +int blk_show_device(enum uclass_id uclass_id, int devnum) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; int ret; @@ -174,11 +173,10 @@ int blk_show_device(enum if_type if_type, int devnum) return 0; } -#endif /* CONFIG_HAVE_BLOCK_DEVICE */ -struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum) +struct blk_desc *blk_get_devnum_by_uclass_id(enum uclass_id uclass_id, int devnum) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; if (!drv) @@ -192,7 +190,7 @@ struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum) int blk_dselect_hwpart(struct blk_desc *desc, int hwpart) { - struct blk_driver *drv = blk_driver_lookup_type(desc->if_type); + struct blk_driver *drv = blk_driver_lookup_type(desc->uclass_id); if (!drv) return -ENOSYS; @@ -202,9 +200,9 @@ int blk_dselect_hwpart(struct blk_desc *desc, int hwpart) return 0; } -struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) +struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname, int devnum) { - struct blk_driver *drv = blk_driver_lookup_typename(if_typename); + struct blk_driver *drv = blk_driver_lookup_typename(uclass_idname); struct blk_desc *desc; if (!drv) @@ -216,10 +214,10 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) return desc; } -ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start, +ulong blk_read_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, void *buffer) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; ulong n; int ret; @@ -236,10 +234,10 @@ ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start, return n; } -ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start, +ulong blk_write_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, const void *buffer) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; int ret; @@ -251,9 +249,9 @@ ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start, return desc->block_write(desc, start, blkcnt, buffer); } -int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart) +int blk_select_hwpart_devnum(enum uclass_id uclass_id, int devnum, int hwpart) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; int ret; diff --git a/drivers/block/efi_blk.c b/drivers/block/efi_blk.c index 9d25ecbf37..917a19f602 100644 --- a/drivers/block/efi_blk.c +++ b/drivers/block/efi_blk.c @@ -94,7 +94,7 @@ static int efi_media_bind(struct udevice *dev) struct udevice *blk; int ret; - ret = blk_create_devicef(dev, "efi_block", "blk", IF_TYPE_EFI_MEDIA, + ret = blk_create_devicef(dev, "efi_block", "blk", UCLASS_EFI_MEDIA, dev_seq(dev), plat->blkio->media->block_size, plat->blkio->media->last_block, &blk); if (ret) { diff --git a/drivers/block/ide.c b/drivers/block/ide.c index 3270a9f032..eaa58d859c 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -62,7 +62,7 @@ static void ide_reset(void) /* the reset signal shall be asserted for et least 25 us */ udelay(25); - WATCHDOG_RESET(); + schedule(); /* de-assert RESET signal */ ide_set_reset(0); @@ -525,8 +525,8 @@ static void ide_ident(struct blk_desc *dev_desc) { unsigned char c; hd_driveid_t iop; - #ifdef CONFIG_ATAPI + bool is_atapi = false; int retries = 0; #endif int device; @@ -537,7 +537,7 @@ static void ide_ident(struct blk_desc *dev_desc) /* Select device */ ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); - dev_desc->if_type = IF_TYPE_IDE; + dev_desc->uclass_id = UCLASS_IDE; #ifdef CONFIG_ATAPI retries = 0; @@ -550,7 +550,7 @@ static void ide_ident(struct blk_desc *dev_desc) (ide_inb(device, ATA_CYL_LOW) == 0x14) && (ide_inb(device, ATA_CYL_HIGH) == 0xEB)) { /* ATAPI Signature found */ - dev_desc->if_type = IF_TYPE_ATAPI; + is_atapi = true; /* * Start Ident Command */ @@ -623,7 +623,7 @@ static void ide_ident(struct blk_desc *dev_desc) dev_desc->removable = 0; #ifdef CONFIG_ATAPI - if (dev_desc->if_type == IF_TYPE_ATAPI) { + if (is_atapi) { atapi_inquiry(dev_desc); return; } @@ -695,7 +695,7 @@ void ide_init(void) unsigned char c; int i, bus; - WATCHDOG_RESET(); + schedule(); /* ATAPI Drives seems to need a proper IDE Reset */ ide_reset(); @@ -745,14 +745,14 @@ void ide_init(void) puts("OK "); ide_bus_ok[bus] = 1; } - WATCHDOG_RESET(); + schedule(); } putc('\n'); for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) { ide_dev_desc[i].type = DEV_TYPE_UNKNOWN; - ide_dev_desc[i].if_type = IF_TYPE_IDE; + ide_dev_desc[i].uclass_id = UCLASS_IDE; ide_dev_desc[i].devnum = i; ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN; ide_dev_desc[i].blksz = 0; @@ -775,7 +775,7 @@ void ide_init(void) } #endif } - WATCHDOG_RESET(); + schedule(); #ifdef CONFIG_BLK struct udevice *dev; @@ -1110,7 +1110,7 @@ static int ide_probe(struct udevice *udev) if (!blksz) continue; ret = blk_create_devicef(udev, "ide_blk", name, - IF_TYPE_IDE, i, + UCLASS_IDE, i, blksz, size, &blk_dev); if (ret) return ret; @@ -1143,8 +1143,8 @@ UCLASS_DRIVER(ide) = { }; #else U_BOOT_LEGACY_BLK(ide) = { - .if_typename = "ide", - .if_type = IF_TYPE_IDE, + .uclass_idname = "ide", + .uclass_id = UCLASS_IDE, .max_devs = CONFIG_SYS_IDE_MAXDEVICE, .desc = ide_dev_desc, }; diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c index 1388498a1d..f2aae89716 100644 --- a/drivers/block/sandbox.c +++ b/drivers/block/sandbox.c @@ -98,7 +98,7 @@ int host_dev_bind(int devnum, char *filename, bool removable) int ret, fd; /* Remove and unbind the old device, if any */ - ret = blk_get_device(IF_TYPE_HOST, devnum, &dev); + ret = blk_get_device(UCLASS_ROOT, devnum, &dev); if (ret == 0) { ret = device_remove(dev, DM_REMOVE_NORMAL); if (ret) @@ -135,7 +135,7 @@ int host_dev_bind(int devnum, char *filename, bool removable) } } ret = blk_create_device(gd->dm_root, "sandbox_host_blk", str, - IF_TYPE_HOST, devnum, 512, + UCLASS_ROOT, devnum, 512, os_lseek(fd, 0, OS_SEEK_END) / 512, &dev); if (ret) goto err_file; @@ -150,7 +150,7 @@ int host_dev_bind(int devnum, char *filename, bool removable) goto err_file; } - desc = blk_get_devnum_by_type(IF_TYPE_HOST, devnum); + desc = blk_get_devnum_by_uclass_id(UCLASS_ROOT, devnum); desc->removable = removable; snprintf(desc->vendor, BLK_VEN_SIZE, "U-Boot"); snprintf(desc->product, BLK_PRD_SIZE, "hostfile"); @@ -192,7 +192,7 @@ int host_dev_bind(int dev, char *filename, bool removable) } struct blk_desc *blk_dev = &host_dev->blk_dev; - blk_dev->if_type = IF_TYPE_HOST; + blk_dev->uclass_id = UCLASS_ROOT; blk_dev->priv = host_dev; blk_dev->blksz = 512; blk_dev->lba = os_lseek(host_dev->fd, 0, OS_SEEK_END) / blk_dev->blksz; @@ -216,7 +216,7 @@ int host_get_dev_err(int devnum, struct blk_desc **blk_devp) struct udevice *dev; int ret; - ret = blk_get_device(IF_TYPE_HOST, devnum, &dev); + ret = blk_get_device(UCLASS_ROOT, devnum, &dev); if (ret) return ret; *blk_devp = dev_get_uclass_plat(dev); @@ -262,8 +262,8 @@ U_BOOT_DRIVER(sandbox_host_blk) = { }; #else U_BOOT_LEGACY_BLK(sandbox_host) = { - .if_typename = "host", - .if_type = IF_TYPE_HOST, + .uclass_idname = "host", + .uclass_id = UCLASS_ROOT, .max_devs = SANDBOX_HOST_MAX_DEVICES, .get_dev = host_get_dev_err, }; diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index fd9e1a80c6..09aa97ee8c 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -184,7 +184,7 @@ config CLK_VERSACLOCK config CLK_VERSAL bool "Enable clock driver support for Versal" - depends on ARCH_VERSAL + depends on (ARCH_VERSAL || ARCH_VERSAL_NET) select ZYNQMP_FIRMWARE help This clock driver adds support for clock realted settings for diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c index 623c6915b8..dc446ce9fb 100644 --- a/drivers/clk/aspeed/clk_ast2500.c +++ b/drivers/clk/aspeed/clk_ast2500.c @@ -30,6 +30,12 @@ #define D2PLL_DEFAULT_RATE (250 * 1000 * 1000) +/* + * AXI/AHB clock selection, taken from Aspeed SDK + */ +#define SCU_HWSTRAP_AXIAHB_DIV_SHIFT 9 +#define SCU_HWSTRAP_AXIAHB_DIV_MASK (0x7 << SCU_HWSTRAP_AXIAHB_DIV_SHIFT) + DECLARE_GLOBAL_DATA_PTR; /* @@ -86,6 +92,20 @@ static ulong ast2500_get_clkin(struct ast2500_scu *scu) ? 25 * 1000 * 1000 : 24 * 1000 * 1000; } +static u32 ast2500_get_hclk(ulong clkin, struct ast2500_scu *scu) +{ + u32 hpll_reg = readl(&scu->h_pll_param); + ulong axi_div = 2; + u32 rate; + ulong ahb_div = 1 + ((readl(&scu->hwstrap) + & SCU_HWSTRAP_AXIAHB_DIV_MASK) + >> SCU_HWSTRAP_AXIAHB_DIV_SHIFT); + + rate = ast2500_get_hpll_rate(clkin, hpll_reg); + + return (rate / axi_div / ahb_div); +} + /** * Get current rate or uart clock * @@ -147,6 +167,9 @@ static ulong ast2500_clk_get_rate(struct clk *clk) rate = rate / apb_div; } break; + case ASPEED_CLK_AHB: + rate = ast2500_get_hclk(clkin, priv->scu); + break; case ASPEED_CLK_SDIO: { ulong apb_div = 4 + 4 * ((readl(&priv->scu->clk_sel1) diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c index 4d00ee2ddc..6b5486c6c9 100644 --- a/drivers/clk/at91/sam9x60.c +++ b/drivers/clk/at91/sam9x60.c @@ -265,10 +265,10 @@ static const struct { u8 id; u8 cid; } sam9x60_systemck[] = { - { .n = "ddrck", .p = "mck_pres", .id = 2, .cid = ID_DDR, }, + { .n = "ddrck", .p = "mck_div", .id = 2, .cid = ID_DDR, }, { .n = "pck0", .p = "prog0", .id = 8, .cid = ID_PCK0, }, { .n = "pck1", .p = "prog1", .id = 9, .cid = ID_PCK1, }, - { .n = "qspick", .p = "mck_pres", .id = 19, .cid = ID_QSPI, }, + { .n = "qspick", .p = "mck_div", .id = 19, .cid = ID_QSPI, }, }; /** diff --git a/drivers/clk/clk_versal.c b/drivers/clk/clk_versal.c index a9dd57b098..b2f62061ce 100644 --- a/drivers/clk/clk_versal.c +++ b/drivers/clk/clk_versal.c @@ -739,6 +739,7 @@ static struct clk_ops versal_clk_ops = { static const struct udevice_id versal_clk_ids[] = { { .compatible = "xlnx,versal-clk" }, + { .compatible = "xlnx,versal-net-clk" }, { } }; diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 522e724221..1decf31a77 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -7,6 +7,8 @@ obj-$(CONFIG_MT8512) += clk-mt8512.o obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o obj-$(CONFIG_TARGET_MT7622) += clk-mt7622.o obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o +obj-$(CONFIG_TARGET_MT7986) += clk-mt7986.o +obj-$(CONFIG_TARGET_MT7981) += clk-mt7981.o obj-$(CONFIG_TARGET_MT8183) += clk-mt8183.o obj-$(CONFIG_TARGET_MT8516) += clk-mt8516.o obj-$(CONFIG_TARGET_MT8518) += clk-mt8518.o diff --git a/drivers/clk/mediatek/clk-mt7981.c b/drivers/clk/mediatek/clk-mt7981.c new file mode 100644 index 0000000000..7fcb81419c --- /dev/null +++ b/drivers/clk/mediatek/clk-mt7981.c @@ -0,0 +1,683 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek clock driver for MT7981 SoC + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include +#include +#include +#include +#include + +#include "clk-mtk.h" + +#define MT7981_CLK_PDN 0x250 +#define MT7981_CLK_PDN_EN_WRITE BIT(31) + +#define PLL_FACTOR(_id, _name, _parent, _mult, _div) \ + FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED) + +#define TOP_FACTOR(_id, _name, _parent, _mult, _div) \ + FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN) + +#define INFRA_FACTOR(_id, _name, _parent, _mult, _div) \ + FACTOR(_id, _parent, _mult, _div, CLK_PARENT_INFRASYS) + +/* FIXED PLLS */ +static const struct mtk_fixed_clk fixed_pll_clks[] = { + FIXED_CLK(CK_APMIXED_ARMPLL, CLK_XTAL, 1300000000), + FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 800000000), + FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 720000000), + FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 325000000), + FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 208000000), + FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 2500000000), + FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 416000000), + FIXED_CLK(CK_APMIXED_APLL2, CLK_XTAL, 196608000), +}; + +/* TOPCKGEN FIXED CLK */ +static const struct mtk_fixed_clk top_fixed_clks[] = { + FIXED_CLK(CK_TOP_CB_CKSQ_40M, CLK_XTAL, 40000000), +}; + +/* TOPCKGEN FIXED DIV */ +static const struct mtk_fixed_factor top_fixed_divs[] = { + PLL_FACTOR(CK_TOP_CB_M_416M, "cb_m_416m", CK_APMIXED_MPLL, 1, 1), + PLL_FACTOR(CK_TOP_CB_M_D2, "cb_m_d2", CK_APMIXED_MPLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_M_D3, "cb_m_d3", CK_APMIXED_MPLL, 1, 3), + PLL_FACTOR(CK_TOP_M_D3_D2, "m_d3_d2", CK_APMIXED_MPLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_M_D4, "cb_m_d4", CK_APMIXED_MPLL, 1, 4), + PLL_FACTOR(CK_TOP_CB_M_D8, "cb_m_d8", CK_APMIXED_MPLL, 1, 8), + PLL_FACTOR(CK_TOP_M_D8_D2, "m_d8_d2", CK_APMIXED_MPLL, 1, 16), + PLL_FACTOR(CK_TOP_CB_MM_720M, "cb_mm_720m", CK_APMIXED_MMPLL, 1, 1), + PLL_FACTOR(CK_TOP_CB_MM_D2, "cb_mm_d2", CK_APMIXED_MMPLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_MM_D3, "cb_mm_d3", CK_APMIXED_MMPLL, 1, 3), + PLL_FACTOR(CK_TOP_CB_MM_D3_D5, "cb_mm_d3_d5", CK_APMIXED_MMPLL, 1, 15), + PLL_FACTOR(CK_TOP_CB_MM_D4, "cb_mm_d4", CK_APMIXED_MMPLL, 1, 4), + PLL_FACTOR(CK_TOP_CB_MM_D6, "cb_mm_d6", CK_APMIXED_MMPLL, 1, 6), + PLL_FACTOR(CK_TOP_MM_D6_D2, "mm_d6_d2", CK_APMIXED_MMPLL, 1, 12), + PLL_FACTOR(CK_TOP_CB_MM_D8, "cb_mm_d8", CK_APMIXED_MMPLL, 1, 8), + PLL_FACTOR(CK_TOP_CB_APLL2_196M, "cb_apll2_196m", CK_APMIXED_APLL2, 1, + 1), + PLL_FACTOR(CK_TOP_APLL2_D2, "apll2_d2", CK_APMIXED_APLL2, 1, 2), + PLL_FACTOR(CK_TOP_APLL2_D4, "apll2_d4", CK_APMIXED_APLL2, 1, 4), + PLL_FACTOR(CK_TOP_NET1_2500M, "net1_2500m", CK_APMIXED_NET1PLL, 1, 1), + PLL_FACTOR(CK_TOP_CB_NET1_D4, "cb_net1_d4", CK_APMIXED_NET1PLL, 1, 4), + PLL_FACTOR(CK_TOP_CB_NET1_D5, "cb_net1_d5", CK_APMIXED_NET1PLL, 1, 5), + PLL_FACTOR(CK_TOP_NET1_D5_D2, "net1_d5_d2", CK_APMIXED_NET1PLL, 1, 10), + PLL_FACTOR(CK_TOP_NET1_D5_D4, "net1_d5_d4", CK_APMIXED_NET1PLL, 1, 20), + PLL_FACTOR(CK_TOP_CB_NET1_D8, "cb_net1_d8", CK_APMIXED_NET1PLL, 1, 8), + PLL_FACTOR(CK_TOP_NET1_D8_D2, "net1_d8_d2", CK_APMIXED_NET1PLL, 1, 16), + PLL_FACTOR(CK_TOP_NET1_D8_D4, "net1_d8_d4", CK_APMIXED_NET1PLL, 1, 32), + PLL_FACTOR(CK_TOP_CB_NET2_800M, "cb_net2_800m", CK_APMIXED_NET2PLL, 1, + 1), + PLL_FACTOR(CK_TOP_CB_NET2_D2, "cb_net2_d2", CK_APMIXED_NET2PLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_NET2_D4, "cb_net2_d4", CK_APMIXED_NET2PLL, 1, 4), + PLL_FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", CK_APMIXED_NET2PLL, 1, 8), + PLL_FACTOR(CK_TOP_NET2_D4_D4, "net2_d4_d4", CK_APMIXED_NET2PLL, 1, 16), + PLL_FACTOR(CK_TOP_CB_NET2_D6, "cb_net2_d6", CK_APMIXED_NET2PLL, 1, 6), + PLL_FACTOR(CK_TOP_CB_WEDMCU_208M, "cb_wedmcu_208m", + CK_APMIXED_WEDMCUPLL, 1, 1), + PLL_FACTOR(CK_TOP_CB_SGM_325M, "cb_sgm_325m", CK_APMIXED_SGMPLL, 1, 1), + TOP_FACTOR(CK_TOP_CKSQ_40M_D2, "cksq_40m_d2", CK_TOP_CB_CKSQ_40M, 1, 2), + TOP_FACTOR(CK_TOP_CB_RTC_32K, "cb_rtc_32k", CK_TOP_CB_CKSQ_40M, 1, + 1250), + TOP_FACTOR(CK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", CK_TOP_CB_CKSQ_40M, 1, + 1220), + TOP_FACTOR(CK_TOP_USB_TX250M, "usb_tx250m", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_FAUD, "faud", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_NFI1X, "nfi1x", CK_TOP_NFI1X_SEL, 1, 1), + TOP_FACTOR(CK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", CK_TOP_CB_CKSQ_40M, 1, + 1), + TOP_FACTOR(CK_TOP_USB_CDR_CK, "usb_cdr", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_USB_LN0_CK, "usb_ln0", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_SPINFI_BCK, "spinfi_bck", CK_TOP_SPINFI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_SPI, "spi", CK_TOP_SPI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_SPIM_MST, "spim_mst", CK_TOP_SPIM_MST_SEL, 1, 1), + TOP_FACTOR(CK_TOP_UART_BCK, "uart_bck", CK_TOP_UART_SEL, 1, 1), + TOP_FACTOR(CK_TOP_PWM_BCK, "pwm_bck", CK_TOP_PWM_SEL, 1, 1), + TOP_FACTOR(CK_TOP_I2C_BCK, "i2c_bck", CK_TOP_I2C_SEL, 1, 1), + TOP_FACTOR(CK_TOP_PEXTP_TL, "pextp_tl", CK_TOP_PEXTP_TL_SEL, 1, 1), + TOP_FACTOR(CK_TOP_EMMC_208M, "emmc_208m", CK_TOP_EMMC_208M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_EMMC_400M, "emmc_400m", CK_TOP_EMMC_400M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_DRAMC_REF, "dramc_ref", CK_TOP_DRAMC_SEL, 1, 1), + TOP_FACTOR(CK_TOP_DRAMC_MD32, "dramc_md32", CK_TOP_DRAMC_MD32_SEL, 1, + 1), + TOP_FACTOR(CK_TOP_SYSAXI, "sysaxi", CK_TOP_SYSAXI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_SYSAPB, "sysapb", CK_TOP_SYSAPB_SEL, 1, 1), + TOP_FACTOR(CK_TOP_ARM_DB_MAIN, "arm_db_main", CK_TOP_ARM_DB_MAIN_SEL, 1, + 1), + TOP_FACTOR(CK_TOP_AP2CNN_HOST, "ap2cnn_host", CK_TOP_AP2CNN_HOST_SEL, 1, + 1), + TOP_FACTOR(CK_TOP_NETSYS, "netsys", CK_TOP_NETSYS_SEL, 1, 1), + TOP_FACTOR(CK_TOP_NETSYS_500M, "netsys_500m", CK_TOP_NETSYS_500M_SEL, 1, + 1), + TOP_FACTOR(CK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu", + CK_TOP_NETSYS_MCU_SEL, 1, 1), + TOP_FACTOR(CK_TOP_NETSYS_2X, "netsys_2x", CK_TOP_NETSYS_2X_SEL, 1, 1), + TOP_FACTOR(CK_TOP_SGM_325M, "sgm_325m", CK_TOP_SGM_325M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_SGM_REG, "sgm_reg", CK_TOP_SGM_REG_SEL, 1, 1), + TOP_FACTOR(CK_TOP_F26M, "csw_f26m", CK_TOP_F26M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_EIP97B, "eip97b", CK_TOP_EIP97B_SEL, 1, 1), + TOP_FACTOR(CK_TOP_USB3_PHY, "usb3_phy", CK_TOP_USB3_PHY_SEL, 1, 1), + TOP_FACTOR(CK_TOP_AUD, "aud", CK_TOP_FAUD, 1, 1), + TOP_FACTOR(CK_TOP_A1SYS, "a1sys", CK_TOP_A1SYS_SEL, 1, 1), + TOP_FACTOR(CK_TOP_AUD_L, "aud_l", CK_TOP_AUD_L_SEL, 1, 1), + TOP_FACTOR(CK_TOP_A_TUNER, "a_tuner", CK_TOP_A_TUNER_SEL, 1, 1), + TOP_FACTOR(CK_TOP_U2U3_REF, "u2u3_ref", CK_TOP_U2U3_SEL, 1, 1), + TOP_FACTOR(CK_TOP_U2U3_SYS, "u2u3_sys", CK_TOP_U2U3_SYS_SEL, 1, 1), + TOP_FACTOR(CK_TOP_U2U3_XHCI, "u2u3_xhci", CK_TOP_U2U3_XHCI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_USB_FRMCNT, "usb_frmcnt", CK_TOP_USB_FRMCNT_SEL, 1, + 1), +}; + +/* TOPCKGEN MUX PARENTS */ +static const int nfi1x_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D4, + CK_TOP_NET1_D8_D2, CK_TOP_CB_NET2_D6, + CK_TOP_CB_M_D4, CK_TOP_CB_MM_D8, + CK_TOP_NET1_D8_D4, CK_TOP_CB_M_D8 }; + +static const int spinfi_parents[] = { CK_TOP_CKSQ_40M_D2, CK_TOP_CB_CKSQ_40M, + CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4, + CK_TOP_CB_MM_D8, CK_TOP_NET1_D8_D4, + CK_TOP_MM_D6_D2, CK_TOP_CB_M_D8 }; + +static const int spi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2, + CK_TOP_CB_MM_D4, CK_TOP_NET1_D8_D2, + CK_TOP_CB_NET2_D6, CK_TOP_NET1_D5_D4, + CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 }; + +static const int uart_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D8, + CK_TOP_M_D8_D2 }; + +static const int pwm_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2, + CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4, + CK_TOP_M_D8_D2, CK_TOP_CB_RTC_32K }; + +static const int i2c_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4, + CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 }; + +static const int pextp_tl_ck_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4, + CK_TOP_CB_RTC_32K }; + +static const int emmc_208m_parents[] = { + CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2, CK_TOP_CB_NET2_D4, + CK_TOP_CB_APLL2_196M, CK_TOP_CB_MM_D4, CK_TOP_NET1_D8_D2, + CK_TOP_CB_MM_D6 +}; + +static const int emmc_400m_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET2_D2, + CK_TOP_CB_MM_D2, CK_TOP_CB_NET2_D2 }; + +static const int csw_f26m_parents[] = { CK_TOP_CKSQ_40M_D2, CK_TOP_M_D8_D2 }; + +static const int dramc_md32_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2, + CK_TOP_CB_WEDMCU_208M }; + +static const int sysaxi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2 }; + +static const int sysapb_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D3_D2 }; + +static const int arm_db_main_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_NET2_D6 }; + +static const int ap2cnn_host_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_NET1_D8_D4 }; + +static const int netsys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D2 }; + +static const int netsys_500m_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_NET1_D5 }; + +static const int netsys_mcu_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_720M, + CK_TOP_CB_NET1_D4, CK_TOP_CB_NET1_D5, + CK_TOP_CB_M_416M }; + +static const int netsys_2x_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_NET2_800M, + CK_TOP_CB_MM_720M }; + +static const int sgm_325m_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_SGM_325M }; + +static const int sgm_reg_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET2_D4 }; + +static const int eip97b_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET1_D5, + CK_TOP_CB_M_416M, CK_TOP_CB_MM_D2, + CK_TOP_NET1_D5_D2 }; + +static const int aud_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M }; + +static const int a1sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4 }; + +static const int aud_l_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M, + CK_TOP_M_D8_D2 }; + +static const int a_tuner_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4, + CK_TOP_M_D8_D2 }; + +static const int u2u3_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D8_D2 }; + +static const int u2u3_sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4 }; + +static const int usb_frmcnt_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_MM_D3_D5 }; + +#define TOP_MUX(_id, _name, _parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd) \ + { \ + .id = _id, .mux_reg = _mux_ofs, .mux_set_reg = _mux_set_ofs, \ + .mux_clr_reg = _mux_clr_ofs, .upd_reg = _upd_ofs, \ + .upd_shift = _upd, .mux_shift = _shift, \ + .mux_mask = BIT(_width) - 1, .gate_reg = _mux_ofs, \ + .gate_shift = _gate, .parent = _parents, \ + .num_parents = ARRAY_SIZE(_parents), \ + .flags = CLK_MUX_SETCLR_UPD, \ + } + +/* TOPCKGEN MUX_GATE */ +static const struct mtk_composite top_muxes[] = { + TOP_MUX(CK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x0, 0x4, 0x8, 0, + 3, 7, 0x1c0, 0), + TOP_MUX(CK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents, 0x0, 0x4, 0x8, + 8, 3, 15, 0x1c0, 1), + TOP_MUX(CK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0, 0x4, 0x8, 16, 3, + 23, 0x1c0, 2), + TOP_MUX(CK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents, 0x0, 0x4, 0x8, + 24, 3, 31, 0x1c0, 3), + TOP_MUX(CK_TOP_UART_SEL, "uart_sel", uart_parents, 0x10, 0x14, 0x18, 0, + 2, 7, 0x1c0, 4), + TOP_MUX(CK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x10, 0x14, 0x18, 8, 3, + 15, 0x1c0, 5), + TOP_MUX(CK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x10, 0x14, 0x18, 16, 2, + 23, 0x1c0, 6), + TOP_MUX(CK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel", pextp_tl_ck_parents, + 0x10, 0x14, 0x18, 24, 2, 31, 0x1c0, 7), + TOP_MUX(CK_TOP_EMMC_208M_SEL, "emmc_208m_sel", emmc_208m_parents, 0x20, + 0x24, 0x28, 0, 3, 7, 0x1c0, 8), + TOP_MUX(CK_TOP_EMMC_400M_SEL, "emmc_400m_sel", emmc_400m_parents, 0x20, + 0x24, 0x28, 8, 2, 15, 0x1c0, 9), + TOP_MUX(CK_TOP_F26M_SEL, "csw_f26m_sel", csw_f26m_parents, 0x20, 0x24, + 0x28, 16, 1, 23, 0x1c0, 10), + TOP_MUX(CK_TOP_DRAMC_SEL, "dramc_sel", csw_f26m_parents, 0x20, 0x24, + 0x28, 24, 1, 31, 0x1c0, 11), + TOP_MUX(CK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents, + 0x30, 0x34, 0x38, 0, 2, 7, 0x1c0, 12), + TOP_MUX(CK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents, 0x30, 0x34, + 0x38, 8, 1, 15, 0x1c0, 13), + TOP_MUX(CK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents, 0x30, 0x34, + 0x38, 16, 1, 23, 0x1c0, 14), + TOP_MUX(CK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel", arm_db_main_parents, + 0x30, 0x34, 0x38, 24, 1, 31, 0x1c0, 15), + TOP_MUX(CK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel", ap2cnn_host_parents, + 0x40, 0x44, 0x48, 0, 1, 7, 0x1c0, 16), + TOP_MUX(CK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents, 0x40, 0x44, + 0x48, 8, 1, 15, 0x1c0, 17), + TOP_MUX(CK_TOP_NETSYS_500M_SEL, "netsys_500m_sel", netsys_500m_parents, + 0x40, 0x44, 0x48, 16, 1, 23, 0x1c0, 18), + TOP_MUX(CK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel", netsys_mcu_parents, + 0x40, 0x44, 0x48, 24, 3, 31, 0x1c0, 19), + TOP_MUX(CK_TOP_NETSYS_2X_SEL, "netsys_2x_sel", netsys_2x_parents, 0x50, + 0x54, 0x58, 0, 2, 7, 0x1c0, 20), + TOP_MUX(CK_TOP_SGM_325M_SEL, "sgm_325m_sel", sgm_325m_parents, 0x50, + 0x54, 0x58, 8, 1, 15, 0x1c0, 21), + TOP_MUX(CK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents, 0x50, 0x54, + 0x58, 16, 1, 23, 0x1c0, 22), + TOP_MUX(CK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents, 0x50, 0x54, + 0x58, 24, 3, 31, 0x1c0, 23), + TOP_MUX(CK_TOP_USB3_PHY_SEL, "usb3_phy_sel", csw_f26m_parents, 0x60, + 0x64, 0x68, 0, 1, 7, 0x1c0, 24), + TOP_MUX(CK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x60, 0x64, 0x68, 8, 1, + 15, 0x1c0, 25), + TOP_MUX(CK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents, 0x60, 0x64, 0x68, + 16, 1, 23, 0x1c0, 26), + TOP_MUX(CK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents, 0x60, 0x64, 0x68, + 24, 2, 31, 0x1c0, 27), + TOP_MUX(CK_TOP_A_TUNER_SEL, "a_tuner_sel", a_tuner_parents, 0x70, 0x74, + 0x78, 0, 2, 7, 0x1c0, 28), + TOP_MUX(CK_TOP_U2U3_SEL, "u2u3_sel", u2u3_parents, 0x70, 0x74, 0x78, 8, + 1, 15, 0x1c0, 29), + TOP_MUX(CK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel", u2u3_sys_parents, 0x70, + 0x74, 0x78, 16, 1, 23, 0x1c0, 30), + TOP_MUX(CK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel", u2u3_sys_parents, 0x70, + 0x74, 0x78, 24, 1, 31, 0x1c4, 0), + TOP_MUX(CK_TOP_USB_FRMCNT_SEL, "usb_frmcnt_sel", usb_frmcnt_parents, + 0x80, 0x84, 0x88, 0, 1, 7, 0x1c4, 1), +}; + +/* INFRA FIXED DIV */ +static const struct mtk_fixed_factor infra_fixed_divs[] = { + TOP_FACTOR(CK_INFRA_CK_F26M, "infra_ck_f26m", CK_TOP_F26M_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_UART, "infra_uart", CK_TOP_UART_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_ISPI0, "infra_ispi0", CK_TOP_SPI_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_I2C, "infra_i2c", CK_TOP_I2C_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_ISPI1, "infra_ispi1", CK_TOP_SPIM_MST_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_PWM, "infra_pwm", CK_TOP_PWM_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_66M_MCK, "infra_66m_mck", CK_TOP_SYSAXI_SEL, 1, 2), + TOP_FACTOR(CK_INFRA_CK_F32K, "infra_ck_f32k", CK_TOP_CB_RTC_32P7K, 1, + 1), + TOP_FACTOR(CK_INFRA_PCIE_CK, "infra_pcie", CK_TOP_PEXTP_TL_SEL, 1, 1), + INFRA_FACTOR(CK_INFRA_PWM_BCK, "infra_pwm_bck", CK_INFRA_PWM_BSEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_PWM_CK1, "infra_pwm_ck1", CK_INFRA_PWM1_SEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_PWM_CK2, "infra_pwm_ck2", CK_INFRA_PWM2_SEL, 1, + 1), + TOP_FACTOR(CK_INFRA_133M_HCK, "infra_133m_hck", CK_TOP_SYSAXI, 1, 1), + INFRA_FACTOR(CK_INFRA_66M_PHCK, "infra_66m_phck", CK_INFRA_133M_HCK, 1, + 1), + TOP_FACTOR(CK_INFRA_FAUD_L_CK, "infra_faud_l", CK_TOP_AUD_L, 1, 1), + TOP_FACTOR(CK_INFRA_FAUD_AUD_CK, "infra_faud_aud", CK_TOP_A1SYS, 1, 1), + TOP_FACTOR(CK_INFRA_FAUD_EG2_CK, "infra_faud_eg2", CK_TOP_A_TUNER, 1, + 1), + TOP_FACTOR(CK_INFRA_I2CS_CK, "infra_i2cs", CK_TOP_I2C_BCK, 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_UART0, "infra_mux_uart0", CK_INFRA_UART0_SEL, + 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_UART1, "infra_mux_uart1", CK_INFRA_UART1_SEL, + 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_UART2, "infra_mux_uart2", CK_INFRA_UART2_SEL, + 1, 1), + TOP_FACTOR(CK_INFRA_NFI_CK, "infra_nfi", CK_TOP_NFI1X, 1, 1), + TOP_FACTOR(CK_INFRA_SPINFI_CK, "infra_spinfi", CK_TOP_SPINFI_BCK, 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_SPI0, "infra_mux_spi0", CK_INFRA_SPI0_SEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_MUX_SPI1, "infra_mux_spi1", CK_INFRA_SPI1_SEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_MUX_SPI2, "infra_mux_spi2", CK_INFRA_SPI2_SEL, 1, + 1), + TOP_FACTOR(CK_INFRA_RTC_32K, "infra_rtc_32k", CK_TOP_CB_RTC_32K, 1, 1), + TOP_FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc", CK_TOP_EMMC_400M, 1, 1), + TOP_FACTOR(CK_INFRA_FMSDC_HCK_CK, "infra_fmsdc_hck", CK_TOP_EMMC_208M, + 1, 1), + TOP_FACTOR(CK_INFRA_PERI_133M, "infra_peri_133m", CK_TOP_SYSAXI, 1, 1), + TOP_FACTOR(CK_INFRA_133M_PHCK, "infra_133m_phck", CK_TOP_SYSAXI, 1, 1), + TOP_FACTOR(CK_INFRA_USB_SYS_CK, "infra_usb_sys", CK_TOP_U2U3_SYS, 1, 1), + TOP_FACTOR(CK_INFRA_USB_CK, "infra_usb", CK_TOP_U2U3_REF, 1, 1), + TOP_FACTOR(CK_INFRA_USB_XHCI_CK, "infra_usb_xhci", CK_TOP_U2U3_XHCI, 1, + 1), + TOP_FACTOR(CK_INFRA_PCIE_GFMUX_TL_O_PRE, "infra_pcie_mux", + CK_TOP_PEXTP_TL, 1, 1), + TOP_FACTOR(CK_INFRA_F26M_CK0, "infra_f26m_ck0", CK_TOP_F26M, 1, 1), + TOP_FACTOR(CK_INFRA_133M_MCK, "infra_133m_mck", CK_TOP_SYSAXI, 1, 1), +}; + +/* INFRASYS MUX PARENTS */ +static const int infra_uart0_parents[] = { CK_INFRA_CK_F26M, CK_INFRA_UART }; + +static const int infra_spi0_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI0 }; + +static const int infra_spi1_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI1 }; + +static const int infra_pwm1_parents[] = { -1, -1, -1, CK_INFRA_PWM }; + +static const int infra_pwm_bsel_parents[] = { -1, -1, -1, CK_INFRA_PWM }; + +static const int infra_pcie_parents[] = { CK_INFRA_CK_F32K, CK_INFRA_CK_F26M, + CK_TOP_CB_CKSQ_40M, CK_INFRA_PCIE_CK}; + +#define INFRA_MUX(_id, _name, _parents, _reg, _shift, _width) \ + { \ + .id = _id, .mux_reg = (_reg) + 0x8, \ + .mux_set_reg = (_reg) + 0x0, .mux_clr_reg = (_reg) + 0x4, \ + .mux_shift = _shift, .mux_mask = BIT(_width) - 1, \ + .parent = _parents, .num_parents = ARRAY_SIZE(_parents), \ + .flags = CLK_MUX_SETCLR_UPD | CLK_PARENT_INFRASYS, \ + } + +/* INFRA MUX */ +static const struct mtk_composite infra_muxes[] = { + INFRA_MUX(CK_INFRA_UART0_SEL, "infra_uart0_sel", infra_uart0_parents, + 0x10, 0, 1), + INFRA_MUX(CK_INFRA_UART1_SEL, "infra_uart1_sel", infra_uart0_parents, + 0x10, 1, 1), + INFRA_MUX(CK_INFRA_UART2_SEL, "infra_uart2_sel", infra_uart0_parents, + 0x10, 2, 1), + INFRA_MUX(CK_INFRA_SPI0_SEL, "infra_spi0_sel", infra_spi0_parents, 0x10, + 4, 1), + INFRA_MUX(CK_INFRA_SPI1_SEL, "infra_spi1_sel", infra_spi1_parents, 0x10, + 5, 1), + INFRA_MUX(CK_INFRA_SPI2_SEL, "infra_spi2_sel", infra_spi0_parents, 0x10, + 6, 1), + INFRA_MUX(CK_INFRA_PWM1_SEL, "infra_pwm1_sel", infra_pwm1_parents, 0x10, + 9, 2), + INFRA_MUX(CK_INFRA_PWM2_SEL, "infra_pwm2_sel", infra_pwm1_parents, 0x10, + 11, 2), + INFRA_MUX(CK_INFRA_PWM_BSEL, "infra_pwm_bsel", infra_pwm_bsel_parents, + 0x10, 13, 2), + INFRA_MUX(CK_INFRA_PCIE_SEL, "infra_pcie_sel", infra_pcie_parents, 0x20, + 0, 2), +}; + +static const struct mtk_gate_regs infra_0_cg_regs = { + .set_ofs = 0x40, + .clr_ofs = 0x44, + .sta_ofs = 0x48, +}; + +static const struct mtk_gate_regs infra_1_cg_regs = { + .set_ofs = 0x50, + .clr_ofs = 0x54, + .sta_ofs = 0x58, +}; + +static const struct mtk_gate_regs infra_2_cg_regs = { + .set_ofs = 0x60, + .clr_ofs = 0x64, + .sta_ofs = 0x68, +}; + +#define GATE_INFRA0(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = &infra_0_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ + } + +#define GATE_INFRA1(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = &infra_1_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ + } + +#define GATE_INFRA2(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = &infra_2_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ + } + +/* INFRA GATE */ +static const struct mtk_gate infracfg_ao_gates[] = { + GATE_INFRA0(CK_INFRA_GPT_STA, "infra_gpt_sta", CK_INFRA_66M_MCK, 0), + GATE_INFRA0(CK_INFRA_PWM_HCK, "infra_pwm_hck", CK_INFRA_66M_MCK, 1), + GATE_INFRA0(CK_INFRA_PWM_STA, "infra_pwm_sta", CK_INFRA_PWM_BCK, 2), + GATE_INFRA0(CK_INFRA_PWM1_CK, "infra_pwm1", CK_INFRA_PWM_CK1, 3), + GATE_INFRA0(CK_INFRA_PWM2_CK, "infra_pwm2", CK_INFRA_PWM_CK2, 4), + GATE_INFRA0(CK_INFRA_CQ_DMA_CK, "infra_cq_dma", CK_INFRA_133M_HCK, 6), + GATE_INFRA0(CK_INFRA_AUD_BUS_CK, "infra_aud_bus", CK_INFRA_66M_PHCK, 8), + GATE_INFRA0(CK_INFRA_AUD_26M_CK, "infra_aud_26m", CK_INFRA_CK_F26M, 9), + GATE_INFRA0(CK_INFRA_AUD_L_CK, "infra_aud_l", CK_INFRA_FAUD_L_CK, 10), + GATE_INFRA0(CK_INFRA_AUD_AUD_CK, "infra_aud_aud", CK_INFRA_FAUD_AUD_CK, + 11), + GATE_INFRA0(CK_INFRA_AUD_EG2_CK, "infra_aud_eg2", CK_INFRA_FAUD_EG2_CK, + 13), + GATE_INFRA0(CK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", CK_INFRA_CK_F26M, + 14), + GATE_INFRA0(CK_INFRA_DBG_CK, "infra_dbg", CK_INFRA_66M_MCK, 15), + GATE_INFRA0(CK_INFRA_AP_DMA_CK, "infra_ap_dma", CK_INFRA_66M_MCK, 16), + GATE_INFRA0(CK_INFRA_SEJ_CK, "infra_sej", CK_INFRA_66M_MCK, 24), + GATE_INFRA0(CK_INFRA_SEJ_13M_CK, "infra_sej_13m", CK_INFRA_CK_F26M, 25), + GATE_INFRA1(CK_INFRA_THERM_CK, "infra_therm", CK_INFRA_CK_F26M, 0), + GATE_INFRA1(CK_INFRA_I2CO_CK, "infra_i2co", CK_INFRA_I2CS_CK, 1), + GATE_INFRA1(CK_INFRA_UART0_CK, "infra_uart0", CK_INFRA_MUX_UART0, 2), + GATE_INFRA1(CK_INFRA_UART1_CK, "infra_uart1", CK_INFRA_MUX_UART1, 3), + GATE_INFRA1(CK_INFRA_UART2_CK, "infra_uart2", CK_INFRA_MUX_UART2, 4), + GATE_INFRA1(CK_INFRA_SPI2_CK, "infra_spi2", CK_INFRA_MUX_SPI2, 6), + GATE_INFRA1(CK_INFRA_SPI2_HCK_CK, "infra_spi2_hck", CK_INFRA_66M_MCK, + 7), + GATE_INFRA1(CK_INFRA_NFI1_CK, "infra_nfi1", CK_INFRA_NFI_CK, 8), + GATE_INFRA1(CK_INFRA_SPINFI1_CK, "infra_spinfi1", CK_INFRA_SPINFI_CK, + 9), + GATE_INFRA1(CK_INFRA_NFI_HCK_CK, "infra_nfi_hck", CK_INFRA_66M_MCK, 10), + GATE_INFRA1(CK_INFRA_SPI0_CK, "infra_spi0", CK_INFRA_MUX_SPI0, 11), + GATE_INFRA1(CK_INFRA_SPI1_CK, "infra_spi1", CK_INFRA_MUX_SPI1, 12), + GATE_INFRA1(CK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", CK_INFRA_66M_MCK, + 13), + GATE_INFRA1(CK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", CK_INFRA_66M_MCK, + 14), + GATE_INFRA1(CK_INFRA_FRTC_CK, "infra_frtc", CK_INFRA_RTC_32K, 15), + GATE_INFRA1(CK_INFRA_MSDC_CK, "infra_msdc", CK_INFRA_FMSDC_CK, 16), + GATE_INFRA1(CK_INFRA_MSDC_HCK_CK, "infra_msdc_hck", + CK_INFRA_FMSDC_HCK_CK, 17), + GATE_INFRA1(CK_INFRA_MSDC_133M_CK, "infra_msdc_133m", + CK_INFRA_PERI_133M, 18), + GATE_INFRA1(CK_INFRA_MSDC_66M_CK, "infra_msdc_66m", CK_INFRA_66M_PHCK, + 19), + GATE_INFRA1(CK_INFRA_ADC_26M_CK, "infra_adc_26m", CK_TOP_F26M, 20), + GATE_INFRA1(CK_INFRA_ADC_FRC_CK, "infra_adc_frc", CK_TOP_F26M, 21), + GATE_INFRA1(CK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", CK_INFRA_NFI_CK, + 23), + GATE_INFRA1(CK_INFRA_I2C_MCK_CK, "infra_i2c_mck", CK_INFRA_133M_MCK, + 25), + GATE_INFRA1(CK_INFRA_I2C_PCK_CK, "infra_i2c_pck", CK_INFRA_66M_MCK, 26), + GATE_INFRA2(CK_INFRA_IUSB_133_CK, "infra_iusb_133", CK_INFRA_133M_PHCK, + 0), + GATE_INFRA2(CK_INFRA_IUSB_66M_CK, "infra_iusb_66m", CK_INFRA_66M_PHCK, + 1), + GATE_INFRA2(CK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", CK_INFRA_USB_SYS_CK, + 2), + GATE_INFRA2(CK_INFRA_IUSB_CK, "infra_iusb", CK_INFRA_USB_CK, 3), + GATE_INFRA2(CK_INFRA_IPCIE_CK, "infra_ipcie", + CK_INFRA_PCIE_GFMUX_TL_O_PRE, 12), + GATE_INFRA2(CK_INFRA_IPCIER_CK, "infra_ipcier", CK_INFRA_F26M_CK0, 14), + GATE_INFRA2(CK_INFRA_IPCIEB_CK, "infra_ipcieb", CK_INFRA_133M_PHCK, 15), +}; + +static const struct mtk_clk_tree mt7981_fixed_pll_clk_tree = { + .fdivs_offs = CLK_APMIXED_NR_CLK, + .xtal_rate = 40 * MHZ, + .fclks = fixed_pll_clks, +}; + +static const struct mtk_clk_tree mt7981_topckgen_clk_tree = { + .fdivs_offs = CK_TOP_CB_M_416M, + .muxes_offs = CK_TOP_NFI1X_SEL, + .fclks = top_fixed_clks, + .fdivs = top_fixed_divs, + .muxes = top_muxes, + .flags = CLK_BYPASS_XTAL, +}; + +static const struct mtk_clk_tree mt7981_infracfg_clk_tree = { + .fdivs_offs = CK_INFRA_CK_F26M, + .muxes_offs = CK_INFRA_UART0_SEL, + .fdivs = infra_fixed_divs, + .muxes = infra_muxes, +}; + +static const struct udevice_id mt7981_fixed_pll_compat[] = { + { .compatible = "mediatek,mt7981-fixed-plls" }, + {} +}; + +static const struct udevice_id mt7981_topckgen_compat[] = { + { .compatible = "mediatek,mt7981-topckgen" }, + {} +}; + +static int mt7981_fixed_pll_probe(struct udevice *dev) +{ + return mtk_common_clk_init(dev, &mt7981_fixed_pll_clk_tree); +} + +static int mt7981_topckgen_probe(struct udevice *dev) +{ + struct mtk_clk_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev); + writel(MT7981_CLK_PDN_EN_WRITE, priv->base + MT7981_CLK_PDN); + + return mtk_common_clk_init(dev, &mt7981_topckgen_clk_tree); +} + +U_BOOT_DRIVER(mtk_clk_apmixedsys) = { + .name = "mt7981-clock-fixed-pll", + .id = UCLASS_CLK, + .of_match = mt7981_fixed_pll_compat, + .probe = mt7981_fixed_pll_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_topckgen_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +U_BOOT_DRIVER(mtk_clk_topckgen) = { + .name = "mt7981-clock-topckgen", + .id = UCLASS_CLK, + .of_match = mt7981_topckgen_compat, + .probe = mt7981_topckgen_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_topckgen_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +static const struct udevice_id mt7981_infracfg_compat[] = { + { .compatible = "mediatek,mt7981-infracfg" }, + {} +}; + +static const struct udevice_id mt7981_infracfg_ao_compat[] = { + { .compatible = "mediatek,mt7981-infracfg_ao" }, + {} +}; + +static int mt7981_infracfg_probe(struct udevice *dev) +{ + return mtk_common_clk_init(dev, &mt7981_infracfg_clk_tree); +} + +static int mt7981_infracfg_ao_probe(struct udevice *dev) +{ + return mtk_common_clk_gate_init(dev, &mt7981_infracfg_clk_tree, + infracfg_ao_gates); +} + +U_BOOT_DRIVER(mtk_clk_infracfg) = { + .name = "mt7981-clock-infracfg", + .id = UCLASS_CLK, + .of_match = mt7981_infracfg_compat, + .probe = mt7981_infracfg_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_infrasys_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +U_BOOT_DRIVER(mtk_clk_infracfg_ao) = { + .name = "mt7981-clock-infracfg-ao", + .id = UCLASS_CLK, + .of_match = mt7981_infracfg_ao_compat, + .probe = mt7981_infracfg_ao_probe, + .priv_auto = sizeof(struct mtk_cg_priv), + .ops = &mtk_clk_gate_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +/* ethsys */ +static const struct mtk_gate_regs eth_cg_regs = { + .set_ofs = 0x30, + .clr_ofs = 0x30, + .sta_ofs = 0x30, +}; + +#define GATE_ETH(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = ð_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN, \ + } + +static const struct mtk_gate eth_cgs[] = { + GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 6), + GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 7), + GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8), + GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en", CK_TOP_NETSYS_WED_MCU, 15), +}; + +static int mt7981_ethsys_probe(struct udevice *dev) +{ + return mtk_common_clk_gate_init(dev, &mt7981_topckgen_clk_tree, + eth_cgs); +} + +static int mt7981_ethsys_bind(struct udevice *dev) +{ + int ret = 0; + + if (CONFIG_IS_ENABLED(RESET_MEDIATEK)) { + ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1); + if (ret) + debug("Warning: failed to bind reset controller\n"); + } + + return ret; +} + +static const struct udevice_id mt7981_ethsys_compat[] = { + { .compatible = "mediatek,mt7981-ethsys", }, + {} +}; + +U_BOOT_DRIVER(mtk_clk_ethsys) = { + .name = "mt7981-clock-ethsys", + .id = UCLASS_CLK, + .of_match = mt7981_ethsys_compat, + .probe = mt7981_ethsys_probe, + .bind = mt7981_ethsys_bind, + .priv_auto = sizeof(struct mtk_cg_priv), + .ops = &mtk_clk_gate_ops, +}; diff --git a/drivers/clk/mediatek/clk-mt7986.c b/drivers/clk/mediatek/clk-mt7986.c new file mode 100644 index 0000000000..b3fa63fc0a --- /dev/null +++ b/drivers/clk/mediatek/clk-mt7986.c @@ -0,0 +1,672 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek clock driver for MT7986 SoC + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include +#include +#include +#include +#include + +#include "clk-mtk.h" + +#define MT7986_CLK_PDN 0x250 +#define MT7986_CLK_PDN_EN_WRITE BIT(31) + +#define PLL_FACTOR(_id, _name, _parent, _mult, _div) \ + FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED) + +#define TOP_FACTOR(_id, _name, _parent, _mult, _div) \ + FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN) + +#define INFRA_FACTOR(_id, _name, _parent, _mult, _div) \ + FACTOR(_id, _parent, _mult, _div, CLK_PARENT_INFRASYS) + +/* FIXED PLLS */ +static const struct mtk_fixed_clk fixed_pll_clks[] = { + FIXED_CLK(CK_APMIXED_ARMPLL, CLK_XTAL, 2000000000), + FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 800000000), + FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 1440000000), + FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 325000000), + FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 760000000), + FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 2500000000), + FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 416000000), + FIXED_CLK(CK_APMIXED_APLL2, CLK_XTAL, 196608000), +}; + +/* TOPCKGEN FIXED CLK */ +static const struct mtk_fixed_clk top_fixed_clks[] = { + FIXED_CLK(CK_TOP_CB_CKSQ_40M, CLK_XTAL, 40000000), +}; + +/* TOPCKGEN FIXED DIV */ +static const struct mtk_fixed_factor top_fixed_divs[] = { + PLL_FACTOR(CK_TOP_CB_M_416M, "cb_m_416m", CK_APMIXED_MPLL, 1, 1), + PLL_FACTOR(CK_TOP_CB_M_D2, "cb_m_d2", CK_APMIXED_MPLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_M_D4, "cb_m_d4", CK_APMIXED_MPLL, 1, 4), + PLL_FACTOR(CK_TOP_CB_M_D8, "cb_m_d8", CK_APMIXED_MPLL, 1, 8), + PLL_FACTOR(CK_TOP_M_D8_D2, "m_d8_d2", CK_APMIXED_MPLL, 1, 16), + PLL_FACTOR(CK_TOP_M_D3_D2, "m_d3_d2", CK_APMIXED_MPLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_MM_D2, "cb_mm_d2", CK_APMIXED_MMPLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_MM_D4, "cb_mm_d4", CK_APMIXED_MMPLL, 1, 4), + PLL_FACTOR(CK_TOP_CB_MM_D8, "cb_mm_d8", CK_APMIXED_MMPLL, 1, 8), + PLL_FACTOR(CK_TOP_MM_D8_D2, "mm_d8_d2", CK_APMIXED_MMPLL, 1, 16), + PLL_FACTOR(CK_TOP_MM_D3_D8, "mm_d3_d8", CK_APMIXED_MMPLL, 1, 8), + PLL_FACTOR(CK_TOP_CB_U2_PHYD_CK, "cb_u2_phyd", CK_APMIXED_MMPLL, 1, 30), + PLL_FACTOR(CK_TOP_CB_APLL2_196M, "cb_apll2_196m", CK_APMIXED_APLL2, 1, + 1), + PLL_FACTOR(CK_TOP_APLL2_D4, "apll2_d4", CK_APMIXED_APLL2, 1, 4), + PLL_FACTOR(CK_TOP_CB_NET1_D4, "cb_net1_d4", CK_APMIXED_NET1PLL, 1, 4), + PLL_FACTOR(CK_TOP_CB_NET1_D5, "cb_net1_d5", CK_APMIXED_NET1PLL, 1, 5), + PLL_FACTOR(CK_TOP_NET1_D5_D2, "net1_d5_d2", CK_APMIXED_NET1PLL, 1, 10), + PLL_FACTOR(CK_TOP_NET1_D5_D4, "net1_d5_d4", CK_APMIXED_NET1PLL, 1, 20), + PLL_FACTOR(CK_TOP_NET1_D8_D2, "net1_d8_d2", CK_APMIXED_NET1PLL, 1, 16), + PLL_FACTOR(CK_TOP_NET1_D8_D4, "net1_d8_d4", CK_APMIXED_NET1PLL, 1, 32), + PLL_FACTOR(CK_TOP_CB_NET2_800M, "cb_net2_800m", CK_APMIXED_NET2PLL, 1, + 1), + PLL_FACTOR(CK_TOP_CB_NET2_D4, "cb_net2_d4", CK_APMIXED_NET2PLL, 1, 4), + PLL_FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", CK_APMIXED_NET2PLL, 1, 8), + PLL_FACTOR(CK_TOP_NET2_D3_D2, "net2_d3_d2", CK_APMIXED_NET2PLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_WEDMCU_760M, "cb_wedmcu_760m", + CK_APMIXED_WEDMCUPLL, 1, 1), + PLL_FACTOR(CK_TOP_WEDMCU_D5_D2, "wedmcu_d5_d2", CK_APMIXED_WEDMCUPLL, 1, + 10), + PLL_FACTOR(CK_TOP_CB_SGM_325M, "cb_sgm_325m", CK_APMIXED_SGMPLL, 1, 1), + TOP_FACTOR(CK_TOP_CB_CKSQ_40M_D2, "cb_cksq_40m_d2", CK_TOP_CB_CKSQ_40M, + 1, 2), + TOP_FACTOR(CK_TOP_CB_RTC_32K, "cb_rtc_32k", CK_TOP_CB_CKSQ_40M, 1, + 1250), + TOP_FACTOR(CK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", CK_TOP_CB_CKSQ_40M, 1, + 1220), + TOP_FACTOR(CK_TOP_NFI1X, "nfi1x", CK_TOP_NFI1X_SEL, 1, 1), + TOP_FACTOR(CK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", CK_TOP_CB_CKSQ_40M, 1, + 1), + TOP_FACTOR(CK_TOP_USB_TX250M, "usb_tx250m", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_USB_LN0_CK, "usb_ln0", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_USB_CDR_CK, "usb_cdr", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_SPINFI_BCK, "spinfi_bck", CK_TOP_SPINFI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_I2C_BCK, "i2c_bck", CK_TOP_I2C_SEL, 1, 1), + TOP_FACTOR(CK_TOP_PEXTP_TL, "pextp_tl", CK_TOP_PEXTP_TL_SEL, 1, 1), + TOP_FACTOR(CK_TOP_EMMC_250M, "emmc_250m", CK_TOP_EMMC_250M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_EMMC_416M, "emmc_416m", CK_TOP_EMMC_416M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_F_26M_ADC_CK, "f_26m_adc", CK_TOP_F_26M_ADC_SEL, 1, + 1), + TOP_FACTOR(CK_TOP_SYSAXI, "sysaxi", CK_TOP_SYSAXI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu", + CK_TOP_NETSYS_MCU_SEL, 1, 1), + TOP_FACTOR(CK_TOP_NETSYS_2X, "netsys_2x", CK_TOP_NETSYS_2X_SEL, 1, 1), + TOP_FACTOR(CK_TOP_SGM_325M, "sgm_325m", CK_TOP_SGM_325M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_A1SYS, "a1sys", CK_TOP_A1SYS_SEL, 1, 1), + TOP_FACTOR(CK_TOP_EIP_B, "eip_b", CK_TOP_EIP_B_SEL, 1, 1), + TOP_FACTOR(CK_TOP_F26M, "csw_f26m", CK_TOP_F26M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_AUD_L, "aud_l", CK_TOP_AUD_L_SEL, 1, 1), + TOP_FACTOR(CK_TOP_A_TUNER, "a_tuner", CK_TOP_A_TUNER_SEL, 2, 1), + TOP_FACTOR(CK_TOP_U2U3_REF, "u2u3_ref", CK_TOP_U2U3_SEL, 1, 1), + TOP_FACTOR(CK_TOP_U2U3_SYS, "u2u3_sys", CK_TOP_U2U3_SYS_SEL, 1, 1), + TOP_FACTOR(CK_TOP_U2U3_XHCI, "u2u3_xhci", CK_TOP_U2U3_XHCI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_AP2CNN_HOST, "ap2cnn_host", CK_TOP_AP2CNN_HOST_SEL, 1, + 1), +}; + +/* TOPCKGEN MUX PARENTS */ +static const int nfi1x_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D8, + CK_TOP_NET1_D8_D2, CK_TOP_NET2_D3_D2, + CK_TOP_CB_M_D4, CK_TOP_MM_D8_D2, + CK_TOP_WEDMCU_D5_D2, CK_TOP_CB_M_D8 }; + +static const int spinfi_parents[] = { + CK_TOP_CB_CKSQ_40M_D2, CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4, + CK_TOP_CB_M_D4, CK_TOP_MM_D8_D2, CK_TOP_WEDMCU_D5_D2, + CK_TOP_MM_D3_D8, CK_TOP_CB_M_D8 +}; + +static const int spi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2, + CK_TOP_CB_MM_D8, CK_TOP_NET1_D8_D2, + CK_TOP_NET2_D3_D2, CK_TOP_NET1_D5_D4, + CK_TOP_CB_M_D4, CK_TOP_WEDMCU_D5_D2 }; + +static const int uart_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D8, + CK_TOP_M_D8_D2 }; + +static const int pwm_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2, + CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4 }; + +static const int i2c_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4, + CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 }; + +static const int pextp_tl_ck_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_NET1_D5_D4, CK_TOP_NET2_D4_D2, + CK_TOP_CB_RTC_32K }; + +static const int emmc_250m_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_NET1_D5_D2 }; + +static const int emmc_416m_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_416M }; + +static const int f_26m_adc_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D8_D2 }; + +static const int dramc_md32_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2 }; + +static const int sysaxi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2, + CK_TOP_CB_NET2_D4 }; + +static const int sysapb_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D3_D2, + CK_TOP_NET2_D4_D2 }; + +static const int arm_db_main_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_NET2_D3_D2 }; + +static const int arm_db_jtsel_parents[] = { -1, CK_TOP_CB_CKSQ_40M }; + +static const int netsys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D4 }; + +static const int netsys_500m_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_NET1_D5 }; + +static const int netsys_mcu_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_WEDMCU_760M, + CK_TOP_CB_MM_D2, CK_TOP_CB_NET1_D4, + CK_TOP_CB_NET1_D5 }; + +static const int netsys_2x_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_NET2_800M, + CK_TOP_CB_WEDMCU_760M, + CK_TOP_CB_MM_D2 }; + +static const int sgm_325m_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_SGM_325M }; + +static const int sgm_reg_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D4 }; + +static const int a1sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4 }; + +static const int conn_mcusys_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_MM_D2 }; + +static const int eip_b_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET2_800M }; + +static const int aud_l_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M, + CK_TOP_M_D8_D2 }; + +static const int a_tuner_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4, + CK_TOP_M_D8_D2 }; + +static const int u2u3_sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4 }; + +static const int da_u2_refsel_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_U2_PHYD_CK }; + +#define TOP_MUX(_id, _name, _parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd) \ + { \ + .id = _id, .mux_reg = _mux_ofs, .mux_set_reg = _mux_set_ofs, \ + .mux_clr_reg = _mux_clr_ofs, .upd_reg = _upd_ofs, \ + .upd_shift = _upd, .mux_shift = _shift, \ + .mux_mask = BIT(_width) - 1, .gate_reg = _mux_ofs, \ + .gate_shift = _gate, .parent = _parents, \ + .num_parents = ARRAY_SIZE(_parents), \ + .flags = CLK_MUX_SETCLR_UPD, \ + } + +/* TOPCKGEN MUX_GATE */ +static const struct mtk_composite top_muxes[] = { + /* CLK_CFG_0 */ + TOP_MUX(CK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x000, 0x004, + 0x008, 0, 3, 7, 0x1C0, 0), + TOP_MUX(CK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents, 0x000, 0x004, + 0x008, 8, 3, 15, 0x1C0, 1), + TOP_MUX(CK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x000, 0x004, 0x008, 16, + 3, 23, 0x1C0, 2), + TOP_MUX(CK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents, 0x000, 0x004, + 0x008, 24, 3, 31, 0x1C0, 3), + /* CLK_CFG_1 */ + TOP_MUX(CK_TOP_UART_SEL, "uart_sel", uart_parents, 0x010, 0x014, 0x018, + 0, 2, 7, 0x1C0, 4), + TOP_MUX(CK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x010, 0x014, 0x018, 8, + 2, 15, 0x1C0, 5), + TOP_MUX(CK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x010, 0x014, 0x018, 16, + 2, 23, 0x1C0, 6), + TOP_MUX(CK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel", pextp_tl_ck_parents, + 0x010, 0x014, 0x018, 24, 2, 31, 0x1C0, 7), + /* CLK_CFG_2 */ + TOP_MUX(CK_TOP_EMMC_250M_SEL, "emmc_250m_sel", emmc_250m_parents, 0x020, + 0x024, 0x028, 0, 1, 7, 0x1C0, 8), + TOP_MUX(CK_TOP_EMMC_416M_SEL, "emmc_416m_sel", emmc_416m_parents, 0x020, + 0x024, 0x028, 8, 1, 15, 0x1C0, 9), + TOP_MUX(CK_TOP_F_26M_ADC_SEL, "f_26m_adc_sel", f_26m_adc_parents, 0x020, + 0x024, 0x028, 16, 1, 23, 0x1C0, 10), + TOP_MUX(CK_TOP_DRAMC_SEL, "dramc_sel", f_26m_adc_parents, 0x020, 0x024, + 0x028, 24, 1, 31, 0x1C0, 11), + /* CLK_CFG_3 */ + TOP_MUX(CK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents, + 0x030, 0x034, 0x038, 0, 1, 7, 0x1C0, 12), + TOP_MUX(CK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents, 0x030, 0x034, + 0x038, 8, 2, 15, 0x1C0, 13), + TOP_MUX(CK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents, 0x030, 0x034, + 0x038, 16, 2, 23, 0x1C0, 14), + TOP_MUX(CK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel", arm_db_main_parents, + 0x030, 0x034, 0x038, 24, 1, 31, 0x1C0, 15), + /* CLK_CFG_4 */ + TOP_MUX(CK_TOP_ARM_DB_JTSEL, "arm_db_jtsel", arm_db_jtsel_parents, + 0x040, 0x044, 0x048, 0, 1, 7, 0x1C0, 16), + TOP_MUX(CK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents, 0x040, 0x044, + 0x048, 8, 1, 15, 0x1C0, 17), + TOP_MUX(CK_TOP_NETSYS_500M_SEL, "netsys_500m_sel", netsys_500m_parents, + 0x040, 0x044, 0x048, 16, 1, 23, 0x1C0, 18), + TOP_MUX(CK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel", netsys_mcu_parents, + 0x040, 0x044, 0x048, 24, 3, 31, 0x1C0, 19), + /* CLK_CFG_5 */ + TOP_MUX(CK_TOP_NETSYS_2X_SEL, "netsys_2x_sel", netsys_2x_parents, 0x050, + 0x054, 0x058, 0, 2, 7, 0x1C0, 20), + TOP_MUX(CK_TOP_SGM_325M_SEL, "sgm_325m_sel", sgm_325m_parents, 0x050, + 0x054, 0x058, 8, 1, 15, 0x1C0, 21), + TOP_MUX(CK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents, 0x050, + 0x054, 0x058, 16, 1, 23, 0x1C0, 22), + TOP_MUX(CK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents, 0x050, 0x054, + 0x058, 24, 1, 31, 0x1C0, 23), + /* CLK_CFG_6 */ + TOP_MUX(CK_TOP_CONN_MCUSYS_SEL, "conn_mcusys_sel", conn_mcusys_parents, + 0x060, 0x064, 0x068, 0, 1, 7, 0x1C0, 24), + TOP_MUX(CK_TOP_EIP_B_SEL, "eip_b_sel", eip_b_parents, 0x060, 0x064, + 0x068, 8, 1, 15, 0x1C0, 25), + TOP_MUX(CK_TOP_PCIE_PHY_SEL, "pcie_phy_sel", f_26m_adc_parents, 0x060, + 0x064, 0x068, 16, 1, 23, 0x1C0, 26), + TOP_MUX(CK_TOP_USB3_PHY_SEL, "usb3_phy_sel", f_26m_adc_parents, 0x060, + 0x064, 0x068, 24, 1, 31, 0x1C0, 27), + /* CLK_CFG_7 */ + TOP_MUX(CK_TOP_F26M_SEL, "csw_f26m_sel", f_26m_adc_parents, 0x070, + 0x074, 0x078, 0, 1, 7, 0x1C0, 28), + TOP_MUX(CK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents, 0x070, 0x074, + 0x078, 8, 2, 15, 0x1C0, 29), + TOP_MUX(CK_TOP_A_TUNER_SEL, "a_tuner_sel", a_tuner_parents, 0x070, + 0x074, 0x078, 16, 2, 23, 0x1C0, 30), + TOP_MUX(CK_TOP_U2U3_SEL, "u2u3_sel", f_26m_adc_parents, 0x070, 0x074, + 0x078, 24, 1, 31, 0x1C4, 0), + /* CLK_CFG_8 */ + TOP_MUX(CK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel", u2u3_sys_parents, 0x080, + 0x084, 0x088, 0, 1, 7, 0x1C4, 1), + TOP_MUX(CK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel", u2u3_sys_parents, 0x080, + 0x084, 0x088, 8, 1, 15, 0x1C4, 2), + TOP_MUX(CK_TOP_DA_U2_REFSEL, "da_u2_refsel", da_u2_refsel_parents, + 0x080, 0x084, 0x088, 16, 1, 23, 0x1C4, 3), + TOP_MUX(CK_TOP_DA_U2_CK_1P_SEL, "da_u2_ck_1p_sel", da_u2_refsel_parents, + 0x080, 0x084, 0x088, 24, 1, 31, 0x1C4, 4), + /* CLK_CFG_9 */ + TOP_MUX(CK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel", sgm_reg_parents, + 0x090, 0x094, 0x098, 0, 1, 7, 0x1C4, 5), +}; + +/* INFRA FIXED DIV */ +static const struct mtk_fixed_factor infra_fixed_divs[] = { + TOP_FACTOR(CK_INFRA_CK_F26M, "infra_ck_f26m", CK_TOP_F26M_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_UART, "infra_uart", CK_TOP_UART_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_ISPI0, "infra_ispi0", CK_TOP_SPI_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_I2C, "infra_i2c", CK_TOP_I2C_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_ISPI1, "infra_ispi1", CK_TOP_SPINFI_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_PWM, "infra_pwm", CK_TOP_PWM_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_66M_MCK, "infra_66m_mck", CK_TOP_SYSAXI_SEL, 1, 2), + TOP_FACTOR(CK_INFRA_CK_F32K, "infra_ck_f32k", CK_TOP_CB_RTC_32P7K, 1, + 1), + TOP_FACTOR(CK_INFRA_PCIE_CK, "infra_pcie", CK_TOP_PEXTP_TL_SEL, 1, 1), + INFRA_FACTOR(CK_INFRA_PWM_BCK, "infra_pwm_bck", CK_INFRA_PWM_BSEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_PWM_CK1, "infra_pwm_ck1", CK_INFRA_PWM1_SEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_PWM_CK2, "infra_pwm_ck2", CK_INFRA_PWM2_SEL, 1, + 1), + TOP_FACTOR(CK_INFRA_133M_HCK, "infra_133m_hck", CK_TOP_SYSAXI, 1, 1), + TOP_FACTOR(CK_INFRA_EIP_CK, "infra_eip", CK_TOP_EIP_B, 1, 1), + INFRA_FACTOR(CK_INFRA_66M_PHCK, "infra_66m_phck", CK_INFRA_133M_HCK, 1, + 1), + TOP_FACTOR(CK_INFRA_FAUD_L_CK, "infra_faud_l", CK_TOP_AUD_L, 1, 1), + TOP_FACTOR(CK_INFRA_FAUD_AUD_CK, "infra_faud_aud", CK_TOP_A1SYS, 1, 1), + TOP_FACTOR(CK_INFRA_FAUD_EG2_CK, "infra_faud_eg2", CK_TOP_A_TUNER, 1, + 1), + TOP_FACTOR(CK_INFRA_I2CS_CK, "infra_i2cs", CK_TOP_I2C_BCK, 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_UART0, "infra_mux_uart0", CK_INFRA_UART0_SEL, + 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_UART1, "infra_mux_uart1", CK_INFRA_UART1_SEL, + 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_UART2, "infra_mux_uart2", CK_INFRA_UART2_SEL, + 1, 1), + TOP_FACTOR(CK_INFRA_NFI_CK, "infra_nfi", CK_TOP_NFI1X, 1, 1), + TOP_FACTOR(CK_INFRA_SPINFI_CK, "infra_spinfi", CK_TOP_SPINFI_BCK, 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_SPI0, "infra_mux_spi0", CK_INFRA_SPI0_SEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_MUX_SPI1, "infra_mux_spi1", CK_INFRA_SPI1_SEL, 1, + 1), + TOP_FACTOR(CK_INFRA_RTC_32K, "infra_rtc_32k", CK_TOP_CB_RTC_32K, 1, 1), + TOP_FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc", CK_TOP_EMMC_416M, 1, 1), + TOP_FACTOR(CK_INFRA_FMSDC_HCK_CK, "infra_fmsdc_hck", CK_TOP_EMMC_250M, + 1, 1), + TOP_FACTOR(CK_INFRA_PERI_133M, "infra_peri_133m", CK_TOP_SYSAXI, 1, 1), + TOP_FACTOR(CK_INFRA_133M_PHCK, "infra_133m_phck", CK_TOP_SYSAXI, 1, 1), + TOP_FACTOR(CK_INFRA_USB_SYS_CK, "infra_usb_sys", CK_TOP_U2U3_SYS, 1, 1), + TOP_FACTOR(CK_INFRA_USB_CK, "infra_usb", CK_TOP_U2U3_REF, 1, 1), + TOP_FACTOR(CK_INFRA_USB_XHCI_CK, "infra_usb_xhci", CK_TOP_U2U3_XHCI, 1, + 1), + TOP_FACTOR(CK_INFRA_PCIE_GFMUX_TL_O_PRE, "infra_pcie_mux", + CK_TOP_PEXTP_TL, 1, 1), + TOP_FACTOR(CK_INFRA_F26M_CK0, "infra_f26m_ck0", CK_TOP_F26M, 1, 1), + TOP_FACTOR(CK_INFRA_HD_133M, "infra_hd_133m", CK_TOP_SYSAXI, 1, 1), +}; + +/* INFRASYS MUX PARENTS */ +static const int infra_uart0_parents[] = { CK_INFRA_CK_F26M, CK_INFRA_UART }; + +static const int infra_spi0_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI0 }; + +static const int infra_spi1_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI1 }; + +static const int infra_pwm_bsel_parents[] = { CK_INFRA_CK_F32K, + CK_INFRA_CK_F26M, + CK_INFRA_66M_MCK, CK_INFRA_PWM }; + +static const int infra_pcie_parents[] = { CK_INFRA_CK_F32K, CK_INFRA_CK_F26M, + -1, CK_INFRA_PCIE_CK }; + +#define INFRA_MUX(_id, _name, _parents, _reg, _shift, _width) \ + { \ + .id = _id, .mux_reg = (_reg) + 0x8, \ + .mux_set_reg = (_reg) + 0x0, .mux_clr_reg = (_reg) + 0x4, \ + .mux_shift = _shift, .mux_mask = BIT(_width) - 1, \ + .parent = _parents, .num_parents = ARRAY_SIZE(_parents), \ + .flags = CLK_MUX_SETCLR_UPD | CLK_PARENT_INFRASYS, \ + } + +/* INFRA MUX */ + +static const struct mtk_composite infra_muxes[] = { + /* MODULE_CLK_SEL_0 */ + INFRA_MUX(CK_INFRA_UART0_SEL, "infra_uart0_sel", infra_uart0_parents, + 0x10, 0, 1), + INFRA_MUX(CK_INFRA_UART1_SEL, "infra_uart1_sel", infra_uart0_parents, + 0x10, 1, 1), + INFRA_MUX(CK_INFRA_UART2_SEL, "infra_uart2_sel", infra_uart0_parents, + 0x10, 2, 1), + INFRA_MUX(CK_INFRA_SPI0_SEL, "infra_spi0_sel", infra_spi0_parents, 0x10, + 4, 1), + INFRA_MUX(CK_INFRA_SPI1_SEL, "infra_spi1_sel", infra_spi1_parents, 0x10, + 5, 1), + INFRA_MUX(CK_INFRA_PWM1_SEL, "infra_pwm1_sel", infra_pwm_bsel_parents, + 0x10, 9, 2), + INFRA_MUX(CK_INFRA_PWM2_SEL, "infra_pwm2_sel", infra_pwm_bsel_parents, + 0x10, 11, 2), + INFRA_MUX(CK_INFRA_PWM_BSEL, "infra_pwm_bsel", infra_pwm_bsel_parents, + 0x10, 13, 2), + /* MODULE_CLK_SEL_1 */ + INFRA_MUX(CK_INFRA_PCIE_SEL, "infra_pcie_sel", infra_pcie_parents, 0x20, + 0, 2), +}; + +static const struct mtk_gate_regs infra_0_cg_regs = { + .set_ofs = 0x40, + .clr_ofs = 0x44, + .sta_ofs = 0x48, +}; + +static const struct mtk_gate_regs infra_1_cg_regs = { + .set_ofs = 0x50, + .clr_ofs = 0x54, + .sta_ofs = 0x58, +}; + +static const struct mtk_gate_regs infra_2_cg_regs = { + .set_ofs = 0x60, + .clr_ofs = 0x64, + .sta_ofs = 0x68, +}; + +#define GATE_INFRA0(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = &infra_0_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ + } + +#define GATE_INFRA1(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = &infra_1_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ + } + +#define GATE_INFRA2(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = &infra_2_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ + } + +/* INFRA GATE */ + +static const struct mtk_gate infracfg_ao_gates[] = { + /* INFRA0 */ + GATE_INFRA0(CK_INFRA_GPT_STA, "infra_gpt_sta", CK_INFRA_66M_MCK, 0), + GATE_INFRA0(CK_INFRA_PWM_HCK, "infra_pwm_hck", CK_INFRA_66M_MCK, 1), + GATE_INFRA0(CK_INFRA_PWM_STA, "infra_pwm_sta", CK_INFRA_PWM_BCK, 2), + GATE_INFRA0(CK_INFRA_PWM1_CK, "infra_pwm1", CK_INFRA_PWM_CK1, 3), + GATE_INFRA0(CK_INFRA_PWM2_CK, "infra_pwm2", CK_INFRA_PWM_CK2, 4), + GATE_INFRA0(CK_INFRA_CQ_DMA_CK, "infra_cq_dma", CK_INFRA_133M_HCK, 6), + GATE_INFRA0(CK_INFRA_EIP97_CK, "infra_eip97", CK_INFRA_EIP_CK, 7), + GATE_INFRA0(CK_INFRA_AUD_BUS_CK, "infra_aud_bus", CK_INFRA_66M_PHCK, 8), + GATE_INFRA0(CK_INFRA_AUD_26M_CK, "infra_aud_26m", CK_INFRA_CK_F26M, 9), + GATE_INFRA0(CK_INFRA_AUD_L_CK, "infra_aud_l", CK_INFRA_FAUD_L_CK, 10), + GATE_INFRA0(CK_INFRA_AUD_AUD_CK, "infra_aud_aud", CK_INFRA_FAUD_AUD_CK, + 11), + GATE_INFRA0(CK_INFRA_AUD_EG2_CK, "infra_aud_eg2", CK_INFRA_FAUD_EG2_CK, + 13), + GATE_INFRA0(CK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", CK_INFRA_CK_F26M, + 14), + GATE_INFRA0(CK_INFRA_DBG_CK, "infra_dbg", CK_INFRA_66M_MCK, 15), + GATE_INFRA0(CK_INFRA_AP_DMA_CK, "infra_ap_dma", CK_INFRA_66M_MCK, 16), + GATE_INFRA0(CK_INFRA_SEJ_CK, "infra_sej", CK_INFRA_66M_MCK, 24), + GATE_INFRA0(CK_INFRA_SEJ_13M_CK, "infra_sej_13m", CK_INFRA_CK_F26M, 25), + GATE_INFRA0(CK_INFRA_TRNG_CK, "infra_trng", CK_INFRA_HD_133M, 26), + /* INFRA1 */ + GATE_INFRA1(CK_INFRA_THERM_CK, "infra_therm", CK_INFRA_CK_F26M, 0), + GATE_INFRA1(CK_INFRA_I2CO_CK, "infra_i2co", CK_INFRA_I2CS_CK, 1), + GATE_INFRA1(CK_INFRA_UART0_CK, "infra_uart0", CK_INFRA_MUX_UART0, 2), + GATE_INFRA1(CK_INFRA_UART1_CK, "infra_uart1", CK_INFRA_MUX_UART1, 3), + GATE_INFRA1(CK_INFRA_UART2_CK, "infra_uart2", CK_INFRA_MUX_UART2, 4), + GATE_INFRA1(CK_INFRA_NFI1_CK, "infra_nfi1", CK_INFRA_NFI_CK, 8), + GATE_INFRA1(CK_INFRA_SPINFI1_CK, "infra_spinfi1", CK_INFRA_SPINFI_CK, + 9), + GATE_INFRA1(CK_INFRA_NFI_HCK_CK, "infra_nfi_hck", CK_INFRA_66M_MCK, 10), + GATE_INFRA1(CK_INFRA_SPI0_CK, "infra_spi0", CK_INFRA_MUX_SPI0, 11), + GATE_INFRA1(CK_INFRA_SPI1_CK, "infra_spi1", CK_INFRA_MUX_SPI1, 12), + GATE_INFRA1(CK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", CK_INFRA_66M_MCK, + 13), + GATE_INFRA1(CK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", CK_INFRA_66M_MCK, + 14), + GATE_INFRA1(CK_INFRA_FRTC_CK, "infra_frtc", CK_INFRA_RTC_32K, 15), + GATE_INFRA1(CK_INFRA_MSDC_CK, "infra_msdc", CK_INFRA_FMSDC_CK, 16), + GATE_INFRA1(CK_INFRA_MSDC_HCK_CK, "infra_msdc_hck", + CK_INFRA_FMSDC_HCK_CK, 17), + GATE_INFRA1(CK_INFRA_MSDC_133M_CK, "infra_msdc_133m", + CK_INFRA_PERI_133M, 18), + GATE_INFRA1(CK_INFRA_MSDC_66M_CK, "infra_msdc_66m", CK_INFRA_66M_PHCK, + 19), + GATE_INFRA1(CK_INFRA_ADC_26M_CK, "infra_adc_26m", CK_INFRA_CK_F26M, 20), + GATE_INFRA1(CK_INFRA_ADC_FRC_CK, "infra_adc_frc", CK_INFRA_CK_F26M, 21), + GATE_INFRA1(CK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", CK_INFRA_NFI_CK, + 23), + /* INFRA2 */ + GATE_INFRA2(CK_INFRA_IUSB_133_CK, "infra_iusb_133", CK_INFRA_133M_PHCK, + 0), + GATE_INFRA2(CK_INFRA_IUSB_66M_CK, "infra_iusb_66m", CK_INFRA_66M_PHCK, + 1), + GATE_INFRA2(CK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", CK_INFRA_USB_SYS_CK, + 2), + GATE_INFRA2(CK_INFRA_IUSB_CK, "infra_iusb", CK_INFRA_USB_CK, 3), + GATE_INFRA2(CK_INFRA_IPCIE_CK, "infra_ipcie", CK_INFRA_PCIE_CK, 13), + GATE_INFRA2(CK_INFRA_IPCIER_CK, "infra_ipcier", CK_INFRA_F26M_CK0, 15), + GATE_INFRA2(CK_INFRA_IPCIEB_CK, "infra_ipcieb", CK_INFRA_133M_PHCK, 15), +}; + +static const struct mtk_clk_tree mt7986_fixed_pll_clk_tree = { + .fdivs_offs = CLK_APMIXED_NR_CLK, + .xtal_rate = 40 * MHZ, + .fclks = fixed_pll_clks, +}; + +static const struct mtk_clk_tree mt7986_topckgen_clk_tree = { + .fdivs_offs = CK_TOP_CB_M_416M, + .muxes_offs = CK_TOP_NFI1X_SEL, + .fclks = top_fixed_clks, + .fdivs = top_fixed_divs, + .muxes = top_muxes, + .flags = CLK_BYPASS_XTAL, +}; + +static const struct mtk_clk_tree mt7986_infracfg_clk_tree = { + .fdivs_offs = CK_INFRA_CK_F26M, + .muxes_offs = CK_INFRA_UART0_SEL, + .fdivs = infra_fixed_divs, + .muxes = infra_muxes, +}; + +static const struct udevice_id mt7986_fixed_pll_compat[] = { + { .compatible = "mediatek,mt7986-fixed-plls" }, + {} +}; + +static const struct udevice_id mt7986_topckgen_compat[] = { + { .compatible = "mediatek,mt7986-topckgen" }, + {} +}; + +static int mt7986_fixed_pll_probe(struct udevice *dev) +{ + return mtk_common_clk_init(dev, &mt7986_fixed_pll_clk_tree); +} + +static int mt7986_topckgen_probe(struct udevice *dev) +{ + struct mtk_clk_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev); + writel(MT7986_CLK_PDN_EN_WRITE, priv->base + MT7986_CLK_PDN); + + return mtk_common_clk_init(dev, &mt7986_topckgen_clk_tree); +} + +U_BOOT_DRIVER(mtk_clk_apmixedsys) = { + .name = "mt7986-clock-fixed-pll", + .id = UCLASS_CLK, + .of_match = mt7986_fixed_pll_compat, + .probe = mt7986_fixed_pll_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_topckgen_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +U_BOOT_DRIVER(mtk_clk_topckgen) = { + .name = "mt7986-clock-topckgen", + .id = UCLASS_CLK, + .of_match = mt7986_topckgen_compat, + .probe = mt7986_topckgen_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_topckgen_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +static const struct udevice_id mt7986_infracfg_compat[] = { + { .compatible = "mediatek,mt7986-infracfg" }, + {} +}; + +static const struct udevice_id mt7986_infracfg_ao_compat[] = { + { .compatible = "mediatek,mt7986-infracfg_ao" }, + {} +}; + +static int mt7986_infracfg_probe(struct udevice *dev) +{ + return mtk_common_clk_init(dev, &mt7986_infracfg_clk_tree); +} + +static int mt7986_infracfg_ao_probe(struct udevice *dev) +{ + return mtk_common_clk_gate_init(dev, &mt7986_infracfg_clk_tree, + infracfg_ao_gates); +} + +U_BOOT_DRIVER(mtk_clk_infracfg) = { + .name = "mt7986-clock-infracfg", + .id = UCLASS_CLK, + .of_match = mt7986_infracfg_compat, + .probe = mt7986_infracfg_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_infrasys_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +U_BOOT_DRIVER(mtk_clk_infracfg_ao) = { + .name = "mt7986-clock-infracfg-ao", + .id = UCLASS_CLK, + .of_match = mt7986_infracfg_ao_compat, + .probe = mt7986_infracfg_ao_probe, + .priv_auto = sizeof(struct mtk_cg_priv), + .ops = &mtk_clk_gate_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +/* ethsys */ +static const struct mtk_gate_regs eth_cg_regs = { + .sta_ofs = 0x30, +}; + +#define GATE_ETH(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = ð_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN, \ + } + +static const struct mtk_gate eth_cgs[] = { + GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 7), + GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 8), + GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8), + GATE_ETH(CK_ETH_WOCPU1_EN, "eth_wocpu1_en", CK_TOP_NETSYS_WED_MCU, 14), + GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en", CK_TOP_NETSYS_WED_MCU, 15), +}; + +static int mt7986_ethsys_probe(struct udevice *dev) +{ + return mtk_common_clk_gate_init(dev, &mt7986_topckgen_clk_tree, + eth_cgs); +} + +static int mt7986_ethsys_bind(struct udevice *dev) +{ + int ret = 0; + + if (CONFIG_IS_ENABLED(RESET_MEDIATEK)) { + ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1); + if (ret) + debug("Warning: failed to bind reset controller\n"); + } + + return ret; +} + +static const struct udevice_id mt7986_ethsys_compat[] = { + { .compatible = "mediatek,mt7986-ethsys" }, + { } +}; + +U_BOOT_DRIVER(mtk_clk_ethsys) = { + .name = "mt7986-clock-ethsys", + .id = UCLASS_CLK, + .of_match = mt7986_ethsys_compat, + .probe = mt7986_ethsys_probe, + .bind = mt7986_ethsys_bind, + .priv_auto = sizeof(struct mtk_cg_priv), + .ops = &mtk_clk_gate_ops, +}; diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index d43b8a0648..4303300d3a 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -42,20 +42,14 @@ * the accurate frequency. */ static ulong mtk_clk_find_parent_rate(struct clk *clk, int id, - const struct driver *drv) + struct udevice *pdev) { struct clk parent = { .id = id, }; - if (drv) { - struct udevice *dev; - - if (uclass_get_device_by_driver(UCLASS_CLK, drv, &dev)) - return -ENODEV; - - parent.dev = dev; - } else { + if (pdev) + parent.dev = pdev; + else parent.dev = clk->dev; - } return clk_get_rate(&parent); } @@ -296,12 +290,13 @@ static ulong mtk_topckgen_get_factor_rate(struct clk *clk, u32 off) switch (fdiv->flags & CLK_PARENT_MASK) { case CLK_PARENT_APMIXED: rate = mtk_clk_find_parent_rate(clk, fdiv->parent, - DM_DRIVER_GET(mtk_clk_apmixedsys)); + priv->parent); break; case CLK_PARENT_TOPCKGEN: rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL); break; + case CLK_PARENT_XTAL: default: rate = priv->tree->xtal_rate; } @@ -309,6 +304,27 @@ static ulong mtk_topckgen_get_factor_rate(struct clk *clk, u32 off) return mtk_factor_recalc_rate(fdiv, rate); } +static ulong mtk_infrasys_get_factor_rate(struct clk *clk, u32 off) +{ + struct mtk_clk_priv *priv = dev_get_priv(clk->dev); + const struct mtk_fixed_factor *fdiv = &priv->tree->fdivs[off]; + ulong rate; + + switch (fdiv->flags & CLK_PARENT_MASK) { + case CLK_PARENT_TOPCKGEN: + rate = mtk_clk_find_parent_rate(clk, fdiv->parent, + priv->parent); + break; + case CLK_PARENT_XTAL: + rate = priv->tree->xtal_rate; + break; + default: + rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL); + } + + return mtk_factor_recalc_rate(fdiv, rate); +} + static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); @@ -319,13 +335,51 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off) index &= mux->mux_mask << mux->mux_shift; index = index >> mux->mux_shift; - if (mux->parent[index]) - return mtk_clk_find_parent_rate(clk, mux->parent[index], - NULL); + if (mux->parent[index] > 0 || + (mux->parent[index] == CLK_XTAL && + priv->tree->flags & CLK_BYPASS_XTAL)) { + switch (mux->flags & CLK_PARENT_MASK) { + case CLK_PARENT_APMIXED: + return mtk_clk_find_parent_rate(clk, mux->parent[index], + priv->parent); + break; + default: + return mtk_clk_find_parent_rate(clk, mux->parent[index], + NULL); + break; + } + } return priv->tree->xtal_rate; } +static ulong mtk_infrasys_get_mux_rate(struct clk *clk, u32 off) +{ + struct mtk_clk_priv *priv = dev_get_priv(clk->dev); + const struct mtk_composite *mux = &priv->tree->muxes[off]; + u32 index; + + index = readl(priv->base + mux->mux_reg); + index &= mux->mux_mask << mux->mux_shift; + index = index >> mux->mux_shift; + + if (mux->parent[index] > 0 || + (mux->parent[index] == CLK_XTAL && + priv->tree->flags & CLK_BYPASS_XTAL)) { + switch (mux->flags & CLK_PARENT_MASK) { + case CLK_PARENT_TOPCKGEN: + return mtk_clk_find_parent_rate(clk, mux->parent[index], + priv->parent); + break; + default: + return mtk_clk_find_parent_rate(clk, mux->parent[index], + NULL); + break; + } + } + return 0; +} + static ulong mtk_topckgen_get_rate(struct clk *clk) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); @@ -340,7 +394,26 @@ static ulong mtk_topckgen_get_rate(struct clk *clk) priv->tree->muxes_offs); } -static int mtk_topckgen_enable(struct clk *clk) +static ulong mtk_infrasys_get_rate(struct clk *clk) +{ + struct mtk_clk_priv *priv = dev_get_priv(clk->dev); + + ulong rate; + + if (clk->id < priv->tree->fdivs_offs) { + rate = priv->tree->fclks[clk->id].rate; + } else if (clk->id < priv->tree->muxes_offs) { + rate = mtk_infrasys_get_factor_rate(clk, clk->id - + priv->tree->fdivs_offs); + } else { + rate = mtk_infrasys_get_mux_rate(clk, clk->id - + priv->tree->muxes_offs); + } + + return rate; +} + +static int mtk_clk_mux_enable(struct clk *clk) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); const struct mtk_composite *mux; @@ -373,7 +446,7 @@ static int mtk_topckgen_enable(struct clk *clk) return 0; } -static int mtk_topckgen_disable(struct clk *clk) +static int mtk_clk_mux_disable(struct clk *clk) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); const struct mtk_composite *mux; @@ -399,7 +472,7 @@ static int mtk_topckgen_disable(struct clk *clk) return 0; } -static int mtk_topckgen_set_parent(struct clk *clk, struct clk *parent) +static int mtk_common_clk_set_parent(struct clk *clk, struct clk *parent) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); @@ -471,19 +544,7 @@ static ulong mtk_clk_gate_get_rate(struct clk *clk) struct mtk_cg_priv *priv = dev_get_priv(clk->dev); const struct mtk_gate *gate = &priv->gates[clk->id]; - switch (gate->flags & CLK_PARENT_MASK) { - case CLK_PARENT_APMIXED: - return mtk_clk_find_parent_rate(clk, gate->parent, - DM_DRIVER_GET(mtk_clk_apmixedsys)); - break; - case CLK_PARENT_TOPCKGEN: - return mtk_clk_find_parent_rate(clk, gate->parent, - DM_DRIVER_GET(mtk_clk_topckgen)); - break; - - default: - return priv->tree->xtal_rate; - } + return mtk_clk_find_parent_rate(clk, gate->parent, priv->parent); } const struct clk_ops mtk_clk_apmixedsys_ops = { @@ -494,10 +555,17 @@ const struct clk_ops mtk_clk_apmixedsys_ops = { }; const struct clk_ops mtk_clk_topckgen_ops = { - .enable = mtk_topckgen_enable, - .disable = mtk_topckgen_disable, + .enable = mtk_clk_mux_enable, + .disable = mtk_clk_mux_disable, .get_rate = mtk_topckgen_get_rate, - .set_parent = mtk_topckgen_set_parent, + .set_parent = mtk_common_clk_set_parent, +}; + +const struct clk_ops mtk_clk_infrasys_ops = { + .enable = mtk_clk_mux_enable, + .disable = mtk_clk_mux_disable, + .get_rate = mtk_infrasys_get_rate, + .set_parent = mtk_common_clk_set_parent, }; const struct clk_ops mtk_clk_gate_ops = { @@ -510,11 +578,22 @@ int mtk_common_clk_init(struct udevice *dev, const struct mtk_clk_tree *tree) { struct mtk_clk_priv *priv = dev_get_priv(dev); + struct udevice *parent; + int ret; priv->base = dev_read_addr_ptr(dev); if (!priv->base) return -ENOENT; + ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent); + if (ret || !parent) { + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(mtk_clk_apmixedsys), &parent); + if (ret || !parent) + return -ENOENT; + } + + priv->parent = parent; priv->tree = tree; return 0; @@ -525,11 +604,22 @@ int mtk_common_clk_gate_init(struct udevice *dev, const struct mtk_gate *gates) { struct mtk_cg_priv *priv = dev_get_priv(dev); + struct udevice *parent; + int ret; priv->base = dev_read_addr_ptr(dev); if (!priv->base) return -ENOENT; + ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent); + if (ret || !parent) { + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(mtk_clk_topckgen), &parent); + if (ret || !parent) + return -ENOENT; + } + + priv->parent = parent; priv->tree = tree; priv->gates = gates; diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index 95a23d14a8..48ce16484e 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -11,6 +11,11 @@ #define CLK_XTAL 0 #define MHZ (1000 * 1000) +/* flags in struct mtk_clk_tree */ + +/* clk id == 0 doesn't mean it's xtal clk */ +#define CLK_BYPASS_XTAL BIT(0) + #define HAVE_RST_BAR BIT(0) #define CLK_DOMAIN_SCPSYS BIT(0) #define CLK_MUX_SETCLR_UPD BIT(1) @@ -23,7 +28,9 @@ #define CLK_PARENT_APMIXED BIT(4) #define CLK_PARENT_TOPCKGEN BIT(5) -#define CLK_PARENT_MASK GENMASK(5, 4) +#define CLK_PARENT_INFRASYS BIT(6) +#define CLK_PARENT_XTAL BIT(7) +#define CLK_PARENT_MASK GENMASK(7, 4) #define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34 @@ -197,14 +204,17 @@ struct mtk_clk_tree { const struct mtk_fixed_clk *fclks; const struct mtk_fixed_factor *fdivs; const struct mtk_composite *muxes; + u32 flags; }; struct mtk_clk_priv { + struct udevice *parent; void __iomem *base; const struct mtk_clk_tree *tree; }; struct mtk_cg_priv { + struct udevice *parent; void __iomem *base; const struct mtk_clk_tree *tree; const struct mtk_gate *gates; @@ -212,6 +222,7 @@ struct mtk_cg_priv { extern const struct clk_ops mtk_clk_apmixedsys_ops; extern const struct clk_ops mtk_clk_topckgen_ops; +extern const struct clk_ops mtk_clk_infrasys_ops; extern const struct clk_ops mtk_clk_gate_ops; int mtk_common_clk_init(struct udevice *dev, diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 007dc6a1de..c9bf5de433 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -400,6 +400,30 @@ config DM_DEV_READ_INLINE bool default y if !OF_LIVE +config OFNODE_MULTI_TREE + bool "Allow the ofnode interface to access any tree" + default y if EVENT && !DM_DEV_READ_INLINE && !DM_INLINE_OFNODE + help + Normally U-Boot makes use of its control FDT, the one used to bind + devices and provide options. In some cases, U-Boot must also process + a separate FDT, e.g. one provided by the operating system, which + needs additions to the /chosen node. + + This works fine with live tree (OF_LIVE), but with flat tree the + offset provided in ofnode is only useful with the control FDT. This + option adds a 'tree ID' to the offset, so that multiple trees can + be used. Call oftree_from_fdt() to register a new tree. + +config OFNODE_MULTI_TREE_MAX + int "Maximum number of FDTs" + range 2 8 + depends on OFNODE_MULTI_TREE + default 4 + help + Sets the maximum number of device trees which can be used with the + ofnode interface when using flat trees (OF_LIVE). This is only + available in U-Boot proper and only after relocation. + config ACPIGEN bool "Support ACPI table generation in driver model" default y if SANDBOX || (GENERATE_ACPI_TABLE && !QEMU) diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c index c3a50a2b0c..91bcd1a2c2 100644 --- a/drivers/core/fdtaddr.c +++ b/drivers/core/fdtaddr.c @@ -21,6 +21,8 @@ DECLARE_GLOBAL_DATA_PTR; fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) { #if CONFIG_IS_ENABLED(OF_REAL) + int offset = dev_of_offset(dev); + int parent = dev_of_offset(dev->parent); fdt_addr_t addr; if (CONFIG_IS_ENABLED(OF_TRANSLATE)) { @@ -28,21 +30,19 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) int len = 0; int na, ns; - na = fdt_address_cells(gd->fdt_blob, - dev_of_offset(dev->parent)); + na = fdt_address_cells(gd->fdt_blob, parent); if (na < 1) { debug("bad #address-cells\n"); return FDT_ADDR_T_NONE; } - ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent)); + ns = fdt_size_cells(gd->fdt_blob, parent); if (ns < 0) { debug("bad #size-cells\n"); return FDT_ADDR_T_NONE; } - reg = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "reg", - &len); + reg = fdt_getprop(gd->fdt_blob, offset, "reg", &len); if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns)))) { debug("Req index out of range\n"); return FDT_ADDR_T_NONE; @@ -56,7 +56,7 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) * bus setups. */ addr = fdt_translate_address((void *)gd->fdt_blob, - dev_of_offset(dev), reg); + offset, reg); } else { /* Non translatable if #size-cells == 0 */ addr = fdt_read_number(reg, na); @@ -66,9 +66,9 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) * Use the "simple" translate function for less complex * bus setups. */ - addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, - dev_of_offset(dev->parent), dev_of_offset(dev), - "reg", index, NULL, false); + addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, parent, + offset, "reg", index, + NULL, false); if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) { if (device_get_uclass_id(dev->parent) == UCLASS_SIMPLE_BUS) diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index a52f5a6b18..85f7da5a49 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -445,14 +445,15 @@ struct device_node *of_find_node_by_prop_value(struct device_node *from, return np; } -struct device_node *of_find_node_by_phandle(phandle handle) +struct device_node *of_find_node_by_phandle(struct device_node *root, + phandle handle) { struct device_node *np; if (!handle) return NULL; - for_each_of_allnodes(np) + for_each_of_allnodes_from(root, np) if (np->phandle == handle) break; (void)of_node_get(np); @@ -470,8 +471,7 @@ struct device_node *of_find_node_by_phandle(phandle handle) * @len: requested length of property value * * Return: the property value on success, -EINVAL if the property does not - * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the - * property data isn't large enough. + * exist and -EOVERFLOW if the property data isn't large enough. */ static void *of_find_property_value_of_size(const struct device_node *np, const char *propname, u32 len) @@ -480,14 +480,50 @@ static void *of_find_property_value_of_size(const struct device_node *np, if (!prop) return ERR_PTR(-EINVAL); - if (!prop->value) - return ERR_PTR(-ENODATA); if (len > prop->length) return ERR_PTR(-EOVERFLOW); return prop->value; } +int of_read_u8(const struct device_node *np, const char *propname, u8 *outp) +{ + const u8 *val; + + debug("%s: %s: ", __func__, propname); + if (!np) + return -EINVAL; + val = of_find_property_value_of_size(np, propname, sizeof(*outp)); + if (IS_ERR(val)) { + debug("(not found)\n"); + return PTR_ERR(val); + } + + *outp = *val; + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + +int of_read_u16(const struct device_node *np, const char *propname, u16 *outp) +{ + const __be16 *val; + + debug("%s: %s: ", __func__, propname); + if (!np) + return -EINVAL; + val = of_find_property_value_of_size(np, propname, sizeof(*outp)); + if (IS_ERR(val)) { + debug("(not found)\n"); + return PTR_ERR(val); + } + + *outp = be16_to_cpup(val); + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + int of_read_u32(const struct device_node *np, const char *propname, u32 *outp) { return of_read_u32_index(np, propname, 0, outp); @@ -659,7 +695,7 @@ static int __of_parse_phandle_with_args(const struct device_node *np, * below. */ if (cells_name || cur_index == index) { - node = of_find_node_by_phandle(phandle); + node = of_find_node_by_phandle(NULL, phandle); if (!node) { debug("%s: could not find phandle\n", np->full_name); @@ -908,9 +944,6 @@ int of_write_prop(struct device_node *np, const char *propname, int len, pp_last = pp; } - if (!pp_last) - return -ENOENT; - /* Property does not exist -> append new property */ new = malloc(sizeof(struct property)); if (!new) @@ -926,7 +959,73 @@ int of_write_prop(struct device_node *np, const char *propname, int len, new->length = len; new->next = NULL; - pp_last->next = new; + if (pp_last) + pp_last->next = new; + else + np->properties = new; + + return 0; +} + +int of_add_subnode(struct device_node *parent, const char *name, int len, + struct device_node **childp) +{ + struct device_node *child, *new, *last_sibling = NULL; + char *new_name, *full_name; + int parent_fnl; + + if (len == -1) + len = strlen(name); + __for_each_child_of_node(parent, child) { + /* + * make sure we don't use a child called "trevor" when we are + * searching for "trev". + */ + if (!strncmp(child->name, name, len) && strlen(name) == len) { + *childp = child; + return -EEXIST; + } + last_sibling = child; + } + + /* Subnode does not exist -> append new subnode */ + new = calloc(1, sizeof(struct device_node)); + if (!new) + return -ENOMEM; + + new_name = memdup(name, len + 1); + if (!new_name) { + free(new); + return -ENOMEM; + } + new_name[len] = '\0'; + + /* + * if the parent is the root node (named "") we don't need to prepend + * its full path + */ + parent_fnl = *parent->name ? strlen(parent->full_name) : 0; + full_name = calloc(1, parent_fnl + 1 + len + 1); + if (!full_name) { + free(new_name); + free(new); + return -ENOMEM; + } + new->name = new_name; /* assign to constant pointer */ + + strcpy(full_name, parent->full_name); /* "" for root node */ + full_name[parent_fnl] = '/'; + strlcpy(&full_name[parent_fnl + 1], name, len + 1); + new->full_name = full_name; + + /* Add as last sibling of the parent */ + if (last_sibling) + last_sibling->sibling = new; + if (!parent->child) + parent->child = new; + new->parent = parent; + + *childp = new; return 0; } diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 45ea84e9fb..14bbfe7232 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -4,6 +4,8 @@ * Written by Simon Glass */ +#define LOG_CATEGORY LOGC_DT + #include #include #include @@ -18,6 +20,186 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + +#if CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) +static void *oftree_list[CONFIG_OFNODE_MULTI_TREE_MAX]; +static int oftree_count; + +void oftree_reset(void) +{ + if (gd->flags & GD_FLG_RELOC) { + oftree_count = 0; + oftree_list[oftree_count++] = (void *)gd->fdt_blob; + } +} + +static int oftree_find(const void *fdt) +{ + int i; + + for (i = 0; i < oftree_count; i++) { + if (fdt == oftree_list[i]) + return i; + } + + return -1; +} + +static oftree oftree_ensure(void *fdt) +{ + oftree tree; + int i; + + if (gd->flags & GD_FLG_RELOC) { + i = oftree_find(fdt); + if (i == -1) { + if (oftree_count == CONFIG_OFNODE_MULTI_TREE_MAX) { + log_warning("Too many registered device trees (max %d)\n", + CONFIG_OFNODE_MULTI_TREE_MAX); + return oftree_null(); + } + + /* register the new tree */ + i = oftree_count++; + oftree_list[i] = fdt; + log_debug("oftree: registered tree %d: %p\n", i, fdt); + } + } else { + if (fdt != gd->fdt_blob) { + log_debug("Cannot only access control FDT before relocation\n"); + return oftree_null(); + } + } + + tree.fdt = fdt; + + return tree; +} + +void *ofnode_lookup_fdt(ofnode node) +{ + if (gd->flags & GD_FLG_RELOC) { + uint i = OFTREE_TREE_ID(node.of_offset); + + if (i > oftree_count) { + log_debug("Invalid tree ID %x\n", i); + return NULL; + } + + return oftree_list[i]; + } else { + return (void *)gd->fdt_blob; + } +} + +void *ofnode_to_fdt(ofnode node) +{ +#ifdef OF_CHECKS + if (of_live_active()) + return NULL; +#endif + if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && ofnode_valid(node)) + return ofnode_lookup_fdt(node); + + /* Use the control FDT by default */ + return (void *)gd->fdt_blob; +} + +/** + * ofnode_to_offset() - convert an ofnode to a flat DT offset + * + * This cannot be called if the reference contains a node pointer. + * + * @node: Reference containing offset (possibly invalid) + * Return: DT offset (can be -1) + */ +int ofnode_to_offset(ofnode node) +{ +#ifdef OF_CHECKS + if (of_live_active()) + return -1; +#endif + if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && node.of_offset >= 0) + return OFTREE_OFFSET(node.of_offset); + + return node.of_offset; +} + +oftree oftree_from_fdt(void *fdt) +{ + oftree tree; + + if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE)) + return oftree_ensure(fdt); + + tree.fdt = fdt; + + return tree; +} + +/** + * noffset_to_ofnode() - convert a DT offset to an ofnode + * + * @other_node: Node in the same tree to use as a reference + * @of_offset: DT offset (either valid, or -1) + * Return: reference to the associated DT offset + */ +ofnode noffset_to_ofnode(ofnode other_node, int of_offset) +{ + ofnode node; + + if (of_live_active()) + node.np = NULL; + else if (!CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) || of_offset < 0 || + !ofnode_valid(other_node)) + node.of_offset = of_offset; + else + node.of_offset = OFTREE_MAKE_NODE(other_node.of_offset, + of_offset); + + return node; +} + +#else /* !OFNODE_MULTI_TREE */ + +static inline int oftree_find(const void *fdt) +{ + return 0; +} + +#endif /* OFNODE_MULTI_TREE */ + +/** + * ofnode_from_tree_offset() - get an ofnode from a tree offset (flat tree) + * + * Looks up the tree and returns an ofnode with the correct of_offset (i.e. + * containing the tree ID). + * + * If @offset is < 0 then this returns an ofnode with that offset and no tree + * ID. + * + * @tree: tree to check + * @offset: offset within that tree (can be < 0) + * @return node for that offset, with the correct ID + */ +static ofnode ofnode_from_tree_offset(oftree tree, int offset) +{ + ofnode node; + + if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && offset >= 0) { + int tree_id = oftree_find(tree.fdt); + + if (tree_id == -1) + return ofnode_null(); + node.of_offset = OFTREE_NODE(tree_id, offset); + } else { + node.of_offset = offset; + } + + return node; +} + bool ofnode_name_eq(ofnode node, const char *name) { const char *node_name; @@ -31,6 +213,68 @@ bool ofnode_name_eq(ofnode node, const char *name) return (strlen(name) == len) && !strncmp(node_name, name, len); } +int ofnode_read_u8(ofnode node, const char *propname, u8 *outp) +{ + const u8 *cell; + int len; + + assert(ofnode_valid(node)); + debug("%s: %s: ", __func__, propname); + + if (ofnode_is_np(node)) + return of_read_u8(ofnode_to_np(node), propname, outp); + + cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, + &len); + if (!cell || len < sizeof(*cell)) { + debug("(not found)\n"); + return -EINVAL; + } + *outp = *cell; + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + +u8 ofnode_read_u8_default(ofnode node, const char *propname, u8 def) +{ + assert(ofnode_valid(node)); + ofnode_read_u8(node, propname, &def); + + return def; +} + +int ofnode_read_u16(ofnode node, const char *propname, u16 *outp) +{ + const fdt16_t *cell; + int len; + + assert(ofnode_valid(node)); + debug("%s: %s: ", __func__, propname); + + if (ofnode_is_np(node)) + return of_read_u16(ofnode_to_np(node), propname, outp); + + cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, + &len); + if (!cell || len < sizeof(*cell)) { + debug("(not found)\n"); + return -EINVAL; + } + *outp = be16_to_cpup(cell); + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + +u16 ofnode_read_u16_default(ofnode node, const char *propname, u16 def) +{ + assert(ofnode_valid(node)); + ofnode_read_u16(node, propname, &def); + + return def; +} + int ofnode_read_u32(ofnode node, const char *propname, u32 *outp) { return ofnode_read_u32_index(node, propname, 0, outp); @@ -57,8 +301,8 @@ int ofnode_read_u32_index(ofnode node, const char *propname, int index, return of_read_u32_index(ofnode_to_np(node), propname, index, outp); - cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, - &len); + cell = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), + propname, &len); if (!cell) { debug("(not found)\n"); return -EINVAL; @@ -103,8 +347,8 @@ int ofnode_read_u64(ofnode node, const char *propname, u64 *outp) if (ofnode_is_np(node)) return of_read_u64(ofnode_to_np(node), propname, outp); - cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, - &len); + cell = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), + propname, &len); if (!cell || len < sizeof(*cell)) { debug("(not found)\n"); return -EINVAL; @@ -155,7 +399,7 @@ const void *ofnode_read_prop(ofnode node, const char *propname, int *sizep) len = prop->length; } } else { - val = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), + val = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), propname, &len); } if (!val) { @@ -206,7 +450,7 @@ ofnode ofnode_find_subnode(ofnode node, const char *subnode_name) debug("%s: %s: ", __func__, subnode_name); if (ofnode_is_np(node)) { - const struct device_node *np = ofnode_to_np(node); + struct device_node *np = ofnode_to_np(node); for (np = np->child; np; np = np->sibling) { if (!strcmp(subnode_name, np->name)) @@ -214,9 +458,9 @@ ofnode ofnode_find_subnode(ofnode node, const char *subnode_name) } subnode = np_to_ofnode(np); } else { - int ooffset = fdt_subnode_offset(gd->fdt_blob, + int ooffset = fdt_subnode_offset(ofnode_to_fdt(node), ofnode_to_offset(node), subnode_name); - subnode = offset_to_ofnode(ooffset); + subnode = noffset_to_ofnode(node, ooffset); } debug("%s\n", ofnode_valid(subnode) ? ofnode_get_name(subnode) : ""); @@ -234,9 +478,20 @@ int ofnode_read_u32_array(ofnode node, const char *propname, return of_read_u32_array(ofnode_to_np(node), propname, out_values, sz); } else { - return fdtdec_get_int_array(gd->fdt_blob, - ofnode_to_offset(node), propname, - out_values, sz); + int ret; + + ret = fdtdec_get_int_array(ofnode_to_fdt(node), + ofnode_to_offset(node), propname, + out_values, sz); + + /* get the error right, but space is more important in SPL */ + if (!IS_ENABLED(CONFIG_SPL_BUILD)) { + if (ret == -FDT_ERR_NOTFOUND) + return -EINVAL; + else if (ret == -FDT_ERR_BADLAYOUT) + return -EOVERFLOW; + } + return ret; } } @@ -246,7 +501,7 @@ bool ofnode_is_enabled(ofnode node) if (ofnode_is_np(node)) { return of_device_is_available(ofnode_to_np(node)); } else { - return fdtdec_get_is_enabled(gd->fdt_blob, + return fdtdec_get_is_enabled(ofnode_to_fdt(node), ofnode_to_offset(node)); } } @@ -257,8 +512,8 @@ ofnode ofnode_first_subnode(ofnode node) if (ofnode_is_np(node)) return np_to_ofnode(node.np->child); - return offset_to_ofnode( - fdt_first_subnode(gd->fdt_blob, ofnode_to_offset(node))); + return noffset_to_ofnode(node, + fdt_first_subnode(ofnode_to_fdt(node), ofnode_to_offset(node))); } ofnode ofnode_next_subnode(ofnode node) @@ -267,8 +522,8 @@ ofnode ofnode_next_subnode(ofnode node) if (ofnode_is_np(node)) return np_to_ofnode(node.np->sibling); - return offset_to_ofnode( - fdt_next_subnode(gd->fdt_blob, ofnode_to_offset(node))); + return noffset_to_ofnode(node, + fdt_next_subnode(ofnode_to_fdt(node), ofnode_to_offset(node))); } #endif /* !DM_INLINE_OFNODE */ @@ -280,7 +535,7 @@ ofnode ofnode_get_parent(ofnode node) if (ofnode_is_np(node)) parent = np_to_ofnode(of_get_parent(ofnode_to_np(node))); else - parent.of_offset = fdt_parent_offset(gd->fdt_blob, + parent.of_offset = fdt_parent_offset(ofnode_to_fdt(node), ofnode_to_offset(node)); return parent; @@ -294,9 +549,9 @@ const char *ofnode_get_name(ofnode node) } if (ofnode_is_np(node)) - return strrchr(node.np->full_name, '/') + 1; + return node.np->name; - return fdt_get_name(gd->fdt_blob, ofnode_to_offset(node), NULL); + return fdt_get_name(ofnode_to_fdt(node), ofnode_to_offset(node), NULL); } int ofnode_get_path(ofnode node, char *buf, int buflen) @@ -313,7 +568,7 @@ int ofnode_get_path(ofnode node, char *buf, int buflen) } else { int res; - res = fdt_get_path(gd->fdt_blob, ofnode_to_offset(node), buf, + res = fdt_get_path(ofnode_to_fdt(node), ofnode_to_offset(node), buf, buflen); if (!res) return res; @@ -329,7 +584,7 @@ ofnode ofnode_get_by_phandle(uint phandle) ofnode node; if (of_live_active()) - node = np_to_ofnode(of_find_node_by_phandle(phandle)); + node = np_to_ofnode(of_find_node_by_phandle(NULL, phandle)); else node.of_offset = fdt_node_offset_by_phandle(gd->fdt_blob, phandle); @@ -337,6 +592,20 @@ ofnode ofnode_get_by_phandle(uint phandle) return node; } +ofnode oftree_get_by_phandle(oftree tree, uint phandle) +{ + ofnode node; + + if (of_live_active()) + node = np_to_ofnode(of_find_node_by_phandle(tree.np, phandle)); + else + node = ofnode_from_tree_offset(tree, + fdt_node_offset_by_phandle(oftree_lookup_fdt(tree), + phandle)); + + return node; +} + static fdt_addr_t __ofnode_get_addr_size_index(ofnode node, int index, fdt_size_t *size, bool translate) { @@ -369,7 +638,7 @@ static fdt_addr_t __ofnode_get_addr_size_index(ofnode node, int index, } else { na = ofnode_read_simple_addr_cells(ofnode_get_parent(node)); ns = ofnode_read_simple_size_cells(ofnode_get_parent(node)); - return fdtdec_get_addr_size_fixed(gd->fdt_blob, + return fdtdec_get_addr_size_fixed(ofnode_to_fdt(node), ofnode_to_offset(node), "reg", index, na, ns, size, translate); @@ -417,7 +686,7 @@ int ofnode_stringlist_search(ofnode node, const char *property, } else { int ret; - ret = fdt_stringlist_search(gd->fdt_blob, + ret = fdt_stringlist_search(ofnode_to_fdt(node), ofnode_to_offset(node), property, string); if (ret == -FDT_ERR_NOTFOUND) @@ -438,7 +707,8 @@ int ofnode_read_string_index(ofnode node, const char *property, int index, } else { int len; - *outp = fdt_stringlist_get(gd->fdt_blob, ofnode_to_offset(node), + *outp = fdt_stringlist_get(ofnode_to_fdt(node), + ofnode_to_offset(node), property, index, &len); if (len < 0) return -EINVAL; @@ -451,7 +721,7 @@ int ofnode_read_string_count(ofnode node, const char *property) if (ofnode_is_np(node)) { return of_property_count_strings(ofnode_to_np(node), property); } else { - return fdt_stringlist_count(gd->fdt_blob, + return fdt_stringlist_count(ofnode_to_fdt(node), ofnode_to_offset(node), property); } } @@ -520,7 +790,7 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name, struct fdtdec_phandle_args args; int ret; - ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, + ret = fdtdec_parse_phandle_with_args(ofnode_to_fdt(node), ofnode_to_offset(node), list_name, cells_name, cell_count, index, &args); @@ -539,7 +809,7 @@ int ofnode_count_phandle_with_args(ofnode node, const char *list_name, return of_count_phandle_with_args(ofnode_to_np(node), list_name, cells_name, cell_count); else - return fdtdec_parse_phandle_with_args(gd->fdt_blob, + return fdtdec_parse_phandle_with_args(ofnode_to_fdt(node), ofnode_to_offset(node), list_name, cells_name, cell_count, -1, NULL); } @@ -552,15 +822,27 @@ ofnode ofnode_path(const char *path) return offset_to_ofnode(fdt_path_offset(gd->fdt_blob, path)); } -ofnode ofnode_path_root(oftree tree, const char *path) +ofnode oftree_root(oftree tree) { - if (of_live_active()) + if (of_live_active()) { + return np_to_ofnode(tree.np); + } else { + return ofnode_from_tree_offset(tree, 0); + } +} + +ofnode oftree_path(oftree tree, const char *path) +{ + if (of_live_active()) { return np_to_ofnode(of_find_node_opts_by_path(tree.np, path, NULL)); - else if (*path != '/' && tree.fdt != gd->fdt_blob) + } else if (*path != '/' && tree.fdt != gd->fdt_blob) { return ofnode_null(); /* Aliases only on control FDT */ - else - return offset_to_ofnode(fdt_path_offset(tree.fdt, path)); + } else { + int offset = fdt_path_offset(tree.fdt, path); + + return ofnode_from_tree_offset(tree, offset); + } } const void *ofnode_read_chosen_prop(const char *propname, int *sizep) @@ -714,11 +996,11 @@ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp) if (ofnode_is_np(node)) return of_get_property(ofnode_to_np(node), propname, lenp); else - return fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), + return fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), propname, lenp); } -int ofnode_get_first_property(ofnode node, struct ofprop *prop) +int ofnode_first_property(ofnode node, struct ofprop *prop) { prop->node = node; @@ -728,7 +1010,7 @@ int ofnode_get_first_property(ofnode node, struct ofprop *prop) return -FDT_ERR_NOTFOUND; } else { prop->offset = - fdt_first_property_offset(gd->fdt_blob, + fdt_first_property_offset(ofnode_to_fdt(node), ofnode_to_offset(prop->node)); if (prop->offset < 0) return prop->offset; @@ -737,7 +1019,7 @@ int ofnode_get_first_property(ofnode node, struct ofprop *prop) return 0; } -int ofnode_get_next_property(struct ofprop *prop) +int ofnode_next_property(struct ofprop *prop) { if (ofnode_is_np(prop->node)) { prop->prop = of_get_next_property(ofnode_to_np(prop->node), @@ -745,8 +1027,9 @@ int ofnode_get_next_property(struct ofprop *prop) if (!prop->prop) return -FDT_ERR_NOTFOUND; } else { - prop->offset = fdt_next_property_offset(gd->fdt_blob, - prop->offset); + prop->offset = + fdt_next_property_offset(ofnode_to_fdt(prop->node), + prop->offset); if (prop->offset < 0) return prop->offset; } @@ -754,27 +1037,18 @@ int ofnode_get_next_property(struct ofprop *prop) return 0; } -const void *ofnode_get_property_by_prop(const struct ofprop *prop, - const char **propname, int *lenp) +const void *ofprop_get_property(const struct ofprop *prop, + const char **propname, int *lenp) { if (ofnode_is_np(prop->node)) return of_get_property_by_prop(ofnode_to_np(prop->node), prop->prop, propname, lenp); else - return fdt_getprop_by_offset(gd->fdt_blob, + return fdt_getprop_by_offset(ofnode_to_fdt(prop->node), prop->offset, propname, lenp); } -bool ofnode_is_available(ofnode node) -{ - if (ofnode_is_np(node)) - return of_device_is_available(ofnode_to_np(node)); - else - return fdtdec_get_is_enabled(gd->fdt_blob, - ofnode_to_offset(node)); -} - fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property, fdt_size_t *sizep) { @@ -795,7 +1069,7 @@ fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property, else return of_read_number(prop, na); } else { - return fdtdec_get_addr_size(gd->fdt_blob, + return fdtdec_get_addr_size(ofnode_to_fdt(node), ofnode_to_offset(node), property, sizep); } @@ -814,7 +1088,7 @@ const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname, return (uint8_t *)prop; } else { - return fdtdec_locate_byte_array(gd->fdt_blob, + return fdtdec_locate_byte_array(ofnode_to_fdt(node), ofnode_to_offset(node), propname, sz); } } @@ -950,10 +1224,10 @@ int ofnode_read_addr_cells(ofnode node) if (ofnode_is_np(node)) { return of_n_addr_cells(ofnode_to_np(node)); } else { - int parent = fdt_parent_offset(gd->fdt_blob, + int parent = fdt_parent_offset(ofnode_to_fdt(node), ofnode_to_offset(node)); - return fdt_address_cells(gd->fdt_blob, parent); + return fdt_address_cells(ofnode_to_fdt(node), parent); } } @@ -962,10 +1236,10 @@ int ofnode_read_size_cells(ofnode node) if (ofnode_is_np(node)) { return of_n_size_cells(ofnode_to_np(node)); } else { - int parent = fdt_parent_offset(gd->fdt_blob, + int parent = fdt_parent_offset(ofnode_to_fdt(node), ofnode_to_offset(node)); - return fdt_size_cells(gd->fdt_blob, parent); + return fdt_size_cells(ofnode_to_fdt(node), parent); } } @@ -974,7 +1248,8 @@ int ofnode_read_simple_addr_cells(ofnode node) if (ofnode_is_np(node)) return of_simple_addr_cells(ofnode_to_np(node)); else - return fdt_address_cells(gd->fdt_blob, ofnode_to_offset(node)); + return fdt_address_cells(ofnode_to_fdt(node), + ofnode_to_offset(node)); } int ofnode_read_simple_size_cells(ofnode node) @@ -982,7 +1257,8 @@ int ofnode_read_simple_size_cells(ofnode node) if (ofnode_is_np(node)) return of_simple_size_cells(ofnode_to_np(node)); else - return fdt_size_cells(gd->fdt_blob, ofnode_to_offset(node)); + return fdt_size_cells(ofnode_to_fdt(node), + ofnode_to_offset(node)); } bool ofnode_pre_reloc(ofnode node) @@ -1019,7 +1295,8 @@ int ofnode_read_resource(ofnode node, uint index, struct resource *res) struct fdt_resource fres; int ret; - ret = fdt_get_resource(gd->fdt_blob, ofnode_to_offset(node), + ret = fdt_get_resource(ofnode_to_fdt(node), + ofnode_to_offset(node), "reg", index, &fres); if (ret < 0) return -EINVAL; @@ -1048,7 +1325,8 @@ u64 ofnode_translate_address(ofnode node, const fdt32_t *in_addr) if (ofnode_is_np(node)) return of_translate_address(ofnode_to_np(node), in_addr); else - return fdt_translate_address(gd->fdt_blob, ofnode_to_offset(node), in_addr); + return fdt_translate_address(ofnode_to_fdt(node), + ofnode_to_offset(node), in_addr); } u64 ofnode_translate_dma_address(ofnode node, const fdt32_t *in_addr) @@ -1056,7 +1334,8 @@ u64 ofnode_translate_dma_address(ofnode node, const fdt32_t *in_addr) if (ofnode_is_np(node)) return of_translate_dma_address(ofnode_to_np(node), in_addr); else - return fdt_translate_dma_address(gd->fdt_blob, ofnode_to_offset(node), in_addr); + return fdt_translate_dma_address(ofnode_to_fdt(node), + ofnode_to_offset(node), in_addr); } int ofnode_get_dma_range(ofnode node, phys_addr_t *cpu, dma_addr_t *bus, u64 *size) @@ -1064,7 +1343,8 @@ int ofnode_get_dma_range(ofnode node, phys_addr_t *cpu, dma_addr_t *bus, u64 *si if (ofnode_is_np(node)) return of_get_dma_range(ofnode_to_np(node), cpu, bus, size); else - return fdt_get_dma_range(gd->fdt_blob, ofnode_to_offset(node), + return fdt_get_dma_range(ofnode_to_fdt(node), + ofnode_to_offset(node), cpu, bus, size); } @@ -1074,7 +1354,7 @@ int ofnode_device_is_compatible(ofnode node, const char *compat) return of_device_is_compatible(ofnode_to_np(node), compat, NULL, NULL); else - return !fdt_node_check_compatible(gd->fdt_blob, + return !fdt_node_check_compatible(ofnode_to_fdt(node), ofnode_to_offset(node), compat); } @@ -1086,8 +1366,9 @@ ofnode ofnode_by_compatible(ofnode from, const char *compat) (struct device_node *)ofnode_to_np(from), NULL, compat)); } else { - return offset_to_ofnode(fdt_node_offset_by_compatible( - gd->fdt_blob, ofnode_to_offset(from), compat)); + return noffset_to_ofnode(from, + fdt_node_offset_by_compatible(ofnode_to_fdt(from), + ofnode_to_offset(from), compat)); } } @@ -1099,22 +1380,35 @@ ofnode ofnode_by_prop_value(ofnode from, const char *propname, (struct device_node *)ofnode_to_np(from), propname, propval, proplen)); } else { - return offset_to_ofnode(fdt_node_offset_by_prop_value( - gd->fdt_blob, ofnode_to_offset(from), - propname, propval, proplen)); + return noffset_to_ofnode(from, + fdt_node_offset_by_prop_value(ofnode_to_fdt(from), + ofnode_to_offset(from), propname, propval, + proplen)); } } int ofnode_write_prop(ofnode node, const char *propname, const void *value, - int len) + int len, bool copy) { - if (of_live_active()) - return of_write_prop(ofnode_to_npw(node), propname, len, value); - else - return fdt_setprop((void *)gd->fdt_blob, ofnode_to_offset(node), - propname, value, len); + if (of_live_active()) { + void *newval; + int ret; - return 0; + if (copy) { + newval = malloc(len); + if (!newval) + return log_ret(-ENOMEM); + memcpy(newval, value, len); + value = newval; + } + ret = of_write_prop(ofnode_to_np(node), propname, len, value); + if (ret && copy) + free(newval); + return ret; + } else { + return fdt_setprop(ofnode_to_fdt(node), ofnode_to_offset(node), + propname, value, len); + } } int ofnode_write_string(ofnode node, const char *propname, const char *value) @@ -1123,7 +1417,8 @@ int ofnode_write_string(ofnode node, const char *propname, const char *value) debug("%s: %s = %s", __func__, propname, value); - return ofnode_write_prop(node, propname, value, strlen(value) + 1); + return ofnode_write_prop(node, propname, value, strlen(value) + 1, + false); } int ofnode_write_u32(ofnode node, const char *propname, u32 value) @@ -1138,7 +1433,7 @@ int ofnode_write_u32(ofnode node, const char *propname, u32 value) return -ENOMEM; *val = cpu_to_fdt32(value); - return ofnode_write_prop(node, propname, val, sizeof(value)); + return ofnode_write_prop(node, propname, val, sizeof(value), false); } int ofnode_set_enabled(ofnode node, bool value) @@ -1227,3 +1522,62 @@ phy_interface_t ofnode_read_phy_mode(ofnode node) return PHY_INTERFACE_MODE_NA; } + +int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep) +{ + ofnode subnode; + int ret = 0; + + assert(ofnode_valid(node)); + + if (ofnode_is_np(node)) { + struct device_node *np, *child; + + np = (struct device_node *)ofnode_to_np(node); + ret = of_add_subnode(np, name, -1, &child); + if (ret && ret != -EEXIST) + return ret; + subnode = np_to_ofnode(child); + } else { + void *fdt = ofnode_to_fdt(node); + int poffset = ofnode_to_offset(node); + int offset; + + offset = fdt_add_subnode(fdt, poffset, name); + if (offset == -FDT_ERR_EXISTS) { + offset = fdt_subnode_offset(fdt, poffset, name); + ret = -EEXIST; + } + if (offset < 0) + return -EINVAL; + subnode = noffset_to_ofnode(node, offset); + } + + *subnodep = subnode; + + return ret; /* 0 or -EEXIST */ +} + +int ofnode_copy_props(ofnode src, ofnode dst) +{ + struct ofprop prop; + + ofnode_for_each_prop(prop, src) { + const char *name; + const char *val; + int len, ret; + + val = ofprop_get_property(&prop, &name, &len); + if (!val) { + log_debug("Cannot read prop (err=%d)\n", len); + return log_msg_ret("get", -EINVAL); + } + ret = ofnode_write_prop(dst, name, val, len, true); + if (ret) { + log_debug("Cannot write prop (err=%d)\n", ret); + return log_msg_ret("wr", -EINVAL); + } + } + + return 0; +} diff --git a/drivers/core/read.c b/drivers/core/read.c index c73508d276..3e5fea87d8 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -13,6 +13,27 @@ #include #include +int dev_read_u8(const struct udevice *dev, const char *propname, u8 *outp) +{ + return ofnode_read_u8(dev_ofnode(dev), propname, outp); +} + +u8 dev_read_u8_default(const struct udevice *dev, const char *propname, u8 def) +{ + return ofnode_read_u8_default(dev_ofnode(dev), propname, def); +} + +int dev_read_u16(const struct udevice *dev, const char *propname, u16 *outp) +{ + return ofnode_read_u16(dev_ofnode(dev), propname, outp); +} + +u16 dev_read_u16_default(const struct udevice *dev, const char *propname, + u16 def) +{ + return ofnode_read_u16_default(dev_ofnode(dev), propname, def); +} + int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp) { return ofnode_read_u32(dev_ofnode(dev), propname, outp); @@ -266,18 +287,18 @@ const void *dev_read_prop(const struct udevice *dev, const char *propname, int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop) { - return ofnode_get_first_property(dev_ofnode(dev), prop); + return ofnode_first_property(dev_ofnode(dev), prop); } int dev_read_next_prop(struct ofprop *prop) { - return ofnode_get_next_property(prop); + return ofnode_next_property(prop); } const void *dev_read_prop_by_prop(struct ofprop *prop, const char **propname, int *lenp) { - return ofnode_get_property_by_prop(prop, propname, lenp); + return ofprop_get_property(prop, propname, lenp); } int dev_read_alias_seq(const struct udevice *dev, int *devnump) diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile index 20884b1795..3b38ba9c58 100644 --- a/drivers/cpu/Makefile +++ b/drivers/cpu/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_CPU) += cpu-uclass.o obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o obj-$(CONFIG_ARCH_IMX8) += imx8_cpu.o obj-$(CONFIG_ARCH_AT91) += at91_cpu.o +obj-$(CONFIG_ARCH_MEDIATEK) += mtk_cpu.o obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o obj-$(CONFIG_CPU_RISCV) += riscv_cpu.o obj-$(CONFIG_CPU_MICROBLAZE) += microblaze_cpu.o diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index abddbef57b..b8eb2d2800 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -144,7 +144,7 @@ static int cpu_imx_get_count(const struct udevice *dev) ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) { const char *device_type; - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue; device_type = ofnode_read_string(node, "device_type"); diff --git a/drivers/cpu/microblaze_cpu.c b/drivers/cpu/microblaze_cpu.c index 969a1047e5..b9d0792822 100644 --- a/drivers/cpu/microblaze_cpu.c +++ b/drivers/cpu/microblaze_cpu.c @@ -97,8 +97,10 @@ static int microblaze_cpu_get_desc(const struct udevice *dev, char *buf, ret = snprintf(buf, size, "MicroBlaze @ %uMHz, Rev: %s, FPGA family: %s", cpu_freq_mhz, cpu_ver, fpga_family); + if (ret < 0) + return ret; - return 0; + return (ret >= size) ? -ENOSPC : 0; } static int microblaze_cpu_get_info(const struct udevice *dev, diff --git a/drivers/cpu/mtk_cpu.c b/drivers/cpu/mtk_cpu.c new file mode 100644 index 0000000000..2a08be9b6d --- /dev/null +++ b/drivers/cpu/mtk_cpu.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct mtk_cpu_plat { + struct regmap *hwver; +}; + +static int mtk_cpu_get_desc(const struct udevice *dev, char *buf, int size) +{ + struct mtk_cpu_plat *plat = dev_get_plat(dev); + uint val; + + regmap_read(plat->hwver, 0, &val); + + snprintf(buf, size, "MediaTek MT%04X", val); + + return 0; +} + +static int mtk_cpu_get_count(const struct udevice *dev) +{ + return 1; +} + +static int mtk_cpu_get_vendor(const struct udevice *dev, char *buf, int size) +{ + snprintf(buf, size, "MediaTek"); + + return 0; +} + +static int mtk_cpu_probe(struct udevice *dev) +{ + struct mtk_cpu_plat *plat = dev_get_plat(dev); + struct ofnode_phandle_args args; + int ret; + + ret = dev_read_phandle_with_args(dev, "mediatek,hwver", NULL, 0, 0, + &args); + if (ret) + return ret; + + plat->hwver = syscon_node_to_regmap(args.node); + if (IS_ERR(plat->hwver)) + return PTR_ERR(plat->hwver); + + return 0; +} + +static const struct cpu_ops mtk_cpu_ops = { + .get_desc = mtk_cpu_get_desc, + .get_count = mtk_cpu_get_count, + .get_vendor = mtk_cpu_get_vendor, +}; + +static const struct udevice_id mtk_cpu_ids[] = { + { .compatible = "arm,cortex-a7" }, + { .compatible = "arm,cortex-a53" }, + { .compatible = "arm,cortex-a73" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(cpu_mtk) = { + .name = "mtk-cpu", + .id = UCLASS_CPU, + .of_match = mtk_cpu_ids, + .ops = &mtk_cpu_ops, + .probe = mtk_cpu_probe, + .plat_auto = sizeof(struct mtk_cpu_plat), + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c index b30dceba37..d6484d7f4b 100644 --- a/drivers/cpu/riscv_cpu.c +++ b/drivers/cpu/riscv_cpu.c @@ -77,7 +77,7 @@ static int riscv_cpu_get_count(const struct udevice *dev) const char *device_type; /* skip if hart is marked as not available in the device tree */ - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue; device_type = ofnode_read_string(node, "device_type"); diff --git a/drivers/crypto/aspeed/aspeed_hace.c b/drivers/crypto/aspeed/aspeed_hace.c index 1178cc6a76..a1b0b9f564 100644 --- a/drivers/crypto/aspeed/aspeed_hace.c +++ b/drivers/crypto/aspeed/aspeed_hace.c @@ -302,7 +302,7 @@ static int aspeed_hace_digest_wd(struct udevice *dev, enum HASH_ALGO algo, return rc; cur += chunk; - WATCHDOG_RESET(); + schedule(); } } else { rc = aspeed_hace_update(dev, ctx, ibuf, ilen); diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index acd29924f7..8c0fb27b53 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -853,7 +853,7 @@ static int caam_jr_probe(struct udevice *dev) /* Check for enabled job ring node */ ofnode_for_each_subnode(node, dev_ofnode(dev)) { - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue; jr_node = ofnode_read_u32_default(node, "reg", -1); diff --git a/drivers/crypto/hash/hash_sw.c b/drivers/crypto/hash/hash_sw.c index fea9d12609..553c068010 100644 --- a/drivers/crypto/hash/hash_sw.c +++ b/drivers/crypto/hash/hash_sw.c @@ -258,7 +258,7 @@ static int sw_hash_digest_wd(struct udevice *dev, enum HASH_ALGO algo, return rc; cur += chunk; - WATCHDOG_RESET(); + schedule(); } } else { rc = sw_hash_update(dev, ctx, ibuf, ilen); diff --git a/drivers/ddr/altera/sdram_arria10.c b/drivers/ddr/altera/sdram_arria10.c index 4a8f8dea1c..8ef5fa4c48 100644 --- a/drivers/ddr/altera/sdram_arria10.c +++ b/drivers/ddr/altera/sdram_arria10.c @@ -671,7 +671,7 @@ static int of_sdram_firewall_setup(const void *blob) int ddr_calibration_sequence(void) { - WATCHDOG_RESET(); + schedule(); /* Check to see if SDRAM cal was success */ if (sdram_startup()) { @@ -681,7 +681,7 @@ int ddr_calibration_sequence(void) puts("DDRCAL: Success\n"); - WATCHDOG_RESET(); + schedule(); /* initialize the MMR register */ sdram_mmr_init(); diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c index 737a4e2ff1..d9039443b9 100644 --- a/drivers/ddr/altera/sdram_n5x.c +++ b/drivers/ddr/altera/sdram_n5x.c @@ -517,7 +517,7 @@ static int ensure_retry_procedure_complete(phys_addr_t umctl2_base) DDR4_CRCPARSTAT_CMD_IN_ERR_WINDOW; udelay(1); - WATCHDOG_RESET(); + schedule(); } return 0; @@ -1349,7 +1349,7 @@ static int ddr_post_handoff_config(phys_addr_t umctl2_base, } udelay(1); - WATCHDOG_RESET(); + schedule(); /* Polling until SDRAM entered normal operating mode */ value = readl(umctl2_base + DDR4_STAT_OFFSET) & diff --git a/drivers/ddr/altera/sdram_soc64.c b/drivers/ddr/altera/sdram_soc64.c index 9b1710c135..4716abfc9a 100644 --- a/drivers/ddr/altera/sdram_soc64.c +++ b/drivers/ddr/altera/sdram_soc64.c @@ -161,7 +161,7 @@ void sdram_init_ecc_bits(struct bd_info *bd) sdram_clear_mem(start_addr, size_init); size -= size_init; start_addr += size_init; - WATCHDOG_RESET(); + schedule(); } bank++; diff --git a/drivers/ddr/fsl/lc_common_dimm_params.c b/drivers/ddr/fsl/lc_common_dimm_params.c index d738ae3a7c..5e4ad56f07 100644 --- a/drivers/ddr/fsl/lc_common_dimm_params.c +++ b/drivers/ddr/fsl/lc_common_dimm_params.c @@ -422,6 +422,9 @@ compute_lowest_common_dimm_parameters(const unsigned int ctrl_num, dimm_params[i].mpart); #endif } +#ifndef CONFIG_SPL_BUILD + puts(" "); +#endif } } diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c index 1903562ac4..ed3313a531 100644 --- a/drivers/ddr/fsl/main.c +++ b/drivers/ddr/fsl/main.c @@ -857,17 +857,32 @@ phys_size_t __fsl_ddr_sdram(fsl_ddr_info_t *pinfo) debug("total_memory by %s = %llu\n", __func__, total_memory); #if !defined(CONFIG_PHYS_64BIT) - /* Check for 4G or more. Bad. */ - if ((first_ctrl == 0) && (total_memory >= (1ull << 32))) { + /* + * Show warning about big DDR moodules. But avoid warning for 4 GB DDR + * modules when U-Boot supports RAM of maximal size 4 GB - 1 byte. + */ + if ((first_ctrl == 0) && (total_memory - 1 > (phys_size_t)~0ULL)) { puts("Detected "); print_size(total_memory, " of memory\n"); - printf(" This U-Boot only supports < 4G of DDR\n"); - printf(" You could rebuild it with CONFIG_PHYS_64BIT\n"); - printf(" "); /* re-align to match init_dram print */ - total_memory = CONFIG_MAX_MEM_MAPPED; +#ifndef CONFIG_SPL_BUILD + puts(" "); /* re-align to match init_dram print */ +#endif + puts("This U-Boot only supports <= "); + print_size((unsigned long long)((phys_size_t)~0ULL)+1, " of DDR\n"); +#ifndef CONFIG_SPL_BUILD + puts(" "); /* re-align to match init_dram print */ +#endif + puts("You could rebuild it with CONFIG_PHYS_64BIT\n"); +#ifndef CONFIG_SPL_BUILD + puts(" "); /* re-align to match init_dram print */ +#endif } #endif + /* Ensure that total_memory does not overflow on return */ + if (total_memory > (phys_size_t)~0ULL) + total_memory = (phys_size_t)~0ULL; + return total_memory; } @@ -941,5 +956,9 @@ fsl_ddr_sdram_size(void) /* Compute it once normally. */ total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 1); + /* Ensure that total_memory does not overflow on return */ + if (total_memory > (phys_size_t)~0ULL) + total_memory = (phys_size_t)~0ULL; + return total_memory; } diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c index a91da972d4..f5832083ba 100644 --- a/drivers/dfu/dfu_mmc.c +++ b/drivers/dfu/dfu_mmc.c @@ -52,7 +52,7 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu, if (dfu->data.mmc.hw_partition >= 0) { part_num_bkp = mmc_get_blk_desc(mmc)->hwpart; - ret = blk_select_hwpart_devnum(IF_TYPE_MMC, + ret = blk_select_hwpart_devnum(UCLASS_MMC, dfu->data.mmc.dev_num, dfu->data.mmc.hw_partition); if (ret) @@ -77,14 +77,14 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu, if (n != blk_count) { pr_err("MMC operation failed"); if (dfu->data.mmc.hw_partition >= 0) - blk_select_hwpart_devnum(IF_TYPE_MMC, + blk_select_hwpart_devnum(UCLASS_MMC, dfu->data.mmc.dev_num, part_num_bkp); return -EIO; } if (dfu->data.mmc.hw_partition >= 0) { - ret = blk_select_hwpart_devnum(IF_TYPE_MMC, + ret = blk_select_hwpart_devnum(UCLASS_MMC, dfu->data.mmc.dev_num, part_num_bkp); if (ret) diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 76ddc6b4f4..d8e0d79c57 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -370,6 +370,7 @@ int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2, static const struct udevice_id zynqmp_firmware_ids[] = { { .compatible = "xlnx,zynqmp-firmware" }, { .compatible = "xlnx,versal-firmware"}, + { .compatible = "xlnx,versal-net-firmware"}, { } }; diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c index 2b6211c4e6..c3f3d1f440 100644 --- a/drivers/firmware/scmi/scmi_agent-uclass.c +++ b/drivers/firmware/scmi/scmi_agent-uclass.c @@ -65,7 +65,7 @@ static int scmi_bind_protocols(struct udevice *dev) struct driver *drv = NULL; u32 protocol_id; - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue; if (ofnode_read_u32(node, "reg", &protocol_id)) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 0b6ba35b59..727e090e8a 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -134,8 +134,11 @@ static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info, if (rx_message_size > info->desc->max_msg_size || tx_message_size > info->desc->max_msg_size || (rx_message_size > 0 && rx_message_size < sizeof(*hdr)) || - tx_message_size < sizeof(*hdr)) + tx_message_size < sizeof(*hdr)) { + dev_err(info->dev, "TI-SCI message transfer size not sane\n"); return ERR_PTR(-ERANGE); + } + info->seq = ~info->seq; xfer->tx_message.buf = buf; @@ -161,7 +164,7 @@ static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info, * return corresponding error, else if all goes well, * return 0. */ -static inline int ti_sci_get_response(struct ti_sci_info *info, +static int ti_sci_get_response(struct ti_sci_info *info, struct ti_sci_xfer *xfer, struct mbox_chan *chan) { @@ -208,6 +211,19 @@ static inline int ti_sci_get_response(struct ti_sci_info *info, return ret; } +/** + * ti_sci_is_response_ack() - Generic ACK/NACK message checkup + * @r: pointer to response buffer + * + * Return: true if the response was an ACK, else returns false. + */ +static bool ti_sci_is_response_ack(void *r) +{ + struct ti_sci_msg_hdr *hdr = r; + + return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false; +} + /** * ti_sci_do_xfer() - Do one transfer * @info: Pointer to SCI entity information @@ -215,7 +231,7 @@ static inline int ti_sci_get_response(struct ti_sci_info *info, * * Return: 0 if all went fine, else return appropriate error. */ -static inline int ti_sci_do_xfer(struct ti_sci_info *info, +static int ti_sci_do_xfer(struct ti_sci_info *info, struct ti_sci_xfer *xfer) { struct k3_sec_proxy_msg *msg = &xfer->tx_message; @@ -246,8 +262,13 @@ static inline int ti_sci_do_xfer(struct ti_sci_info *info, } /* Get response if requested */ - if (xfer->rx_len) + if (xfer->rx_len) { ret = ti_sci_get_response(info, xfer, &info->chan_rx); + if (!ti_sci_is_response_ack(xfer->tx_message.buf)) { + dev_err(info->dev, "Message not acknowledged"); + ret = -ENODEV; + } + } return ret; } @@ -282,15 +303,12 @@ static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle) sizeof(*rev_info)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox communication fail %d\n", ret); + if (ret) return ret; - } rev_info = (struct ti_sci_msg_resp_version *)xfer->tx_message.buf; @@ -304,19 +322,6 @@ static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle) return 0; } -/** - * ti_sci_is_response_ack() - Generic ACK/NACK message checkup - * @r: pointer to response buffer - * - * Return: true if the response was an ACK, else returns false. - */ -static inline bool ti_sci_is_response_ack(void *r) -{ - struct ti_sci_msg_hdr *hdr = r; - - return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false; -} - /** * cmd_set_board_config_using_msg() - Common command to send board configuration * message @@ -348,7 +353,6 @@ static int cmd_set_board_config_using_msg(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.boardcfgp_high = (addr >> 32) & 0xffffffff; @@ -356,15 +360,8 @@ static int cmd_set_board_config_using_msg(const struct ti_sci_handle *handle, req.boardcfg_size = size; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; return ret; } @@ -509,22 +506,14 @@ static int ti_sci_set_device_state(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.id = id; req.state = state; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; if (state == MSG_DEVICE_SW_STATE_AUTO_OFF) ti_sci_delete_exclusive_dev(info, id); @@ -564,7 +553,6 @@ static int ti_sci_set_device_state_no_wait(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), 0); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.id = id; @@ -572,7 +560,7 @@ static int ti_sci_set_device_state_no_wait(const struct ti_sci_handle *handle, ret = ti_sci_do_xfer(info, xfer); if (ret) - dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; return ret; } @@ -613,20 +601,15 @@ static int ti_sci_get_device_state(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.id = id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_get_device_state *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; if (clcnt) *clcnt = resp->context_loss_count; @@ -901,22 +884,14 @@ static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.id = id; req.resets = reset_state; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; return ret; } @@ -971,7 +946,6 @@ static int ti_sci_set_clock_state(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; @@ -979,15 +953,8 @@ static int ti_sci_set_clock_state(const struct ti_sci_handle *handle, req.request_state = state; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; return ret; } @@ -1029,23 +996,17 @@ static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; req.clk_id = clk_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - if (programmed_state) *programmed_state = resp->programmed_state; if (current_state) @@ -1245,7 +1206,6 @@ static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; @@ -1253,15 +1213,8 @@ static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle, req.parent_id = parent_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; return ret; } @@ -1298,24 +1251,16 @@ static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; req.clk_id = clk_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; - else - *parent_id = resp->parent_id; + *parent_id = resp->parent_id; return ret; } @@ -1353,25 +1298,19 @@ static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; req.clk_id = clk_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_get_clock_num_parents *) xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; - else - *num_parents = resp->num_parents; + *num_parents = resp->num_parents; return ret; } @@ -1418,7 +1357,6 @@ static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; @@ -1428,17 +1366,12 @@ static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle, req.max_freq_hz = max_freq; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; - else - *match_freq = resp->freq_hz; + *match_freq = resp->freq_hz; return ret; } @@ -1483,7 +1416,6 @@ static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; @@ -1493,15 +1425,8 @@ static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle, req.max_freq_hz = max_freq; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; return ret; } @@ -1538,24 +1463,18 @@ static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; req.clk_id = clk_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; - else - *freq = resp->freq_hz; + *freq = resp->freq_hz; return ret; } @@ -1586,21 +1505,13 @@ static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle) (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.domain = 0; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; return ret; } @@ -1641,7 +1552,6 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } @@ -1650,15 +1560,11 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle, req.subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) goto fail; - } resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) { - ret = -ENODEV; - } else if (!resp->range_start && !resp->range_num) { + if (!resp->range_start && !resp->range_num) { ret = -ENODEV; } else { *range_start = resp->range_start; @@ -1769,21 +1675,15 @@ static int ti_sci_cmd_query_msmc(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_query_msmc *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - *msmc_start = ((u64)resp->msmc_start_high << TISCI_ADDR_HIGH_SHIFT) | resp->msmc_start_low; *msmc_end = ((u64)resp->msmc_end_high << TISCI_ADDR_HIGH_SHIFT) | @@ -1820,21 +1720,13 @@ static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; return ret; } @@ -1867,21 +1759,13 @@ static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; return ret; } @@ -1917,22 +1801,14 @@ static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; req.host_id = host_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; return ret; } @@ -1970,7 +1846,6 @@ static int ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; @@ -1981,15 +1856,8 @@ static int ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle *handle, req.config_flags_clear = config_flags_clear; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; return ret; } @@ -2026,7 +1894,6 @@ static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; @@ -2034,15 +1901,8 @@ static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle, req.control_flags_clear = control_flags_clear; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; return ret; } @@ -2080,7 +1940,6 @@ static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.cert_addr_low = *image_addr & TISCI_ADDR_LOW_MASK; @@ -2088,16 +1947,11 @@ static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle, TISCI_ADDR_HIGH_SHIFT; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_proc_auth_boot_image *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - *image_addr = (resp->image_addr_low & TISCI_ADDR_LOW_MASK) | (((u64)resp->image_addr_high << TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK); @@ -2135,22 +1989,17 @@ static int ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_get_proc_boot_status *) xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; *bv = (resp->bootvector_low & TISCI_ADDR_LOW_MASK) | (((u64)resp->bootvector_high << TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK); @@ -2225,7 +2074,6 @@ ti_sci_proc_wait_boot_status_no_wait(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), 0); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; @@ -2240,7 +2088,7 @@ ti_sci_proc_wait_boot_status_no_wait(const struct ti_sci_handle *handle, ret = ti_sci_do_xfer(info, xfer); if (ret) - dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; return ret; } @@ -2340,7 +2188,6 @@ static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "RM_RA:Message config failed(%d)\n", ret); return ret; } req.valid_params = valid_params; @@ -2354,14 +2201,8 @@ static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle, req.order_id = order_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "RM_RA:Mbox config send fail %d\n", ret); + if (ret) goto fail; - } - - resp = (struct ti_sci_msg_rm_ring_cfg_resp *)xfer->tx_message.buf; - - ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; fail: dev_dbg(info->dev, "RM_RA:config ring %u ret:%d\n", index, ret); @@ -2389,7 +2230,6 @@ static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret); return ret; } req.nav_id = nav_id; @@ -2397,13 +2237,8 @@ static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle, req.dst_thread = dst_thread; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret); + if (ret) goto fail; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; fail: dev_dbg(info->dev, "RM_PSIL: nav: %u link pair %u->%u ret:%u\n", @@ -2432,7 +2267,6 @@ static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret); return ret; } req.nav_id = nav_id; @@ -2440,13 +2274,8 @@ static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle, req.dst_thread = dst_thread; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret); + if (ret) goto fail; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; fail: dev_dbg(info->dev, "RM_PSIL: link unpair %u->%u ret:%u\n", @@ -2476,7 +2305,6 @@ static int ti_sci_cmd_rm_udmap_tx_ch_cfg( (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message TX_CH_CFG alloc failed(%d)\n", ret); return ret; } req.valid_params = params->valid_params; @@ -2501,14 +2329,8 @@ static int ti_sci_cmd_rm_udmap_tx_ch_cfg( req.extended_ch_type = params->extended_ch_type; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send TX_CH_CFG fail %d\n", ret); + if (ret) goto fail; - } - - resp = - (struct ti_sci_msg_rm_udmap_tx_ch_cfg_resp *)xfer->tx_message.buf; - ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL; fail: dev_dbg(info->dev, "TX_CH_CFG: chn %u ret:%u\n", params->index, ret); @@ -2537,7 +2359,6 @@ static int ti_sci_cmd_rm_udmap_rx_ch_cfg( (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message RX_CH_CFG alloc failed(%d)\n", ret); return ret; } @@ -2559,14 +2380,8 @@ static int ti_sci_cmd_rm_udmap_rx_ch_cfg( req.rx_ignore_long = params->rx_ignore_long; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send RX_CH_CFG fail %d\n", ret); + if (ret) goto fail; - } - - resp = - (struct ti_sci_msg_rm_udmap_rx_ch_cfg_resp *)xfer->tx_message.buf; - ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL; fail: dev_dbg(info->dev, "RX_CH_CFG: chn %u ret:%d\n", params->index, ret); @@ -2595,8 +2410,6 @@ static int ti_sci_cmd_rm_udmap_rx_flow_cfg( (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "RX_FL_CFG: Message alloc failed(%d)\n", - ret); return ret; } @@ -2624,14 +2437,8 @@ static int ti_sci_cmd_rm_udmap_rx_flow_cfg( req.rx_ps_location = params->rx_ps_location; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "RX_FL_CFG: Mbox send fail %d\n", ret); + if (ret) goto fail; - } - - resp = - (struct ti_sci_msg_rm_udmap_flow_cfg_resp *)xfer->tx_message.buf; - ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL; fail: dev_dbg(info->dev, "RX_FL_CFG: %u ret:%d\n", params->flow_index, ret); @@ -2666,7 +2473,6 @@ static int ti_sci_cmd_set_fwl_region(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } @@ -2681,15 +2487,8 @@ static int ti_sci_cmd_set_fwl_region(const struct ti_sci_handle *handle, req.end_address = region->end_address; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } - - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; return 0; } @@ -2722,7 +2521,6 @@ static int ti_sci_cmd_get_fwl_region(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } @@ -2731,16 +2529,11 @@ static int ti_sci_cmd_get_fwl_region(const struct ti_sci_handle *handle, req.n_permission_regs = region->n_permission_regs; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_fwl_get_firewall_region_resp *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - region->fwl_id = resp->fwl_id; region->region = resp->region; region->n_permission_regs = resp->n_permission_regs; @@ -2782,7 +2575,6 @@ static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } @@ -2791,16 +2583,11 @@ static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle, req.owner_index = owner->owner_index; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_fwl_change_owner_info_resp *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - owner->fwl_id = resp->fwl_id; owner->region = resp->region; owner->owner_index = resp->owner_index; diff --git a/drivers/fpga/intel_sdm_mb.c b/drivers/fpga/intel_sdm_mb.c index f5fd9a14c2..903d143a36 100644 --- a/drivers/fpga/intel_sdm_mb.c +++ b/drivers/fpga/intel_sdm_mb.c @@ -44,7 +44,7 @@ static int reconfig_status_polling_resp(void) puts("."); udelay(RECONFIG_STATUS_INTERVAL_DELAY_US); - WATCHDOG_RESET(); + schedule(); } return -ETIMEDOUT; @@ -104,7 +104,7 @@ static int send_bitstream(const void *rbf_data, size_t rbf_size) udelay(20000); } - WATCHDOG_RESET(); + schedule(); } return 0; @@ -252,7 +252,7 @@ static int reconfig_status_polling_resp(void) puts("."); udelay(RECONFIG_STATUS_INTERVAL_DELAY_US); - WATCHDOG_RESET(); + schedule(); } return -ETIMEDOUT; @@ -378,7 +378,7 @@ static int send_reconfig_data(const void *rbf_data, size_t rbf_size, if (resp_err && !xfer_count) return resp_err; } - WATCHDOG_RESET(); + schedule(); } return 0; diff --git a/drivers/fpga/socfpga_arria10.c b/drivers/fpga/socfpga_arria10.c index d8089122af..3b785e67d0 100644 --- a/drivers/fpga/socfpga_arria10.c +++ b/drivers/fpga/socfpga_arria10.c @@ -383,7 +383,7 @@ static int fpgamgr_program_poll_cd(void) printf("nstatus == 0 while waiting for condone\n"); return -EPERM; } - WATCHDOG_RESET(); + schedule(); } if (i == FPGA_TIMEOUT_CNT) @@ -534,7 +534,7 @@ static void get_rbf_image_info(struct rbf_info *rbf, u16 *buffer) rbf->section = unknown; break; - WATCHDOG_RESET(); + schedule(); } } @@ -555,14 +555,14 @@ static int first_loading_rbf_to_buffer(struct udevice *dev, /* Load image header into buffer */ ret = request_firmware_into_buf(dev, fpga_loadfs->fpga_fsinfo->filename, - buffer_p, sizeof(struct image_header), + buffer_p, sizeof(struct legacy_img_hdr), 0); if (ret < 0) { debug("FPGA: Failed to read image header from flash.\n"); return -ENOENT; } - if (image_get_magic((struct image_header *)buffer_p) != FDT_MAGIC) { + if (image_get_magic((struct legacy_img_hdr *)buffer_p) != FDT_MAGIC) { debug("FPGA: No FDT magic was found.\n"); return -EBADF; } @@ -635,7 +635,7 @@ static int first_loading_rbf_to_buffer(struct udevice *dev, break; } } - WATCHDOG_RESET(); + schedule(); } if (!fpga_node_name) { @@ -879,7 +879,7 @@ int socfpga_loadfs(fpga_fs_info *fpga_fsinfo, const void *buf, size_t bsize, total_sizeof_image += buffer_sizebytes_ori; - WATCHDOG_RESET(); + schedule(); } wait_for_fifo_empty(); diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index d8ebd542ab..0c83df46da 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -413,7 +413,8 @@ static int zynq_load(xilinx_desc *desc, const void *buf, size_t bsize, if (bstype != BIT_PARTIAL) zynq_slcr_devcfg_enable(); - puts("INFO:post config was not run, please run manually if needed\n"); + if (!IS_ENABLED(CONFIG_SPL_BUILD)) + puts("INFO:post config was not run, please run manually if needed\n"); return FPGA_SUCCESS; } diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 7e4c3577b3..c949f9d2f7 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -303,14 +303,14 @@ config CMD_PCA953X legacy GPIO interface. Several subcommands are provided which mirror the standard 'gpio' command. It should use that instead. -config PM8916_GPIO - bool "Qualcomm PM8916 PMIC GPIO/keypad driver" - depends on DM_GPIO && PMIC_PM8916 +config QCOM_PMIC_GPIO + bool "Qualcomm generic PMIC GPIO/keypad driver" + depends on DM_GPIO && PMIC_QCOM help Support for GPIO pins and power/reset buttons found on - Qualcomm PM8916 PMIC. + Qualcomm SoCs PMIC. Default name for GPIO bank is "pm8916". - Power and reset buttons are placed in "pm8916_key" bank and + Power and reset buttons are placed in "pwkey_qcom" bank and have gpio numbers 0 and 1 respectively. config PCF8575_GPIO diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 39762fa06c..9d718a554e 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -63,7 +63,7 @@ obj-$(CONFIG_OCTEON_GPIO) += octeon_gpio.o obj-$(CONFIG_MVEBU_GPIO) += mvebu_gpio.o obj-$(CONFIG_MSM_GPIO) += msm_gpio.o obj-$(CONFIG_$(SPL_)PCF8575_GPIO) += pcf8575_gpio.o -obj-$(CONFIG_$(SPL_TPL_)PM8916_GPIO) += pm8916_gpio.o +obj-$(CONFIG_$(SPL_TPL_)QCOM_PMIC_GPIO) += qcom_pmic_gpio.o obj-$(CONFIG_MT7620_GPIO) += mt7620_gpio.o obj-$(CONFIG_MT7621_GPIO) += mt7621_gpio.o obj-$(CONFIG_MSCC_SGPIO) += mscc_sgpio.o diff --git a/drivers/gpio/atmel_pio4.c b/drivers/gpio/atmel_pio4.c index 77a76c1d50..47ed297981 100644 --- a/drivers/gpio/atmel_pio4.c +++ b/drivers/gpio/atmel_pio4.c @@ -350,10 +350,8 @@ static const struct atmel_pioctrl_data microchip_sama7g5_pioctrl_data = { static const struct udevice_id atmel_pio4_ids[] = { { - .compatible = "atmel,sama5d2-gpio", .data = (ulong)&atmel_sama5d2_pioctrl_data, }, { - .compatible = "microchip,sama7g5-gpio", .data = (ulong)µchip_sama7g5_pioctrl_data, }, {} diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 0ed32b7217..a00880e446 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -884,26 +884,31 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize) const struct dm_gpio_ops *ops = gpio_get_ops(dev); struct gpio_dev_priv *priv; char *str = buf; + const char *label; int func; int ret; int len; + bool used; BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function)); *buf = 0; priv = dev_get_uclass_priv(dev); - ret = gpio_get_raw_function(dev, offset, NULL); + ret = gpio_get_raw_function(dev, offset, &label); if (ret < 0) return ret; func = ret; len = snprintf(str, buffsize, "%s%d: %s", priv->bank_name ? priv->bank_name : "", offset, gpio_function[func]); - if (func == GPIOF_INPUT || func == GPIOF_OUTPUT || - func == GPIOF_UNUSED) { - const char *label; - bool used; + switch (func) { + case GPIOF_FUNC: + snprintf(str + len, buffsize - len, " %s", label ? label : ""); + break; + case GPIOF_INPUT: + case GPIOF_OUTPUT: + case GPIOF_UNUSED: ret = ops->get_value(dev, offset); if (ret < 0) return ret; @@ -911,8 +916,9 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize) snprintf(str + len, buffsize - len, ": %d [%c]%s%s", ret, used ? 'x' : ' ', - used ? " " : "", + label ? " " : "", label ? label : ""); + break; } return 0; diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c index a3c3cd7824..51670f2637 100644 --- a/drivers/gpio/msm_gpio.c +++ b/drivers/gpio/msm_gpio.c @@ -116,20 +116,12 @@ static int msm_gpio_of_to_plat(struct udevice *dev) return 0; } -static const struct udevice_id msm_gpio_ids[] = { - { .compatible = "qcom,msm8916-pinctrl" }, - { .compatible = "qcom,apq8016-pinctrl" }, - { .compatible = "qcom,ipq4019-pinctrl" }, - { .compatible = "qcom,sdm845-pinctrl" }, - { } -}; - U_BOOT_DRIVER(gpio_msm) = { .name = "gpio_msm", .id = UCLASS_GPIO, - .of_match = msm_gpio_ids, .of_to_plat = msm_gpio_of_to_plat, .probe = msm_gpio_probe, .ops = &gpio_msm_ops, + .flags = DM_UC_FLAG_SEQ_ALIAS, .priv_auto = sizeof(struct msm_gpio_bank), }; diff --git a/drivers/gpio/pm8916_gpio.c b/drivers/gpio/pm8916_gpio.c deleted file mode 100644 index 7ad95784a8..0000000000 --- a/drivers/gpio/pm8916_gpio.c +++ /dev/null @@ -1,303 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Qualcomm pm8916 pmic gpio driver - part of Qualcomm PM8916 PMIC - * - * (C) Copyright 2015 Mateusz Kulikowski - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* Register offset for each gpio */ -#define REG_OFFSET(x) ((x) * 0x100) - -/* Register maps */ - -/* Type and subtype are shared for all pm8916 peripherals */ -#define REG_TYPE 0x4 -#define REG_SUBTYPE 0x5 - -#define REG_STATUS 0x08 -#define REG_STATUS_VAL_MASK 0x1 - -/* MODE_CTL */ -#define REG_CTL 0x40 -#define REG_CTL_MODE_MASK 0x70 -#define REG_CTL_MODE_INPUT 0x00 -#define REG_CTL_MODE_INOUT 0x20 -#define REG_CTL_MODE_OUTPUT 0x10 -#define REG_CTL_OUTPUT_MASK 0x0F - -#define REG_DIG_VIN_CTL 0x41 -#define REG_DIG_VIN_VIN0 0 - -#define REG_DIG_PULL_CTL 0x42 -#define REG_DIG_PULL_NO_PU 0x5 - -#define REG_DIG_OUT_CTL 0x45 -#define REG_DIG_OUT_CTL_CMOS (0x0 << 4) -#define REG_DIG_OUT_CTL_DRIVE_L 0x1 - -#define REG_EN_CTL 0x46 -#define REG_EN_CTL_ENABLE (1 << 7) - -struct pm8916_gpio_bank { - uint32_t pid; /* Peripheral ID on SPMI bus */ -}; - -static int pm8916_gpio_set_direction(struct udevice *dev, unsigned offset, - bool input, int value) -{ - struct pm8916_gpio_bank *priv = dev_get_priv(dev); - uint32_t gpio_base = priv->pid + REG_OFFSET(offset); - int ret; - - /* Disable the GPIO */ - ret = pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL, - REG_EN_CTL_ENABLE, 0); - if (ret < 0) - return ret; - - /* Select the mode */ - if (input) - ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL, - REG_CTL_MODE_INPUT); - else - ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL, - REG_CTL_MODE_INOUT | (value ? 1 : 0)); - if (ret < 0) - return ret; - - /* Set the right pull (no pull) */ - ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_PULL_CTL, - REG_DIG_PULL_NO_PU); - if (ret < 0) - return ret; - - /* Configure output pin drivers if needed */ - if (!input) { - /* Select the VIN - VIN0, pin is input so it doesn't matter */ - ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_VIN_CTL, - REG_DIG_VIN_VIN0); - if (ret < 0) - return ret; - - /* Set the right dig out control */ - ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_OUT_CTL, - REG_DIG_OUT_CTL_CMOS | - REG_DIG_OUT_CTL_DRIVE_L); - if (ret < 0) - return ret; - } - - /* Enable the GPIO */ - return pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL, 0, - REG_EN_CTL_ENABLE); -} - -static int pm8916_gpio_direction_input(struct udevice *dev, unsigned offset) -{ - return pm8916_gpio_set_direction(dev, offset, true, 0); -} - -static int pm8916_gpio_direction_output(struct udevice *dev, unsigned offset, - int value) -{ - return pm8916_gpio_set_direction(dev, offset, false, value); -} - -static int pm8916_gpio_get_function(struct udevice *dev, unsigned offset) -{ - struct pm8916_gpio_bank *priv = dev_get_priv(dev); - uint32_t gpio_base = priv->pid + REG_OFFSET(offset); - int reg; - - /* Set the output value of the gpio */ - reg = pmic_reg_read(dev->parent, gpio_base + REG_CTL); - if (reg < 0) - return reg; - - switch (reg & REG_CTL_MODE_MASK) { - case REG_CTL_MODE_INPUT: - return GPIOF_INPUT; - case REG_CTL_MODE_INOUT: /* Fallthrough */ - case REG_CTL_MODE_OUTPUT: - return GPIOF_OUTPUT; - default: - return GPIOF_UNKNOWN; - } -} - -static int pm8916_gpio_get_value(struct udevice *dev, unsigned offset) -{ - struct pm8916_gpio_bank *priv = dev_get_priv(dev); - uint32_t gpio_base = priv->pid + REG_OFFSET(offset); - int reg; - - reg = pmic_reg_read(dev->parent, gpio_base + REG_STATUS); - if (reg < 0) - return reg; - - return !!(reg & REG_STATUS_VAL_MASK); -} - -static int pm8916_gpio_set_value(struct udevice *dev, unsigned offset, - int value) -{ - struct pm8916_gpio_bank *priv = dev_get_priv(dev); - uint32_t gpio_base = priv->pid + REG_OFFSET(offset); - - /* Set the output value of the gpio */ - return pmic_clrsetbits(dev->parent, gpio_base + REG_CTL, - REG_CTL_OUTPUT_MASK, !!value); -} - -static const struct dm_gpio_ops pm8916_gpio_ops = { - .direction_input = pm8916_gpio_direction_input, - .direction_output = pm8916_gpio_direction_output, - .get_value = pm8916_gpio_get_value, - .set_value = pm8916_gpio_set_value, - .get_function = pm8916_gpio_get_function, -}; - -static int pm8916_gpio_probe(struct udevice *dev) -{ - struct pm8916_gpio_bank *priv = dev_get_priv(dev); - int reg; - - priv->pid = dev_read_addr(dev); - if (priv->pid == FDT_ADDR_T_NONE) - return log_msg_ret("bad address", -EINVAL); - - /* Do a sanity check */ - reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE); - if (reg != 0x10) - return log_msg_ret("bad type", -ENXIO); - - reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE); - if (reg != 0x5 && reg != 0x1) - return log_msg_ret("bad subtype", -ENXIO); - - return 0; -} - -static int pm8916_gpio_of_to_plat(struct udevice *dev) -{ - struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); - - uc_priv->gpio_count = dev_read_u32_default(dev, "gpio-count", 0); - uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name"); - if (uc_priv->bank_name == NULL) - uc_priv->bank_name = "pm8916"; - - return 0; -} - -static const struct udevice_id pm8916_gpio_ids[] = { - { .compatible = "qcom,pm8916-gpio" }, - { .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */ - { .compatible = "qcom,pm8998-gpio" }, - { } -}; - -U_BOOT_DRIVER(gpio_pm8916) = { - .name = "gpio_pm8916", - .id = UCLASS_GPIO, - .of_match = pm8916_gpio_ids, - .of_to_plat = pm8916_gpio_of_to_plat, - .probe = pm8916_gpio_probe, - .ops = &pm8916_gpio_ops, - .priv_auto = sizeof(struct pm8916_gpio_bank), -}; - - -/* Add pmic buttons as GPIO as well - there is no generic way for now */ -#define PON_INT_RT_STS 0x10 -#define KPDPWR_ON_INT_BIT 0 -#define RESIN_ON_INT_BIT 1 - -static int pm8941_pwrkey_get_function(struct udevice *dev, unsigned offset) -{ - return GPIOF_INPUT; -} - -static int pm8941_pwrkey_get_value(struct udevice *dev, unsigned offset) -{ - struct pm8916_gpio_bank *priv = dev_get_priv(dev); - - int reg = pmic_reg_read(dev->parent, priv->pid + PON_INT_RT_STS); - - if (reg < 0) - return 0; - - switch (offset) { - case 0: /* Power button */ - return (reg & BIT(KPDPWR_ON_INT_BIT)) != 0; - break; - case 1: /* Reset button */ - default: - return (reg & BIT(RESIN_ON_INT_BIT)) != 0; - break; - } -} - -static const struct dm_gpio_ops pm8941_pwrkey_ops = { - .get_value = pm8941_pwrkey_get_value, - .get_function = pm8941_pwrkey_get_function, -}; - -static int pm8941_pwrkey_probe(struct udevice *dev) -{ - struct pm8916_gpio_bank *priv = dev_get_priv(dev); - int reg; - - priv->pid = dev_read_addr(dev); - if (priv->pid == FDT_ADDR_T_NONE) - return log_msg_ret("bad address", -EINVAL); - - /* Do a sanity check */ - reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE); - if (reg != 0x1) - return log_msg_ret("bad type", -ENXIO); - - reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE); - if ((reg & 0x5) == 0) - return log_msg_ret("bad subtype", -ENXIO); - - return 0; -} - -static int pm8941_pwrkey_of_to_plat(struct udevice *dev) -{ - struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); - - uc_priv->gpio_count = 2; - uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name"); - if (uc_priv->bank_name == NULL) - uc_priv->bank_name = "pm8916_key"; - - return 0; -} - -static const struct udevice_id pm8941_pwrkey_ids[] = { - { .compatible = "qcom,pm8916-pwrkey" }, - { .compatible = "qcom,pm8994-pwrkey" }, - { .compatible = "qcom,pm8998-pwrkey" }, - { } -}; - -U_BOOT_DRIVER(pwrkey_pm89xx) = { - .name = "pwrkey_pm89xx", - .id = UCLASS_GPIO, - .of_match = pm8941_pwrkey_ids, - .of_to_plat = pm8941_pwrkey_of_to_plat, - .probe = pm8941_pwrkey_probe, - .ops = &pm8941_pwrkey_ops, - .priv_auto = sizeof(struct pm8916_gpio_bank), -}; diff --git a/drivers/gpio/qcom_pmic_gpio.c b/drivers/gpio/qcom_pmic_gpio.c new file mode 100644 index 0000000000..3be1be8692 --- /dev/null +++ b/drivers/gpio/qcom_pmic_gpio.c @@ -0,0 +1,359 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Qualcomm generic pmic gpio driver + * + * (C) Copyright 2015 Mateusz Kulikowski + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register offset for each gpio */ +#define REG_OFFSET(x) ((x) * 0x100) + +/* Register maps */ + +/* Type and subtype are shared for all PMIC peripherals */ +#define REG_TYPE 0x4 +#define REG_SUBTYPE 0x5 + +/* GPIO peripheral type and subtype out_values */ +#define REG_TYPE_VAL 0x10 +#define REG_SUBTYPE_GPIO_4CH 0x1 +#define REG_SUBTYPE_GPIOC_4CH 0x5 +#define REG_SUBTYPE_GPIO_8CH 0x9 +#define REG_SUBTYPE_GPIOC_8CH 0xd +#define REG_SUBTYPE_GPIO_LV 0x10 +#define REG_SUBTYPE_GPIO_MV 0x11 + +#define REG_STATUS 0x08 +#define REG_STATUS_VAL_MASK 0x1 + +/* MODE_CTL */ +#define REG_CTL 0x40 +#define REG_CTL_MODE_MASK 0x70 +#define REG_CTL_MODE_INPUT 0x00 +#define REG_CTL_MODE_INOUT 0x20 +#define REG_CTL_MODE_OUTPUT 0x10 +#define REG_CTL_OUTPUT_MASK 0x0F +#define REG_CTL_LV_MV_MODE_MASK 0x3 +#define REG_CTL_LV_MV_MODE_INPUT 0x0 +#define REG_CTL_LV_MV_MODE_INOUT 0x2 +#define REG_CTL_LV_MV_MODE_OUTPUT 0x1 + +#define REG_DIG_VIN_CTL 0x41 +#define REG_DIG_VIN_VIN0 0 + +#define REG_DIG_PULL_CTL 0x42 +#define REG_DIG_PULL_NO_PU 0x5 + +#define REG_LV_MV_OUTPUT_CTL 0x44 +#define REG_LV_MV_OUTPUT_CTL_MASK 0x80 +#define REG_LV_MV_OUTPUT_CTL_SHIFT 7 + +#define REG_DIG_OUT_CTL 0x45 +#define REG_DIG_OUT_CTL_CMOS (0x0 << 4) +#define REG_DIG_OUT_CTL_DRIVE_L 0x1 + +#define REG_EN_CTL 0x46 +#define REG_EN_CTL_ENABLE (1 << 7) + +struct qcom_gpio_bank { + uint32_t pid; /* Peripheral ID on SPMI bus */ + bool lv_mv_type; /* If subtype is GPIO_LV(0x10) or GPIO_MV(0x11) */ +}; + +static int qcom_gpio_set_direction(struct udevice *dev, unsigned offset, + bool input, int value) +{ + struct qcom_gpio_bank *priv = dev_get_priv(dev); + uint32_t gpio_base = priv->pid + REG_OFFSET(offset); + uint32_t reg_ctl_val; + int ret; + + /* Disable the GPIO */ + ret = pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL, + REG_EN_CTL_ENABLE, 0); + if (ret < 0) + return ret; + + /* Select the mode and output */ + if (priv->lv_mv_type) { + if (input) + reg_ctl_val = REG_CTL_LV_MV_MODE_INPUT; + else + reg_ctl_val = REG_CTL_LV_MV_MODE_INOUT; + } else { + if (input) + reg_ctl_val = REG_CTL_MODE_INPUT; + else + reg_ctl_val = REG_CTL_MODE_INOUT | !!value; + } + + ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL, reg_ctl_val); + if (ret < 0) + return ret; + + if (priv->lv_mv_type && !input) { + ret = pmic_reg_write(dev->parent, + gpio_base + REG_LV_MV_OUTPUT_CTL, + !!value << REG_LV_MV_OUTPUT_CTL_SHIFT); + if (ret < 0) + return ret; + } + + /* Set the right pull (no pull) */ + ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_PULL_CTL, + REG_DIG_PULL_NO_PU); + if (ret < 0) + return ret; + + /* Configure output pin drivers if needed */ + if (!input) { + /* Select the VIN - VIN0, pin is input so it doesn't matter */ + ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_VIN_CTL, + REG_DIG_VIN_VIN0); + if (ret < 0) + return ret; + + /* Set the right dig out control */ + ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_OUT_CTL, + REG_DIG_OUT_CTL_CMOS | + REG_DIG_OUT_CTL_DRIVE_L); + if (ret < 0) + return ret; + } + + /* Enable the GPIO */ + return pmic_clrsetbits(dev->parent, gpio_base + REG_EN_CTL, 0, + REG_EN_CTL_ENABLE); +} + +static int qcom_gpio_direction_input(struct udevice *dev, unsigned offset) +{ + return qcom_gpio_set_direction(dev, offset, true, 0); +} + +static int qcom_gpio_direction_output(struct udevice *dev, unsigned offset, + int value) +{ + return qcom_gpio_set_direction(dev, offset, false, value); +} + +static int qcom_gpio_get_function(struct udevice *dev, unsigned offset) +{ + struct qcom_gpio_bank *priv = dev_get_priv(dev); + uint32_t gpio_base = priv->pid + REG_OFFSET(offset); + int reg; + + reg = pmic_reg_read(dev->parent, gpio_base + REG_CTL); + if (reg < 0) + return reg; + + if (priv->lv_mv_type) { + switch (reg & REG_CTL_LV_MV_MODE_MASK) { + case REG_CTL_LV_MV_MODE_INPUT: + return GPIOF_INPUT; + case REG_CTL_LV_MV_MODE_INOUT: /* Fallthrough */ + case REG_CTL_LV_MV_MODE_OUTPUT: + return GPIOF_OUTPUT; + default: + return GPIOF_UNKNOWN; + } + } else { + switch (reg & REG_CTL_MODE_MASK) { + case REG_CTL_MODE_INPUT: + return GPIOF_INPUT; + case REG_CTL_MODE_INOUT: /* Fallthrough */ + case REG_CTL_MODE_OUTPUT: + return GPIOF_OUTPUT; + default: + return GPIOF_UNKNOWN; + } + } +} + +static int qcom_gpio_get_value(struct udevice *dev, unsigned offset) +{ + struct qcom_gpio_bank *priv = dev_get_priv(dev); + uint32_t gpio_base = priv->pid + REG_OFFSET(offset); + int reg; + + reg = pmic_reg_read(dev->parent, gpio_base + REG_STATUS); + if (reg < 0) + return reg; + + return !!(reg & REG_STATUS_VAL_MASK); +} + +static int qcom_gpio_set_value(struct udevice *dev, unsigned offset, + int value) +{ + struct qcom_gpio_bank *priv = dev_get_priv(dev); + uint32_t gpio_base = priv->pid + REG_OFFSET(offset); + + /* Set the output value of the gpio */ + if (priv->lv_mv_type) + return pmic_clrsetbits(dev->parent, + gpio_base + REG_LV_MV_OUTPUT_CTL, + REG_LV_MV_OUTPUT_CTL_MASK, + !!value << REG_LV_MV_OUTPUT_CTL_SHIFT); + else + return pmic_clrsetbits(dev->parent, gpio_base + REG_CTL, + REG_CTL_OUTPUT_MASK, !!value); +} + +static const struct dm_gpio_ops qcom_gpio_ops = { + .direction_input = qcom_gpio_direction_input, + .direction_output = qcom_gpio_direction_output, + .get_value = qcom_gpio_get_value, + .set_value = qcom_gpio_set_value, + .get_function = qcom_gpio_get_function, +}; + +static int qcom_gpio_probe(struct udevice *dev) +{ + struct qcom_gpio_bank *priv = dev_get_priv(dev); + int reg; + + priv->pid = dev_read_addr(dev); + if (priv->pid == FDT_ADDR_T_NONE) + return log_msg_ret("bad address", -EINVAL); + + /* Do a sanity check */ + reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE); + if (reg != REG_TYPE_VAL) + return log_msg_ret("bad type", -ENXIO); + + reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE); + if (reg != REG_SUBTYPE_GPIO_4CH && reg != REG_SUBTYPE_GPIOC_4CH && + reg != REG_SUBTYPE_GPIO_LV && reg != REG_SUBTYPE_GPIO_MV) + return log_msg_ret("bad subtype", -ENXIO); + + priv->lv_mv_type = reg == REG_SUBTYPE_GPIO_LV || + reg == REG_SUBTYPE_GPIO_MV; + + return 0; +} + +static int qcom_gpio_of_to_plat(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + uc_priv->gpio_count = dev_read_u32_default(dev, "gpio-count", 0); + uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name"); + if (uc_priv->bank_name == NULL) + uc_priv->bank_name = "qcom_pmic"; + + return 0; +} + +static const struct udevice_id qcom_gpio_ids[] = { + { .compatible = "qcom,pm8916-gpio" }, + { .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */ + { .compatible = "qcom,pm8998-gpio" }, + { .compatible = "qcom,pms405-gpio" }, + { } +}; + +U_BOOT_DRIVER(qcom_pmic_gpio) = { + .name = "qcom_pmic_gpio", + .id = UCLASS_GPIO, + .of_match = qcom_gpio_ids, + .of_to_plat = qcom_gpio_of_to_plat, + .probe = qcom_gpio_probe, + .ops = &qcom_gpio_ops, + .priv_auto = sizeof(struct qcom_gpio_bank), +}; + + +/* Add pmic buttons as GPIO as well - there is no generic way for now */ +#define PON_INT_RT_STS 0x10 +#define KPDPWR_ON_INT_BIT 0 +#define RESIN_ON_INT_BIT 1 + +static int qcom_pwrkey_get_function(struct udevice *dev, unsigned offset) +{ + return GPIOF_INPUT; +} + +static int qcom_pwrkey_get_value(struct udevice *dev, unsigned offset) +{ + struct qcom_gpio_bank *priv = dev_get_priv(dev); + + int reg = pmic_reg_read(dev->parent, priv->pid + PON_INT_RT_STS); + + if (reg < 0) + return 0; + + switch (offset) { + case 0: /* Power button */ + return (reg & BIT(KPDPWR_ON_INT_BIT)) != 0; + break; + case 1: /* Reset button */ + default: + return (reg & BIT(RESIN_ON_INT_BIT)) != 0; + break; + } +} + +static const struct dm_gpio_ops qcom_pwrkey_ops = { + .get_value = qcom_pwrkey_get_value, + .get_function = qcom_pwrkey_get_function, +}; + +static int qcom_pwrkey_probe(struct udevice *dev) +{ + struct qcom_gpio_bank *priv = dev_get_priv(dev); + int reg; + + priv->pid = dev_read_addr(dev); + if (priv->pid == FDT_ADDR_T_NONE) + return log_msg_ret("bad address", -EINVAL); + + /* Do a sanity check */ + reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE); + if (reg != 0x1) + return log_msg_ret("bad type", -ENXIO); + + reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE); + if ((reg & 0x5) == 0) + return log_msg_ret("bad subtype", -ENXIO); + + return 0; +} + +static int qcom_pwrkey_of_to_plat(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + uc_priv->gpio_count = 2; + uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name"); + if (uc_priv->bank_name == NULL) + uc_priv->bank_name = "pwkey_qcom"; + + return 0; +} + +static const struct udevice_id qcom_pwrkey_ids[] = { + { .compatible = "qcom,pm8916-pwrkey" }, + { .compatible = "qcom,pm8994-pwrkey" }, + { .compatible = "qcom,pm8998-pwrkey" }, + { } +}; + +U_BOOT_DRIVER(pwrkey_qcom) = { + .name = "pwrkey_qcom", + .id = UCLASS_GPIO, + .of_match = qcom_pwrkey_ids, + .of_to_plat = qcom_pwrkey_of_to_plat, + .probe = qcom_pwrkey_probe, + .ops = &qcom_pwrkey_ops, + .priv_auto = sizeof(struct qcom_gpio_bank), +}; diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c index 106b2a7b27..305f9a6ff6 100644 --- a/drivers/gpio/sandbox.c +++ b/drivers/gpio/sandbox.c @@ -196,6 +196,8 @@ static int sb_gpio_get_function(struct udevice *dev, unsigned offset) return GPIOF_OUTPUT; if (get_gpio_flag(dev, offset, GPIOD_IS_IN)) return GPIOF_INPUT; + if (get_gpio_flag(dev, offset, GPIOD_IS_AF)) + return GPIOF_FUNC; return GPIOF_INPUT; /*GPIO is not configurated */ } @@ -219,6 +221,9 @@ static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, if (args->args[1] & GPIO_OUT_ACTIVE) desc->flags |= GPIOD_IS_OUT_ACTIVE; + if (args->args[1] & GPIO_AF) + desc->flags |= GPIOD_IS_AF; + return 0; } diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index be4724bf8e..08b6c7bdcc 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -261,6 +261,15 @@ config SYS_I2C_MESON internal buffer holding up to 8 bytes for transfers and supports both 7-bit and 10-bit addresses. +config SYS_I2C_MTK + bool "MediaTek I2C driver" + help + This selects the MediaTek Integrated Inter Circuit bus driver. + The I2C bus adapter is the base for some other I2C client, + eg: touch, sensors. + If you want to use MediaTek I2C interface, say Y here. + If unsure, say N. + config SYS_I2C_MICROCHIP bool "Microchip I2C driver" help diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 7e046f809a..920aafb91c 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_SYS_I2C_MICROCHIP) += i2c-microchip.o obj-$(CONFIG_SYS_I2C_MV) += mv_i2c.o obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o +obj-$(CONFIG_SYS_I2C_MTK) += mtk_i2c.o obj-$(CONFIG_SYS_I2C_NEXELL) += nx_i2c.o obj-$(CONFIG_SYS_I2C_NPCM) += npcm_i2c.o obj-$(CONFIG_SYS_I2C_OCORES) += ocores_i2c.o diff --git a/drivers/i2c/mtk_i2c.c b/drivers/i2c/mtk_i2c.c new file mode 100644 index 0000000000..5528bcd7cc --- /dev/null +++ b/drivers/i2c/mtk_i2c.c @@ -0,0 +1,822 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 MediaTek Inc. All Rights Reserved. + * + * Author: Mingming Lee + * + * MediaTek I2C Interface driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define I2C_RS_TRANSFER BIT(4) +#define I2C_HS_NACKERR BIT(2) +#define I2C_ACKERR BIT(1) +#define I2C_TRANSAC_COMP BIT(0) +#define I2C_TRANSAC_START BIT(0) +#define I2C_RS_MUL_CNFG BIT(15) +#define I2C_RS_MUL_TRIG BIT(14) +#define I2C_DCM_DISABLE 0x0000 +#define I2C_IO_CONFIG_OPEN_DRAIN 0x0003 +#define I2C_IO_CONFIG_PUSH_PULL 0x0000 +#define I2C_SOFT_RST 0x0001 +#define I2C_FIFO_ADDR_CLR 0x0001 +#define I2C_DELAY_LEN 0x0002 +#define I2C_ST_START_CON 0x8001 +#define I2C_FS_START_CON 0x1800 +#define I2C_TIME_CLR_VALUE 0x0000 +#define I2C_TIME_DEFAULT_VALUE 0x0003 +#define I2C_WRRD_TRANAC_VALUE 0x0002 +#define I2C_RD_TRANAC_VALUE 0x0001 + +#define I2C_DMA_CON_TX 0x0000 +#define I2C_DMA_CON_RX 0x0001 +#define I2C_DMA_START_EN 0x0001 +#define I2C_DMA_INT_FLAG_NONE 0x0000 +#define I2C_DMA_CLR_FLAG 0x0000 +#define I2C_DMA_TX_RX 0x0000 +#define I2C_DMA_HARD_RST 0x0002 + +#define MAX_ST_MODE_SPEED 100000 +#define MAX_FS_MODE_SPEED 400000 +#define MAX_HS_MODE_SPEED 3400000 +#define MAX_SAMPLE_CNT_DIV 8 +#define MAX_STEP_CNT_DIV 64 +#define MAX_HS_STEP_CNT_DIV 8 +#define I2C_DEFAULT_CLK_DIV 4 + +#define MAX_I2C_ADDR 0x7f +#define MAX_I2C_LEN 0xff +#define TRANS_ADDR_ONLY BIT(8) +#define TRANSFER_TIMEOUT 50000 /* us */ +#define I2C_FIFO_STAT1_MASK 0x001f +#define TIMING_SAMPLE_OFFSET 8 +#define HS_SAMPLE_OFFSET 12 +#define HS_STEP_OFFSET 8 + +#define I2C_CONTROL_WRAPPER BIT(0) +#define I2C_CONTROL_RS BIT(1) +#define I2C_CONTROL_DMA_EN BIT(2) +#define I2C_CONTROL_CLK_EXT_EN BIT(3) +#define I2C_CONTROL_DIR_CHANGE BIT(4) +#define I2C_CONTROL_ACKERR_DET_EN BIT(5) +#define I2C_CONTROL_TRANSFER_LEN_CHANGE BIT(6) +#define I2C_CONTROL_DMAACK BIT(8) +#define I2C_CONTROL_ASYNC BIT(9) + +#define I2C_MASTER_WR BIT(0) +#define I2C_MASTER_RD BIT(1) +#define I2C_MASTER_WRRD (I2C_MASTER_WR | I2C_MASTER_RD) + +enum I2C_REGS_OFFSET { + REG_PORT, + REG_SLAVE_ADDR, + REG_INTR_MASK, + REG_INTR_STAT, + REG_CONTROL, + REG_TRANSFER_LEN, + REG_TRANSAC_LEN, + REG_DELAY_LEN, + REG_TIMING, + REG_START, + REG_EXT_CONF, + REG_FIFO_STAT1, + REG_LTIMING, + REG_FIFO_STAT, + REG_FIFO_THRESH, + REG_FIFO_ADDR_CLR, + REG_IO_CONFIG, + REG_RSV_DEBUG, + REG_HS, + REG_SOFTRESET, + REG_DCM_EN, + REG_PATH_DIR, + REG_DEBUGSTAT, + REG_DEBUGCTRL, + REG_TRANSFER_LEN_AUX, + REG_CLOCK_DIV, + REG_SCL_HL_RATIO, + REG_SCL_HS_HL_RATIO, + REG_SCL_MIS_COMP_POINT, + REG_STA_STOP_AC_TIME, + REG_HS_STA_STOP_AC_TIME, + REG_DATA_TIME, +}; + +enum DMA_REGS_OFFSET { + REG_INT_FLAG = 0x0, + REG_INT_EN = 0x04, + REG_EN = 0x08, + REG_RST = 0x0c, + REG_CON = 0x18, + REG_TX_MEM_ADDR = 0x1c, + REG_RX_MEM_ADDR = 0x20, + REG_TX_LEN = 0x24, + REG_RX_LEN = 0x28, +}; + +static const uint mt_i2c_regs_v1[] = { + [REG_PORT] = 0x0, + [REG_SLAVE_ADDR] = 0x4, + [REG_INTR_MASK] = 0x8, + [REG_INTR_STAT] = 0xc, + [REG_CONTROL] = 0x10, + [REG_TRANSFER_LEN] = 0x14, + [REG_TRANSAC_LEN] = 0x18, + [REG_DELAY_LEN] = 0x1c, + [REG_TIMING] = 0x20, + [REG_START] = 0x24, + [REG_EXT_CONF] = 0x28, + [REG_FIFO_STAT1] = 0x2c, + [REG_FIFO_STAT] = 0x30, + [REG_FIFO_THRESH] = 0x34, + [REG_FIFO_ADDR_CLR] = 0x38, + [REG_IO_CONFIG] = 0x40, + [REG_RSV_DEBUG] = 0x44, + [REG_HS] = 0x48, + [REG_SOFTRESET] = 0x50, + [REG_SOFTRESET] = 0x50, + [REG_DCM_EN] = 0x54, + [REG_DEBUGSTAT] = 0x64, + [REG_DEBUGCTRL] = 0x68, + [REG_TRANSFER_LEN_AUX] = 0x6c, + [REG_CLOCK_DIV] = 0x70, + [REG_SCL_HL_RATIO] = 0x74, + [REG_SCL_HS_HL_RATIO] = 0x78, + [REG_SCL_MIS_COMP_POINT] = 0x7c, + [REG_STA_STOP_AC_TIME] = 0x80, + [REG_HS_STA_STOP_AC_TIME] = 0x84, + [REG_DATA_TIME] = 0x88, +}; + +static const uint mt_i2c_regs_v2[] = { + [REG_PORT] = 0x0, + [REG_SLAVE_ADDR] = 0x4, + [REG_INTR_MASK] = 0x8, + [REG_INTR_STAT] = 0xc, + [REG_CONTROL] = 0x10, + [REG_TRANSFER_LEN] = 0x14, + [REG_TRANSAC_LEN] = 0x18, + [REG_DELAY_LEN] = 0x1c, + [REG_TIMING] = 0x20, + [REG_START] = 0x24, + [REG_EXT_CONF] = 0x28, + [REG_LTIMING] = 0x2c, + [REG_HS] = 0x30, + [REG_IO_CONFIG] = 0x34, + [REG_FIFO_ADDR_CLR] = 0x38, + [REG_TRANSFER_LEN_AUX] = 0x44, + [REG_CLOCK_DIV] = 0x48, + [REG_SOFTRESET] = 0x50, + [REG_DEBUGSTAT] = 0xe0, + [REG_DEBUGCTRL] = 0xe8, + [REG_FIFO_STAT] = 0xf4, + [REG_FIFO_THRESH] = 0xf8, + [REG_DCM_EN] = 0xf88, +}; + +struct mtk_i2c_soc_data { + const uint *regs; + uint dma_sync: 1; +}; + +struct mtk_i2c_priv { + /* set in i2c probe */ + void __iomem *base; /* i2c base addr */ + void __iomem *pdmabase; /* dma base address*/ + struct clk clk_main; /* main clock for i2c bus */ + struct clk clk_dma; /* DMA clock for i2c via DMA */ + const struct mtk_i2c_soc_data *soc_data; /* Compatible data for different IC */ + int op; /* operation mode */ + bool zero_len; /* Only transfer slave address, no data */ + bool pushpull; /* push pull mode or open drain mode */ + bool filter_msg; /* filter msg error log */ + bool auto_restart; /* restart mode */ + bool ignore_restart_irq; /* ignore restart IRQ */ + uint speed; /* i2c speed, unit: hz */ +}; + +static inline void i2c_writel(struct mtk_i2c_priv *priv, uint reg, uint value) +{ + u32 offset = priv->soc_data->regs[reg]; + + writel(value, priv->base + offset); +} + +static inline uint i2c_readl(struct mtk_i2c_priv *priv, uint offset) +{ + return readl(priv->base + priv->soc_data->regs[offset]); +} + +static int mtk_i2c_clk_enable(struct mtk_i2c_priv *priv) +{ + int ret; + + ret = clk_enable(&priv->clk_main); + if (ret) + return log_msg_ret("enable clk_main", ret); + + ret = clk_enable(&priv->clk_dma); + if (ret) + return log_msg_ret("enable clk_dma", ret); + + return 0; +} + +static int mtk_i2c_clk_disable(struct mtk_i2c_priv *priv) +{ + int ret; + + ret = clk_disable(&priv->clk_dma); + if (ret) + return log_msg_ret("disable clk_dma", ret); + + ret = clk_disable(&priv->clk_main); + if (ret) + return log_msg_ret("disable clk_main", ret); + + return 0; +} + +static void mtk_i2c_init_hw(struct mtk_i2c_priv *priv) +{ + uint control_reg; + + writel(I2C_DMA_HARD_RST, priv->pdmabase + REG_RST); + writel(I2C_DMA_CLR_FLAG, priv->pdmabase + REG_RST); + i2c_writel(priv, REG_SOFTRESET, I2C_SOFT_RST); + /* set ioconfig */ + if (priv->pushpull) + i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_PUSH_PULL); + else + i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_OPEN_DRAIN); + + i2c_writel(priv, REG_DCM_EN, I2C_DCM_DISABLE); + control_reg = I2C_CONTROL_ACKERR_DET_EN | I2C_CONTROL_CLK_EXT_EN; + if (priv->soc_data->dma_sync) + control_reg |= I2C_CONTROL_DMAACK | I2C_CONTROL_ASYNC; + i2c_writel(priv, REG_CONTROL, control_reg); + i2c_writel(priv, REG_DELAY_LEN, I2C_DELAY_LEN); +} + +/* + * Calculate i2c port speed + * + * Hardware design: + * i2c_bus_freq = parent_clk / (clock_div * 2 * sample_cnt * step_cnt) + * clock_div: fixed in hardware, but may be various in different SoCs + * + * The calculation want to pick the highest bus frequency that is still + * less than or equal to target_speed. The calculation try to get + * sample_cnt and step_cn + * @param[in] + * clk_src: i2c clock source + * @param[out] + * timing_step_cnt: step cnt calculate result + * @param[out] + * timing_sample_cnt: sample cnt calculate result + * @return + * 0, set speed successfully. + * -EINVAL, Unsupported speed. + */ +static int mtk_i2c_calculate_speed(uint clk_src, + uint target_speed, + uint *timing_step_cnt, + uint *timing_sample_cnt) +{ + uint base_sample_cnt = MAX_SAMPLE_CNT_DIV; + uint base_step_cnt; + uint max_step_cnt; + uint sample_cnt; + uint step_cnt; + uint opt_div; + uint best_mul; + uint cnt_mul; + + if (target_speed > MAX_HS_MODE_SPEED) + target_speed = MAX_HS_MODE_SPEED; + + if (target_speed > MAX_FS_MODE_SPEED) + max_step_cnt = MAX_HS_STEP_CNT_DIV; + else + max_step_cnt = MAX_STEP_CNT_DIV; + + base_step_cnt = max_step_cnt; + /* Find the best combination */ + opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed); + best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt; + + /* + * Search for the best pair (sample_cnt, step_cnt) with + * 0 < sample_cnt < MAX_SAMPLE_CNT_DIV + * 0 < step_cnt < max_step_cnt + * sample_cnt * step_cnt >= opt_div + * optimizing for sample_cnt * step_cnt being minimal + */ + for (sample_cnt = 1; sample_cnt <= MAX_SAMPLE_CNT_DIV; sample_cnt++) { + step_cnt = DIV_ROUND_UP(opt_div, sample_cnt); + cnt_mul = step_cnt * sample_cnt; + if (step_cnt > max_step_cnt) + continue; + + if (cnt_mul < best_mul) { + best_mul = cnt_mul; + base_sample_cnt = sample_cnt; + base_step_cnt = step_cnt; + if (best_mul == opt_div) + break; + } + } + + sample_cnt = base_sample_cnt; + step_cnt = base_step_cnt; + + if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed) { + /* + * In this case, hardware can't support such + * low i2c_bus_freq + */ + debug("Unsupported speed(%uhz)\n", target_speed); + return log_msg_ret("calculate speed", -EINVAL); + } + + *timing_step_cnt = step_cnt - 1; + *timing_sample_cnt = sample_cnt - 1; + + return 0; +} + +/* + * mtk_i2c_set_speed + * + * @par Description + * Calculate i2c speed and write sample_cnt, step_cnt to TIMING register. + * @param[in] + * dev: udevice pointer, struct udevice contains i2c source clock, + * clock divide and speed. + * @return + * 0, set speed successfully.\n + * error code from mtk_i2c_calculate_speed(). + */ +static int mtk_i2c_set_speed(struct udevice *dev, uint speed) +{ + struct mtk_i2c_priv *priv = dev_get_priv(dev); + uint high_speed_reg; + uint sample_cnt; + uint timing_reg; + uint step_cnt; + uint clk_src; + int ret = 0; + + priv->speed = speed; + if (mtk_i2c_clk_enable(priv)) + return log_msg_ret("set_speed enable clk", -1); + + clk_src = clk_get_rate(&priv->clk_main) / I2C_DEFAULT_CLK_DIV; + i2c_writel(priv, REG_CLOCK_DIV, (I2C_DEFAULT_CLK_DIV - 1)); + if (priv->speed > MAX_FS_MODE_SPEED) { + /* Set master code speed register */ + ret = mtk_i2c_calculate_speed(clk_src, MAX_FS_MODE_SPEED, + &step_cnt, &sample_cnt); + if (ret < 0) + goto exit; + + timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt; + i2c_writel(priv, REG_TIMING, timing_reg); + /* Set the high speed mode register */ + ret = mtk_i2c_calculate_speed(clk_src, priv->speed, + &step_cnt, &sample_cnt); + if (ret < 0) + goto exit; + + high_speed_reg = I2C_TIME_DEFAULT_VALUE | + (sample_cnt << HS_SAMPLE_OFFSET) | + (step_cnt << HS_STEP_OFFSET); + i2c_writel(priv, REG_HS, high_speed_reg); + } else { + ret = mtk_i2c_calculate_speed(clk_src, priv->speed, + &step_cnt, &sample_cnt); + if (ret < 0) + goto exit; + + timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt; + /* Disable the high speed transaction */ + high_speed_reg = I2C_TIME_CLR_VALUE; + i2c_writel(priv, REG_TIMING, timing_reg); + i2c_writel(priv, REG_HS, high_speed_reg); + } +exit: + if (mtk_i2c_clk_disable(priv)) + return log_msg_ret("set_speed disable clk", -1); + + return ret; +} + +/* + * mtk_i2c_do_transfer + * + * @par Description + * Configure i2c register and trigger transfer. + * @param[in] + * priv: mtk_i2cmtk_i2c_priv pointer, struct mtk_i2c_priv contains register base\n + * address, operation mode, interrupt status and i2c driver data. + * @param[in] + * msgs: i2c_msg pointer, struct i2c_msg contains slave\n + * address, operation mode, msg length and data buffer. + * @param[in] + * num: i2c_msg number. + * @param[in] + * left_num: left i2c_msg number. + * @return + * 0, i2c transfer successfully.\n + * -ETIMEDOUT, i2c transfer timeout.\n + * -EREMOTEIO, i2c transfer ack error. + */ +static int mtk_i2c_do_transfer(struct mtk_i2c_priv *priv, + struct i2c_msg *msgs, + int num, int left_num) +{ + struct i2c_msg *msg_rx = NULL; + uint restart_flag = 0; + uint trans_error = 0; + uint irq_stat = 0; + uint tmo_poll = 0; + uint control_reg; + bool tmo = false; + uint start_reg; + uint addr_reg; + int ret = 0; + + if (priv->auto_restart) + restart_flag = I2C_RS_TRANSFER; + + control_reg = i2c_readl(priv, REG_CONTROL) & + ~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS); + + if (priv->speed > MAX_FS_MODE_SPEED || num > 1) + control_reg |= I2C_CONTROL_RS; + + if (priv->op == I2C_MASTER_WRRD) + control_reg |= I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS; + + control_reg |= I2C_CONTROL_DMA_EN; + i2c_writel(priv, REG_CONTROL, control_reg); + + /* set start condition */ + if (priv->speed <= MAX_ST_MODE_SPEED) + i2c_writel(priv, REG_EXT_CONF, I2C_ST_START_CON); + else + i2c_writel(priv, REG_EXT_CONF, I2C_FS_START_CON); + + addr_reg = msgs->addr << 1; + if (priv->op == I2C_MASTER_RD) + addr_reg |= I2C_M_RD; + if (priv->zero_len) + i2c_writel(priv, REG_SLAVE_ADDR, addr_reg | TRANS_ADDR_ONLY); + else + i2c_writel(priv, REG_SLAVE_ADDR, addr_reg); + + /* clear interrupt status */ + i2c_writel(priv, REG_INTR_STAT, restart_flag | I2C_HS_NACKERR | + I2C_ACKERR | I2C_TRANSAC_COMP); + i2c_writel(priv, REG_FIFO_ADDR_CLR, I2C_FIFO_ADDR_CLR); + + /* enable interrupt */ + i2c_writel(priv, REG_INTR_MASK, restart_flag | I2C_HS_NACKERR | + I2C_ACKERR | I2C_TRANSAC_COMP); + + /* set transfer and transaction len */ + if (priv->op == I2C_MASTER_WRRD) { + i2c_writel(priv, REG_TRANSFER_LEN, msgs->len); + i2c_writel(priv, REG_TRANSFER_LEN_AUX, (msgs + 1)->len); + i2c_writel(priv, REG_TRANSAC_LEN, I2C_WRRD_TRANAC_VALUE); + } else { + i2c_writel(priv, REG_TRANSFER_LEN, msgs->len); + i2c_writel(priv, REG_TRANSAC_LEN, num); + } + + /* Clear DMA interrupt flag */ + writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase + REG_INT_FLAG); + + /* Flush cache for first msg */ + flush_cache((ulong)msgs->buf, msgs->len); + + /* + * prepare buffer data to start transfer + * three cases here: read, write, write then read + */ + if (priv->op & I2C_MASTER_WR) { + /* Set DMA direction TX (w/ or w/o RX) */ + writel(I2C_DMA_CON_TX, priv->pdmabase + REG_CON); + + /* Write the tx buffer address to dma register */ + writel((ulong)msgs->buf, priv->pdmabase + REG_TX_MEM_ADDR); + /* Write the tx length to dma register */ + writel(msgs->len, priv->pdmabase + REG_TX_LEN); + + if (priv->op & I2C_MASTER_RD) { + /* write then read */ + msg_rx = msgs + 1; + + /* Flush cache for second msg */ + flush_cache((ulong)msg_rx->buf, msg_rx->len); + } + } + + if (priv->op & I2C_MASTER_RD) { + if (!msg_rx) { + /* Set DMA direction RX */ + writel(I2C_DMA_CON_RX, priv->pdmabase + REG_CON); + + msg_rx = msgs; + } + + /* Write the rx buffer address to dma register */ + writel((ulong)msg_rx->buf, priv->pdmabase + REG_RX_MEM_ADDR); + /* Write the rx length to dma register */ + writel(msg_rx->len, priv->pdmabase + REG_RX_LEN); + } + + writel(I2C_DMA_START_EN, priv->pdmabase + REG_EN); + + if (!priv->auto_restart) { + start_reg = I2C_TRANSAC_START; + } else { + start_reg = I2C_TRANSAC_START | I2C_RS_MUL_TRIG; + if (left_num >= 1) + start_reg |= I2C_RS_MUL_CNFG; + } + i2c_writel(priv, REG_START, start_reg); + + for (;;) { + irq_stat = i2c_readl(priv, REG_INTR_STAT); + + /* ignore the first restart irq after the master code */ + if (priv->ignore_restart_irq && (irq_stat & restart_flag)) { + priv->ignore_restart_irq = false; + irq_stat = 0; + i2c_writel(priv, REG_START, I2C_RS_MUL_CNFG | + I2C_RS_MUL_TRIG | I2C_TRANSAC_START); + } + + if (irq_stat & (I2C_TRANSAC_COMP | restart_flag)) { + tmo = false; + if (irq_stat & (I2C_HS_NACKERR | I2C_ACKERR)) + trans_error = 1; + + break; + } + udelay(1); + if (tmo_poll++ >= TRANSFER_TIMEOUT) { + tmo = true; + break; + } + } + + /* clear interrupt mask */ + i2c_writel(priv, REG_INTR_MASK, ~(restart_flag | I2C_HS_NACKERR | + I2C_ACKERR | I2C_TRANSAC_COMP)); + + if (!tmo && trans_error != 0) { + if (tmo) { + ret = -ETIMEDOUT; + if (!priv->filter_msg) + debug("I2C timeout! addr: 0x%x,\n", msgs->addr); + } else { + ret = -EREMOTEIO; + if (!priv->filter_msg) + debug("I2C ACKERR! addr: 0x%x,IRQ:0x%x\n", + msgs->addr, irq_stat); + } + mtk_i2c_init_hw(priv); + } + + return ret; +} + +/* + * mtk_i2c_transfer + * + * @par Description + * Common i2c transfer API. Set i2c transfer mode according to i2c_msg\n + * information, then call mtk_i2c_do_transfer() to configure i2c register\n + * and trigger transfer. + * @param[in] + * dev: udevice pointer, struct udevice contains struct mtk_i2c_priv, \n + * struct mtk_i2c_priv contains register base\n + * address, operation mode, interrupt status and i2c driver data. + * @param[in] + * msgs: i2c_msg pointer, struct i2c_msg contains slave\n + * address, operation mode, msg length and data buffer. + * @param[in] + * num: i2c_msg number. + * @return + * i2c_msg number, i2c transfer successfully.\n + * -EINVAL, msg length is more than 16\n + * use DMA MODE or slave address more than 0x7f.\n + * error code from mtk_i2c_init_base().\n + * error code from mtk_i2c_set_speed().\n + * error code from mtk_i2c_do_transfer(). + */ +static int mtk_i2c_transfer(struct udevice *dev, struct i2c_msg *msg, + int nmsgs) +{ + struct mtk_i2c_priv *priv = dev_get_priv(dev); + int left_num; + uint num_cnt; + int ret; + + priv->auto_restart = true; + left_num = nmsgs; + if (mtk_i2c_clk_enable(priv)) + return log_msg_ret("transfer enable clk", -1); + + for (num_cnt = 0; num_cnt < nmsgs; num_cnt++) { + if (((msg + num_cnt)->addr) > MAX_I2C_ADDR) { + ret = -EINVAL; + goto err_exit; + } + if ((msg + num_cnt)->len > MAX_I2C_LEN) { + ret = -EINVAL; + goto err_exit; + } + } + + /* check if we can skip restart and optimize using WRRD mode */ + if (priv->auto_restart && nmsgs == 2) { + if (!(msg[0].flags & I2C_M_RD) && (msg[1].flags & I2C_M_RD) && + msg[0].addr == msg[1].addr) { + priv->auto_restart = false; + } + } + + if (priv->auto_restart && nmsgs >= 2 && priv->speed > MAX_FS_MODE_SPEED) + /* ignore the first restart irq after the master code, + * otherwise the first transfer will be discarded. + */ + priv->ignore_restart_irq = true; + else + priv->ignore_restart_irq = false; + + while (left_num--) { + /* transfer slave address only to support devices detect */ + if (!msg->buf) + priv->zero_len = true; + else + priv->zero_len = false; + + if (msg->flags & I2C_M_RD) + priv->op = I2C_MASTER_RD; + else + priv->op = I2C_MASTER_WR; + + if (!priv->auto_restart) { + if (nmsgs > 1) { + /* combined two messages into one transaction */ + priv->op = I2C_MASTER_WRRD; + left_num--; + } + } + ret = mtk_i2c_do_transfer(priv, msg, nmsgs, left_num); + if (ret < 0) + goto err_exit; + msg++; + } + ret = 0; + +err_exit: + if (mtk_i2c_clk_disable(priv)) + return log_msg_ret("transfer disable clk", -1); + + return ret; +} + +static int mtk_i2c_of_to_plat(struct udevice *dev) +{ + struct mtk_i2c_priv *priv = dev_get_priv(dev); + int ret; + + priv->base = dev_remap_addr_index(dev, 0); + priv->pdmabase = dev_remap_addr_index(dev, 1); + ret = clk_get_by_index(dev, 0, &priv->clk_main); + if (ret) + return log_msg_ret("clk_get_by_index 0", ret); + + ret = clk_get_by_index(dev, 1, &priv->clk_dma); + + return ret; +} + +static int mtk_i2c_probe(struct udevice *dev) +{ + struct mtk_i2c_priv *priv = dev_get_priv(dev); + + priv->soc_data = (struct mtk_i2c_soc_data *)dev_get_driver_data(dev); + + if (mtk_i2c_clk_enable(priv)) + return log_msg_ret("probe enable clk", -1); + + mtk_i2c_init_hw(priv); + + if (mtk_i2c_clk_disable(priv)) + return log_msg_ret("probe disable clk", -1); + + return 0; +} + +static int mtk_i2c_deblock(struct udevice *dev) +{ + struct mtk_i2c_priv *priv = dev_get_priv(dev); + + if (mtk_i2c_clk_enable(priv)) + return log_msg_ret("deblock enable clk", -1); + + mtk_i2c_init_hw(priv); + + if (mtk_i2c_clk_disable(priv)) + return log_msg_ret("deblock disable clk", -1); + + return 0; +} + +static const struct mtk_i2c_soc_data mt76xx_soc_data = { + .regs = mt_i2c_regs_v1, + .dma_sync = 0, +}; + +static const struct mtk_i2c_soc_data mt7981_soc_data = { + .regs = mt_i2c_regs_v1, + .dma_sync = 1, +}; + +static const struct mtk_i2c_soc_data mt7986_soc_data = { + .regs = mt_i2c_regs_v1, + .dma_sync = 1, +}; + +static const struct mtk_i2c_soc_data mt8183_soc_data = { + .regs = mt_i2c_regs_v2, + .dma_sync = 1, +}; + +static const struct mtk_i2c_soc_data mt8518_soc_data = { + .regs = mt_i2c_regs_v1, + .dma_sync = 0, +}; + +static const struct mtk_i2c_soc_data mt8512_soc_data = { + .regs = mt_i2c_regs_v1, + .dma_sync = 1, +}; + +static const struct dm_i2c_ops mtk_i2c_ops = { + .xfer = mtk_i2c_transfer, + .set_bus_speed = mtk_i2c_set_speed, + .deblock = mtk_i2c_deblock, +}; + +static const struct udevice_id mtk_i2c_ids[] = { + { + .compatible = "mediatek,mt7622-i2c", + .data = (ulong)&mt76xx_soc_data, + }, { + .compatible = "mediatek,mt7623-i2c", + .data = (ulong)&mt76xx_soc_data, + }, { + .compatible = "mediatek,mt7629-i2c", + .data = (ulong)&mt76xx_soc_data, + }, { + .compatible = "mediatek,mt7981-i2c", + .data = (ulong)&mt7981_soc_data, + }, { + .compatible = "mediatek,mt7986-i2c", + .data = (ulong)&mt7986_soc_data, + }, { + .compatible = "mediatek,mt8183-i2c", + .data = (ulong)&mt8183_soc_data, + }, { + .compatible = "mediatek,mt8512-i2c", + .data = (ulong)&mt8512_soc_data, + }, { + .compatible = "mediatek,mt8518-i2c", + .data = (ulong)&mt8518_soc_data, + } +}; + +U_BOOT_DRIVER(mtk_i2c) = { + .name = "mtk_i2c", + .id = UCLASS_I2C, + .of_match = mtk_i2c_ids, + .of_to_plat = mtk_i2c_of_to_plat, + .probe = mtk_i2c_probe, + .priv_auto = sizeof(struct mtk_i2c_priv), + .ops = &mtk_i2c_ops, +}; diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index aa13af3ae1..f80ff5383b 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -199,7 +199,7 @@ static int wait_for_sr_state(struct mxc_i2c_bus *i2c_bus, unsigned state) } if ((sr & (state >> 8)) == (unsigned char)state) return sr; - WATCHDOG_RESET(); + schedule(); elapsed = get_timer(start_time); if (elapsed > (CONFIG_SYS_HZ / 10)) /* .1 seconds */ break; @@ -447,7 +447,7 @@ int i2c_idle_bus(struct mxc_i2c_bus *i2c_bus) sda = dm_gpio_get_value(sda_gpio); if ((sda & scl) == 1) break; - WATCHDOG_RESET(); + schedule(); elapsed = get_timer(start_time); if (elapsed > (CONFIG_SYS_HZ / 5)) { /* .2 seconds */ ret = -EBUSY; diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index acbdce11b7..47f24e0a02 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -54,7 +54,7 @@ config K3_SEC_PROXY config ZYNQMP_IPI bool "Xilinx ZynqMP IPI controller support" - depends on DM_MAILBOX && (ARCH_ZYNQMP || ARCH_VERSAL) + depends on DM_MAILBOX && (ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET) help This enables support for the Xilinx ZynqMP Inter Processor Interrupt communication controller. diff --git a/drivers/misc/usb251xb.c b/drivers/misc/usb251xb.c index 077edc2504..a78ad1843a 100644 --- a/drivers/misc/usb251xb.c +++ b/drivers/misc/usb251xb.c @@ -400,14 +400,14 @@ static int usb251xb_of_to_plat(struct udevice *dev) } } - if (dev_read_u32(dev, "vendor-id", &hub->vendor_id)) - hub->vendor_id = USB251XB_DEF_VENDOR_ID; + hub->vendor_id = dev_read_u16_default(dev, "vendor-id", + USB251XB_DEF_VENDOR_ID); - if (dev_read_u32(dev, "product-id", &hub->product_id)) - hub->product_id = data->product_id; + hub->product_id = dev_read_u16_default(dev, "product-id", + data->product_id); - if (dev_read_u32(dev, "device-id", &hub->device_id)) - hub->device_id = USB251XB_DEF_DEVICE_ID; + hub->device_id = dev_read_u16_default(dev, "device-id", + USB251XB_DEF_DEVICE_ID); hub->conf_data1 = USB251XB_DEF_CONFIG_DATA_1; if (dev_read_bool(dev, "self-powered")) { @@ -513,11 +513,11 @@ static int usb251xb_of_to_plat(struct udevice *dev) if (!dev_read_u32(dev, "power-on-time-ms", &property_u32)) hub->power_on_time = min_t(u8, property_u32 / 2, 255); - if (dev_read_u32(dev, "language-id", &hub->lang_id)) - hub->lang_id = USB251XB_DEF_LANGUAGE_ID; + hub->lang_id = dev_read_u16_default(dev, "language-id", + USB251XB_DEF_LANGUAGE_ID); - if (!dev_read_u32(dev, "boost-up", &hub->boost_up)) - hub->boost_up = USB251XB_DEF_BOOST_UP; + hub->boost_up = dev_read_u8_default(dev, "boost-up", + USB251XB_DEF_BOOST_UP); cproperty_char = dev_read_string(dev, "manufacturer"); strlcpy(str, cproperty_char ? : USB251XB_DEF_MANUFACTURER_STRING, diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 0dcec8adce..f799f70e43 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -3,7 +3,6 @@ menu "MMC Host controller Support" config MMC bool "MMC/SD/SDIO card support" default ARM || PPC || SANDBOX - select HAVE_BLOCK_DEVICE select DM_MMC if DM help This selects MultiMediaCard, Secure Digital and Secure diff --git a/drivers/mmc/atmel_sdhci.c b/drivers/mmc/atmel_sdhci.c index 2b5ceeab94..37b0beeed4 100644 --- a/drivers/mmc/atmel_sdhci.c +++ b/drivers/mmc/atmel_sdhci.c @@ -52,6 +52,17 @@ struct atmel_sdhci_plat { struct mmc mmc; }; +static int atmel_sdhci_deferred_probe(struct sdhci_host *host) +{ + struct udevice *dev = host->mmc->dev; + + return sdhci_probe(dev); +} + +static const struct sdhci_ops atmel_sdhci_ops = { + .deferred_probe = atmel_sdhci_deferred_probe, +}; + static int atmel_sdhci_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); @@ -104,6 +115,7 @@ static int atmel_sdhci_probe(struct udevice *dev) return ret; host->mmc->priv = host; + host->ops = &atmel_sdhci_ops; upriv->mmc = host->mmc; clk_free(&clk); diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 688bdc06d4..759a6b728c 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -290,7 +290,7 @@ struct mmc *find_mmc_device(int dev_num) struct udevice *dev, *mmc_dev; int ret; - ret = blk_find_device(IF_TYPE_MMC, dev_num, &dev); + ret = blk_find_device(UCLASS_MMC, dev_num, &dev); if (ret) { #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) @@ -308,12 +308,12 @@ struct mmc *find_mmc_device(int dev_num) int get_mmc_num(void) { - return max((blk_find_max_devnum(IF_TYPE_MMC) + 1), 0); + return max((blk_find_max_devnum(UCLASS_MMC) + 1), 0); } int mmc_get_next_devnum(void) { - return blk_find_max_devnum(IF_TYPE_MMC); + return blk_find_max_devnum(UCLASS_MMC); } int mmc_get_blk(struct udevice *dev, struct udevice **blkp) @@ -411,8 +411,8 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg) /* Use the fixed index with aliases node's index */ debug("%s: alias devnum=%d\n", __func__, dev_seq(dev)); - ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC, - dev_seq(dev), 512, 0, &bdev); + ret = blk_create_devicef(dev, "mmc_blk", "blk", UCLASS_MMC, + dev_seq(dev), 512, 0, &bdev); if (ret) { debug("Cannot create block device\n"); return ret; @@ -472,7 +472,7 @@ static int mmc_select_hwpart(struct udevice *bdev, int hwpart) ret = mmc_switch_part(mmc, hwpart); if (!ret) - blkcache_invalidate(desc->if_type, desc->devnum); + blkcache_invalidate(desc->uclass_id, desc->devnum); return ret; } diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c index a05da6c2e8..a101ee43fd 100644 --- a/drivers/mmc/mmc_legacy.c +++ b/drivers/mmc/mmc_legacy.c @@ -132,7 +132,7 @@ static struct mmc mmc_static = { .dsr_imp = 0, .dsr = 0xffffffff, .block_dev = { - .if_type = IF_TYPE_MMC, + .uclass_id = UCLASS_MMC, .removable = 1, .devnum = 0, .block_read = mmc_bread, @@ -194,7 +194,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) mmc->dsr = 0xffffffff; /* Setup the universal parts of the block interface just once */ bdesc = mmc_get_blk_desc(mmc); - bdesc->if_type = IF_TYPE_MMC; + bdesc->uclass_id = UCLASS_MMC; bdesc->removable = 1; bdesc->devnum = mmc_get_next_devnum(); bdesc->block_read = mmc_bread; @@ -253,8 +253,8 @@ static int mmc_get_dev(int dev, struct blk_desc **descp) } U_BOOT_LEGACY_BLK(mmc) = { - .if_typename = "mmc", - .if_type = IF_TYPE_MMC, + .uclass_idname = "mmc", + .uclass_id = UCLASS_MMC, .max_devs = -1, .get_dev = mmc_get_dev, .select_hwpart = mmc_select_hwpartp, diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c index eab94c7b60..5b7aeeb012 100644 --- a/drivers/mmc/mmc_write.c +++ b/drivers/mmc/mmc_write.c @@ -85,7 +85,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) if (!mmc) return -1; - err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num, + err = blk_select_hwpart_devnum(UCLASS_MMC, dev_num, block_dev->hwpart); if (err < 0) return -1; @@ -203,7 +203,7 @@ ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, if (!mmc) return 0; - err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num, block_dev->hwpart); + err = blk_select_hwpart_devnum(UCLASS_MMC, dev_num, block_dev->hwpart); if (err < 0) return 0; diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c index e61e8cf4b9..b206b0a085 100644 --- a/drivers/mmc/mtk-sd.c +++ b/drivers/mmc/mtk-sd.c @@ -1496,7 +1496,12 @@ static void msdc_init_hw(struct msdc_host *host) /* Enable data & cmd interrupts */ writel(DATA_INTS_MASK | CMD_INTS_MASK, &host->base->msdc_inten); - writel(0, tune_reg); + if (host->top_base) { + writel(0, &host->top_base->emmc_top_control); + writel(0, &host->top_base->emmc_top_cmd); + } else { + writel(0, tune_reg); + } writel(0, &host->base->msdc_iocon); if (host->r_smpl) @@ -1507,9 +1512,14 @@ static void msdc_init_hw(struct msdc_host *host) writel(0x403c0046, &host->base->patch_bit0); writel(0xffff4089, &host->base->patch_bit1); - if (host->dev_comp->stop_clk_fix) + if (host->dev_comp->stop_clk_fix) { clrsetbits_le32(&host->base->patch_bit1, MSDC_PB1_STOP_DLY_M, 3 << MSDC_PB1_STOP_DLY_S); + clrbits_le32(&host->base->sdc_fifo_cfg, + SDC_FIFO_CFG_WRVALIDSEL); + clrbits_le32(&host->base->sdc_fifo_cfg, + SDC_FIFO_CFG_RDVALIDSEL); + } if (host->dev_comp->busy_check) clrbits_le32(&host->base->patch_bit1, (1 << 7)); @@ -1544,15 +1554,28 @@ static void msdc_init_hw(struct msdc_host *host) } if (host->dev_comp->data_tune) { - setbits_le32(tune_reg, - MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL); - clrsetbits_le32(&host->base->patch_bit0, - MSDC_INT_DAT_LATCH_CK_SEL_M, - host->latch_ck << - MSDC_INT_DAT_LATCH_CK_SEL_S); + if (host->top_base) { + setbits_le32(&host->top_base->emmc_top_control, + PAD_DAT_RD_RXDLY_SEL); + clrbits_le32(&host->top_base->emmc_top_control, + DATA_K_VALUE_SEL); + setbits_le32(&host->top_base->emmc_top_cmd, + PAD_CMD_RD_RXDLY_SEL); + } else { + setbits_le32(tune_reg, + MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL); + clrsetbits_le32(&host->base->patch_bit0, + MSDC_INT_DAT_LATCH_CK_SEL_M, + host->latch_ck << + MSDC_INT_DAT_LATCH_CK_SEL_S); + } } else { /* choose clock tune */ - setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL); + if (host->top_base) + setbits_le32(&host->top_base->emmc_top_control, + PAD_RXDLY_SEL); + else + setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL); } if (host->dev_comp->builtin_pad_ctrl) { @@ -1604,12 +1627,6 @@ static void msdc_init_hw(struct msdc_host *host) clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC_M, 3 << SDC_CFG_DTOC_S); - if (host->dev_comp->stop_clk_fix) { - clrbits_le32(&host->base->sdc_fifo_cfg, - SDC_FIFO_CFG_WRVALIDSEL); - clrbits_le32(&host->base->sdc_fifo_cfg, - SDC_FIFO_CFG_RDVALIDSEL); - } host->def_tune_para.iocon = readl(&host->base->msdc_iocon); host->def_tune_para.pad_tune = readl(&host->base->pad_tune); @@ -1792,6 +1809,25 @@ static const struct msdc_compatible mt7623_compat = { .enhance_rx = false }; +static const struct msdc_compatible mt7986_compat = { + .clk_div_bits = 12, + .pad_tune0 = true, + .async_fifo = true, + .data_tune = true, + .busy_check = true, + .stop_clk_fix = true, + .enhance_rx = true, +}; + +static const struct msdc_compatible mt7981_compat = { + .clk_div_bits = 12, + .pad_tune0 = true, + .async_fifo = true, + .data_tune = true, + .busy_check = true, + .stop_clk_fix = true, +}; + static const struct msdc_compatible mt8512_compat = { .clk_div_bits = 12, .pad_tune0 = true, @@ -1824,6 +1860,8 @@ static const struct udevice_id msdc_ids[] = { { .compatible = "mediatek,mt7621-mmc", .data = (ulong)&mt7621_compat }, { .compatible = "mediatek,mt7622-mmc", .data = (ulong)&mt7622_compat }, { .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat }, + { .compatible = "mediatek,mt7986-mmc", .data = (ulong)&mt7986_compat }, + { .compatible = "mediatek,mt7981-mmc", .data = (ulong)&mt7981_compat }, { .compatible = "mediatek,mt8512-mmc", .data = (ulong)&mt8512_compat }, { .compatible = "mediatek,mt8516-mmc", .data = (ulong)&mt8516_compat }, { .compatible = "mediatek,mt8183-mmc", .data = (ulong)&mt8183_compat }, diff --git a/drivers/mmc/octeontx_hsmmc.c b/drivers/mmc/octeontx_hsmmc.c index 6e9acf7310..4ee62df9d4 100644 --- a/drivers/mmc/octeontx_hsmmc.c +++ b/drivers/mmc/octeontx_hsmmc.c @@ -1023,7 +1023,7 @@ static void octeontx_mmc_cleanup_dma(struct mmc *mmc, start = get_timer(0); do { rsp_sts.u = read_csr(mmc, MIO_EMM_RSP_STS()); - WATCHDOG_RESET(); + schedule(); } while (get_timer(start) < 100 && (rsp_sts.s.dma_val || rsp_sts.s.dma_pend)); } while (retries-- >= 0 && rsp_sts.s.dma_pend); @@ -1107,7 +1107,7 @@ static int octeontx_mmc_wait_dma(struct mmc *mmc, bool write, ulong timeout, } else if (!rsp_sts.s.dma_val && emm_dma_int.s.done) { break; } - WATCHDOG_RESET(); + schedule(); timed_out = (get_timer(start_time) > timeout); } while (!timed_out); @@ -1219,7 +1219,7 @@ static int octeontx_mmc_read_blocks(struct mmc *mmc, struct mmc_cmd *cmd, } return blkcnt - count; } - WATCHDOG_RESET(); + schedule(); } while (--count); } #ifdef DEBUG @@ -1253,7 +1253,7 @@ static int octeontx_mmc_poll_ready(struct mmc *mmc, ulong timeout) } else if (cmd.response[0] & R1_READY_FOR_DATA) { return 0; } - WATCHDOG_RESET(); + schedule(); } while (get_timer(start) < timeout); if (not_ready) @@ -1328,7 +1328,7 @@ static ulong octeontx_mmc_write_blocks(struct mmc *mmc, struct mmc_cmd *cmd, read_csr(mmc, MIO_EMM_DMA())); return blkcnt - count; } - WATCHDOG_RESET(); + schedule(); } while (--count); } @@ -1491,7 +1491,7 @@ static int octeontx_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, start = get_timer(0); do { rsp_sts.u = read_csr(mmc, MIO_EMM_RSP_STS()); - WATCHDOG_RESET(); + schedule(); } while (!rsp_sts.s.cmd_done && !rsp_sts.s.rsp_timeout && (get_timer(start) < timeout + 10)); octeontx_mmc_print_rsp_errors(mmc, rsp_sts); diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 830e29cdd4..76dc1c68b8 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -242,7 +242,7 @@ static int sh_mmcif_multi_read(struct sh_mmcif_host *host, for (i = 0; i < blocksize / 4; i++) *p++ = sh_mmcif_read(&host->regs->ce_data); - WATCHDOG_RESET(); + schedule(); } return 0; } @@ -309,7 +309,7 @@ static int sh_mmcif_multi_write(struct sh_mmcif_host *host, for (i = 0; i < blocksize / 4; i++) sh_mmcif_write(*p++, &host->regs->ce_data); - WATCHDOG_RESET(); + schedule(); } return 0; } @@ -523,7 +523,7 @@ static int sh_mmcif_send_cmd_common(struct sh_mmcif_host *host, { int ret; - WATCHDOG_RESET(); + schedule(); switch (cmd->cmdidx) { case MMC_CMD_APP_CMD: diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c index bfce8a2e4a..7ab4d949e7 100644 --- a/drivers/mmc/stm32_sdmmc2.c +++ b/drivers/mmc/stm32_sdmmc2.c @@ -445,7 +445,7 @@ static int stm32_sdmmc2_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, u32 cmdat = data ? SDMMC_CMD_CMDTRANS : 0; int ret, retry = 3; - WATCHDOG_RESET(); + schedule(); retry_cmd: ctx.data_length = 0; diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 4950410706..d34d8ee976 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -584,7 +584,7 @@ static int flash_status_check(flash_info_t *info, flash_sect_t sector, reset_timer(); #endif start = get_timer(0); - WATCHDOG_RESET(); + schedule(); while (flash_is_busy(info, sector)) { if (get_timer(start) > tout) { printf("Flash %s timeout at address %lx data %lx\n", @@ -677,7 +677,7 @@ static int flash_status_poll(flash_info_t *info, void *src, void *dst, reset_timer(); #endif start = get_timer(0); - WATCHDOG_RESET(); + schedule(); while (1) { switch (info->portwidth) { case FLASH_CFI_8BIT: diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 56aa58b58b..4886392a1c 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -895,7 +895,7 @@ int add_mtd_partitions_of(struct mtd_info *master) else parts = ofnode_find_subnode(master->flash_node, "partitions"); - if (!ofnode_valid(parts) || !ofnode_is_available(parts) || + if (!ofnode_valid(parts) || !ofnode_is_enabled(parts) || !ofnode_device_is_compatible(parts, "fixed-partitions")) return 0; @@ -905,7 +905,7 @@ int add_mtd_partitions_of(struct mtd_info *master) fdt_addr_t offset; fdt_size_t size; - if (!ofnode_is_available(child)) + if (!ofnode_is_enabled(child)) continue; offset = ofnode_get_addr_size_index_notrans(child, 0, &size); diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c index 090834a495..99c29670c7 100644 --- a/drivers/mtd/nand/core.c +++ b/drivers/mtd/nand/core.c @@ -173,7 +173,7 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo) nanddev_offs_to_pos(nand, einfo->addr, &pos); nanddev_offs_to_pos(nand, einfo->addr + einfo->len - 1, &last); while (nanddev_pos_cmp(&pos, &last) <= 0) { - WATCHDOG_RESET(); + schedule(); ret = nanddev_erase(nand, &pos); if (ret) { einfo->fail_addr = nanddev_pos_to_offs(nand, &pos); diff --git a/drivers/mtd/nand/raw/atmel_nand.c b/drivers/mtd/nand/raw/atmel_nand.c index 06bf5ac18f..61bfd175be 100644 --- a/drivers/mtd/nand/raw/atmel_nand.c +++ b/drivers/mtd/nand/raw/atmel_nand.c @@ -420,7 +420,7 @@ static int pmecc_err_location(struct mtd_info *mtd) while (--timeout) { if (pmecc_readl(host->pmerrloc, elisr) & PMERRLOC_CALC_DONE) break; - WATCHDOG_RESET(); + schedule(); udelay(1); } @@ -558,7 +558,7 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, while (--timeout) { if (!(pmecc_readl(host->pmecc, sr) & PMECC_SR_BUSY)) break; - WATCHDOG_RESET(); + schedule(); udelay(1); } @@ -598,7 +598,7 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, while (--timeout) { if (!(pmecc_readl(host->pmecc, sr) & PMECC_SR_BUSY)) break; - WATCHDOG_RESET(); + schedule(); udelay(1); } diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c index 48a3687f27..4f0acd7c89 100644 --- a/drivers/mtd/nand/raw/fsl_elbc_nand.c +++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c @@ -732,7 +732,6 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr, struct udevice *dev) nand->bbt_md = &bbt_mirror_descr; /* set up nand options */ - nand->options = NAND_NO_SUBPAGE_WRITE; nand->bbt_options = NAND_BBT_USE_FLASH; nand->controller = &elbc_ctrl->controller; @@ -839,7 +838,7 @@ void board_nand_init(void) static int fsl_elbc_nand_probe(struct udevice *dev) { - return fsl_elbc_chip_init(0, (void *)dev_read_addr(dev), dev); + return fsl_elbc_chip_init(0, dev_read_addr_ptr(dev), dev); } static const struct udevice_id fsl_elbc_nand_dt_ids[] = { diff --git a/drivers/mtd/nand/raw/mt7621_nand.c b/drivers/mtd/nand/raw/mt7621_nand.c index 9763ae6dc5..f6eddb84a9 100644 --- a/drivers/mtd/nand/raw/mt7621_nand.c +++ b/drivers/mtd/nand/raw/mt7621_nand.c @@ -1184,13 +1184,12 @@ int mt7621_nfc_spl_post_init(struct mt7621_nfc *nfc) { struct nand_chip *nand = &nfc->nand; int nand_maf_id, nand_dev_id; - struct nand_flash_dev *type; + int ret; - type = nand_get_flash_type(nand, &nand_maf_id, - &nand_dev_id, NULL); + ret = nand_detect(nand, &nand_maf_id, &nand_dev_id, NULL); - if (IS_ERR(type)) - return PTR_ERR(type); + if (ret) + return ret; nand->numchips = 1; nand->mtd.size = nand->chipsize; diff --git a/drivers/mtd/nand/raw/mxs_nand_spl.c b/drivers/mtd/nand/raw/mxs_nand_spl.c index 3daacbb330..ef03b7789d 100644 --- a/drivers/mtd/nand/raw/mxs_nand_spl.c +++ b/drivers/mtd/nand/raw/mxs_nand_spl.c @@ -81,13 +81,13 @@ static int mxs_flash_full_ident(struct mtd_info *mtd) { int nand_maf_id, nand_dev_id; struct nand_chip *chip = mtd_to_nand(mtd); - struct nand_flash_dev *type; + int ret; - type = nand_get_flash_type(mtd, chip, &nand_maf_id, &nand_dev_id, NULL); + ret = nand_detect(chip, &nand_maf_id, &nand_dev_id, NULL); - if (IS_ERR(type)) { + if (ret) { chip->select_chip(mtd, -1); - return PTR_ERR(type); + return ret; } return 0; diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 4b09a11288..215b9ba84f 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -595,7 +595,7 @@ static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo) if (status & NAND_STATUS_READY) break; - WATCHDOG_RESET(); + schedule(); } }; @@ -2342,7 +2342,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, while (1) { unsigned int ecc_failures = mtd->ecc_stats.failed; - WATCHDOG_RESET(); + schedule(); bytes = min(mtd->writesize - col, readlen); aligned = (bytes == mtd->writesize); @@ -2695,7 +2695,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, page = realpage & chip->pagemask; while (1) { - WATCHDOG_RESET(); + schedule(); if (ops->mode == MTD_OPS_RAW) ret = chip->ecc.read_oob_raw(mtd, chip, page); @@ -3263,7 +3263,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, else use_bufpoi = 0; - WATCHDOG_RESET(); + schedule(); /* Partial page write?, or need to use bounce buffer */ if (use_bufpoi) { pr_debug("%s: using write bounce buffer for buf@%p\n", @@ -3556,7 +3556,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, instr->state = MTD_ERASING; while (len) { - WATCHDOG_RESET(); + schedule(); /* Check if we have a bad block, we do not erase bad blocks! */ if (!instr->scrub && nand_block_checkbad(mtd, ((loff_t) page) << @@ -4261,7 +4261,7 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip, * Returns a nand_manufacturer_desc object if the manufacturer is defined * in the NAND manufacturers database, NULL otherwise. */ -static const struct nand_manufacturers *nand_get_manufacturer_desc(u8 id) +static const struct nand_manufacturer *nand_get_manufacturer_desc(u8 id) { int i; @@ -4276,12 +4276,11 @@ static const struct nand_manufacturers *nand_get_manufacturer_desc(u8 id) /* * Get the flash and manufacturer id and lookup if the type is supported. */ -struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, - int *dev_id, - struct nand_flash_dev *type) +int nand_detect(struct nand_chip *chip, int *maf_id, + int *dev_id, struct nand_flash_dev *type) { struct mtd_info *mtd = &chip->mtd; - const struct nand_manufacturers *manufacturer_desc; + const struct nand_manufacturer *manufacturer_desc; int busw, ret; u8 *id_data = chip->id.data; @@ -4291,7 +4290,7 @@ struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, */ ret = nand_reset(chip, 0); if (ret) - return ERR_PTR(ret); + return ret; /* Select the device */ chip->select_chip(mtd, 0); @@ -4299,7 +4298,7 @@ struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, /* Send the command for reading device ID */ ret = nand_readid_op(chip, 0, id_data, 2); if (ret) - return ERR_PTR(ret); + return ret; /* Read manufacturer and device IDs */ *maf_id = id_data[0]; @@ -4315,12 +4314,12 @@ struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, /* Read entire ID string */ ret = nand_readid_op(chip, 0, id_data, 8); if (ret) - return ERR_PTR(ret); + return ret; if (id_data[0] != *maf_id || id_data[1] != *dev_id) { pr_info("second ID read did not match %02x,%02x against %02x,%02x\n", *maf_id, *dev_id, id_data[0], id_data[1]); - return ERR_PTR(-ENODEV); + return -ENODEV; } chip->id.len = nand_id_len(id_data, ARRAY_SIZE(chip->id.data)); @@ -4368,7 +4367,7 @@ struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, } if (!type->name) - return ERR_PTR(-ENODEV); + return -ENODEV; if (!mtd->name) mtd->name = type->name; @@ -4401,7 +4400,7 @@ ident_done: pr_warn("bus width %d instead %d bit\n", (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, busw ? 16 : 8); - return ERR_PTR(-EINVAL); + return -EINVAL; } nand_decode_bbm_options(mtd, chip); @@ -4432,7 +4431,7 @@ ident_done: ret = nand_manufacturer_init(chip); if (ret) - return ERR_PTR(ret); + return ret; pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n", *maf_id, *dev_id); @@ -4460,9 +4459,9 @@ ident_done: pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); - return type; + return 0; } -EXPORT_SYMBOL(nand_get_flash_type); +EXPORT_SYMBOL(nand_detect); #if CONFIG_IS_ENABLED(OF_CONTROL) @@ -4547,7 +4546,6 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, { int i, nand_maf_id, nand_dev_id; struct nand_chip *chip = mtd_to_nand(mtd); - struct nand_flash_dev *type; int ret; if (ofnode_valid(chip->flash_node)) { @@ -4560,14 +4558,13 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); /* Read the flash type */ - type = nand_get_flash_type(chip, &nand_maf_id, - &nand_dev_id, table); + ret = nand_detect(chip, &nand_maf_id, &nand_dev_id, table); - if (IS_ERR(type)) { + if (ret) { if (!(chip->options & NAND_SCAN_SILENT_NODEV)) pr_warn("No NAND device found\n"); chip->select_chip(mtd, -1); - return PTR_ERR(type); + return ret; } /* Initialize the ->data_interface field. */ @@ -4593,7 +4590,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, for (i = 1; i < maxchips; i++) { u8 id[2]; - /* See comment in nand_get_flash_type for reset */ + /* See comment in nand_detect for reset */ nand_reset(chip, i); chip->select_chip(mtd, i); diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index 4dece1b206..d0cfacc69b 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -177,7 +177,7 @@ struct nand_flash_dev nand_flash_ids[] = { }; /* Manufacturer IDs */ -struct nand_manufacturers nand_manuf_ids[] = { +struct nand_manufacturer nand_manuf_ids[] = { {NAND_MFR_TOSHIBA, "Toshiba", &toshiba_nand_manuf_ops}, {NAND_MFR_SAMSUNG, "Samsung", &samsung_nand_manuf_ops}, {NAND_MFR_FUJITSU, "Fujitsu"}, diff --git a/drivers/mtd/nand/raw/nand_samsung.c b/drivers/mtd/nand/raw/nand_samsung.c index 0ab8062193..36ef48e5ec 100644 --- a/drivers/mtd/nand/raw/nand_samsung.c +++ b/drivers/mtd/nand/raw/nand_samsung.c @@ -64,6 +64,26 @@ static void samsung_nand_decode_id(struct nand_chip *chip) extid >>= 2; mtd->erasesize = (128 * 1024) << (((extid >> 1) & 0x04) | (extid & 0x03)); + + /* Extract ECC requirements from 5th id byte*/ + extid = (chip->id.data[4] >> 4) & 0x07; + if (extid < 5) { + chip->ecc_step_ds = 512; + chip->ecc_strength_ds = 1 << extid; + } else { + chip->ecc_step_ds = 1024; + switch (extid) { + case 5: + chip->ecc_strength_ds = 24; + break; + case 6: + chip->ecc_strength_ds = 40; + break; + case 7: + chip->ecc_strength_ds = 60; + break; + } + } } else { nand_decode_ext_id(chip); } diff --git a/drivers/mtd/nand/raw/nand_util.c b/drivers/mtd/nand/raw/nand_util.c index 5150607d8a..b2345dca7f 100644 --- a/drivers/mtd/nand/raw/nand_util.c +++ b/drivers/mtd/nand/raw/nand_util.c @@ -103,7 +103,7 @@ int nand_erase_opts(struct mtd_info *mtd, erased_length < erase_length; erase.addr += mtd->erasesize) { - WATCHDOG_RESET(); + schedule(); if (opts->lim && (erase.addr >= (opts->offset + opts->lim))) { puts("Size of erase exceeds limit\n"); @@ -638,7 +638,7 @@ int nand_write_skip_bad(struct mtd_info *mtd, loff_t offset, size_t *length, size_t block_offset = offset & (mtd->erasesize - 1); size_t write_size, truncated_write_size; - WATCHDOG_RESET(); + schedule(); if (nand_block_isbad(mtd, block_start)) { printf("Skip bad block 0x%08llx\n", block_start); @@ -753,7 +753,7 @@ int nand_read_skip_bad(struct mtd_info *mtd, loff_t offset, size_t *length, size_t block_offset = offset & (mtd->erasesize - 1); size_t read_length; - WATCHDOG_RESET(); + schedule(); if (nand_block_isbad(mtd, offset & ~(mtd->erasesize - 1))) { printf("Skipping bad block 0x%08llx\n", diff --git a/drivers/mtd/nand/raw/zynq_nand.c b/drivers/mtd/nand/raw/zynq_nand.c index 10e9cd18b0..14cb2ba704 100644 --- a/drivers/mtd/nand/raw/zynq_nand.c +++ b/drivers/mtd/nand/raw/zynq_nand.c @@ -1095,7 +1095,7 @@ static int zynq_nand_probe(struct udevice *dev) } } - if (!ofnode_is_available(of_nand)) { + if (!ofnode_is_enabled(of_nand)) { debug("Nand node in dt disabled\n"); return dm_scan_fdt_dev(dev); } diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index e5330958c7..134bf22c80 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -579,7 +579,7 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from, #endif nanddev_io_for_each_page(nand, from, ops, &iter) { - WATCHDOG_RESET(); + schedule(); ret = spinand_select_target(spinand, iter.req.pos.target); if (ret) break; @@ -631,7 +631,7 @@ static int spinand_mtd_write(struct mtd_info *mtd, loff_t to, #endif nanddev_io_for_each_page(nand, to, ops, &iter) { - WATCHDOG_RESET(); + schedule(); ret = spinand_select_target(spinand, iter.req.pos.target); if (ret) break; diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index f94597c061..08fe7d427a 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -478,7 +478,7 @@ static int onenand_wait(struct mtd_info *mtd, int state) u32 timeo = (CONFIG_SYS_HZ * 20) / 1000; u32 time_start = get_timer(0); do { - WATCHDOG_RESET(); + schedule(); if (get_timer(time_start) > timeo) return -EIO; interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); @@ -1170,7 +1170,7 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state) u32 timeo = (CONFIG_SYS_HZ * 20) / 1000; u32 time_start = get_timer(0); do { - WATCHDOG_RESET(); + schedule(); if (get_timer(time_start) > timeo) return ONENAND_BBT_READ_FATAL_ERROR; interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index f461082e03..e192f97efd 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -10,13 +10,69 @@ #include #include #include +#include #include #include #include #include +#include #include "sf_internal.h" +static int spi_nor_create_read_dirmap(struct spi_nor *nor) +{ + struct spi_mem_dirmap_info info = { + .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0), + SPI_MEM_OP_ADDR(nor->addr_width, 0, 0), + SPI_MEM_OP_DUMMY(nor->read_dummy, 0), + SPI_MEM_OP_DATA_IN(0, NULL, 0)), + .offset = 0, + .length = nor->mtd.size, + }; + struct spi_mem_op *op = &info.op_tmpl; + + /* get transfer protocols. */ + spi_nor_setup_op(nor, op, nor->read_proto); + op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto); + + /* convert the dummy cycles to the number of bytes */ + op->dummy.nbytes = (nor->read_dummy * op->dummy.buswidth) / 8; + if (spi_nor_protocol_is_dtr(nor->read_proto)) + op->dummy.nbytes *= 2; + + nor->dirmap.rdesc = spi_mem_dirmap_create(nor->spi, &info); + if (IS_ERR(nor->dirmap.rdesc)) + return PTR_ERR(nor->dirmap.rdesc); + + return 0; +} + +static int spi_nor_create_write_dirmap(struct spi_nor *nor) +{ + struct spi_mem_dirmap_info info = { + .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0), + SPI_MEM_OP_ADDR(nor->addr_width, 0, 0), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_OUT(0, NULL, 0)), + .offset = 0, + .length = nor->mtd.size, + }; + struct spi_mem_op *op = &info.op_tmpl; + + /* get transfer protocols. */ + spi_nor_setup_op(nor, op, nor->write_proto); + op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto); + + if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second) + op->addr.nbytes = 0; + + nor->dirmap.wdesc = spi_mem_dirmap_create(nor->spi, &info); + if (IS_ERR(nor->dirmap.wdesc)) + return PTR_ERR(nor->dirmap.wdesc); + + return 0; +} + /** * spi_flash_probe_slave() - Probe for a SPI flash device on a bus * @@ -45,6 +101,16 @@ static int spi_flash_probe_slave(struct spi_flash *flash) if (ret) goto err_read_id; + if (CONFIG_IS_ENABLED(SPI_DIRMAP)) { + ret = spi_nor_create_read_dirmap(flash); + if (ret) + return ret; + + ret = spi_nor_create_write_dirmap(flash); + if (ret) + return ret; + } + if (CONFIG_IS_ENABLED(SPI_FLASH_MTD)) ret = spi_flash_mtd_register(flash); @@ -83,6 +149,11 @@ struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs, void spi_flash_free(struct spi_flash *flash) { + if (CONFIG_IS_ENABLED(SPI_DIRMAP)) { + spi_mem_dirmap_destroy(flash->dirmap.wdesc); + spi_mem_dirmap_destroy(flash->dirmap.rdesc); + } + if (CONFIG_IS_ENABLED(SPI_FLASH_MTD)) spi_flash_mtd_unregister(flash); @@ -153,6 +224,11 @@ static int spi_flash_std_remove(struct udevice *dev) struct spi_flash *flash = dev_get_uclass_priv(dev); int ret; + if (CONFIG_IS_ENABLED(SPI_DIRMAP)) { + spi_mem_dirmap_destroy(flash->dirmap.wdesc); + spi_mem_dirmap_destroy(flash->dirmap.rdesc); + } + ret = spi_nor_remove(flash); if (ret) return ret; diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index e3c86e080a..c73636d7d1 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -246,9 +246,9 @@ static u8 spi_nor_get_cmd_ext(const struct spi_nor *nor, * need to be initialized. * @proto: the protocol from which the properties need to be set. */ -static void spi_nor_setup_op(const struct spi_nor *nor, - struct spi_mem_op *op, - const enum spi_nor_protocol proto) +void spi_nor_setup_op(const struct spi_nor *nor, + struct spi_mem_op *op, + const enum spi_nor_protocol proto) { u8 ext; @@ -369,13 +369,29 @@ static ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len, while (remaining) { op.data.nbytes = remaining < UINT_MAX ? remaining : UINT_MAX; - ret = spi_mem_adjust_op_size(nor->spi, &op); - if (ret) - return ret; - ret = spi_mem_exec_op(nor->spi, &op); - if (ret) - return ret; + if (CONFIG_IS_ENABLED(SPI_DIRMAP) && nor->dirmap.rdesc) { + /* + * Record current operation information which may be used + * when the address or data length exceeds address mapping. + */ + memcpy(&nor->dirmap.rdesc->info.op_tmpl, &op, + sizeof(struct spi_mem_op)); + ret = spi_mem_dirmap_read(nor->dirmap.rdesc, + op.addr.val, op.data.nbytes, + op.data.buf.in); + if (ret < 0) + return ret; + op.data.nbytes = ret; + } else { + ret = spi_mem_adjust_op_size(nor->spi, &op); + if (ret) + return ret; + + ret = spi_mem_exec_op(nor->spi, &op); + if (ret) + return ret; + } op.addr.val += op.data.nbytes; remaining -= op.data.nbytes; @@ -400,14 +416,21 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len, spi_nor_setup_op(nor, &op, nor->write_proto); - ret = spi_mem_adjust_op_size(nor->spi, &op); - if (ret) - return ret; - op.data.nbytes = len < op.data.nbytes ? len : op.data.nbytes; + if (CONFIG_IS_ENABLED(SPI_DIRMAP) && nor->dirmap.wdesc) { + memcpy(&nor->dirmap.wdesc->info.op_tmpl, &op, + sizeof(struct spi_mem_op)); + op.data.nbytes = spi_mem_dirmap_write(nor->dirmap.wdesc, op.addr.val, + op.data.nbytes, op.data.buf.out); + } else { + ret = spi_mem_adjust_op_size(nor->spi, &op); + if (ret) + return ret; + op.data.nbytes = len < op.data.nbytes ? len : op.data.nbytes; - ret = spi_mem_exec_op(nor->spi, &op); - if (ret) - return ret; + ret = spi_mem_exec_op(nor->spi, &op); + if (ret) + return ret; + } return op.data.nbytes; } @@ -935,7 +958,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) addr_known = true; while (len) { - WATCHDOG_RESET(); + schedule(); if (!IS_ENABLED(CONFIG_SPL_BUILD) && ctrlc()) { addr_known = false; ret = -EINTR; @@ -1698,7 +1721,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, for (i = 0; i < len; ) { ssize_t written; loff_t addr = to + i; - WATCHDOG_RESET(); + schedule(); /* * If page_size is a power of two, the offset can be quickly diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c index 4fe8b0d92c..65eb35a918 100644 --- a/drivers/mtd/spi/spi-nor-ids.c +++ b/drivers/mtd/spi/spi-nor-ids.c @@ -424,6 +424,11 @@ const struct flash_info spi_nor_ids[] = { SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, + { + INFO("w25q512jvq", 0xef4020, 0, 64 * 1024, 1024, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, { INFO("w25q01jv", 0xef4021, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 8bc2b46d40..bbc4434ddb 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -1078,7 +1078,7 @@ static int device_get_phy_addr(struct fec_priv *priv, struct udevice *dev) return ret; } - if (!ofnode_is_available(phandle_args.node)) + if (!ofnode_is_enabled(phandle_args.node)) return -ENOENT; priv->phy_of_node = phandle_args.node; diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c index 835e5bd8bd..1fd5089cc4 100644 --- a/drivers/net/fsl_enetc.c +++ b/drivers/net/fsl_enetc.c @@ -146,7 +146,7 @@ static int enetc_init_sgmii(struct udevice *dev) if (!enetc_has_imdio(dev)) return 0; - if (priv->if_type == PHY_INTERFACE_MODE_2500BASEX) + if (priv->uclass_id == PHY_INTERFACE_MODE_2500BASEX) is2500 = true; /* @@ -221,7 +221,7 @@ static void enetc_setup_mac_iface(struct udevice *dev, struct enetc_priv *priv = dev_get_priv(dev); u32 if_mode; - switch (priv->if_type) { + switch (priv->uclass_id) { case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII_RXID: @@ -278,14 +278,14 @@ static void enetc_start_pcs(struct udevice *dev) return; } - priv->if_type = dev_read_phy_mode(dev); - if (priv->if_type == PHY_INTERFACE_MODE_NA) { + priv->uclass_id = dev_read_phy_mode(dev); + if (priv->uclass_id == PHY_INTERFACE_MODE_NA) { enetc_dbg(dev, "phy-mode property not found, defaulting to SGMII\n"); - priv->if_type = PHY_INTERFACE_MODE_SGMII; + priv->uclass_id = PHY_INTERFACE_MODE_SGMII; } - switch (priv->if_type) { + switch (priv->uclass_id) { case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_2500BASEX: enetc_init_sgmii(dev); @@ -323,7 +323,7 @@ static int enetc_probe(struct udevice *dev) struct enetc_priv *priv = dev_get_priv(dev); int res; - if (ofnode_valid(dev_ofnode(dev)) && !ofnode_is_available(dev_ofnode(dev))) { + if (ofnode_valid(dev_ofnode(dev)) && !ofnode_is_enabled(dev_ofnode(dev))) { enetc_dbg(dev, "interface disabled\n"); return -ENODEV; } diff --git a/drivers/net/fsl_enetc.h b/drivers/net/fsl_enetc.h index 69f2f4aaff..f2acf367aa 100644 --- a/drivers/net/fsl_enetc.h +++ b/drivers/net/fsl_enetc.h @@ -158,7 +158,7 @@ struct enetc_priv { struct bd_ring tx_bdr; struct bd_ring rx_bdr; - int if_type; + int uclass_id; struct mii_dev imdio; struct phy_device *phy; }; diff --git a/drivers/net/mscc_eswitch/felix_switch.c b/drivers/net/mscc_eswitch/felix_switch.c index 709c9e3ef5..2e5f45e574 100644 --- a/drivers/net/mscc_eswitch/felix_switch.c +++ b/drivers/net/mscc_eswitch/felix_switch.c @@ -287,7 +287,7 @@ static int felix_probe(struct udevice *dev) int err; if (ofnode_valid(dev_ofnode(dev)) && - !ofnode_is_available(dev_ofnode(dev))) { + !ofnode_is_enabled(dev_ofnode(dev))) { dev_dbg(dev, "switch disabled\n"); return -ENODEV; } diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c index 4fe7ee0d36..4c9fb266c7 100644 --- a/drivers/net/mtk_eth.c +++ b/drivers/net/mtk_eth.c @@ -65,95 +65,34 @@ (DP_DISCARD << MC_DP_S) | \ (DP_DISCARD << UN_DP_S)) -struct pdma_rxd_info1 { - u32 PDP0; -}; - -struct pdma_rxd_info2 { - u32 PLEN1 : 14; - u32 LS1 : 1; - u32 UN_USED : 1; - u32 PLEN0 : 14; - u32 LS0 : 1; - u32 DDONE : 1; -}; - -struct pdma_rxd_info3 { - u32 PDP1; -}; - -struct pdma_rxd_info4 { - u32 FOE_ENTRY : 14; - u32 CRSN : 5; - u32 SP : 3; - u32 L4F : 1; - u32 L4VLD : 1; - u32 TACK : 1; - u32 IP4F : 1; - u32 IP4 : 1; - u32 IP6 : 1; - u32 UN_USED : 4; -}; - -struct pdma_rxdesc { - struct pdma_rxd_info1 rxd_info1; - struct pdma_rxd_info2 rxd_info2; - struct pdma_rxd_info3 rxd_info3; - struct pdma_rxd_info4 rxd_info4; -}; - -struct pdma_txd_info1 { - u32 SDP0; -}; - -struct pdma_txd_info2 { - u32 SDL1 : 14; - u32 LS1 : 1; - u32 BURST : 1; - u32 SDL0 : 14; - u32 LS0 : 1; - u32 DDONE : 1; -}; - -struct pdma_txd_info3 { - u32 SDP1; -}; - -struct pdma_txd_info4 { - u32 VLAN_TAG : 16; - u32 INS : 1; - u32 RESV : 2; - u32 UDF : 6; - u32 FPORT : 3; - u32 TSO : 1; - u32 TUI_CO : 3; -}; - -struct pdma_txdesc { - struct pdma_txd_info1 txd_info1; - struct pdma_txd_info2 txd_info2; - struct pdma_txd_info3 txd_info3; - struct pdma_txd_info4 txd_info4; -}; - enum mtk_switch { SW_NONE, SW_MT7530, SW_MT7531 }; -enum mtk_soc { - SOC_MT7623, - SOC_MT7629, - SOC_MT7622, - SOC_MT7621 +/* struct mtk_soc_data - This is the structure holding all differences + * among various plaforms + * @caps Flags shown the extra capability for the SoC + * @ana_rgc3: The offset for register ANA_RGC3 related to + * sgmiisys syscon + * @pdma_base: Register base of PDMA block + * @txd_size: Tx DMA descriptor size. + * @rxd_size: Rx DMA descriptor size. + */ +struct mtk_soc_data { + u32 caps; + u32 ana_rgc3; + u32 pdma_base; + u32 txd_size; + u32 rxd_size; }; struct mtk_eth_priv { char pkt_pool[TOTAL_PKT_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN); - struct pdma_txdesc *tx_ring_noc; - struct pdma_rxdesc *rx_ring_noc; + void *tx_ring_noc; + void *rx_ring_noc; int rx_dma_owner_idx0; int tx_cpu_owner_idx0; @@ -171,11 +110,12 @@ struct mtk_eth_priv { int (*mmd_write)(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg, u16 val); - enum mtk_soc soc; + const struct mtk_soc_data *soc; int gmac_id; int force_mode; int speed; int duplex; + bool pn_swap; struct phy_device *phydev; int phy_interface; @@ -195,13 +135,13 @@ struct mtk_eth_priv { static void mtk_pdma_write(struct mtk_eth_priv *priv, u32 reg, u32 val) { - writel(val, priv->fe_base + PDMA_BASE + reg); + writel(val, priv->fe_base + priv->soc->pdma_base + reg); } static void mtk_pdma_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set) { - clrsetbits_le32(priv->fe_base + PDMA_BASE + reg, clr, set); + clrsetbits_le32(priv->fe_base + priv->soc->pdma_base + reg, clr, set); } static void mtk_gdma_write(struct mtk_eth_priv *priv, int no, u32 reg, @@ -679,7 +619,7 @@ static int mt7530_setup(struct mtk_eth_priv *priv) u32 val, txdrv; int i; - if (priv->soc != SOC_MT7621) { + if (!MTK_HAS_CAPS(priv->soc->caps, MTK_TRGMII_MT7621_CLK)) { /* Select 250MHz clk for RGMII mode */ mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG, ETHSYS_TRGMII_CLK_SEL362_5, 0); @@ -1108,9 +1048,8 @@ static int mtk_phy_probe(struct udevice *dev) static void mtk_sgmii_init(struct mtk_eth_priv *priv) { /* Set SGMII GEN2 speed(2.5G) */ - clrsetbits_le32(priv->sgmii_base + ((priv->soc == SOC_MT7622) ? - SGMSYS_GEN2_SPEED : SGMSYS_GEN2_SPEED_V2), - SGMSYS_SPEED_2500, SGMSYS_SPEED_2500); + setbits_le32(priv->sgmii_base + priv->soc->ana_rgc3, + SGMSYS_SPEED_2500); /* Disable SGMII AN */ clrsetbits_le32(priv->sgmii_base + SGMSYS_PCS_CONTROL_1, @@ -1119,6 +1058,12 @@ static void mtk_sgmii_init(struct mtk_eth_priv *priv) /* SGMII force mode setting */ writel(SGMII_FORCE_MODE, priv->sgmii_base + SGMSYS_SGMII_MODE); + /* SGMII PN SWAP setting */ + if (priv->pn_swap) { + setbits_le32(priv->sgmii_base + SGMSYS_QPHY_WRAP_CTRL, + SGMII_PN_SWAP_TX_RX); + } + /* Release PHYA power down state */ clrsetbits_le32(priv->sgmii_base + SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD, 0); @@ -1182,7 +1127,8 @@ static void mtk_mac_init(struct mtk_eth_priv *priv) mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), mcr); } - if (priv->soc == SOC_MT7623) { + if (MTK_HAS_CAPS(priv->soc->caps, MTK_GMAC1_TRGMII) && + !MTK_HAS_CAPS(priv->soc->caps, MTK_TRGMII_MT7621_CLK)) { /* Lower Tx Driving for TRGMII path */ for (i = 0 ; i < NUM_TRGMII_CTRL; i++) mtk_gmac_write(priv, GMAC_TRGMII_TD_ODT(i), @@ -1198,14 +1144,16 @@ static void mtk_mac_init(struct mtk_eth_priv *priv) static void mtk_eth_fifo_init(struct mtk_eth_priv *priv) { char *pkt_base = priv->pkt_pool; + struct mtk_tx_dma_v2 *txd; + struct mtk_rx_dma_v2 *rxd; int i; mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0); udelay(500); - memset(priv->tx_ring_noc, 0, NUM_TX_DESC * sizeof(struct pdma_txdesc)); - memset(priv->rx_ring_noc, 0, NUM_RX_DESC * sizeof(struct pdma_rxdesc)); - memset(priv->pkt_pool, 0, TOTAL_PKT_BUF_SIZE); + memset(priv->tx_ring_noc, 0, NUM_TX_DESC * priv->soc->txd_size); + memset(priv->rx_ring_noc, 0, NUM_RX_DESC * priv->soc->rxd_size); + memset(priv->pkt_pool, 0xff, TOTAL_PKT_BUF_SIZE); flush_dcache_range((ulong)pkt_base, (ulong)(pkt_base + TOTAL_PKT_BUF_SIZE)); @@ -1214,17 +1162,29 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv *priv) priv->tx_cpu_owner_idx0 = 0; for (i = 0; i < NUM_TX_DESC; i++) { - priv->tx_ring_noc[i].txd_info2.LS0 = 1; - priv->tx_ring_noc[i].txd_info2.DDONE = 1; - priv->tx_ring_noc[i].txd_info4.FPORT = priv->gmac_id + 1; + txd = priv->tx_ring_noc + i * priv->soc->txd_size; + + txd->txd1 = virt_to_phys(pkt_base); + txd->txd2 = PDMA_TXD2_DDONE | PDMA_TXD2_LS0; + + if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) + txd->txd5 = PDMA_V2_TXD5_FPORT_SET(priv->gmac_id + 1); + else + txd->txd4 = PDMA_V1_TXD4_FPORT_SET(priv->gmac_id + 1); - priv->tx_ring_noc[i].txd_info1.SDP0 = virt_to_phys(pkt_base); pkt_base += PKTSIZE_ALIGN; } for (i = 0; i < NUM_RX_DESC; i++) { - priv->rx_ring_noc[i].rxd_info2.PLEN0 = PKTSIZE_ALIGN; - priv->rx_ring_noc[i].rxd_info1.PDP0 = virt_to_phys(pkt_base); + rxd = priv->rx_ring_noc + i * priv->soc->rxd_size; + + rxd->rxd1 = virt_to_phys(pkt_base); + + if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) + rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN); + else + rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN); + pkt_base += PKTSIZE_ALIGN; } @@ -1252,6 +1212,9 @@ static int mtk_eth_start(struct udevice *dev) reset_deassert(&priv->rst_fe); mdelay(10); + if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) + setbits_le32(priv->fe_base + FE_GLO_MISC_REG, PDMA_VER_V2); + /* Packets forward to PDMA */ mtk_gdma_write(priv, priv->gmac_id, GDMA_IG_CTRL_REG, GDMA_FWD_TO_CPU); @@ -1286,7 +1249,7 @@ static void mtk_eth_stop(struct udevice *dev) TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN, 0); udelay(500); - wait_for_bit_le32(priv->fe_base + PDMA_BASE + PDMA_GLO_CFG_REG, + wait_for_bit_le32(priv->fe_base + priv->soc->pdma_base + PDMA_GLO_CFG_REG, RX_DMA_BUSY | TX_DMA_BUSY, 0, 5000, 0); } @@ -1311,20 +1274,25 @@ static int mtk_eth_send(struct udevice *dev, void *packet, int length) { struct mtk_eth_priv *priv = dev_get_priv(dev); u32 idx = priv->tx_cpu_owner_idx0; + struct mtk_tx_dma_v2 *txd; void *pkt_base; - if (!priv->tx_ring_noc[idx].txd_info2.DDONE) { + txd = priv->tx_ring_noc + idx * priv->soc->txd_size; + + if (!(txd->txd2 & PDMA_TXD2_DDONE)) { debug("mtk-eth: TX DMA descriptor ring is full\n"); return -EPERM; } - pkt_base = (void *)phys_to_virt(priv->tx_ring_noc[idx].txd_info1.SDP0); + pkt_base = (void *)phys_to_virt(txd->txd1); memcpy(pkt_base, packet, length); flush_dcache_range((ulong)pkt_base, (ulong)pkt_base + roundup(length, ARCH_DMA_MINALIGN)); - priv->tx_ring_noc[idx].txd_info2.SDL0 = length; - priv->tx_ring_noc[idx].txd_info2.DDONE = 0; + if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) + txd->txd2 = PDMA_TXD2_LS0 | PDMA_V2_TXD2_SDL0_SET(length); + else + txd->txd2 = PDMA_TXD2_LS0 | PDMA_V1_TXD2_SDL0_SET(length); priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC; mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0); @@ -1336,16 +1304,23 @@ static int mtk_eth_recv(struct udevice *dev, int flags, uchar **packetp) { struct mtk_eth_priv *priv = dev_get_priv(dev); u32 idx = priv->rx_dma_owner_idx0; + struct mtk_rx_dma_v2 *rxd; uchar *pkt_base; u32 length; - if (!priv->rx_ring_noc[idx].rxd_info2.DDONE) { + rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size; + + if (!(rxd->rxd2 & PDMA_RXD2_DDONE)) { debug("mtk-eth: RX DMA descriptor ring is empty\n"); return -EAGAIN; } - length = priv->rx_ring_noc[idx].rxd_info2.PLEN0; - pkt_base = (void *)phys_to_virt(priv->rx_ring_noc[idx].rxd_info1.PDP0); + if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) + length = PDMA_V2_RXD2_PLEN0_GET(rxd->rxd2); + else + length = PDMA_V1_RXD2_PLEN0_GET(rxd->rxd2); + + pkt_base = (void *)phys_to_virt(rxd->rxd1); invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base + roundup(length, ARCH_DMA_MINALIGN)); @@ -1359,10 +1334,14 @@ static int mtk_eth_free_pkt(struct udevice *dev, uchar *packet, int length) { struct mtk_eth_priv *priv = dev_get_priv(dev); u32 idx = priv->rx_dma_owner_idx0; + struct mtk_rx_dma_v2 *rxd; - priv->rx_ring_noc[idx].rxd_info2.DDONE = 0; - priv->rx_ring_noc[idx].rxd_info2.LS0 = 0; - priv->rx_ring_noc[idx].rxd_info2.PLEN0 = PKTSIZE_ALIGN; + rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size; + + if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) + rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN); + else + rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN); mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx); priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC; @@ -1389,11 +1368,11 @@ static int mtk_eth_probe(struct udevice *dev) return ret; /* Prepare for tx/rx rings */ - priv->tx_ring_noc = (struct pdma_txdesc *) - noncached_alloc(sizeof(struct pdma_txdesc) * NUM_TX_DESC, + priv->tx_ring_noc = (void *) + noncached_alloc(priv->soc->txd_size * NUM_TX_DESC, ARCH_DMA_MINALIGN); - priv->rx_ring_noc = (struct pdma_rxdesc *) - noncached_alloc(sizeof(struct pdma_rxdesc) * NUM_RX_DESC, + priv->rx_ring_noc = (void *) + noncached_alloc(priv->soc->rxd_size * NUM_RX_DESC, ARCH_DMA_MINALIGN); /* Set MAC mode */ @@ -1431,7 +1410,11 @@ static int mtk_eth_of_to_plat(struct udevice *dev) ofnode subnode; int ret; - priv->soc = dev_get_driver_data(dev); + priv->soc = (const struct mtk_soc_data *)dev_get_driver_data(dev); + if (!priv->soc) { + dev_err(dev, "missing soc compatible data\n"); + return -EINVAL; + } pdata->iobase = (phys_addr_t)dev_remap_addr(dev); @@ -1494,6 +1477,8 @@ static int mtk_eth_of_to_plat(struct udevice *dev) dev_err(dev, "Unable to find sgmii\n"); return -ENODEV; } + + priv->pn_swap = ofnode_read_bool(args.node, "pn_swap"); } /* check for switch first, otherwise phy will be used */ @@ -1544,11 +1529,57 @@ static int mtk_eth_of_to_plat(struct udevice *dev) return 0; } +static const struct mtk_soc_data mt7986_data = { + .caps = MT7986_CAPS, + .ana_rgc3 = 0x128, + .pdma_base = PDMA_V2_BASE, + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +}; + +static const struct mtk_soc_data mt7981_data = { + .caps = MT7986_CAPS, + .ana_rgc3 = 0x128, + .pdma_base = PDMA_V2_BASE, + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +}; + +static const struct mtk_soc_data mt7629_data = { + .ana_rgc3 = 0x128, + .pdma_base = PDMA_V1_BASE, + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +}; + +static const struct mtk_soc_data mt7623_data = { + .caps = MT7623_CAPS, + .pdma_base = PDMA_V1_BASE, + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +}; + +static const struct mtk_soc_data mt7622_data = { + .ana_rgc3 = 0x2028, + .pdma_base = PDMA_V1_BASE, + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +}; + +static const struct mtk_soc_data mt7621_data = { + .caps = MT7621_CAPS, + .pdma_base = PDMA_V1_BASE, + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), +}; + static const struct udevice_id mtk_eth_ids[] = { - { .compatible = "mediatek,mt7629-eth", .data = SOC_MT7629 }, - { .compatible = "mediatek,mt7623-eth", .data = SOC_MT7623 }, - { .compatible = "mediatek,mt7622-eth", .data = SOC_MT7622 }, - { .compatible = "mediatek,mt7621-eth", .data = SOC_MT7621 }, + { .compatible = "mediatek,mt7986-eth", .data = (ulong)&mt7986_data }, + { .compatible = "mediatek,mt7981-eth", .data = (ulong)&mt7981_data }, + { .compatible = "mediatek,mt7629-eth", .data = (ulong)&mt7629_data }, + { .compatible = "mediatek,mt7623-eth", .data = (ulong)&mt7623_data }, + { .compatible = "mediatek,mt7622-eth", .data = (ulong)&mt7622_data }, + { .compatible = "mediatek,mt7621-eth", .data = (ulong)&mt7621_data }, {} }; diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h index 057ecfaabf..1382ccbeb2 100644 --- a/drivers/net/mtk_eth.h +++ b/drivers/net/mtk_eth.h @@ -9,9 +9,38 @@ #ifndef _MTK_ETH_H_ #define _MTK_ETH_H_ -/* Frame Engine Register Bases */ #include -#define PDMA_BASE 0x0800 +#include + +enum mkt_eth_capabilities { + MTK_TRGMII_BIT, + MTK_TRGMII_MT7621_CLK_BIT, + MTK_NETSYS_V2_BIT, + + /* PATH BITS */ + MTK_ETH_PATH_GMAC1_TRGMII_BIT, +}; + +#define MTK_TRGMII BIT(MTK_TRGMII_BIT) +#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) +#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) + +/* Supported path present on SoCs */ +#define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT) + +#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) + +#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) + +#define MT7621_CAPS (MTK_GMAC1_TRGMII | MTK_TRGMII_MT7621_CLK) + +#define MT7623_CAPS (MTK_GMAC1_TRGMII) + +#define MT7986_CAPS (MTK_NETSYS_V2) + +/* Frame Engine Register Bases */ +#define PDMA_V1_BASE 0x0800 +#define PDMA_V2_BASE 0x6000 #define GDMA1_BASE 0x0500 #define GDMA2_BASE 0x1500 #define GMAC_BASE 0x10000 @@ -45,11 +74,16 @@ #define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8 #define SGMII_PHYA_PWD BIT(4) +#define SGMSYS_QPHY_WRAP_CTRL 0xec +#define SGMII_PN_SWAP_TX_RX 0x03 + #define SGMSYS_GEN2_SPEED 0x2028 #define SGMSYS_GEN2_SPEED_V2 0x128 #define SGMSYS_SPEED_2500 BIT(2) /* Frame Engine Registers */ +#define FE_GLO_MISC_REG 0x124 +#define PDMA_VER_V2 BIT(4) /* PDMA */ #define TX_BASE_PTR_REG(n) (0x000 + (n) * 0x10) @@ -412,4 +446,67 @@ #define PHY_POWER_SAVING_M 0x300 #define PHY_POWER_SAVING_TX 0x0 +/* PDMA descriptors */ +struct mtk_rx_dma { + unsigned int rxd1; + unsigned int rxd2; + unsigned int rxd3; + unsigned int rxd4; +} __packed __aligned(4); + +struct mtk_rx_dma_v2 { + unsigned int rxd1; + unsigned int rxd2; + unsigned int rxd3; + unsigned int rxd4; + unsigned int rxd5; + unsigned int rxd6; + unsigned int rxd7; + unsigned int rxd8; +} __packed __aligned(4); + +struct mtk_tx_dma { + unsigned int txd1; + unsigned int txd2; + unsigned int txd3; + unsigned int txd4; +} __packed __aligned(4); + +struct mtk_tx_dma_v2 { + unsigned int txd1; + unsigned int txd2; + unsigned int txd3; + unsigned int txd4; + unsigned int txd5; + unsigned int txd6; + unsigned int txd7; + unsigned int txd8; +} __packed __aligned(4); + +/* PDMA TXD fields */ +#define PDMA_TXD2_DDONE BIT(31) +#define PDMA_TXD2_LS0 BIT(30) +#define PDMA_V1_TXD2_SDL0_M GENMASK(29, 16) +#define PDMA_V1_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_V1_TXD2_SDL0_M, (_v)) +#define PDMA_V2_TXD2_SDL0_M GENMASK(23, 8) +#define PDMA_V2_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_V2_TXD2_SDL0_M, (_v)) + +#define PDMA_V1_TXD4_FPORT_M GENMASK(27, 25) +#define PDMA_V1_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_V1_TXD4_FPORT_M, (_v)) +#define PDMA_V2_TXD4_FPORT_M GENMASK(27, 24) +#define PDMA_V2_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_V2_TXD4_FPORT_M, (_v)) + +#define PDMA_V2_TXD5_FPORT_M GENMASK(19, 16) +#define PDMA_V2_TXD5_FPORT_SET(_v) FIELD_PREP(PDMA_V2_TXD5_FPORT_M, (_v)) + +/* PDMA RXD fields */ +#define PDMA_RXD2_DDONE BIT(31) +#define PDMA_RXD2_LS0 BIT(30) +#define PDMA_V1_RXD2_PLEN0_M GENMASK(29, 16) +#define PDMA_V1_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_V1_RXD2_PLEN0_M, (_v)) +#define PDMA_V1_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_V1_RXD2_PLEN0_M, (_v)) +#define PDMA_V2_RXD2_PLEN0_M GENMASK(23, 8) +#define PDMA_V2_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_V2_RXD2_PLEN0_M, (_v)) +#define PDMA_V2_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_V2_RXD2_PLEN0_M, (_v)) + #endif /* _MTK_ETH_H_ */ diff --git a/drivers/net/octeontx2/nix.c b/drivers/net/octeontx2/nix.c index a5665a25f2..f596b6bca8 100644 --- a/drivers/net/octeontx2/nix.c +++ b/drivers/net/octeontx2/nix.c @@ -580,7 +580,7 @@ int nix_lf_xmit(struct udevice *dev, void *pkt, int pkt_len) __iowmb(); result = lmt_submit((u64)(nix->nix_base + NIXX_LF_OP_SENDX(0))); - WATCHDOG_RESET(); + schedule(); } while (result == 0); return 0; diff --git a/drivers/net/octeontx2/nix_af.c b/drivers/net/octeontx2/nix_af.c index cd098d6cd6..c945ea0f5f 100644 --- a/drivers/net/octeontx2/nix_af.c +++ b/drivers/net/octeontx2/nix_af.c @@ -65,7 +65,7 @@ int npa_attach_aura(struct nix_af *nix_af, int lf, start = get_timer(0); while ((res->s.compcode == NPA_AQ_COMP_E_NOTDONE) && (get_timer(start) < 1000)) - WATCHDOG_RESET(); + schedule(); if (res->s.compcode != NPA_AQ_COMP_E_GOOD) { printf("%s: Error: result 0x%x not good\n", __func__, res->s.compcode); @@ -111,7 +111,7 @@ int npa_attach_pool(struct nix_af *nix_af, int lf, start = get_timer(0); while ((res->s.compcode == NPA_AQ_COMP_E_NOTDONE) && (get_timer(start) < 1000)) - WATCHDOG_RESET(); + schedule(); if (res->s.compcode != NPA_AQ_COMP_E_GOOD) { printf("%s: Error: result 0x%x not good\n", @@ -136,7 +136,7 @@ int npa_lf_admin_setup(struct npa *npa, int lf, dma_addr_t aura_base) do { lf_rst.u = npa_af_reg_read(npa_af, NPA_AF_LF_RST()); - WATCHDOG_RESET(); + schedule(); } while (lf_rst.s.exec); /* Set Aura size and enable caching of contexts */ @@ -199,7 +199,7 @@ int npa_lf_admin_shutdown(struct nix_af *nix_af, int lf, u32 pool_count) start = get_timer(0); while ((res->s.compcode == NPA_AQ_COMP_E_NOTDONE) && (get_timer(start) < 1000)) - WATCHDOG_RESET(); + schedule(); if (res->s.compcode != NPA_AQ_COMP_E_GOOD) { printf("%s: Error: result 0x%x not good for lf %d\n" @@ -235,7 +235,7 @@ int npa_lf_admin_shutdown(struct nix_af *nix_af, int lf, u32 pool_count) start = get_timer(0); while ((res->s.compcode == NPA_AQ_COMP_E_NOTDONE) && (get_timer(start) < 1000)) - WATCHDOG_RESET(); + schedule(); if (res->s.compcode != NPA_AQ_COMP_E_GOOD) { printf("%s: Error: result 0x%x not good for lf %d\n" @@ -255,7 +255,7 @@ int npa_lf_admin_shutdown(struct nix_af *nix_af, int lf, u32 pool_count) do { lf_rst.u = npa_af_reg_read(npa, NPA_AF_LF_RST()); - WATCHDOG_RESET(); + schedule(); } while (lf_rst.s.exec); return 0; @@ -286,7 +286,7 @@ int npa_af_setup(struct npa_af *npa_af) /* Wait for reset to complete */ do { blk_rst.u = npa_af_reg_read(npa_af, NPA_AF_BLK_RST()); - WATCHDOG_RESET(); + schedule(); } while (blk_rst.s.busy); /* Set little Endian */ @@ -318,7 +318,7 @@ int npa_af_shutdown(struct npa_af *npa_af) /* Wait for reset to complete */ do { blk_rst.u = npa_af_reg_read(npa_af, NPA_AF_BLK_RST()); - WATCHDOG_RESET(); + schedule(); } while (blk_rst.s.busy); rvu_aq_free(&npa_af->aq); @@ -481,7 +481,7 @@ static int nix_aq_issue_command(struct nix_af *nix_af, start = get_timer(0); /* Wait for completion */ do { - WATCHDOG_RESET(); + schedule(); dsb(); } while (result->s.compcode == 0 && get_timer(start) < 2); @@ -645,7 +645,7 @@ int nix_lf_admin_setup(struct nix *nix) do { lf_rst.u = nix_af_reg_read(nix_af, NIXX_AF_LF_RST()); - WATCHDOG_RESET(); + schedule(); } while (lf_rst.s.exec); /* Config NIX RQ HW context and base*/ @@ -767,7 +767,7 @@ int nix_lf_admin_shutdown(struct nix_af *nix_af, int lf, do { sw_sync.u = nix_af_reg_read(nix_af, NIXX_AF_RX_SW_SYNC()); - WATCHDOG_RESET(); + schedule(); } while (sw_sync.s.ena); for (index = 0; index < rq_count; index++) { @@ -832,7 +832,7 @@ int nix_lf_admin_shutdown(struct nix_af *nix_af, int lf, do { lf_rst.u = nix_af_reg_read(nix_af, NIXX_AF_LF_RST()); - WATCHDOG_RESET(); + schedule(); } while (lf_rst.s.exec); return 0; @@ -972,7 +972,7 @@ int npc_af_shutdown(struct nix_af *nix_af) /* Wait for reset to complete */ do { blk_rst.u = npc_af_reg_read(nix_af, NPC_AF_BLK_RST()); - WATCHDOG_RESET(); + schedule(); } while (blk_rst.s.busy); debug("%s: npc af reset --\n", __func__); @@ -1008,7 +1008,7 @@ int nix_af_setup(struct nix_af *nix_af) /* Wait for reset to complete */ do { blk_rst.u = nix_af_reg_read(nix_af, NIXX_AF_BLK_RST()); - WATCHDOG_RESET(); + schedule(); } while (blk_rst.s.busy); /* Put in LE mode */ @@ -1031,7 +1031,7 @@ int nix_af_setup(struct nix_af *nix_af) /* Wait for calibration to complete */ do { af_status.u = nix_af_reg_read(nix_af, NIXX_AF_STATUS()); - WATCHDOG_RESET(); + schedule(); } while (af_status.s.calibrate_done == 0); af_cfg.u = nix_af_reg_read(nix_af, NIXX_AF_CFG()); @@ -1091,7 +1091,7 @@ int nix_af_shutdown(struct nix_af *nix_af) /* Wait for reset to complete */ do { blk_rst.u = nix_af_reg_read(nix_af, NIXX_AF_BLK_RST()); - WATCHDOG_RESET(); + schedule(); } while (blk_rst.s.busy); rvu_aq_free(&nix_af->aq); diff --git a/drivers/net/sja1105.c b/drivers/net/sja1105.c index 4ca8709e34..48f044c647 100644 --- a/drivers/net/sja1105.c +++ b/drivers/net/sja1105.c @@ -3316,7 +3316,7 @@ static int sja1105_probe(struct udevice *dev) int rc; if (ofnode_valid(dev_ofnode(dev)) && - !ofnode_is_available(dev_ofnode(dev))) { + !ofnode_is_enabled(dev_ofnode(dev))) { dev_dbg(dev, "switch disabled\n"); return -ENODEV; } diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c index 9580fa37ea..b79e06290a 100644 --- a/drivers/net/ti/am65-cpsw-nuss.c +++ b/drivers/net/ti/am65-cpsw-nuss.c @@ -719,7 +719,7 @@ static int am65_cpsw_probe_nuss(struct udevice *dev) node_name = ofnode_get_name(node); - disabled = !ofnode_is_available(node); + disabled = !ofnode_is_enabled(node); ret = ofnode_read_u32(node, "reg", &port_id); if (ret) { diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 4e8dd4badd..61a6c83e33 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -500,10 +500,13 @@ static int zynq_gem_init(struct udevice *dev) } #endif - ret = clk_set_rate(&priv->tx_clk, clk_rate); - if (IS_ERR_VALUE(ret)) { - dev_err(dev, "failed to set tx clock rate\n"); - return ret; + ret = clk_get_rate(&priv->tx_clk); + if (ret != clk_rate) { + ret = clk_set_rate(&priv->tx_clk, clk_rate); + if (IS_ERR_VALUE(ret)) { + dev_err(dev, "failed to set tx clock rate %ld\n", clk_rate); + return ret; + } } ret = clk_enable(&priv->tx_clk); diff --git a/drivers/nvme/Kconfig b/drivers/nvme/Kconfig index 0cb465160b..73edb35516 100644 --- a/drivers/nvme/Kconfig +++ b/drivers/nvme/Kconfig @@ -4,8 +4,6 @@ config NVME bool "NVM Express device support" - depends on BLK - select HAVE_BLOCK_DEVICE help This option enables support for NVM Express devices. It supports basic functions of NVMe (read/write). diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index 5fd2fb9ed6..6d0d3f3ca2 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -71,7 +71,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, } nprps = DIV_ROUND_UP(length, page_size); - num_pages = DIV_ROUND_UP(nprps, prps_per_page); + num_pages = DIV_ROUND_UP(nprps - 1, prps_per_page - 1); if (nprps > dev->prp_entry_num) { free(dev->prp_pool); @@ -84,13 +84,13 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, printf("Error: malloc prp_pool fail\n"); return -ENOMEM; } - dev->prp_entry_num = prps_per_page * num_pages; + dev->prp_entry_num = num_pages * (prps_per_page - 1) + 1; } prp_pool = dev->prp_pool; i = 0; while (nprps) { - if (i == ((page_size >> 3) - 1)) { + if ((i == (prps_per_page - 1)) && nprps > 1) { *(prp_pool + i) = cpu_to_le64((ulong)prp_pool + page_size); i = 0; @@ -103,7 +103,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, *prp2 = (ulong)dev->prp_pool; flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool + - dev->prp_entry_num * sizeof(u64)); + num_pages * page_size); return 0; } @@ -888,7 +888,7 @@ int nvme_init(struct udevice *udev) sprintf(name, "blk#%d", i); /* The real blksz and size will be set by nvme_blk_probe() */ - ret = blk_create_devicef(udev, "nvme-blk", name, IF_TYPE_NVME, + ret = blk_create_devicef(udev, "nvme-blk", name, UCLASS_NVME, -1, 512, 0, &ns_udev); if (ret) goto free_id; diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 16a6a699f9..058b2f6359 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -766,7 +766,7 @@ static int pci_find_and_bind_driver(struct udevice *parent, if (ofnode_valid(dev_ofnode(parent))) pci_dev_find_ofnode(parent, bdf, &node); - if (ofnode_valid(node) && !ofnode_is_available(node)) { + if (ofnode_valid(node) && !ofnode_is_enabled(node)) { debug("%s: Ignoring disabled device\n", __func__); return log_msg_ret("dis", -EPERM); } diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c index 5bd340a421..93a7508d8a 100644 --- a/drivers/pci/pci_mvebu.c +++ b/drivers/pci/pci_mvebu.c @@ -740,7 +740,7 @@ static int mvebu_pcie_bind(struct udevice *parent) /* First phase: Fill mvebu_pcie struct for each port */ ofnode_for_each_subnode(subnode, dev_ofnode(parent)) { - if (!ofnode_is_available(subnode)) + if (!ofnode_is_enabled(subnode)) continue; pcie = calloc(1, sizeof(*pcie)); diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c index bc489d5ec8..29d54117e9 100644 --- a/drivers/pci/pci_tegra.c +++ b/drivers/pci/pci_tegra.c @@ -531,7 +531,7 @@ static int tegra_pcie_parse_dt(struct udevice *dev, enum tegra_pci_id id, lanes |= num_lanes << (index << 3); - if (!ofnode_is_available(subnode)) + if (!ofnode_is_enabled(subnode)) continue; port = malloc(sizeof(*port)); diff --git a/drivers/pci/pcie_mediatek.c b/drivers/pci/pcie_mediatek.c index 051a3bc969..c6e30e2462 100644 --- a/drivers/pci/pcie_mediatek.c +++ b/drivers/pci/pcie_mediatek.c @@ -657,7 +657,7 @@ static int mtk_pcie_probe(struct udevice *dev) struct fdt_pci_addr addr; u32 slot = 0; - if (!ofnode_is_available(subnode)) + if (!ofnode_is_enabled(subnode)) continue; err = ofnode_read_pci_addr(subnode, 0, "reg", &addr); @@ -696,7 +696,7 @@ static int mtk_pcie_probe_v2(struct udevice *dev) pcie->priv = dev; dev_for_each_subnode(subnode, dev) { - if (!ofnode_is_available(subnode)) + if (!ofnode_is_enabled(subnode)) continue; err = ofnode_read_pci_addr(subnode, 0, "reg", &addr); diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index c25b42c68f..cf4d5908d7 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -143,12 +143,6 @@ config STI_USB_PHY used by USB2 and USB3 Host controllers available on STiH407 SoC families. -config PHY_QCOM_IPQ4019_USB - tristate "Qualcomm IPQ4019 USB PHY driver" - depends on PHY && ARCH_IPQ40XX - help - Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s. - config PHY_RCAR_GEN2 tristate "Renesas R-Car Gen2 USB PHY" depends on PHY && RCAR_GEN2 @@ -220,14 +214,6 @@ config MESON_AXG_MIPI_PCIE_ANALOG_PHY This is the generic phy driver for the Amlogic Meson AXG MIPI PCIe Analog PHY. -config MSM8916_USB_PHY - bool "Qualcomm MSM8916 USB PHY support" - depends on PHY - help - Support the USB PHY in msm8916 - - This PHY is found on qualcomm dragonboard410c development board. - config OMAP_USB2_PHY bool "Support OMAP's USB2 PHY" depends on PHY @@ -298,5 +284,6 @@ config PHY_XILINX_ZYNQMP source "drivers/phy/rockchip/Kconfig" source "drivers/phy/cadence/Kconfig" source "drivers/phy/ti/Kconfig" +source "drivers/phy/qcom/Kconfig" endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index d95439c425..a3b9f3c5b1 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o obj-$(CONFIG_AM654_PHY) += phy-ti-am654.o obj-$(CONFIG_STI_USB_PHY) += sti_usb_phy.o -obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o obj-$(CONFIG_PHY_RCAR_GEN3) += phy-rcar-gen3.o obj-$(CONFIG_PHY_STM32_USBPHYC) += phy-stm32-usbphyc.o @@ -30,7 +29,6 @@ obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o obj-$(CONFIG_MESON_G12A_USB_PHY) += meson-g12a-usb2.o meson-g12a-usb3-pcie.o obj-$(CONFIG_MESON_AXG_MIPI_DPHY) += meson-axg-mipi-dphy.o obj-$(CONFIG_MESON_AXG_MIPI_PCIE_ANALOG_PHY) += meson-axg-mipi-pcie-analog.o -obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o obj-$(CONFIG_KEYSTONE_USB_PHY) += keystone-usb-phy.o obj-$(CONFIG_MT7620_USB_PHY) += mt7620-usb-phy.o @@ -42,3 +40,4 @@ obj-$(CONFIG_PHY_IMX8MQ_USB) += phy-imx8mq-usb.o obj-$(CONFIG_PHY_XILINX_ZYNQMP) += phy-zynqmp.o obj-y += cadence/ obj-y += ti/ +obj-y += qcom/ diff --git a/drivers/phy/qcom/Kconfig b/drivers/phy/qcom/Kconfig new file mode 100644 index 0000000000..f4ca174805 --- /dev/null +++ b/drivers/phy/qcom/Kconfig @@ -0,0 +1,29 @@ +config MSM8916_USB_PHY + bool "Qualcomm MSM8916 USB PHY support" + depends on PHY + help + Support the USB PHY in msm8916 + + This PHY is found on qualcomm dragonboard410c development board. + +config PHY_QCOM_IPQ4019_USB + tristate "Qualcomm IPQ4019 USB PHY driver" + depends on PHY && ARCH_IPQ40XX + help + Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s. + +config PHY_QCOM_USB_HS_28NM + tristate "Qualcomm 28nm High-Speed PHY" + depends on PHY && ARCH_SNAPDRAGON + help + Enable this to support the Qualcomm Synopsys DesignWare Core 28nm + High-Speed PHY driver. This driver supports the Hi-Speed PHY which + is usually paired with either the ChipIdea or Synopsys DWC3 USB + IPs on MSM SOCs. + +config PHY_QCOM_USB_SS + tristate "Qualcomm USB Super-Speed PHY driver" + depends on PHY && ARCH_SNAPDRAGON + help + Enable this to support the Super-Speed USB transceiver on various + Qualcomm chipsets. diff --git a/drivers/phy/qcom/Makefile b/drivers/phy/qcom/Makefile new file mode 100644 index 0000000000..2113f178c0 --- /dev/null +++ b/drivers/phy/qcom/Makefile @@ -0,0 +1,4 @@ +obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o +obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o +obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o +obj-$(CONFIG_PHY_QCOM_USB_SS) += phy-qcom-usb-ss.o diff --git a/drivers/phy/msm8916-usbh-phy.c b/drivers/phy/qcom/msm8916-usbh-phy.c similarity index 100% rename from drivers/phy/msm8916-usbh-phy.c rename to drivers/phy/qcom/msm8916-usbh-phy.c diff --git a/drivers/phy/phy-qcom-ipq4019-usb.c b/drivers/phy/qcom/phy-qcom-ipq4019-usb.c similarity index 100% rename from drivers/phy/phy-qcom-ipq4019-usb.c rename to drivers/phy/qcom/phy-qcom-ipq4019-usb.c diff --git a/drivers/phy/qcom/phy-qcom-usb-hs-28nm.c b/drivers/phy/qcom/phy-qcom-usb-hs-28nm.c new file mode 100644 index 0000000000..14c3d8394d --- /dev/null +++ b/drivers/phy/qcom/phy-qcom-usb-hs-28nm.c @@ -0,0 +1,250 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Sumit Garg + * + * Based on Linux driver + */ + +#include +#include +#include +#include +#include +#include +#include + +/* PHY register and bit definitions */ +#define PHY_CTRL_COMMON0 0x078 +#define SIDDQ BIT(2) + +struct hsphy_init_seq { + int offset; + int val; + int delay; +}; + +struct hsphy_data { + const struct hsphy_init_seq *init_seq; + unsigned int init_seq_num; +}; + +struct hsphy_priv { + void __iomem *base; + struct clk_bulk clks; + struct reset_ctl phy_rst; + struct reset_ctl por_rst; + const struct hsphy_data *data; +}; + +static int hsphy_power_on(struct phy *phy) +{ + struct hsphy_priv *priv = dev_get_priv(phy->dev); + u32 val; + + val = readb(priv->base + PHY_CTRL_COMMON0); + val &= ~SIDDQ; + writeb(val, priv->base + PHY_CTRL_COMMON0); + + return 0; +} + +static int hsphy_power_off(struct phy *phy) +{ + struct hsphy_priv *priv = dev_get_priv(phy->dev); + u32 val; + + val = readb(priv->base + PHY_CTRL_COMMON0); + val |= SIDDQ; + writeb(val, priv->base + PHY_CTRL_COMMON0); + + return 0; +} + +static int hsphy_reset(struct hsphy_priv *priv) +{ + int ret; + + ret = reset_assert(&priv->phy_rst); + if (ret) + return ret; + + udelay(10); + + ret = reset_deassert(&priv->phy_rst); + if (ret) + return ret; + + udelay(80); + + return 0; +} + +static void hsphy_init_sequence(struct hsphy_priv *priv) +{ + const struct hsphy_data *data = priv->data; + const struct hsphy_init_seq *seq; + int i; + + /* Device match data is optional. */ + if (!data) + return; + + seq = data->init_seq; + + for (i = 0; i < data->init_seq_num; i++, seq++) { + writeb(seq->val, priv->base + seq->offset); + if (seq->delay) + udelay(seq->delay); + } +} + +static int hsphy_por_reset(struct hsphy_priv *priv) +{ + int ret; + u32 val; + + ret = reset_assert(&priv->por_rst); + if (ret) + return ret; + + /* + * The Femto PHY is POR reset in the following scenarios. + * + * 1. After overriding the parameter registers. + * 2. Low power mode exit from PHY retention. + * + * Ensure that SIDDQ is cleared before bringing the PHY + * out of reset. + */ + val = readb(priv->base + PHY_CTRL_COMMON0); + val &= ~SIDDQ; + writeb(val, priv->base + PHY_CTRL_COMMON0); + + /* + * As per databook, 10 usec delay is required between + * PHY POR assert and de-assert. + */ + udelay(10); + ret = reset_deassert(&priv->por_rst); + if (ret) + return ret; + + /* + * As per databook, it takes 75 usec for PHY to stabilize + * after the reset. + */ + udelay(80); + + return 0; +} + +static int hsphy_clk_init(struct udevice *dev, struct hsphy_priv *priv) +{ + int ret; + + ret = clk_get_bulk(dev, &priv->clks); + if (ret == -ENOSYS || ret == -ENOENT) + return 0; + if (ret) + return ret; + + ret = clk_enable_bulk(&priv->clks); + if (ret) { + clk_release_bulk(&priv->clks); + return ret; + } + + return 0; +} + +static int hsphy_init(struct phy *phy) +{ + struct hsphy_priv *priv = dev_get_priv(phy->dev); + int ret; + + ret = hsphy_clk_init(phy->dev, priv); + if (ret) + return ret; + + ret = hsphy_reset(priv); + if (ret) + return ret; + + hsphy_init_sequence(priv); + + hsphy_por_reset(priv); + if (ret) + return ret; + + return 0; +} + +static int hsphy_probe(struct udevice *dev) +{ + struct hsphy_priv *priv = dev_get_priv(dev); + int ret; + + priv->base = (void *)dev_read_addr(dev); + if ((ulong)priv->base == FDT_ADDR_T_NONE) + return -EINVAL; + + ret = reset_get_by_name(dev, "phy", &priv->phy_rst); + if (ret) + return ret; + + ret = reset_get_by_name(dev, "por", &priv->por_rst); + if (ret) + return ret; + + priv->data = (const struct hsphy_data *)dev_get_driver_data(dev); + + return 0; +} + +static struct phy_ops hsphy_ops = { + .power_on = hsphy_power_on, + .power_off = hsphy_power_off, + .init = hsphy_init, +}; + +/* + * The macro is used to define an initialization sequence. Each tuple + * is meant to program 'value' into phy register at 'offset' with 'delay' + * in us followed. + */ +#define HSPHY_INIT_CFG(o, v, d) { .offset = o, .val = v, .delay = d, } + +static const struct hsphy_init_seq init_seq_femtophy[] = { + HSPHY_INIT_CFG(0xc0, 0x01, 0), + HSPHY_INIT_CFG(0xe8, 0x0d, 0), + HSPHY_INIT_CFG(0x74, 0x12, 0), + HSPHY_INIT_CFG(0x98, 0x63, 0), + HSPHY_INIT_CFG(0x9c, 0x03, 0), + HSPHY_INIT_CFG(0xa0, 0x1d, 0), + HSPHY_INIT_CFG(0xa4, 0x03, 0), + HSPHY_INIT_CFG(0x8c, 0x23, 0), + HSPHY_INIT_CFG(0x78, 0x08, 0), + HSPHY_INIT_CFG(0x7c, 0xdc, 0), + HSPHY_INIT_CFG(0x90, 0xe0, 20), + HSPHY_INIT_CFG(0x74, 0x10, 0), + HSPHY_INIT_CFG(0x90, 0x60, 0), +}; + +static const struct hsphy_data data_femtophy = { + .init_seq = init_seq_femtophy, + .init_seq_num = ARRAY_SIZE(init_seq_femtophy), +}; + +static const struct udevice_id hsphy_ids[] = { + { .compatible = "qcom,usb-hs-28nm-femtophy", .data = (ulong)&data_femtophy }, + { } +}; + +U_BOOT_DRIVER(qcom_usb_hs_28nm) = { + .name = "qcom-usb-hs-28nm", + .id = UCLASS_PHY, + .of_match = hsphy_ids, + .ops = &hsphy_ops, + .probe = hsphy_probe, + .priv_auto = sizeof(struct hsphy_priv), +}; diff --git a/drivers/phy/qcom/phy-qcom-usb-ss.c b/drivers/phy/qcom/phy-qcom-usb-ss.c new file mode 100644 index 0000000000..4e816879c6 --- /dev/null +++ b/drivers/phy/qcom/phy-qcom-usb-ss.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Sumit Garg + * + * Based on Linux driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PHY_CTRL0 0x6C +#define PHY_CTRL1 0x70 +#define PHY_CTRL2 0x74 +#define PHY_CTRL4 0x7C + +/* PHY_CTRL bits */ +#define REF_PHY_EN BIT(0) +#define LANE0_PWR_ON BIT(2) +#define SWI_PCS_CLK_SEL BIT(4) +#define TST_PWR_DOWN BIT(4) +#define PHY_RESET BIT(7) + +struct ssphy_priv { + void __iomem *base; + struct clk_bulk clks; + struct reset_ctl com_rst; + struct reset_ctl phy_rst; +}; + +static inline void ssphy_updatel(void __iomem *addr, u32 mask, u32 val) +{ + writel((readl(addr) & ~mask) | val, addr); +} + +static int ssphy_do_reset(struct ssphy_priv *priv) +{ + int ret; + + ret = reset_assert(&priv->com_rst); + if (ret) + return ret; + + ret = reset_assert(&priv->phy_rst); + if (ret) + return ret; + + udelay(10); + + ret = reset_deassert(&priv->com_rst); + if (ret) + return ret; + + ret = reset_deassert(&priv->phy_rst); + if (ret) + return ret; + + return 0; +} + +static int ssphy_power_on(struct phy *phy) +{ + struct ssphy_priv *priv = dev_get_priv(phy->dev); + int ret; + + ret = ssphy_do_reset(priv); + if (ret) + return ret; + + writeb(SWI_PCS_CLK_SEL, priv->base + PHY_CTRL0); + ssphy_updatel(priv->base + PHY_CTRL4, LANE0_PWR_ON, LANE0_PWR_ON); + ssphy_updatel(priv->base + PHY_CTRL2, REF_PHY_EN, REF_PHY_EN); + ssphy_updatel(priv->base + PHY_CTRL4, TST_PWR_DOWN, 0); + + return 0; +} + +static int ssphy_power_off(struct phy *phy) +{ + struct ssphy_priv *priv = dev_get_priv(phy->dev); + + ssphy_updatel(priv->base + PHY_CTRL4, LANE0_PWR_ON, 0); + ssphy_updatel(priv->base + PHY_CTRL2, REF_PHY_EN, 0); + ssphy_updatel(priv->base + PHY_CTRL4, TST_PWR_DOWN, TST_PWR_DOWN); + + return 0; +} + +static int ssphy_clk_init(struct udevice *dev, struct ssphy_priv *priv) +{ + int ret; + + ret = clk_get_bulk(dev, &priv->clks); + if (ret == -ENOSYS || ret == -ENOENT) + return 0; + if (ret) + return ret; + + ret = clk_enable_bulk(&priv->clks); + if (ret) { + clk_release_bulk(&priv->clks); + return ret; + } + + return 0; +} + +static int ssphy_probe(struct udevice *dev) +{ + struct ssphy_priv *priv = dev_get_priv(dev); + int ret; + + priv->base = (void *)dev_read_addr(dev); + if ((ulong)priv->base == FDT_ADDR_T_NONE) + return -EINVAL; + + ret = ssphy_clk_init(dev, priv); + if (ret) + return ret; + + ret = reset_get_by_name(dev, "com", &priv->com_rst); + if (ret) + return ret; + + ret = reset_get_by_name(dev, "phy", &priv->phy_rst); + if (ret) + return ret; + + return 0; +} + +static struct phy_ops ssphy_ops = { + .power_on = ssphy_power_on, + .power_off = ssphy_power_off, +}; + +static const struct udevice_id ssphy_ids[] = { + { .compatible = "qcom,usb-ss-28nm-phy" }, + { } +}; + +U_BOOT_DRIVER(qcom_usb_ss) = { + .name = "qcom-usb-ss", + .id = UCLASS_PHY, + .of_match = ssphy_ids, + .ops = &ssphy_ops, + .probe = ssphy_probe, + .priv_auto = sizeof(struct ssphy_priv), +}; diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2500.c b/drivers/pinctrl/aspeed/pinctrl_ast2500.c index 3c2e10b88e..93920a6389 100644 --- a/drivers/pinctrl/aspeed/pinctrl_ast2500.c +++ b/drivers/pinctrl/aspeed/pinctrl_ast2500.c @@ -61,6 +61,8 @@ static const struct ast2500_group_config ast2500_groups[] = { { "MDIO2", 5, (1 << 2) }, { "SD1", 5, (1 << 0) }, { "SD2", 5, (1 << 1) }, + { "FWSPICS1", 3, (1 << 24) }, + { "SPI1CS1", 1, (1 << 15) }, }; static int ast2500_pinctrl_get_groups_count(struct udevice *dev) diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig index 58df508d7e..27e8998e59 100644 --- a/drivers/pinctrl/mediatek/Kconfig +++ b/drivers/pinctrl/mediatek/Kconfig @@ -16,6 +16,14 @@ config PINCTRL_MT7629 bool "MT7629 SoC pinctrl driver" select PINCTRL_MTK +config PINCTRL_MT7981 + bool "MT7981 SoC pinctrl driver" + select PINCTRL_MTK + +config PINCTRL_MT7986 + bool "MT7986 SoC pinctrl driver" + select PINCTRL_MTK + config PINCTRL_MT8512 bool "MT8512 SoC pinctrl driver" select PINCTRL_MTK diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile index d7e8cf1727..6e733759f5 100644 --- a/drivers/pinctrl/mediatek/Makefile +++ b/drivers/pinctrl/mediatek/Makefile @@ -6,6 +6,8 @@ obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o obj-$(CONFIG_PINCTRL_MT7622) += pinctrl-mt7622.o obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o +obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o +obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7986.o obj-$(CONFIG_PINCTRL_MT8512) += pinctrl-mt8512.o obj-$(CONFIG_PINCTRL_MT8516) += pinctrl-mt8516.o obj-$(CONFIG_PINCTRL_MT8518) += pinctrl-mt8518.o diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7981.c b/drivers/pinctrl/mediatek/pinctrl-mt7981.c new file mode 100644 index 0000000000..d8875241cb --- /dev/null +++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c @@ -0,0 +1,1049 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * The MT7981 driver based on Linux generic pinctrl binding. + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include "pinctrl-mtk-common.h" + +#define MT7981_TYPE0_PIN(_number, _name) \ + MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP0) + +#define MT7981_TYPE1_PIN(_number, _name) \ + MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP1) + +#define PIN_FIELD_GPIO(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \ + PIN_FIELD_BASE_CALC(_s_pin, _e_pin, GPIO_BASE, _s_addr, _x_addrs, \ + _s_bit, _x_bits, 32, 0) + +#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ + _x_bits) \ + PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ + _x_bits, 32, 0) + +/** + * enum - Locking variants of the iocfg bases + * + * MT7981 have multiple bases to program pin configuration listed as the below: + * iocfg_rt:0x11c00000, iocfg_rm:0x11c10000, iocfg_rb:0x11d20000, + * iocfg_lb:0x11e00000, iocfg_bl:0x11e20000, iocfg_tm:0x11f00000, + * iocfg_tl:0x11f10000, + * _i_based could be used to indicate what base the pin should be mapped into. + * + * Each iocfg register base control different group of pads on the SoC + * + * + * chip carrier + * + * A B C D E F G H + * +------------------------+ + * 8 | o o o o o o o o | + * 7 | o o o o o o o o | + * 6 | o o o o o o o o | + * 5 | o o o o o o o o | + * 4 | o o o o o o o o | + * 3 | o o o o o o o o | + * 2 | o o o o o o o o | + * 1 | o o o o o o o o | + * +------------------------+ + * + * inside Chip carrier + * + * A B C D E F G H + * +------------------------+ + * 8 | | + * 7 | TL TM | + * 6 | +---------+ | + * 5 | | | RT | + * 4 | | | RM | + * 3 | LB | | RB | + * 2 | +---------+ | + * 1 | BL | + * +------------------------+ + * + */ + +enum { + GPIO_BASE, + IOCFG_RT_BASE, + IOCFG_RM_BASE, + IOCFG_RB_BASE, + IOCFG_LB_BASE, + IOCFG_BL_BASE, + IOCFG_TM_BASE, + IOCFG_TL_BASE, +}; + +static const struct mtk_pin_field_calc mt7981_pin_mode_range[] = { + PIN_FIELD_GPIO(0, 56, 0x300, 0x10, 0, 4), +}; + +static const struct mtk_pin_field_calc mt7981_pin_dir_range[] = { + PIN_FIELD_GPIO(0, 56, 0x0, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_di_range[] = { + PIN_FIELD_GPIO(0, 56, 0x200, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_do_range[] = { + PIN_FIELD_GPIO(0, 56, 0x100, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_ies_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x10, 0x10, 1, 1), + PIN_FIELD_BASE(1, 1, 1, 0x10, 0x10, 0, 1), + PIN_FIELD_BASE(2, 2, 5, 0x20, 0x10, 6, 1), + PIN_FIELD_BASE(3, 3, 4, 0x20, 0x10, 6, 1), + PIN_FIELD_BASE(4, 4, 4, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(5, 5, 4, 0x20, 0x10, 1, 1), + PIN_FIELD_BASE(6, 6, 4, 0x20, 0x10, 3, 1), + PIN_FIELD_BASE(7, 7, 4, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(8, 8, 4, 0x20, 0x10, 4, 1), + PIN_FIELD_BASE(9, 9, 4, 0x20, 0x10, 9, 1), + + PIN_FIELD_BASE(10, 10, 5, 0x20, 0x10, 8, 1), + PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1), + PIN_FIELD_BASE(12, 12, 5, 0x20, 0x10, 7, 1), + PIN_FIELD_BASE(13, 13, 5, 0x20, 0x10, 11, 1), + + PIN_FIELD_BASE(14, 14, 4, 0x20, 0x10, 8, 1), + + PIN_FIELD_BASE(15, 15, 2, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(16, 16, 2, 0x20, 0x10, 1, 1), + PIN_FIELD_BASE(17, 17, 2, 0x20, 0x10, 5, 1), + PIN_FIELD_BASE(18, 18, 2, 0x20, 0x10, 4, 1), + PIN_FIELD_BASE(19, 19, 2, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(20, 20, 2, 0x20, 0x10, 3, 1), + PIN_FIELD_BASE(21, 21, 2, 0x20, 0x10, 6, 1), + PIN_FIELD_BASE(22, 22, 2, 0x20, 0x10, 7, 1), + PIN_FIELD_BASE(23, 23, 2, 0x20, 0x10, 10, 1), + PIN_FIELD_BASE(24, 24, 2, 0x20, 0x10, 9, 1), + PIN_FIELD_BASE(25, 25, 2, 0x20, 0x10, 8, 1), + + PIN_FIELD_BASE(26, 26, 5, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(27, 27, 5, 0x20, 0x10, 4, 1), + PIN_FIELD_BASE(28, 28, 5, 0x20, 0x10, 3, 1), + PIN_FIELD_BASE(29, 29, 5, 0x20, 0x10, 1, 1), + PIN_FIELD_BASE(30, 30, 5, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(31, 31, 5, 0x20, 0x10, 5, 1), + + PIN_FIELD_BASE(32, 32, 1, 0x10, 0x10, 2, 1), + PIN_FIELD_BASE(33, 33, 1, 0x10, 0x10, 3, 1), + + PIN_FIELD_BASE(34, 34, 4, 0x20, 0x10, 5, 1), + PIN_FIELD_BASE(35, 35, 4, 0x20, 0x10, 7, 1), + + PIN_FIELD_BASE(36, 36, 3, 0x10, 0x10, 2, 1), + PIN_FIELD_BASE(37, 37, 3, 0x10, 0x10, 3, 1), + PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 0, 1), + PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 1, 1), + + PIN_FIELD_BASE(40, 40, 7, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(41, 41, 7, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(42, 42, 7, 0x30, 0x10, 9, 1), + PIN_FIELD_BASE(43, 43, 7, 0x30, 0x10, 7, 1), + PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1), + PIN_FIELD_BASE(45, 45, 7, 0x30, 0x10, 3, 1), + PIN_FIELD_BASE(46, 46, 7, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(47, 47, 7, 0x30, 0x10, 5, 1), + PIN_FIELD_BASE(48, 48, 7, 0x30, 0x10, 6, 1), + PIN_FIELD_BASE(49, 49, 7, 0x30, 0x10, 2, 1), + + PIN_FIELD_BASE(50, 50, 6, 0x10, 0x10, 0, 1), + PIN_FIELD_BASE(51, 51, 6, 0x10, 0x10, 2, 1), + PIN_FIELD_BASE(52, 52, 6, 0x10, 0x10, 3, 1), + PIN_FIELD_BASE(53, 53, 6, 0x10, 0x10, 4, 1), + PIN_FIELD_BASE(54, 54, 6, 0x10, 0x10, 5, 1), + PIN_FIELD_BASE(55, 55, 6, 0x10, 0x10, 6, 1), + PIN_FIELD_BASE(56, 56, 6, 0x10, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_smt_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x60, 0x10, 1, 1), + PIN_FIELD_BASE(1, 1, 1, 0x60, 0x10, 0, 1), + PIN_FIELD_BASE(2, 2, 5, 0x90, 0x10, 6, 1), + PIN_FIELD_BASE(3, 3, 4, 0x80, 0x10, 6, 1), + PIN_FIELD_BASE(4, 4, 4, 0x80, 0x10, 2, 1), + PIN_FIELD_BASE(5, 5, 4, 0x80, 0x10, 1, 1), + PIN_FIELD_BASE(6, 6, 4, 0x80, 0x10, 3, 1), + PIN_FIELD_BASE(7, 7, 4, 0x80, 0x10, 0, 1), + PIN_FIELD_BASE(8, 8, 4, 0x80, 0x10, 4, 1), + PIN_FIELD_BASE(9, 9, 4, 0x80, 0x10, 9, 1), + + PIN_FIELD_BASE(10, 10, 5, 0x90, 0x10, 8, 1), + PIN_FIELD_BASE(11, 11, 5, 0x90, 0x10, 10, 1), + PIN_FIELD_BASE(12, 12, 5, 0x90, 0x10, 7, 1), + PIN_FIELD_BASE(13, 13, 5, 0x90, 0x10, 11, 1), + + PIN_FIELD_BASE(14, 14, 4, 0x80, 0x10, 8, 1), + + PIN_FIELD_BASE(15, 15, 2, 0x90, 0x10, 0, 1), + PIN_FIELD_BASE(16, 16, 2, 0x90, 0x10, 1, 1), + PIN_FIELD_BASE(17, 17, 2, 0x90, 0x10, 5, 1), + PIN_FIELD_BASE(18, 18, 2, 0x90, 0x10, 4, 1), + PIN_FIELD_BASE(19, 19, 2, 0x90, 0x10, 2, 1), + PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1), + PIN_FIELD_BASE(21, 21, 2, 0x90, 0x10, 6, 1), + PIN_FIELD_BASE(22, 22, 2, 0x90, 0x10, 7, 1), + PIN_FIELD_BASE(23, 23, 2, 0x90, 0x10, 10, 1), + PIN_FIELD_BASE(24, 24, 2, 0x90, 0x10, 9, 1), + PIN_FIELD_BASE(25, 25, 2, 0x90, 0x10, 8, 1), + + PIN_FIELD_BASE(26, 26, 5, 0x90, 0x10, 0, 1), + PIN_FIELD_BASE(27, 27, 5, 0x90, 0x10, 4, 1), + PIN_FIELD_BASE(28, 28, 5, 0x90, 0x10, 3, 1), + PIN_FIELD_BASE(29, 29, 5, 0x90, 0x10, 1, 1), + PIN_FIELD_BASE(30, 30, 5, 0x90, 0x10, 2, 1), + PIN_FIELD_BASE(31, 31, 5, 0x90, 0x10, 5, 1), + + PIN_FIELD_BASE(32, 32, 1, 0x60, 0x10, 2, 1), + PIN_FIELD_BASE(33, 33, 1, 0x60, 0x10, 3, 1), + + PIN_FIELD_BASE(34, 34, 4, 0x80, 0x10, 5, 1), + PIN_FIELD_BASE(35, 35, 4, 0x80, 0x10, 7, 1), + + PIN_FIELD_BASE(36, 36, 3, 0x60, 0x10, 2, 1), + PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 3, 1), + PIN_FIELD_BASE(38, 38, 3, 0x60, 0x10, 0, 1), + PIN_FIELD_BASE(39, 39, 3, 0x60, 0x10, 1, 1), + + PIN_FIELD_BASE(40, 40, 7, 0x70, 0x10, 1, 1), + PIN_FIELD_BASE(41, 41, 7, 0x70, 0x10, 0, 1), + PIN_FIELD_BASE(42, 42, 7, 0x70, 0x10, 9, 1), + PIN_FIELD_BASE(43, 43, 7, 0x70, 0x10, 7, 1), + PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1), + PIN_FIELD_BASE(45, 45, 7, 0x70, 0x10, 3, 1), + PIN_FIELD_BASE(46, 46, 7, 0x70, 0x10, 4, 1), + PIN_FIELD_BASE(47, 47, 7, 0x70, 0x10, 5, 1), + PIN_FIELD_BASE(48, 48, 7, 0x70, 0x10, 6, 1), + PIN_FIELD_BASE(49, 49, 7, 0x70, 0x10, 2, 1), + + PIN_FIELD_BASE(50, 50, 6, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(51, 51, 6, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(52, 52, 6, 0x50, 0x10, 3, 1), + PIN_FIELD_BASE(53, 53, 6, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(54, 54, 6, 0x50, 0x10, 5, 1), + PIN_FIELD_BASE(55, 55, 6, 0x50, 0x10, 6, 1), + PIN_FIELD_BASE(56, 56, 6, 0x50, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_pu_range[] = { + PIN_FIELD_BASE(40, 40, 7, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(41, 41, 7, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(42, 42, 7, 0x50, 0x10, 9, 1), + PIN_FIELD_BASE(43, 43, 7, 0x50, 0x10, 7, 1), + PIN_FIELD_BASE(44, 44, 7, 0x50, 0x10, 8, 1), + PIN_FIELD_BASE(45, 45, 7, 0x50, 0x10, 3, 1), + PIN_FIELD_BASE(46, 46, 7, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(47, 47, 7, 0x50, 0x10, 5, 1), + PIN_FIELD_BASE(48, 48, 7, 0x50, 0x10, 6, 1), + PIN_FIELD_BASE(49, 49, 7, 0x50, 0x10, 2, 1), + + PIN_FIELD_BASE(50, 50, 6, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(51, 51, 6, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(52, 52, 6, 0x30, 0x10, 3, 1), + PIN_FIELD_BASE(53, 53, 6, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(54, 54, 6, 0x30, 0x10, 5, 1), + PIN_FIELD_BASE(55, 55, 6, 0x30, 0x10, 6, 1), + PIN_FIELD_BASE(56, 56, 6, 0x30, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_pd_range[] = { + PIN_FIELD_BASE(40, 40, 7, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(41, 41, 7, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(42, 42, 7, 0x40, 0x10, 9, 1), + PIN_FIELD_BASE(43, 43, 7, 0x40, 0x10, 7, 1), + PIN_FIELD_BASE(44, 44, 7, 0x40, 0x10, 8, 1), + PIN_FIELD_BASE(45, 45, 7, 0x40, 0x10, 3, 1), + PIN_FIELD_BASE(46, 46, 7, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(47, 47, 7, 0x40, 0x10, 5, 1), + PIN_FIELD_BASE(48, 48, 7, 0x40, 0x10, 6, 1), + PIN_FIELD_BASE(49, 49, 7, 0x40, 0x10, 2, 1), + + PIN_FIELD_BASE(50, 50, 6, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(51, 51, 6, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(52, 52, 6, 0x20, 0x10, 3, 1), + PIN_FIELD_BASE(53, 53, 6, 0x20, 0x10, 4, 1), + PIN_FIELD_BASE(54, 54, 6, 0x20, 0x10, 5, 1), + PIN_FIELD_BASE(55, 55, 6, 0x20, 0x10, 6, 1), + PIN_FIELD_BASE(56, 56, 6, 0x20, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_drv_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(1, 1, 1, 0x00, 0x10, 0, 3), + + PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 18, 3), + + PIN_FIELD_BASE(3, 3, 4, 0x00, 0x10, 18, 1), + PIN_FIELD_BASE(4, 4, 4, 0x00, 0x10, 6, 1), + PIN_FIELD_BASE(5, 5, 4, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(6, 6, 4, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(9, 9, 4, 0x00, 0x10, 27, 3), + + PIN_FIELD_BASE(10, 10, 5, 0x00, 0x10, 24, 3), + PIN_FIELD_BASE(11, 11, 5, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(12, 12, 5, 0x00, 0x10, 21, 3), + PIN_FIELD_BASE(13, 13, 5, 0x00, 0x10, 3, 3), + + PIN_FIELD_BASE(14, 14, 4, 0x00, 0x10, 27, 3), + + PIN_FIELD_BASE(15, 15, 2, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(16, 16, 2, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(17, 17, 2, 0x00, 0x10, 15, 3), + PIN_FIELD_BASE(18, 18, 2, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(19, 19, 2, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(20, 20, 2, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(21, 21, 2, 0x00, 0x10, 18, 3), + PIN_FIELD_BASE(22, 22, 2, 0x00, 0x10, 21, 3), + PIN_FIELD_BASE(23, 23, 2, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(24, 24, 2, 0x00, 0x10, 27, 3), + PIN_FIELD_BASE(25, 25, 2, 0x00, 0x10, 24, 3), + + PIN_FIELD_BASE(26, 26, 5, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(27, 27, 5, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(28, 28, 5, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(29, 29, 5, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(30, 30, 5, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(31, 31, 5, 0x00, 0x10, 15, 3), + + PIN_FIELD_BASE(32, 32, 1, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(33, 33, 1, 0x00, 0x10, 12, 3), + + PIN_FIELD_BASE(34, 34, 4, 0x00, 0x10, 15, 3), + PIN_FIELD_BASE(35, 35, 4, 0x00, 0x10, 21, 3), + + PIN_FIELD_BASE(36, 36, 3, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(37, 37, 3, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(38, 38, 3, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(39, 39, 3, 0x00, 0x10, 3, 3), + + PIN_FIELD_BASE(40, 40, 7, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(41, 41, 7, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(42, 42, 7, 0x00, 0x10, 27, 3), + PIN_FIELD_BASE(43, 43, 7, 0x00, 0x10, 21, 3), + PIN_FIELD_BASE(44, 44, 7, 0x00, 0x10, 24, 3), + PIN_FIELD_BASE(45, 45, 7, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(46, 46, 7, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(47, 47, 7, 0x00, 0x10, 15, 3), + PIN_FIELD_BASE(48, 48, 7, 0x00, 0x10, 18, 3), + PIN_FIELD_BASE(49, 49, 7, 0x00, 0x10, 6, 3), + + PIN_FIELD_BASE(50, 50, 6, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(51, 51, 6, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(52, 52, 6, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(53, 53, 6, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(54, 54, 6, 0x00, 0x10, 15, 3), + PIN_FIELD_BASE(55, 55, 6, 0x00, 0x10, 18, 3), + PIN_FIELD_BASE(56, 56, 6, 0x00, 0x10, 3, 3), +}; + +static const struct mtk_pin_field_calc mt7981_pin_pupd_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x20, 0x10, 1, 1), + PIN_FIELD_BASE(1, 1, 1, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 6, 1), + PIN_FIELD_BASE(3, 3, 4, 0x30, 0x10, 6, 1), + PIN_FIELD_BASE(4, 4, 4, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(5, 5, 4, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(6, 6, 4, 0x30, 0x10, 3, 1), + PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(9, 9, 4, 0x30, 0x10, 9, 1), + + PIN_FIELD_BASE(10, 10, 5, 0x30, 0x10, 8, 1), + PIN_FIELD_BASE(11, 11, 5, 0x30, 0x10, 10, 1), + PIN_FIELD_BASE(12, 12, 5, 0x30, 0x10, 7, 1), + PIN_FIELD_BASE(13, 13, 5, 0x30, 0x10, 11, 1), + + PIN_FIELD_BASE(14, 14, 4, 0x30, 0x10, 8, 1), + + PIN_FIELD_BASE(15, 15, 2, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(16, 16, 2, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(17, 17, 2, 0x30, 0x10, 5, 1), + PIN_FIELD_BASE(18, 18, 2, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(19, 19, 2, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1), + PIN_FIELD_BASE(21, 21, 2, 0x30, 0x10, 6, 1), + PIN_FIELD_BASE(22, 22, 2, 0x30, 0x10, 7, 1), + PIN_FIELD_BASE(23, 23, 2, 0x30, 0x10, 10, 1), + PIN_FIELD_BASE(24, 24, 2, 0x30, 0x10, 9, 1), + PIN_FIELD_BASE(25, 25, 2, 0x30, 0x10, 8, 1), + + PIN_FIELD_BASE(26, 26, 5, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(27, 27, 5, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(28, 28, 5, 0x30, 0x10, 3, 1), + PIN_FIELD_BASE(29, 29, 5, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(30, 30, 5, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(31, 31, 5, 0x30, 0x10, 5, 1), + + PIN_FIELD_BASE(32, 32, 1, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(33, 33, 1, 0x20, 0x10, 3, 1), + + PIN_FIELD_BASE(34, 34, 4, 0x30, 0x10, 5, 1), + PIN_FIELD_BASE(35, 35, 4, 0x30, 0x10, 7, 1), + + PIN_FIELD_BASE(36, 36, 3, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(37, 37, 3, 0x20, 0x10, 3, 1), + PIN_FIELD_BASE(38, 38, 3, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(39, 39, 3, 0x20, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_r0_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(1, 1, 1, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(2, 2, 5, 0x40, 0x10, 6, 1), + PIN_FIELD_BASE(3, 3, 4, 0x40, 0x10, 6, 1), + PIN_FIELD_BASE(4, 4, 4, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(5, 5, 4, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(6, 6, 4, 0x40, 0x10, 3, 1), + PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(9, 9, 4, 0x40, 0x10, 9, 1), + + PIN_FIELD_BASE(10, 10, 5, 0x40, 0x10, 8, 1), + PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1), + PIN_FIELD_BASE(12, 12, 5, 0x40, 0x10, 7, 1), + PIN_FIELD_BASE(13, 13, 5, 0x40, 0x10, 11, 1), + + PIN_FIELD_BASE(14, 14, 4, 0x40, 0x10, 8, 1), + + PIN_FIELD_BASE(15, 15, 2, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(16, 16, 2, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(17, 17, 2, 0x40, 0x10, 5, 1), + PIN_FIELD_BASE(18, 18, 2, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(19, 19, 2, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(20, 20, 2, 0x40, 0x10, 3, 1), + PIN_FIELD_BASE(21, 21, 2, 0x40, 0x10, 6, 1), + PIN_FIELD_BASE(22, 22, 2, 0x40, 0x10, 7, 1), + PIN_FIELD_BASE(23, 23, 2, 0x40, 0x10, 10, 1), + PIN_FIELD_BASE(24, 24, 2, 0x40, 0x10, 9, 1), + PIN_FIELD_BASE(25, 25, 2, 0x40, 0x10, 8, 1), + + PIN_FIELD_BASE(26, 26, 5, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(27, 27, 5, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(28, 28, 5, 0x40, 0x10, 3, 1), + PIN_FIELD_BASE(29, 29, 5, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(30, 30, 5, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(31, 31, 5, 0x40, 0x10, 5, 1), + + PIN_FIELD_BASE(32, 32, 1, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(33, 33, 1, 0x30, 0x10, 3, 1), + + PIN_FIELD_BASE(34, 34, 4, 0x40, 0x10, 5, 1), + PIN_FIELD_BASE(35, 35, 4, 0x40, 0x10, 7, 1), + + PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 3, 1), + PIN_FIELD_BASE(38, 38, 3, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(39, 39, 3, 0x30, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_r1_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(1, 1, 1, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 6, 1), + PIN_FIELD_BASE(3, 3, 4, 0x50, 0x10, 6, 1), + PIN_FIELD_BASE(4, 4, 4, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(5, 5, 4, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(6, 6, 4, 0x50, 0x10, 3, 1), + PIN_FIELD_BASE(7, 7, 4, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(8, 8, 4, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(9, 9, 4, 0x50, 0x10, 9, 1), + + PIN_FIELD_BASE(10, 10, 5, 0x50, 0x10, 8, 1), + PIN_FIELD_BASE(11, 11, 5, 0x50, 0x10, 10, 1), + PIN_FIELD_BASE(12, 12, 5, 0x50, 0x10, 7, 1), + PIN_FIELD_BASE(13, 13, 5, 0x50, 0x10, 11, 1), + + PIN_FIELD_BASE(14, 14, 4, 0x50, 0x10, 8, 1), + + PIN_FIELD_BASE(15, 15, 2, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(16, 16, 2, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(17, 17, 2, 0x50, 0x10, 5, 1), + PIN_FIELD_BASE(18, 18, 2, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(19, 19, 2, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(20, 20, 2, 0x50, 0x10, 3, 1), + PIN_FIELD_BASE(21, 21, 2, 0x50, 0x10, 6, 1), + PIN_FIELD_BASE(22, 22, 2, 0x50, 0x10, 7, 1), + PIN_FIELD_BASE(23, 23, 2, 0x50, 0x10, 10, 1), + PIN_FIELD_BASE(24, 24, 2, 0x50, 0x10, 9, 1), + PIN_FIELD_BASE(25, 25, 2, 0x50, 0x10, 8, 1), + + PIN_FIELD_BASE(26, 26, 5, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(27, 27, 5, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(28, 28, 5, 0x50, 0x10, 3, 1), + PIN_FIELD_BASE(29, 29, 5, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(30, 30, 5, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(31, 31, 5, 0x50, 0x10, 5, 1), + + PIN_FIELD_BASE(32, 32, 1, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(33, 33, 1, 0x40, 0x10, 3, 1), + + PIN_FIELD_BASE(34, 34, 4, 0x50, 0x10, 5, 1), + PIN_FIELD_BASE(35, 35, 4, 0x50, 0x10, 7, 1), + + PIN_FIELD_BASE(36, 36, 3, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(37, 37, 3, 0x40, 0x10, 3, 1), + PIN_FIELD_BASE(38, 38, 3, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(39, 39, 3, 0x40, 0x10, 1, 1), +}; + +static const struct mtk_pin_reg_calc mt7981_reg_cals[] = { + [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7981_pin_mode_range), + [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7981_pin_dir_range), + [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7981_pin_di_range), + [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7981_pin_do_range), + [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7981_pin_smt_range), + [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7981_pin_ies_range), + [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7981_pin_pu_range), + [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7981_pin_pd_range), + [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7981_pin_drv_range), + [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7981_pin_pupd_range), + [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7981_pin_r0_range), + [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7981_pin_r1_range), +}; + +static const struct mtk_pin_desc mt7981_pins[] = { + MT7981_TYPE0_PIN(0, "GPIO_WPS"), + MT7981_TYPE0_PIN(1, "GPIO_RESET"), + MT7981_TYPE0_PIN(2, "SYS_WATCHDOG"), + MT7981_TYPE0_PIN(3, "PCIE_PERESET_N"), + MT7981_TYPE0_PIN(4, "JTAG_JTDO"), + MT7981_TYPE0_PIN(5, "JTAG_JTDI"), + MT7981_TYPE0_PIN(6, "JTAG_JTMS"), + MT7981_TYPE0_PIN(7, "JTAG_JTCLK"), + MT7981_TYPE0_PIN(8, "JTAG_JTRST_N"), + MT7981_TYPE0_PIN(9, "WO_JTAG_JTDO"), + MT7981_TYPE0_PIN(10, "WO_JTAG_JTDI"), + MT7981_TYPE0_PIN(11, "WO_JTAG_JTMS"), + MT7981_TYPE0_PIN(12, "WO_JTAG_JTCLK"), + MT7981_TYPE0_PIN(13, "WO_JTAG_JTRST_N"), + MT7981_TYPE0_PIN(14, "USB_VBUS"), + MT7981_TYPE0_PIN(15, "PWM0"), + MT7981_TYPE0_PIN(16, "SPI0_CLK"), + MT7981_TYPE0_PIN(17, "SPI0_MOSI"), + MT7981_TYPE0_PIN(18, "SPI0_MISO"), + MT7981_TYPE0_PIN(19, "SPI0_CS"), + MT7981_TYPE0_PIN(20, "SPI0_HOLD"), + MT7981_TYPE0_PIN(21, "SPI0_WP"), + MT7981_TYPE0_PIN(22, "SPI1_CLK"), + MT7981_TYPE0_PIN(23, "SPI1_MOSI"), + MT7981_TYPE0_PIN(24, "SPI1_MISO"), + MT7981_TYPE0_PIN(25, "SPI1_CS"), + MT7981_TYPE0_PIN(26, "SPI2_CLK"), + MT7981_TYPE0_PIN(27, "SPI2_MOSI"), + MT7981_TYPE0_PIN(28, "SPI2_MISO"), + MT7981_TYPE0_PIN(29, "SPI2_CS"), + MT7981_TYPE0_PIN(30, "SPI2_HOLD"), + MT7981_TYPE0_PIN(31, "SPI2_WP"), + MT7981_TYPE0_PIN(32, "UART0_RXD"), + MT7981_TYPE0_PIN(33, "UART0_TXD"), + MT7981_TYPE0_PIN(34, "PCIE_CLK_REQ"), + MT7981_TYPE0_PIN(35, "PCIE_WAKE_N"), + MT7981_TYPE0_PIN(36, "SMI_MDC"), + MT7981_TYPE0_PIN(37, "SMI_MDIO"), + MT7981_TYPE0_PIN(38, "GBE_INT"), + MT7981_TYPE0_PIN(39, "GBE_RESET"), + MT7981_TYPE1_PIN(40, "WF_DIG_RESETB"), + MT7981_TYPE1_PIN(41, "WF_CBA_RESETB"), + MT7981_TYPE1_PIN(42, "WF_XO_REQ"), + MT7981_TYPE1_PIN(43, "WF_TOP_CLK"), + MT7981_TYPE1_PIN(44, "WF_TOP_DATA"), + MT7981_TYPE1_PIN(45, "WF_HB1"), + MT7981_TYPE1_PIN(46, "WF_HB2"), + MT7981_TYPE1_PIN(47, "WF_HB3"), + MT7981_TYPE1_PIN(48, "WF_HB4"), + MT7981_TYPE1_PIN(49, "WF_HB0"), + MT7981_TYPE1_PIN(50, "WF_HB0_B"), + MT7981_TYPE1_PIN(51, "WF_HB5"), + MT7981_TYPE1_PIN(52, "WF_HB6"), + MT7981_TYPE1_PIN(53, "WF_HB7"), + MT7981_TYPE1_PIN(54, "WF_HB8"), + MT7981_TYPE1_PIN(55, "WF_HB9"), + MT7981_TYPE1_PIN(56, "WF_HB10"), +}; + +/* WA_AICE */ +static int mt7981_wa_aice1_pins[] = { 0, 1, }; +static int mt7981_wa_aice1_funcs[] = { 2, 2, }; + +static int mt7981_wa_aice2_pins[] = { 0, 1, }; +static int mt7981_wa_aice2_funcs[] = { 3, 3, }; + +static int mt7981_wa_aice3_pins[] = { 28, 29, }; +static int mt7981_wa_aice3_funcs[] = { 3, 3, }; + +static int mt7981_wm_aice1_pins[] = { 9, 10, }; +static int mt7981_wm_aice1_funcs[] = { 2, 2, }; + +static int mt7981_wm_aice2_pins[] = { 30, 31, }; +static int mt7981_wm_aice2_funcs[] = { 5, 5, }; + +/* WM_UART */ +static int mt7981_wm_uart_0_pins[] = { 0, 1, }; +static int mt7981_wm_uart_0_funcs[] = { 5, 5, }; + +static int mt7981_wm_uart_1_pins[] = { 20, 21, }; +static int mt7981_wm_uart_1_funcs[] = { 4, 4, }; + +static int mt7981_wm_uart_2_pins[] = { 30, 31, }; +static int mt7981_wm_uart_2_funcs[] = { 3, 3, }; + +/* DFD */ +static int mt7981_dfd_pins[] = { 0, 1, 4, 5, }; +static int mt7981_dfd_funcs[] = { 5, 5, 6, 6, }; + +/* SYS_WATCHDOG */ +static int mt7981_watchdog_pins[] = { 2, }; +static int mt7981_watchdog_funcs[] = { 1, }; + +static int mt7981_watchdog1_pins[] = { 13, }; +static int mt7981_watchdog1_funcs[] = { 5, }; + +/* PCIE_PERESET_N */ +static int mt7981_pcie_pereset_pins[] = { 3, }; +static int mt7981_pcie_pereset_funcs[] = { 1, }; + +/* JTAG */ +static int mt7981_jtag_pins[] = { 4, 5, 6, 7, 8, }; +static int mt7981_jtag_funcs[] = { 1, 1, 1, 1, 1, }; + +/* WM_JTAG */ +static int mt7981_wm_jtag_0_pins[] = { 4, 5, 6, 7, 8, }; +static int mt7981_wm_jtag_0_funcs[] = { 2, 2, 2, 2, 2, }; + +static int mt7981_wm_jtag_1_pins[] = { 20, 21, 22, 23, 24, }; +static int mt7981_wm_jtag_1_funcs[] = { 5, 5, 5, 5, 5, }; + +/* WO0_JTAG */ +static int mt7981_wo0_jtag_0_pins[] = { 9, 10, 11, 12, 13, }; +static int mt7981_wo0_jtag_0_funcs[] = { 1, 1, 1, 1, 1, }; + +static int mt7981_wo0_jtag_1_pins[] = { 25, 26, 27, 28, 29, }; +static int mt7981_wo0_jtag_1_funcs[] = { 5, 5, 5, 5, 5, }; + +/* UART2 */ +static int mt7981_uart2_0_pins[] = { 4, 5, 6, 7, }; +static int mt7981_uart2_0_funcs[] = { 3, 3, 3, 3, }; + +/* GBE_LED0 */ +static int mt7981_gbe_led0_pins[] = { 8, }; +static int mt7981_gbe_led0_funcs[] = { 3, }; + +/* PTA_EXT */ +static int mt7981_pta_ext_0_pins[] = { 4, 5, 6, }; +static int mt7981_pta_ext_0_funcs[] = { 4, 4, 4, }; + +static int mt7981_pta_ext_1_pins[] = { 22, 23, 24, }; +static int mt7981_pta_ext_1_funcs[] = { 4, 4, 4, }; + +/* PWM2 */ +static int mt7981_pwm2_pins[] = { 7, }; +static int mt7981_pwm2_funcs[] = { 4, }; + +/* NET_WO0_UART_TXD */ +static int mt7981_net_wo0_uart_txd_0_pins[] = { 8, }; +static int mt7981_net_wo0_uart_txd_0_funcs[] = { 4, }; + +static int mt7981_net_wo0_uart_txd_1_pins[] = { 14, }; +static int mt7981_net_wo0_uart_txd_1_funcs[] = { 3, }; + +static int mt7981_net_wo0_uart_txd_2_pins[] = { 15, }; +static int mt7981_net_wo0_uart_txd_2_funcs[] = { 4, }; + +/* SPI1 */ +static int mt7981_spi1_0_pins[] = { 4, 5, 6, 7, }; +static int mt7981_spi1_0_funcs[] = { 5, 5, 5, 5, }; + +/* I2C */ +static int mt7981_i2c0_0_pins[] = { 6, 7, }; +static int mt7981_i2c0_0_funcs[] = { 6, 6, }; + +static int mt7981_i2c0_1_pins[] = { 30, 31, }; +static int mt7981_i2c0_1_funcs[] = { 4, 4, }; + +static int mt7981_i2c0_2_pins[] = { 36, 37, }; +static int mt7981_i2c0_2_funcs[] = { 2, 2, }; + +static int mt7981_u2_phy_i2c_pins[] = { 30, 31, }; +static int mt7981_u2_phy_i2c_funcs[] = { 6, 6, }; + +static int mt7981_u3_phy_i2c_pins[] = { 32, 33, }; +static int mt7981_u3_phy_i2c_funcs[] = { 3, 3, }; + +static int mt7981_sgmii1_phy_i2c_pins[] = { 32, 33, }; +static int mt7981_sgmii1_phy_i2c_funcs[] = { 2, 2, }; + +static int mt7981_sgmii0_phy_i2c_pins[] = { 32, 33, }; +static int mt7981_sgmii0_phy_i2c_funcs[] = { 5, 5, }; + +/* DFD_NTRST */ +static int mt7981_dfd_ntrst_pins[] = { 8, }; +static int mt7981_dfd_ntrst_funcs[] = { 6, }; + +/* PWM0 */ +static int mt7981_pwm0_0_pins[] = { 13, }; +static int mt7981_pwm0_0_funcs[] = { 2, }; + +static int mt7981_pwm0_1_pins[] = { 15, }; +static int mt7981_pwm0_1_funcs[] = { 1, }; + +/* PWM1 */ +static int mt7981_pwm1_0_pins[] = { 14, }; +static int mt7981_pwm1_0_funcs[] = { 2, }; + +static int mt7981_pwm1_1_pins[] = { 15, }; +static int mt7981_pwm1_1_funcs[] = { 3, }; + +/* GBE_LED1 */ +static int mt7981_gbe_led1_pins[] = { 13, }; +static int mt7981_gbe_led1_funcs[] = { 3, }; + +/* PCM */ +static int mt7981_pcm_pins[] = { 9, 10, 11, 12, 13, 25 }; +static int mt7981_pcm_funcs[] = { 4, 4, 4, 4, 4, 4, }; + +/* UDI */ +static int mt7981_udi_pins[] = { 9, 10, 11, 12, 13, }; +static int mt7981_udi_funcs[] = { 6, 6, 6, 6, 6, }; + +/* DRV_VBUS */ +static int mt7981_drv_vbus_pins[] = { 14, }; +static int mt7981_drv_vbus_funcs[] = { 1, }; + +/* EMMC */ +static int mt7981_emmc_45_pins[] = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, }; +static int mt7981_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; + +/* SNFI */ +static int mt7981_snfi_pins[] = { 16, 17, 18, 19, 20, 21, }; +static int mt7981_snfi_funcs[] = { 3, 3, 3, 3, 3, 3, }; + +/* SPI0 */ +static int mt7981_spi0_pins[] = { 16, 17, 18, 19, }; +static int mt7981_spi0_funcs[] = { 1, 1, 1, 1, }; + +/* SPI0 */ +static int mt7981_spi0_wp_hold_pins[] = { 20, 21, }; +static int mt7981_spi0_wp_hold_funcs[] = { 1, 1, }; + +/* SPI1 */ +static int mt7981_spi1_1_pins[] = { 22, 23, 24, 25, }; +static int mt7981_spi1_1_funcs[] = { 1, 1, 1, 1, }; + +/* SPI2 */ +static int mt7981_spi2_pins[] = { 26, 27, 28, 29, }; +static int mt7981_spi2_funcs[] = { 1, 1, 1, 1, }; + +/* SPI2 */ +static int mt7981_spi2_wp_hold_pins[] = { 30, 31, }; +static int mt7981_spi2_wp_hold_funcs[] = { 1, 1, }; + +/* UART1 */ +static int mt7981_uart1_0_pins[] = { 16, 17, 18, 19, }; +static int mt7981_uart1_0_funcs[] = { 4, 4, 4, 4, }; + +static int mt7981_uart1_1_pins[] = { 26, 27, 28, 29, }; +static int mt7981_uart1_1_funcs[] = { 2, 2, 2, 2, }; + +/* UART2 */ +static int mt7981_uart2_1_pins[] = { 22, 23, 24, 25, }; +static int mt7981_uart2_1_funcs[] = { 3, 3, 3, 3, }; + +/* UART0 */ +static int mt7981_uart0_pins[] = { 32, 33, }; +static int mt7981_uart0_funcs[] = { 1, 1, }; + +/* PCIE_CLK_REQ */ +static int mt7981_pcie_clk_pins[] = { 34, }; +static int mt7981_pcie_clk_funcs[] = { 2, }; + +/* PCIE_WAKE_N */ +static int mt7981_pcie_wake_pins[] = { 35, }; +static int mt7981_pcie_wake_funcs[] = { 2, }; + +/* MDC_MDIO */ +static int mt7981_smi_mdc_mdio_pins[] = { 36, 37, }; +static int mt7981_smi_mdc_mdio_funcs[] = { 1, 1, }; + +static int mt7981_gbe_ext_mdc_mdio_pins[] = { 36, 37, }; +static int mt7981_gbe_ext_mdc_mdio_funcs[] = { 3, 3, }; + +/* WF0_MODE1 */ +static int mt7981_wf0_mode1_pins[] = { 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56 }; +static int mt7981_wf0_mode1_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1 }; + +/* WF0_MODE3 */ +static int mt7981_wf0_mode3_pins[] = { 45, 46, 47, 48, 49, 51 }; +static int mt7981_wf0_mode3_funcs[] = { 2, 2, 2, 2, 2, 2 }; + +/* WF2G_LED */ +static int mt7981_wf2g_led0_pins[] = { 30, }; +static int mt7981_wf2g_led0_funcs[] = { 2, }; + +static int mt7981_wf2g_led1_pins[] = { 34, }; +static int mt7981_wf2g_led1_funcs[] = { 1, }; + +/* WF5G_LED */ +static int mt7981_wf5g_led0_pins[] = { 31, }; +static int mt7981_wf5g_led0_funcs[] = { 2, }; + +static int mt7981_wf5g_led1_pins[] = { 35, }; +static int mt7981_wf5g_led1_funcs[] = { 1, }; + +/* MT7531_INT */ +static int mt7981_mt7531_int_pins[] = { 38, }; +static int mt7981_mt7531_int_funcs[] = { 1, }; + +/* ANT_SEL */ +static int mt7981_ant_sel_pins[] = { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 34, 35 }; +static int mt7981_ant_sel_funcs[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }; + +static const struct mtk_group_desc mt7981_groups[] = { + /* @GPIO(0,1): WA_AICE(2) */ + PINCTRL_PIN_GROUP("wa_aice1", mt7981_wa_aice1), + /* @GPIO(0,1): WA_AICE(3) */ + PINCTRL_PIN_GROUP("wa_aice2", mt7981_wa_aice2), + /* @GPIO(0,1): WM_UART(5) */ + PINCTRL_PIN_GROUP("wm_uart_0", mt7981_wm_uart_0), + /* @GPIO(0,1,4,5): DFD(6) */ + PINCTRL_PIN_GROUP("dfd", mt7981_dfd), + /* @GPIO(2): SYS_WATCHDOG(1) */ + PINCTRL_PIN_GROUP("watchdog", mt7981_watchdog), + /* @GPIO(3): PCIE_PERESET_N(1) */ + PINCTRL_PIN_GROUP("pcie_pereset", mt7981_pcie_pereset), + /* @GPIO(4,8) JTAG(1) */ + PINCTRL_PIN_GROUP("jtag", mt7981_jtag), + /* @GPIO(4,8) WM_JTAG(2) */ + PINCTRL_PIN_GROUP("wm_jtag_0", mt7981_wm_jtag_0), + /* @GPIO(9,13) WO0_JTAG(1) */ + PINCTRL_PIN_GROUP("wo0_jtag_0", mt7981_wo0_jtag_0), + /* @GPIO(4,7) WM_JTAG(3) */ + PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_0), + /* @GPIO(8) GBE_LED0(3) */ + PINCTRL_PIN_GROUP("gbe_led0", mt7981_gbe_led0), + /* @GPIO(4,6) PTA_EXT(4) */ + PINCTRL_PIN_GROUP("pta_ext_0", mt7981_pta_ext_0), + /* @GPIO(7) PWM2(4) */ + PINCTRL_PIN_GROUP("pwm2", mt7981_pwm2), + /* @GPIO(8) NET_WO0_UART_TXD(4) */ + PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7981_net_wo0_uart_txd_0), + /* @GPIO(4,7) SPI1(5) */ + PINCTRL_PIN_GROUP("spi1_0", mt7981_spi1_0), + /* @GPIO(6,7) I2C(5) */ + PINCTRL_PIN_GROUP("i2c0_0", mt7981_i2c0_0), + /* @GPIO(8): DFD_NTRST(6) */ + PINCTRL_PIN_GROUP("dfd_ntrst", mt7981_dfd_ntrst), + /* @GPIO(9,10): WM_AICE(2) */ + PINCTRL_PIN_GROUP("wm_aice1", mt7981_wm_aice1), + /* @GPIO(13): PWM0(2) */ + PINCTRL_PIN_GROUP("pwm0_0", mt7981_pwm0_0), + /* @GPIO(15): PWM0(1) */ + PINCTRL_PIN_GROUP("pwm0_1", mt7981_pwm0_1), + /* @GPIO(14): PWM1(2) */ + PINCTRL_PIN_GROUP("pwm1_0", mt7981_pwm1_0), + /* @GPIO(15): PWM1(3) */ + PINCTRL_PIN_GROUP("pwm1_1", mt7981_pwm1_1), + /* @GPIO(14) NET_WO0_UART_TXD(3) */ + PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7981_net_wo0_uart_txd_1), + /* @GPIO(15) NET_WO0_UART_TXD(4) */ + PINCTRL_PIN_GROUP("net_wo0_uart_txd_2", mt7981_net_wo0_uart_txd_2), + /* @GPIO(13) GBE_LED0(3) */ + PINCTRL_PIN_GROUP("gbe_led1", mt7981_gbe_led1), + /* @GPIO(9,13) PCM(4) */ + PINCTRL_PIN_GROUP("pcm", mt7981_pcm), + /* @GPIO(13): SYS_WATCHDOG1(5) */ + PINCTRL_PIN_GROUP("watchdog1", mt7981_watchdog1), + /* @GPIO(9,13) UDI(4) */ + PINCTRL_PIN_GROUP("udi", mt7981_udi), + /* @GPIO(14) DRV_VBUS(1) */ + PINCTRL_PIN_GROUP("drv_vbus", mt7981_drv_vbus), + /* @GPIO(15,25): EMMC(2) */ + PINCTRL_PIN_GROUP("emmc_45", mt7981_emmc_45), + /* @GPIO(16,21): SNFI(3) */ + PINCTRL_PIN_GROUP("snfi", mt7981_snfi), + /* @GPIO(16,19): SPI0(1) */ + PINCTRL_PIN_GROUP("spi0", mt7981_spi0), + /* @GPIO(20,21): SPI0(1) */ + PINCTRL_PIN_GROUP("spi0_wp_hold", mt7981_spi0_wp_hold), + /* @GPIO(22,25) SPI1(1) */ + PINCTRL_PIN_GROUP("spi1_1", mt7981_spi1_1), + /* @GPIO(26,29): SPI2(1) */ + PINCTRL_PIN_GROUP("spi2", mt7981_spi2), + /* @GPIO(30,31): SPI2(1) */ + PINCTRL_PIN_GROUP("spi2_wp_hold", mt7981_spi2_wp_hold), + /* @GPIO(16,19): UART1(4) */ + PINCTRL_PIN_GROUP("uart1_0", mt7981_uart1_0), + /* @GPIO(26,29): UART1(2) */ + PINCTRL_PIN_GROUP("uart1_1", mt7981_uart1_1), + /* @GPIO(22,25): UART2(3) */ + PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_1), + /* @GPIO(22,24) PTA_EXT(4) */ + PINCTRL_PIN_GROUP("pta_ext_1", mt7981_pta_ext_1), + /* @GPIO(20,21): WM_UART(4) */ + PINCTRL_PIN_GROUP("wm_aurt_1", mt7981_wm_uart_1), + /* @GPIO(30,31): WM_UART(3) */ + PINCTRL_PIN_GROUP("wm_aurt_2", mt7981_wm_uart_2), + /* @GPIO(20,24) WM_JTAG(5) */ + PINCTRL_PIN_GROUP("wm_jtag_1", mt7981_wm_jtag_1), + /* @GPIO(25,29) WO0_JTAG(5) */ + PINCTRL_PIN_GROUP("wo0_jtag_1", mt7981_wo0_jtag_1), + /* @GPIO(28,29): WA_AICE(3) */ + PINCTRL_PIN_GROUP("wa_aice3", mt7981_wa_aice3), + /* @GPIO(30,31): WM_AICE(5) */ + PINCTRL_PIN_GROUP("wm_aice2", mt7981_wm_aice2), + /* @GPIO(30,31): I2C(4) */ + PINCTRL_PIN_GROUP("i2c0_1", mt7981_i2c0_1), + /* @GPIO(30,31): I2C(6) */ + PINCTRL_PIN_GROUP("u2_phy_i2c", mt7981_u2_phy_i2c), + /* @GPIO(32,33): I2C(1) */ + PINCTRL_PIN_GROUP("uart0", mt7981_uart0), + /* @GPIO(32,33): I2C(2) */ + PINCTRL_PIN_GROUP("sgmii1_phy_i2c", mt7981_sgmii1_phy_i2c), + /* @GPIO(32,33): I2C(3) */ + PINCTRL_PIN_GROUP("u3_phy_i2c", mt7981_u3_phy_i2c), + /* @GPIO(32,33): I2C(5) */ + PINCTRL_PIN_GROUP("sgmii0_phy_i2c", mt7981_sgmii0_phy_i2c), + /* @GPIO(34): PCIE_CLK_REQ(2) */ + PINCTRL_PIN_GROUP("pcie_clk", mt7981_pcie_clk), + /* @GPIO(35): PCIE_WAKE_N(2) */ + PINCTRL_PIN_GROUP("pcie_wake", mt7981_pcie_wake), + /* @GPIO(36,37): I2C(2) */ + PINCTRL_PIN_GROUP("i2c0_2", mt7981_i2c0_2), + /* @GPIO(36,37): MDC_MDIO(1) */ + PINCTRL_PIN_GROUP("smi_mdc_mdio", mt7981_smi_mdc_mdio), + /* @GPIO(36,37): MDC_MDIO(3) */ + PINCTRL_PIN_GROUP("gbe_ext_mdc_mdio", mt7981_gbe_ext_mdc_mdio), + /* @GPIO(40,56): WF0_MODE1(1) */ + PINCTRL_PIN_GROUP("wf0_mode1", mt7981_wf0_mode1), + /* @GPIO(45,46,47,48,49,51): WF0_MODE3(3) */ + PINCTRL_PIN_GROUP("wf0_mode3", mt7981_wf0_mode3), + /* @GPIO(30): WF2G_LED(2) */ + PINCTRL_PIN_GROUP("wf2g_led0", mt7981_wf2g_led0), + /* @GPIO(34): WF2G_LED(1) */ + PINCTRL_PIN_GROUP("wf2g_led1", mt7981_wf2g_led1), + /* @GPIO(31): WF5G_LED(2) */ + PINCTRL_PIN_GROUP("wf5g_led0", mt7981_wf5g_led0), + /* @GPIO(35): WF5G_LED(1) */ + PINCTRL_PIN_GROUP("wf5g_led1", mt7981_wf5g_led1), + /* @GPIO(38): MT7531_INT(1) */ + PINCTRL_PIN_GROUP("mt7531_int", mt7981_mt7531_int), + /* @GPIO(14,15,26,17,18,19,20,21,22,23,24,25,34,35): ANT_SEL(1) */ + PINCTRL_PIN_GROUP("ant_sel", mt7981_ant_sel), +}; + +static const struct mtk_io_type_desc mt7981_io_type_desc[] = { + [IO_TYPE_GRP0] = { + .name = "18OD33", + .bias_set = mtk_pinconf_bias_set_pupd_r1_r0, + .drive_set = mtk_pinconf_drive_set_v1, + .input_enable = mtk_pinconf_input_enable_v1, + }, + [IO_TYPE_GRP1] = { + .name = "18A01", + .bias_set = mtk_pinconf_bias_set_pu_pd, + .drive_set = mtk_pinconf_drive_set_v1, + .input_enable = mtk_pinconf_input_enable_v1, + }, +}; + +/* Joint those groups owning the same capability in user point of view which + * allows that people tend to use through the device tree. + */ +static const char *const mt7981_wa_aice_groups[] = { "wa_aice1", "wa_aice2", + "wm_aice1_1", "wa_aice3", "wm_aice1_2", }; +static const char *const mt7981_uart_groups[] = { "wm_uart_0", "uart2_0", + "net_wo0_uart_txd_0", "net_wo0_uart_txd_1", "net_wo0_uart_txd_2", + "uart1_0", "uart1_1", "uart2_0", "wm_aurt_1", "wm_aurt_2", "uart0", }; +static const char *const mt7981_dfd_groups[] = { "dfd", "dfd_ntrst", }; +static const char *const mt7981_wdt_groups[] = { "watchdog", "watchdog1", }; +static const char *const mt7981_pcie_groups[] = { "pcie_pereset", "pcie_clk", + "pcie_wake", }; +static const char *const mt7981_jtag_groups[] = { "jtag", "wm_jtag_0", + "wo0_jtag_0", "wo0_jtag_1", "wm_jtag_1", }; +static const char *const mt7981_led_groups[] = { "gbe_led0", "gbe_led1", + "wf2g_led0", "wf2g_led1", "wf5g_led0", "wf5g_led1", }; +static const char *const mt7981_pta_groups[] = { "pta_ext_0", "pta_ext_1", }; +static const char *const mt7981_pwm_groups[] = { "pwm2", "pwm0_0", "pwm0_1", + "pwm1_0", "pwm1_1", }; +static const char *const mt7981_spi_groups[] = { "spi1_0", "spi0", + "spi0_wp_hold", "spi1_1", "spi2", "spi2_wp_hold", }; +static const char *const mt7981_i2c_groups[] = { "i2c0_0", "i2c0_1", + "u2_phy_i2c", "sgmii1_phy_i2c", "u3_phy_i2c", "sgmii0_phy_i2c", + "i2c0_2", }; +static const char *const mt7981_pcm_groups[] = { "pcm", }; +static const char *const mt7981_udi_groups[] = { "udi", }; +static const char *const mt7981_usb_groups[] = { "drv_vbus", }; +static const char *const mt7981_flash_groups[] = { "emmc_45", "snfi", }; +static const char *const mt7981_ethernet_groups[] = { "smi_mdc_mdio", + "gbe_ext_mdc_mdio", "wf0_mode1", "wf0_mode3", "mt7531_int", }; +static const char *const mt7981_ant_groups[] = { "ant_sel", }; + +static const struct mtk_function_desc mt7981_functions[] = { + {"wa_aice", mt7981_wa_aice_groups, ARRAY_SIZE(mt7981_wa_aice_groups)}, + {"dfd", mt7981_dfd_groups, ARRAY_SIZE(mt7981_dfd_groups)}, + {"jtag", mt7981_jtag_groups, ARRAY_SIZE(mt7981_jtag_groups)}, + {"pta", mt7981_pta_groups, ARRAY_SIZE(mt7981_pta_groups)}, + {"pcm", mt7981_pcm_groups, ARRAY_SIZE(mt7981_pcm_groups)}, + {"udi", mt7981_udi_groups, ARRAY_SIZE(mt7981_udi_groups)}, + {"usb", mt7981_usb_groups, ARRAY_SIZE(mt7981_usb_groups)}, + {"ant", mt7981_ant_groups, ARRAY_SIZE(mt7981_ant_groups)}, + {"eth", mt7981_ethernet_groups, ARRAY_SIZE(mt7981_ethernet_groups)}, + {"i2c", mt7981_i2c_groups, ARRAY_SIZE(mt7981_i2c_groups)}, + {"led", mt7981_led_groups, ARRAY_SIZE(mt7981_led_groups)}, + {"pwm", mt7981_pwm_groups, ARRAY_SIZE(mt7981_pwm_groups)}, + {"spi", mt7981_spi_groups, ARRAY_SIZE(mt7981_spi_groups)}, + {"uart", mt7981_uart_groups, ARRAY_SIZE(mt7981_uart_groups)}, + {"watchdog", mt7981_wdt_groups, ARRAY_SIZE(mt7981_wdt_groups)}, + {"flash", mt7981_flash_groups, ARRAY_SIZE(mt7981_flash_groups)}, + {"pcie", mt7981_pcie_groups, ARRAY_SIZE(mt7981_pcie_groups)}, +}; + +static const char *const mt7981_pinctrl_register_base_names[] = { + "gpio_base", "iocfg_rt_base", "iocfg_rm_base", "iocfg_rb_base", + "iocfg_lb_base", "iocfg_bl_base", "iocfg_tm_base", "iocfg_tl_base", +}; + +static struct mtk_pinctrl_soc mt7981_data = { + .name = "mt7981_pinctrl", + .reg_cal = mt7981_reg_cals, + .pins = mt7981_pins, + .npins = ARRAY_SIZE(mt7981_pins), + .grps = mt7981_groups, + .ngrps = ARRAY_SIZE(mt7981_groups), + .funcs = mt7981_functions, + .nfuncs = ARRAY_SIZE(mt7981_functions), + .io_type = mt7981_io_type_desc, + .ntype = ARRAY_SIZE(mt7981_io_type_desc), + .gpio_mode = 0, + .base_names = mt7981_pinctrl_register_base_names, + .nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names), + .base_calc = 1, +}; + +static int mtk_pinctrl_mt7981_probe(struct udevice *dev) +{ + return mtk_pinctrl_common_probe(dev, &mt7981_data); +} + +static const struct udevice_id mt7981_pctrl_match[] = { + {.compatible = "mediatek,mt7981-pinctrl"}, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(mt7981_pinctrl) = { + .name = "mt7981_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = mt7981_pctrl_match, + .ops = &mtk_pinctrl_ops, + .probe = mtk_pinctrl_mt7981_probe, + .priv_auto = sizeof(struct mtk_pinctrl_priv), +}; diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7986.c b/drivers/pinctrl/mediatek/pinctrl-mt7986.c new file mode 100644 index 0000000000..449e5adcd9 --- /dev/null +++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c @@ -0,0 +1,775 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * The MT7986 driver based on Linux generic pinctrl binding. + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include "pinctrl-mtk-common.h" + +#define MT7986_TYPE0_PIN(_number, _name) \ + MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP0) + +#define MT7986_TYPE1_PIN(_number, _name) \ + MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP1) + +#define PIN_FIELD_GPIO(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \ + PIN_FIELD_BASE_CALC(_s_pin, _e_pin, GPIO_BASE, _s_addr, _x_addrs, \ + _s_bit, _x_bits, 32, 0) + +#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ + _x_bits) \ + PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ + _x_bits, 32, 0) + +/** + * enum - Locking variants of the iocfg bases + * + * MT7986 have multiple bases to program pin configuration listed as the below: + * iocfg_rt:0x11c30000, iocfg_rb:0x11c40000, iocfg_lt:0x11e20000, + * iocfg_lb:0x11e30000, iocfg_tr:0x11f00000, iocfg_tl:0x11f10000, + * _i_based could be used to indicate what base the pin should be mapped into. + * + * Each iocfg register base control different group of pads on the SoC + * + * + * chip carrier + * + * A B C D E F G H + * +------------------------+ + * 8 | o o o o o o o o | + * 7 | o o o o o o o o | + * 6 | o o o o o o o o | + * 5 | o o o o o o o o | + * 4 | o o o o o o o o | + * 3 | o o o o o o o o | + * 2 | o o o o o o o o | + * 1 | o o o o o o o o | + * +------------------------+ + * + * inside Chip carrier + * + * A B C D E F G H + * +------------------------+ + * 8 | | + * 7 | TL TR | + * 6 | +---------+ | + * 5 | LT | | RT | + * 4 | | | | + * 3 | LB | | RB | + * 2 | +---------+ | + * 1 | | + * +------------------------+ + * + */ + +enum { + GPIO_BASE, + IOCFG_RT_BASE, + IOCFG_RB_BASE, + IOCFG_LT_BASE, + IOCFG_LB_BASE, + IOCFG_TR_BASE, + IOCFG_TL_BASE, +}; + +static const char *const mt7986_pinctrl_register_base_names[] = { + "gpio", "iocfg_rt", "iocfg_rb", "iocfg_lt", "iocfg_lb", "iocfg_tr", + "iocfg_tl", +}; + +static const struct mtk_pin_field_calc mt7986_pin_mode_range[] = { + PIN_FIELD_GPIO(0, 100, 0x300, 0x10, 0, 4), +}; + +static const struct mtk_pin_field_calc mt7986_pin_dir_range[] = { + PIN_FIELD_GPIO(0, 100, 0x0, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_di_range[] = { + PIN_FIELD_GPIO(0, 100, 0x200, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_do_range[] = { + PIN_FIELD_GPIO(0, 100, 0x100, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_ies_range[] = { + PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x40, 0x10, 17, 1), + PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x20, 0x10, 10, 1), + PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x40, 0x10, 8, 1), + PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x30, 0x10, 12, 1), + PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x30, 0x10, 18, 1), + PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x30, 0x10, 17, 1), + PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x30, 0x10, 15, 1), + PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x30, 0x10, 19, 1), + PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x30, 0x10, 23, 1), + PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x30, 0x10, 22, 1), + PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x30, 0x10, 21, 1), + PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x20, 0x10, 4, 1), + PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x20, 0x10, 8, 1), + PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x20, 0x10, 7, 1), + PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x20, 0x10, 5, 1), + PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x20, 0x10, 9, 1), + PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x40, 0x10, 18, 1), + PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x40, 0x10, 12, 1), + PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x40, 0x10, 22, 1), + PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x40, 0x10, 20, 1), + PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x40, 0x10, 26, 1), + PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x40, 0x10, 24, 1), + PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x30, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x40, 0x10, 15, 1), + PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x40, 0x10, 14, 1), + PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x40, 0x10, 13, 1), + PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x40, 0x10, 16, 1), + PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x30, 0x10, 16, 1), + PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x30, 0x10, 14, 1), + PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x30, 0x10, 6, 1), + PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x30, 0x10, 9, 1), + PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x30, 0x10, 5, 1), + PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x30, 0x10, 14, 1), + PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x30, 0x10, 12, 1), + PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x30, 0x10, 8, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_smt_range[] = { + PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0xf0, 0x10, 17, 1), + PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x90, 0x10, 10, 1), + PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x90, 0x10, 0, 1), + PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0xf0, 0x10, 0, 1), + PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x90, 0x10, 0, 1), + PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0xf0, 0x10, 8, 1), + PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0xf0, 0x10, 2, 1), + PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0xc0, 0x10, 12, 1), + PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0xc0, 0x10, 18, 1), + PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0xc0, 0x10, 17, 1), + PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0xc0, 0x10, 15, 1), + PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0xc0, 0x10, 19, 1), + PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0xc0, 0x10, 23, 1), + PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0xc0, 0x10, 22, 1), + PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0xc0, 0x10, 21, 1), + PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x90, 0x10, 4, 1), + PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x90, 0x10, 8, 1), + PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x90, 0x10, 7, 1), + PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x90, 0x10, 5, 1), + PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x90, 0x10, 9, 1), + PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0xf0, 0x10, 18, 1), + PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0xf0, 0x10, 12, 1), + PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0xf0, 0x10, 22, 1), + PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0xf0, 0x10, 20, 1), + PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0xf0, 0x10, 26, 1), + PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0xf0, 0x10, 24, 1), + PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0xc0, 0x10, 2, 1), + PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0xc0, 0x10, 1, 1), + PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0xc0, 0x10, 0, 1), + PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0xc0, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0xf0, 0x10, 15, 1), + PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0xf0, 0x10, 14, 1), + PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0xf0, 0x10, 13, 1), + PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0xf0, 0x10, 16, 1), + PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x90, 0x10, 2, 1), + PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x80, 0x10, 1, 1), + PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x80, 0x10, 0, 1), + PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x80, 0x10, 16, 1), + PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x80, 0x10, 14, 1), + PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x80, 0x10, 4, 1), + PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x80, 0x10, 6, 1), + PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x80, 0x10, 2, 1), + PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x80, 0x10, 9, 1), + PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x80, 0x10, 5, 1), + PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x70, 0x10, 1, 1), + PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x70, 0x10, 0, 1), + PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x70, 0x10, 14, 1), + PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x70, 0x10, 12, 1), + PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x70, 0x10, 4, 1), + PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x70, 0x10, 2, 1), + PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x70, 0x10, 8, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_pu_range[] = { + PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x50, 0x10, 16, 1), + PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x50, 0x10, 14, 1), + PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x50, 0x10, 6, 1), + PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x50, 0x10, 9, 1), + PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x50, 0x10, 5, 1), + PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x50, 0x10, 14, 1), + PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x50, 0x10, 12, 1), + PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x50, 0x10, 8, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_pd_range[] = { + PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x40, 0x10, 16, 1), + PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x40, 0x10, 14, 1), + PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x40, 0x10, 6, 1), + PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x40, 0x10, 9, 1), + PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x40, 0x10, 5, 1), + PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x40, 0x10, 14, 1), + PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x40, 0x10, 12, 1), + PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x40, 0x10, 8, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_drv_range[] = { + PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x10, 0x10, 21, 3), + PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x10, 0x10, 0, 3), + PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x00, 0x10, 0, 1), + PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0x00, 0x10, 21, 3), + PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(11, 12, IOCFG_RB_BASE, 0x00, 0x10, 24, 3), + PIN_FIELD_BASE(13, 14, IOCFG_RB_BASE, 0x10, 0x10, 0, 3), + PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x10, 0x10, 6, 3), + PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x10, 0x10, 24, 3), + PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x10, 0x10, 21, 3), + PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x10, 0x10, 15, 3), + PIN_FIELD_BASE(28, 28, IOCFG_RT_BASE, 0x10, 0x10, 27, 3), + PIN_FIELD_BASE(29, 29, IOCFG_RT_BASE, 0x20, 0x10, 0, 3), + PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x20, 0x10, 9, 3), + PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x20, 0x10, 6, 3), + PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x20, 0x10, 3, 3), + PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x00, 0x10, 24, 3), + PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x00, 0x10, 21, 3), + PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x00, 0x10, 15, 3), + PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x00, 0x10, 27, 3), + PIN_FIELD_BASE(39, 39, IOCFG_RB_BASE, 0x10, 0x10, 27, 3), + PIN_FIELD_BASE(40, 40, IOCFG_RB_BASE, 0x20, 0x10, 0, 3), + PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x10, 0x10, 6, 3), + PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x20, 0x10, 9, 3), + PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x20, 0x10, 3, 3), + PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x20, 0x10, 21, 3), + PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x20, 0x10, 15, 3), + PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x10, 0x10, 0, 3), + PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x10, 0x10, 15, 3), + PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x10, 0x10, 12, 3), + PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x10, 0x10, 9, 3), + PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x10, 0x10, 18, 3), + PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x00, 0x10, 2, 3), + PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x10, 0x10, 18, 3), + PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x10, 0x10, 12, 3), + PIN_FIELD_BASE(74, 77, IOCFG_TR_BASE, 0x00, 0x10, 15, 3), + PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(80, 80, IOCFG_TR_BASE, 0x00, 0x10, 27, 3), + PIN_FIELD_BASE(81, 84, IOCFG_TR_BASE, 0x10, 0x10, 0, 3), + PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x10, 0x10, 12, 3), + PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x10, 0x10, 6, 3), + PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(97, 98, IOCFG_TL_BASE, 0x00, 0x10, 24, 3), + PIN_FIELD_BASE(99, 100, IOCFG_TL_BASE, 0x10, 0x10, 2, 3), +}; + +static const struct mtk_pin_field_calc mt7986_pin_pupd_range[] = { + PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x60, 0x10, 17, 1), + PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x30, 0x10, 10, 1), + PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x60, 0x10, 0, 1), + PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x60, 0x10, 8, 1), + PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x60, 0x10, 2, 1), + PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x40, 0x10, 12, 1), + PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x40, 0x10, 18, 1), + PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x40, 0x10, 17, 1), + PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x40, 0x10, 15, 1), + PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x40, 0x10, 19, 1), + PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x40, 0x10, 23, 1), + PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x40, 0x10, 22, 1), + PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x40, 0x10, 21, 1), + PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x30, 0x10, 8, 1), + PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x30, 0x10, 7, 1), + PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x30, 0x10, 5, 1), + PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x30, 0x10, 9, 1), + PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x60, 0x10, 18, 1), + PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x60, 0x10, 12, 1), + PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x60, 0x10, 23, 1), + PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x60, 0x10, 21, 1), + PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x60, 0x10, 27, 1), + PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x60, 0x10, 25, 1), + PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x40, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x60, 0x10, 15, 1), + PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x60, 0x10, 14, 1), + PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x60, 0x10, 13, 1), + PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x60, 0x10, 16, 1), + PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x40, 0x10, 2, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_r0_range[] = { + PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x70, 0x10, 17, 1), + PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x40, 0x10, 10, 1), + PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x70, 0x10, 0, 1), + PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x70, 0x10, 8, 1), + PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x70, 0x10, 2, 1), + PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x50, 0x10, 12, 1), + PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x50, 0x10, 18, 1), + PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x50, 0x10, 17, 1), + PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x50, 0x10, 15, 1), + PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x50, 0x10, 19, 1), + PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x50, 0x10, 23, 1), + PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x50, 0x10, 22, 1), + PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x50, 0x10, 21, 1), + PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x40, 0x10, 8, 1), + PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x40, 0x10, 7, 1), + PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x40, 0x10, 5, 1), + PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x40, 0x10, 9, 1), + PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x70, 0x10, 18, 1), + PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x70, 0x10, 12, 1), + PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x70, 0x10, 23, 1), + PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x70, 0x10, 21, 1), + PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x70, 0x10, 27, 1), + PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x70, 0x10, 25, 1), + PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x50, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x70, 0x10, 15, 1), + PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x70, 0x10, 14, 1), + PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x70, 0x10, 13, 1), + PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x70, 0x10, 16, 1), + PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x50, 0x10, 2, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_r1_range[] = { + PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x80, 0x10, 17, 1), + PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x50, 0x10, 10, 1), + PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x60, 0x10, 0, 1), + PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x80, 0x10, 0, 1), + PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x80, 0x10, 8, 1), + PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x80, 0x10, 2, 1), + PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x60, 0x10, 12, 1), + PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x60, 0x10, 18, 1), + PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x60, 0x10, 17, 1), + PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x60, 0x10, 15, 1), + PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x60, 0x10, 19, 1), + PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x60, 0x10, 23, 1), + PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x60, 0x10, 22, 1), + PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x60, 0x10, 21, 1), + PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x50, 0x10, 8, 1), + PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x50, 0x10, 7, 1), + PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x50, 0x10, 5, 1), + PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x50, 0x10, 9, 1), + PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x80, 0x10, 18, 1), + PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x80, 0x10, 12, 1), + PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x80, 0x10, 23, 1), + PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x80, 0x10, 21, 1), + PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x80, 0x10, 27, 1), + PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x80, 0x10, 25, 1), + PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x60, 0x10, 2, 1), + PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x60, 0x10, 1, 1), + PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x60, 0x10, 0, 1), + PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x60, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x80, 0x10, 15, 1), + PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x80, 0x10, 14, 1), + PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x80, 0x10, 13, 1), + PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x80, 0x10, 16, 1), + PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x60, 0x10, 2, 1), +}; + +static const struct mtk_pin_reg_calc mt7986_reg_cals[] = { + [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7986_pin_mode_range), + [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7986_pin_dir_range), + [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7986_pin_di_range), + [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7986_pin_do_range), + [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7986_pin_smt_range), + [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7986_pin_ies_range), + [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7986_pin_drv_range), + [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7986_pin_pu_range), + [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7986_pin_pd_range), + [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7986_pin_pupd_range), + [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7986_pin_r0_range), + [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7986_pin_r1_range), +}; + +static const struct mtk_pin_desc mt7986_pins[] = { + MT7986_TYPE0_PIN(0, "SYS_WATCHDOG"), + MT7986_TYPE0_PIN(1, "WF2G_LED"), + MT7986_TYPE0_PIN(2, "WF5G_LED"), + MT7986_TYPE0_PIN(3, "I2C_SCL"), + MT7986_TYPE0_PIN(4, "I2C_SDA"), + MT7986_TYPE0_PIN(5, "GPIO_0"), + MT7986_TYPE0_PIN(6, "GPIO_1"), + MT7986_TYPE0_PIN(7, "GPIO_2"), + MT7986_TYPE0_PIN(8, "GPIO_3"), + MT7986_TYPE0_PIN(9, "GPIO_4"), + MT7986_TYPE0_PIN(10, "GPIO_5"), + MT7986_TYPE0_PIN(11, "GPIO_6"), + MT7986_TYPE0_PIN(12, "GPIO_7"), + MT7986_TYPE0_PIN(13, "GPIO_8"), + MT7986_TYPE0_PIN(14, "GPIO_9"), + MT7986_TYPE0_PIN(15, "GPIO_10"), + MT7986_TYPE0_PIN(16, "GPIO_11"), + MT7986_TYPE0_PIN(17, "GPIO_12"), + MT7986_TYPE0_PIN(18, "GPIO_13"), + MT7986_TYPE0_PIN(19, "GPIO_14"), + MT7986_TYPE0_PIN(20, "GPIO_15"), + MT7986_TYPE0_PIN(21, "PWM0"), + MT7986_TYPE0_PIN(22, "PWM1"), + MT7986_TYPE0_PIN(23, "SPI0_CLK"), + MT7986_TYPE0_PIN(24, "SPI0_MOSI"), + MT7986_TYPE0_PIN(25, "SPI0_MISO"), + MT7986_TYPE0_PIN(26, "SPI0_CS"), + MT7986_TYPE0_PIN(27, "SPI0_HOLD"), + MT7986_TYPE0_PIN(28, "SPI0_WP"), + MT7986_TYPE0_PIN(29, "SPI1_CLK"), + MT7986_TYPE0_PIN(30, "SPI1_MOSI"), + MT7986_TYPE0_PIN(31, "SPI1_MISO"), + MT7986_TYPE0_PIN(32, "SPI1_CS"), + MT7986_TYPE0_PIN(33, "SPI2_CLK"), + MT7986_TYPE0_PIN(34, "SPI2_MOSI"), + MT7986_TYPE0_PIN(35, "SPI2_MISO"), + MT7986_TYPE0_PIN(36, "SPI2_CS"), + MT7986_TYPE0_PIN(37, "SPI2_HOLD"), + MT7986_TYPE0_PIN(38, "SPI2_WP"), + MT7986_TYPE0_PIN(39, "UART0_RXD"), + MT7986_TYPE0_PIN(40, "UART0_TXD"), + MT7986_TYPE0_PIN(41, "PCIE_PERESET_N"), + MT7986_TYPE0_PIN(42, "UART1_RXD"), + MT7986_TYPE0_PIN(43, "UART1_TXD"), + MT7986_TYPE0_PIN(44, "UART1_CTS"), + MT7986_TYPE0_PIN(45, "UART1_RTS"), + MT7986_TYPE0_PIN(46, "UART2_RXD"), + MT7986_TYPE0_PIN(47, "UART2_TXD"), + MT7986_TYPE0_PIN(48, "UART2_CTS"), + MT7986_TYPE0_PIN(49, "UART2_RTS"), + MT7986_TYPE0_PIN(50, "EMMC_DATA_0"), + MT7986_TYPE0_PIN(51, "EMMC_DATA_1"), + MT7986_TYPE0_PIN(52, "EMMC_DATA_2"), + MT7986_TYPE0_PIN(53, "EMMC_DATA_3"), + MT7986_TYPE0_PIN(54, "EMMC_DATA_4"), + MT7986_TYPE0_PIN(55, "EMMC_DATA_5"), + MT7986_TYPE0_PIN(56, "EMMC_DATA_6"), + MT7986_TYPE0_PIN(57, "EMMC_DATA_7"), + MT7986_TYPE0_PIN(58, "EMMC_CMD"), + MT7986_TYPE0_PIN(59, "EMMC_CK"), + MT7986_TYPE0_PIN(60, "EMMC_DSL"), + MT7986_TYPE0_PIN(61, "EMMC_RSTB"), + MT7986_TYPE0_PIN(62, "PCM_DTX"), + MT7986_TYPE0_PIN(63, "PCM_DRX"), + MT7986_TYPE0_PIN(64, "PCM_CLK"), + MT7986_TYPE0_PIN(65, "PCM_FS"), + MT7986_TYPE0_PIN(66, "MT7531_INT"), + MT7986_TYPE0_PIN(67, "SMI_MDC"), + MT7986_TYPE0_PIN(68, "SMI_MDIO"), + MT7986_TYPE1_PIN(69, "WF0_DIG_RESETB"), + MT7986_TYPE1_PIN(70, "WF0_CBA_RESETB"), + MT7986_TYPE1_PIN(71, "WF0_XO_REQ"), + MT7986_TYPE1_PIN(72, "WF0_TOP_CLK"), + MT7986_TYPE1_PIN(73, "WF0_TOP_DATA"), + MT7986_TYPE1_PIN(74, "WF0_HB1"), + MT7986_TYPE1_PIN(75, "WF0_HB2"), + MT7986_TYPE1_PIN(76, "WF0_HB3"), + MT7986_TYPE1_PIN(77, "WF0_HB4"), + MT7986_TYPE1_PIN(78, "WF0_HB0"), + MT7986_TYPE1_PIN(79, "WF0_HB0_B"), + MT7986_TYPE1_PIN(80, "WF0_HB5"), + MT7986_TYPE1_PIN(81, "WF0_HB6"), + MT7986_TYPE1_PIN(82, "WF0_HB7"), + MT7986_TYPE1_PIN(83, "WF0_HB8"), + MT7986_TYPE1_PIN(84, "WF0_HB9"), + MT7986_TYPE1_PIN(85, "WF0_HB10"), + MT7986_TYPE1_PIN(86, "WF1_DIG_RESETB"), + MT7986_TYPE1_PIN(87, "WF1_CBA_RESETB"), + MT7986_TYPE1_PIN(88, "WF1_XO_REQ"), + MT7986_TYPE1_PIN(89, "WF1_TOP_CLK"), + MT7986_TYPE1_PIN(90, "WF1_TOP_DATA"), + MT7986_TYPE1_PIN(91, "WF1_HB1"), + MT7986_TYPE1_PIN(92, "WF1_HB2"), + MT7986_TYPE1_PIN(93, "WF1_HB3"), + MT7986_TYPE1_PIN(94, "WF1_HB4"), + MT7986_TYPE1_PIN(95, "WF1_HB0"), + MT7986_TYPE1_PIN(96, "WF1_HB0_B"), + MT7986_TYPE1_PIN(97, "WF1_HB5"), + MT7986_TYPE1_PIN(98, "WF1_HB6"), + MT7986_TYPE1_PIN(99, "WF1_HB7"), + MT7986_TYPE1_PIN(100, "WF1_HB8"), +}; + +static const struct mtk_io_type_desc mt7986_io_type_desc[] = { + [IO_TYPE_GRP0] = { + .name = "18OD33", + .bias_set = mtk_pinconf_bias_set_pupd_r1_r0, + .drive_set = mtk_pinconf_drive_set_v1, + .input_enable = mtk_pinconf_input_enable_v1, + }, + [IO_TYPE_GRP1] = { + .name = "18A01", + .bias_set = mtk_pinconf_bias_set_pu_pd, + .drive_set = mtk_pinconf_drive_set_v1, + .input_enable = mtk_pinconf_input_enable_v1, + }, +}; + +/* List all groups consisting of these pins dedicated to the enablement of + * certain hardware block and the corresponding mode for all of the pins. + * The hardware probably has multiple combinations of these pinouts. + */ + +static int mt7986_watchdog_pins[] = { 0, }; +static int mt7986_watchdog_funcs[] = { 1, }; + +static int mt7986_wifi_led_pins[] = { 1, 2, }; +static int mt7986_wifi_led_funcs[] = { 1, 1, }; + +static int mt7986_i2c_pins[] = { 3, 4, }; +static int mt7986_i2c_funcs[] = { 1, 1, }; + +static int mt7986_uart1_0_pins[] = { 7, 8, 9, 10, }; +static int mt7986_uart1_0_funcs[] = { 3, 3, 3, 3, }; + +static int mt7986_spi1_0_pins[] = { 11, 12, 13, 14, }; +static int mt7986_spi1_0_funcs[] = { 3, 3, 3, 3, }; + +static int mt7986_pwm1_1_pins[] = { 20, }; +static int mt7986_pwm1_1_funcs[] = { 2, }; + +static int mt7986_pwm0_pins[] = { 21, }; +static int mt7986_pwm0_funcs[] = { 1, }; + +static int mt7986_pwm1_0_pins[] = { 22, }; +static int mt7986_pwm1_0_funcs[] = { 1, }; + +static int mt7986_emmc_45_pins[] = { + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, }; +static int mt7986_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; + +static int mt7986_snfi_pins[] = { 23, 24, 25, 26, 27, 28, }; +static int mt7986_snfi_funcs[] = { 1, 1, 1, 1, 1, 1, }; + +static int mt7986_spi1_1_pins[] = { 23, 24, 25, 26, }; +static int mt7986_spi1_1_funcs[] = { 3, 3, 3, 3, }; + +static int mt7986_uart1_1_pins[] = { 23, 24, 25, 26, }; +static int mt7986_uart1_1_funcs[] = { 4, 4, 4, 4, }; + +static int mt7986_spi1_2_pins[] = { 29, 30, 31, 32, }; +static int mt7986_spi1_2_funcs[] = { 1, 1, 1, 1, }; + +static int mt7986_uart1_2_pins[] = { 29, 30, 31, 32, }; +static int mt7986_uart1_2_funcs[] = { 3, 3, 3, 3, }; + +static int mt7986_uart2_0_pins[] = { 29, 30, 31, 32, }; +static int mt7986_uart2_0_funcs[] = { 4, 4, 4, 4, }; + +static int mt7986_spi0_pins[] = { 33, 34, 35, 36, }; +static int mt7986_spi0_funcs[] = { 1, 1, 1, 1, }; + +static int mt7986_spi0_wp_hold_pins[] = { 37, 38, }; +static int mt7986_spi0_wp_hold_funcs[] = { 1, 1, }; + +static int mt7986_uart2_1_pins[] = { 33, 34, 35, 36, }; +static int mt7986_uart2_1_funcs[] = { 3, 3, 3, 3, }; + +static int mt7986_uart1_3_rx_tx_pins[] = { 35, 36, }; +static int mt7986_uart1_3_rx_tx_funcs[] = { 2, 2, }; + +static int mt7986_uart1_3_cts_rts_pins[] = { 37, 38, }; +static int mt7986_uart1_3_cts_rts_funcs[] = { 2, 2, }; + +static int mt7986_spi1_3_pins[] = { 33, 34, 35, 36, }; +static int mt7986_spi1_3_funcs[] = { 4, 4, 4, 4, }; + +static int mt7986_uart0_pins[] = { 39, 40, }; +static int mt7986_uart0_funcs[] = { 1, 1, }; + +static int mt7986_pcie_reset_pins[] = { 41, }; +static int mt7986_pcie_reset_funcs[] = { 1, }; + +static int mt7986_uart1_pins[] = { 42, 43, 44, 45, }; +static int mt7986_uart1_funcs[] = { 1, 1, 1, 1, }; + +static int mt7986_uart2_pins[] = { 46, 47, 48, 49, }; +static int mt7986_uart2_funcs[] = { 1, 1, 1, 1, }; + +static int mt7986_emmc_51_pins[] = { + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, }; +static int mt7986_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; + +static int mt7986_pcm_pins[] = { 62, 63, 64, 65, }; +static int mt7986_pcm_funcs[] = { 1, 1, 1, 1, }; + +static int mt7986_i2s_pins[] = { 62, 63, 64, 65, }; +static int mt7986_i2s_funcs[] = { 1, 1, 1, 1, }; + +static int mt7986_switch_int_pins[] = { 66, }; +static int mt7986_switch_int_funcs[] = { 1, }; + +static int mt7986_mdc_mdio_pins[] = { 67, 68, }; +static int mt7986_mdc_mdio_funcs[] = { 1, 1, }; + +static int mt7986_wf_2g_pins[] = {74, 75, 76, 77, 78, 79, 80, 81, 82, 83, }; +static int mt7986_wf_2g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; + +static int mt7986_wf_5g_pins[] = {91, 92, 93, 94, 95, 96, 97, 98, 99, 100, }; +static int mt7986_wf_5g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; + +static int mt7986_wf_dbdc_pins[] = { + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, }; +static int mt7986_wf_dbdc_funcs[] = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; + +static int mt7986_pcie_clk_pins[] = { 9, }; +static int mt7986_pcie_clk_funcs[] = { 1, }; + +static int mt7986_pcie_wake_pins[] = { 10, }; +static int mt7986_pcie_wake_funcs[] = { 1, }; + +static const struct mtk_group_desc mt7986_groups[] = { + PINCTRL_PIN_GROUP("watchdog", mt7986_watchdog), + PINCTRL_PIN_GROUP("wifi_led", mt7986_wifi_led), + PINCTRL_PIN_GROUP("i2c", mt7986_i2c), + PINCTRL_PIN_GROUP("uart1_0", mt7986_uart1_0), + PINCTRL_PIN_GROUP("pcie_clk", mt7986_pcie_clk), + PINCTRL_PIN_GROUP("pcie_wake", mt7986_pcie_wake), + PINCTRL_PIN_GROUP("spi1_0", mt7986_spi1_0), + PINCTRL_PIN_GROUP("pwm1_1", mt7986_pwm1_1), + PINCTRL_PIN_GROUP("pwm0", mt7986_pwm0), + PINCTRL_PIN_GROUP("pwm1_0", mt7986_pwm1_0), + PINCTRL_PIN_GROUP("emmc_45", mt7986_emmc_45), + PINCTRL_PIN_GROUP("snfi", mt7986_snfi), + PINCTRL_PIN_GROUP("spi1_1", mt7986_spi1_1), + PINCTRL_PIN_GROUP("uart1_1", mt7986_uart1_1), + PINCTRL_PIN_GROUP("spi1_2", mt7986_spi1_2), + PINCTRL_PIN_GROUP("uart1_2", mt7986_uart1_2), + PINCTRL_PIN_GROUP("uart2_0", mt7986_uart2_0), + PINCTRL_PIN_GROUP("spi0", mt7986_spi0), + PINCTRL_PIN_GROUP("spi0_wp_hold", mt7986_spi0_wp_hold), + PINCTRL_PIN_GROUP("uart2_1", mt7986_uart2_1), + PINCTRL_PIN_GROUP("uart1_3_rx_tx", mt7986_uart1_3_rx_tx), + PINCTRL_PIN_GROUP("uart1_3_cts_rts", mt7986_uart1_3_cts_rts), + PINCTRL_PIN_GROUP("spi1_3", mt7986_spi1_3), + PINCTRL_PIN_GROUP("uart0", mt7986_uart0), + PINCTRL_PIN_GROUP("switch_int", mt7986_switch_int), + PINCTRL_PIN_GROUP("mdc_mdio", mt7986_mdc_mdio), + PINCTRL_PIN_GROUP("pcie_pereset", mt7986_pcie_reset), + PINCTRL_PIN_GROUP("uart1", mt7986_uart1), + PINCTRL_PIN_GROUP("uart2", mt7986_uart2), + PINCTRL_PIN_GROUP("emmc_51", mt7986_emmc_51), + PINCTRL_PIN_GROUP("pcm", mt7986_pcm), + PINCTRL_PIN_GROUP("i2s", mt7986_i2s), + PINCTRL_PIN_GROUP("wf_2g", mt7986_wf_2g), + PINCTRL_PIN_GROUP("wf_5g", mt7986_wf_5g), + PINCTRL_PIN_GROUP("wf_dbdc", mt7986_wf_dbdc), +}; + +/* Joint those groups owning the same capability in user point of view which + * allows that people tend to use through the device tree. + */ + +static const char *const mt7986_audio_groups[] = { "pcm", "i2s" }; +static const char *const mt7986_emmc_groups[] = { "emmc_45", "emmc_51", }; +static const char *const mt7986_ethernet_groups[] = { "switch_int", + "mdc_mdio", }; +static const char *const mt7986_i2c_groups[] = { "i2c", }; +static const char *const mt7986_led_groups[] = { "wifi_led", }; +static const char *const mt7986_flash_groups[] = { "snfi", }; +static const char *const mt7986_pcie_groups[] = { "pcie_clk", "pcie_wake", + "pcie_pereset" }; +static const char *const mt7986_pwm_groups[] = { "pwm0", "pwm1_0", "pwm1_1", }; +static const char *const mt7986_spi_groups[] = { "spi0", "spi0_wp_hold", + "spi1_0", "spi1_1", "spi1_2", "spi1_3", }; +static const char *const mt7986_uart_groups[] = { "uart1_0", "uart1_1", + "uart1_2", "uart1_3_rx_tx", "uart1_3_cts_rts", "uart2_0", "uart2_1", + "uart0", "uart1", "uart2", }; +static const char *const mt7986_wdt_groups[] = { "watchdog", }; +static const char *const mt7986_wf_groups[] = { "wf_2g", "wf_5g", "wf_dbdc", }; + +static const struct mtk_function_desc mt7986_functions[] = { + {"audio", mt7986_audio_groups, ARRAY_SIZE(mt7986_audio_groups)}, + {"emmc", mt7986_emmc_groups, ARRAY_SIZE(mt7986_emmc_groups)}, + {"eth", mt7986_ethernet_groups, ARRAY_SIZE(mt7986_ethernet_groups)}, + {"i2c", mt7986_i2c_groups, ARRAY_SIZE(mt7986_i2c_groups)}, + {"led", mt7986_led_groups, ARRAY_SIZE(mt7986_led_groups)}, + {"flash", mt7986_flash_groups, ARRAY_SIZE(mt7986_flash_groups)}, + {"pcie", mt7986_pcie_groups, ARRAY_SIZE(mt7986_pcie_groups)}, + {"pwm", mt7986_pwm_groups, ARRAY_SIZE(mt7986_pwm_groups)}, + {"spi", mt7986_spi_groups, ARRAY_SIZE(mt7986_spi_groups)}, + {"uart", mt7986_uart_groups, ARRAY_SIZE(mt7986_uart_groups)}, + {"watchdog", mt7986_wdt_groups, ARRAY_SIZE(mt7986_wdt_groups)}, + {"wifi", mt7986_wf_groups, ARRAY_SIZE(mt7986_wf_groups)}, +}; + +static struct mtk_pinctrl_soc mt7986_data = { + .name = "mt7986_pinctrl", + .reg_cal = mt7986_reg_cals, + .pins = mt7986_pins, + .npins = ARRAY_SIZE(mt7986_pins), + .grps = mt7986_groups, + .ngrps = ARRAY_SIZE(mt7986_groups), + .funcs = mt7986_functions, + .nfuncs = ARRAY_SIZE(mt7986_functions), + .io_type = mt7986_io_type_desc, + .ntype = ARRAY_SIZE(mt7986_io_type_desc), + .gpio_mode = 0, + .base_names = mt7986_pinctrl_register_base_names, + .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names), + .base_calc = 1, +}; + +static int mtk_pinctrl_mt7986_probe(struct udevice *dev) +{ + return mtk_pinctrl_common_probe(dev, &mt7986_data); +} + +static const struct udevice_id mt7986_pctrl_match[] = { + {.compatible = "mediatek,mt7986-pinctrl"}, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(mt7986_pinctrl) = { + .name = "mt7986_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = mt7986_pctrl_match, + .ops = &mtk_pinctrl_ops, + .probe = mtk_pinctrl_mt7986_probe, + .priv_auto = sizeof(struct mtk_pinctrl_priv), +}; diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index 26fb5d61d5..50e3dd449a 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -9,10 +9,13 @@ #include #include #include +#include +#include #include #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -28,6 +31,25 @@ struct atmel_pio4_plat { unsigned int slew_rate_support; }; +/* + * Table keeping track of the pinctrl driver's slew rate support and the + * corresponding index into the struct udevice_id of the gpio_atmel_pio4 GPIO + * driver. This has been done in order to align the DT of U-Boot with the DT of + * Linux. In Linux, a phandle from a '-gpio' DT property is linked to the + * pinctrl driver, unlike U-Boot which redirects this phandle to a corresponding + * UCLASS_GPIO driver. Thus, in order to link the two, a hook to the bind method + * of the pinctrl driver in U-Boot has been added. This bind method will attach + * the GPIO driver to the pinctrl DT node using this table. + * @slew_rate_support pinctrl driver's slew rate support + * @gdidx index into the GPIO driver's struct udevide_id + * (needed in order to properly bind with driver_data) + */ + +struct atmel_pinctrl_data { + unsigned int slew_rate_support; + int gdidx; +}; + static const struct pinconf_param conf_params[] = { { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, @@ -130,12 +152,11 @@ static inline struct atmel_pio4_port *atmel_pio4_bank_base(struct udevice *dev, #define MAX_PINMUX_ENTRIES 40 -static int atmel_pinctrl_set_state(struct udevice *dev, struct udevice *config) +static int atmel_process_config_dev(struct udevice *dev, struct udevice *config) { struct atmel_pio4_plat *plat = dev_get_plat(dev); - struct atmel_pio4_port *bank_base; - const void *blob = gd->fdt_blob; int node = dev_of_offset(config); + struct atmel_pio4_port *bank_base; u32 offset, func, bank, line; u32 cells[MAX_PINMUX_ENTRIES]; u32 i, conf; @@ -143,18 +164,17 @@ static int atmel_pinctrl_set_state(struct udevice *dev, struct udevice *config) conf = atmel_pinctrl_get_pinconf(config, plat); - count = fdtdec_get_int_array_count(blob, node, "pinmux", + /* + * The only case where this function returns a negative error value + * is when there is no "pinmux" property attached to this node + */ + count = fdtdec_get_int_array_count(gd->fdt_blob, node, "pinmux", cells, ARRAY_SIZE(cells)); - if (count < 0) { - printf("%s: bad pinmux array %d\n", __func__, count); - return -EINVAL; - } + if (count < 0) + return count; - if (count > MAX_PINMUX_ENTRIES) { - printf("%s: unsupported pinmux array count %d\n", - __func__, count); + if (count > MAX_PINMUX_ENTRIES) return -EINVAL; - } for (i = 0 ; i < count; i++) { offset = ATMEL_GET_PIN_NO(cells[i]); @@ -174,6 +194,56 @@ static int atmel_pinctrl_set_state(struct udevice *dev, struct udevice *config) return 0; } +static int atmel_pinctrl_set_state(struct udevice *dev, struct udevice *config) +{ + int node = dev_of_offset(config); + struct udevice *subconfig; + int subnode, subnode_count = 0, ret; + + /* + * If this function returns a negative error code then that means + * that either the "pinmux" property of the node is missing, which is + * the case for pinctrl nodes that do not have all the pins with the + * same configuration and are split in multiple subnodes, or something + * else went wrong and we have to stop. For the latter case, it would + * mean that the node failed even though it has no subnodes. + */ + ret = atmel_process_config_dev(dev, config); + if (!ret) + return ret; + + /* + * If we reach here, it means that the subnode pinctrl's DT has multiple + * subnodes. If it does not, then something else went wrong in the + * previous call to atmel_process_config_dev. + */ + fdt_for_each_subnode(subnode, gd->fdt_blob, node) { + /* Get subnode as an udevice */ + ret = uclass_find_device_by_of_offset(UCLASS_PINCONFIG, subnode, + &subconfig); + if (ret) + return ret; + + /* + * If this time the function returns an error code on a subnode + * then something is totally wrong so abort. + */ + ret = atmel_process_config_dev(dev, subconfig); + if (ret) + return ret; + + subnode_count++; + } + + /* + * If we somehow got here and we do not have any subnodes, abort. + */ + if (!subnode_count) + return -EINVAL; + + return 0; +} + const struct pinctrl_ops atmel_pinctrl_ops = { .set_state = atmel_pinctrl_set_state, }; @@ -181,24 +251,57 @@ const struct pinctrl_ops atmel_pinctrl_ops = { static int atmel_pinctrl_probe(struct udevice *dev) { struct atmel_pio4_plat *plat = dev_get_plat(dev); - ulong priv = dev_get_driver_data(dev); + struct atmel_pinctrl_data *priv = (struct atmel_pinctrl_data *)dev_get_driver_data(dev); fdt_addr_t addr_base; - dev = dev_get_parent(dev); addr_base = dev_read_addr(dev); if (addr_base == FDT_ADDR_T_NONE) return -EINVAL; plat->reg_base = (struct atmel_pio4_port *)addr_base; - plat->slew_rate_support = priv; + plat->slew_rate_support = priv->slew_rate_support; return 0; } +static int atmel_pinctrl_bind(struct udevice *dev) +{ + struct udevice *g; + struct driver *drv; + ofnode node = dev_ofnode(dev); + struct atmel_pinctrl_data *priv = (struct atmel_pinctrl_data *)dev_get_driver_data(dev); + + if (!CONFIG_IS_ENABLED(ATMEL_PIO4)) + return 0; + + /* Obtain a handle to the GPIO driver */ + drv = lists_driver_lookup_name("gpio_atmel_pio4"); + if (!drv) + return -ENOENT; + + /* + * Bind the GPIO driver to the pinctrl DT node, together + * with its corresponding driver_data. + */ + return device_bind_with_driver_data(dev, drv, drv->name, + drv->of_match[priv->gdidx].data, + node, &g); +} + +static const struct atmel_pinctrl_data atmel_sama5d2_pinctrl_data = { + .gdidx = 0, +}; + +static const struct atmel_pinctrl_data microchip_sama7g5_pinctrl_data = { + .slew_rate_support = 1, + .gdidx = 1, +}; + static const struct udevice_id atmel_pinctrl_match[] = { - { .compatible = "atmel,sama5d2-pinctrl" }, + { .compatible = "atmel,sama5d2-pinctrl", + .data = (ulong)&atmel_sama5d2_pinctrl_data, }, { .compatible = "microchip,sama7g5-pinctrl", - .data = (ulong)1, }, + .data = (ulong)µchip_sama7g5_pinctrl_data, }, {} }; @@ -206,6 +309,7 @@ U_BOOT_DRIVER(atmel_pinctrl) = { .name = "pinctrl_atmel_pio4", .id = UCLASS_PINCTRL, .of_match = atmel_pinctrl_match, + .bind = atmel_pinctrl_bind, .probe = atmel_pinctrl_probe, .plat_auto = sizeof(struct atmel_pio4_plat), .ops = &atmel_pinctrl_ops, diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index 990cd19286..b755fa42b4 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -257,10 +257,12 @@ static int stm32_pinctrl_probe(struct udevice *dev) return 0; } -static int stm32_gpio_config(struct gpio_desc *desc, +static int stm32_gpio_config(ofnode node, + struct gpio_desc *desc, const struct stm32_gpio_ctl *ctl) { struct stm32_gpio_priv *priv = dev_get_priv(desc->dev); + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc->dev); struct stm32_gpio_regs *regs = priv->regs; struct stm32_pinctrl_priv *ctrl_priv; int ret; @@ -291,6 +293,8 @@ static int stm32_gpio_config(struct gpio_desc *desc, index = desc->offset; clrsetbits_le32(®s->otyper, OTYPE_MSK << index, ctl->otype << index); + uc_priv->name[desc->offset] = strdup(ofnode_get_name(node)); + hwspinlock_unlock(&ctrl_priv->hws); return 0; @@ -385,7 +389,7 @@ static int stm32_pinctrl_config(ofnode node) if (rv) return rv; desc.offset = gpio_dsc.pin; - rv = stm32_gpio_config(&desc, &gpio_ctl); + rv = stm32_gpio_config(node, &desc, &gpio_ctl); log_debug("rv = %d\n\n", rv); if (rv) return rv; diff --git a/drivers/power/domain/zynqmp-power-domain.c b/drivers/power/domain/zynqmp-power-domain.c index 6943658be4..adbbb5fdd9 100644 --- a/drivers/power/domain/zynqmp-power-domain.c +++ b/drivers/power/domain/zynqmp-power-domain.c @@ -25,7 +25,10 @@ static int zynqmp_power_domain_request(struct power_domain *power_domain) { dev_dbg(power_domain->dev, "Request for id: %ld\n", power_domain->id); - return zynqmp_pmufw_node(power_domain->id); + if (IS_ENABLED(CONFIG_ARCH_ZYNQMP)) + return zynqmp_pmufw_node(power_domain->id); + + return 0; } static int zynqmp_power_domain_free(struct power_domain *power_domain) diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 66b16b06e0..0478f2aa1d 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -216,10 +216,10 @@ config PMIC_MAX8997 - MUIC - Others -config PMIC_PM8916 - bool "Enable Driver Model for Qualcomm PM8916 PMIC" +config PMIC_QCOM + bool "Enable Driver Model for Qualcomm generic PMIC" ---help--- - The PM8916 is a PMIC connected to one (or several) processors + The Qcom PMIC is connected to one (or several) processors with SPMI bus. It has 2 slaves with several peripherals: - 18x LDO - 4x GPIO @@ -229,7 +229,7 @@ config PMIC_PM8916 - Vibrator drivers - Others - Driver binding info: doc/device-tree-bindings/pmic/pm8916.txt + Driver binding info: doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt config PMIC_RK8XX bool "Enable support for Rockchip PMIC RK8XX" diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index f73b326255..e1d3545490 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -20,7 +20,7 @@ obj-$(CONFIG_PMIC_ACT8846) += act8846.o obj-$(CONFIG_PMIC_AS3722) += as3722.o as3722_gpio.o obj-$(CONFIG_$(SPL_)PMIC_AXP) += axp.o obj-$(CONFIG_PMIC_MAX8997) += max8997.o -obj-$(CONFIG_PMIC_PM8916) += pm8916.o +obj-$(CONFIG_PMIC_QCOM) += pmic_qcom.o obj-$(CONFIG_$(SPL_TPL_)PMIC_RK8XX) += rk8xx.o obj-$(CONFIG_PMIC_RN5T567) += rn5t567.o obj-$(CONFIG_PMIC_TPS65090) += tps65090.o diff --git a/drivers/power/pmic/pm8916.c b/drivers/power/pmic/pmic_qcom.c similarity index 52% rename from drivers/power/pmic/pm8916.c rename to drivers/power/pmic/pmic_qcom.c index 5f4386d4ad..ad8daf43f0 100644 --- a/drivers/power/pmic/pm8916.c +++ b/drivers/power/pmic/pmic_qcom.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Qualcomm pm8916 pmic driver + * Qualcomm generic pmic driver * * (C) Copyright 2015 Mateusz Kulikowski */ @@ -13,19 +13,19 @@ #define PID_MASK (0xFF << PID_SHIFT) #define REG_MASK 0xFF -struct pm8916_priv { +struct pmic_qcom_priv { uint32_t usid; /* Slave ID on SPMI bus */ }; -static int pm8916_reg_count(struct udevice *dev) +static int pmic_qcom_reg_count(struct udevice *dev) { return 0xFFFF; } -static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff, - int len) +static int pmic_qcom_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) { - struct pm8916_priv *priv = dev_get_priv(dev); + struct pmic_qcom_priv *priv = dev_get_priv(dev); if (len != 1) return -EINVAL; @@ -35,9 +35,9 @@ static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff, *buff); } -static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +static int pmic_qcom_read(struct udevice *dev, uint reg, uint8_t *buff, int len) { - struct pm8916_priv *priv = dev_get_priv(dev); + struct pmic_qcom_priv *priv = dev_get_priv(dev); int val; if (len != 1) @@ -52,20 +52,20 @@ static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len) return 0; } -static struct dm_pmic_ops pm8916_ops = { - .reg_count = pm8916_reg_count, - .read = pm8916_read, - .write = pm8916_write, +static struct dm_pmic_ops pmic_qcom_ops = { + .reg_count = pmic_qcom_reg_count, + .read = pmic_qcom_read, + .write = pmic_qcom_write, }; -static const struct udevice_id pm8916_ids[] = { +static const struct udevice_id pmic_qcom_ids[] = { { .compatible = "qcom,spmi-pmic" }, { } }; -static int pm8916_probe(struct udevice *dev) +static int pmic_qcom_probe(struct udevice *dev) { - struct pm8916_priv *priv = dev_get_priv(dev); + struct pmic_qcom_priv *priv = dev_get_priv(dev); priv->usid = dev_read_addr(dev); @@ -75,12 +75,12 @@ static int pm8916_probe(struct udevice *dev) return 0; } -U_BOOT_DRIVER(pmic_pm8916) = { - .name = "pmic_pm8916", +U_BOOT_DRIVER(pmic_qcom) = { + .name = "pmic_qcom", .id = UCLASS_PMIC, - .of_match = pm8916_ids, + .of_match = pmic_qcom_ids, .bind = dm_scan_fdt_dev, - .probe = pm8916_probe, - .ops = &pm8916_ops, - .priv_auto = sizeof(struct pm8916_priv), + .probe = pmic_qcom_probe, + .ops = &pmic_qcom_ops, + .priv_auto = sizeof(struct pmic_qcom_priv), }; diff --git a/drivers/power/pmic/sandbox.c b/drivers/power/pmic/sandbox.c index d7870915de..acfeae2df9 100644 --- a/drivers/power/pmic/sandbox.c +++ b/drivers/power/pmic/sandbox.c @@ -4,11 +4,14 @@ * Przemyslaw Marczak */ +#define LOG_CATEGORY UCLASS_PMIC + #include #include #include #include #include +#include #include #include #include @@ -28,7 +31,7 @@ static int sandbox_pmic_write(struct udevice *dev, uint reg, const uint8_t *buff, int len) { if (dm_i2c_write(dev, reg, buff, len)) { - pr_err("write error to device: %p register: %#x!\n", dev, reg); + log_err("write error to device: %p register: %#x!\n", dev, reg); return -EIO; } @@ -39,7 +42,7 @@ static int sandbox_pmic_read(struct udevice *dev, uint reg, uint8_t *buff, int len) { if (dm_i2c_read(dev, reg, buff, len)) { - pr_err("read error from device: %p register: %#x!\n", dev, reg); + log_err("read error from device: %p register: %#x!\n", dev, reg); return -EIO; } @@ -49,8 +52,7 @@ static int sandbox_pmic_read(struct udevice *dev, uint reg, static int sandbox_pmic_bind(struct udevice *dev) { if (!pmic_bind_children(dev, dev_ofnode(dev), pmic_children_info)) - pr_err("%s:%d PMIC: %s - no child found!", __func__, __LINE__, - dev->name); + log_err("PMIC: %s - no child found!\n", dev->name); /* Always return success for this device - allows for PMIC I/O */ return 0; diff --git a/drivers/pwm/pwm-mtk.c b/drivers/pwm/pwm-mtk.c index aee1d825a0..605142eab0 100644 --- a/drivers/pwm/pwm-mtk.c +++ b/drivers/pwm/pwm-mtk.c @@ -29,13 +29,23 @@ #define NSEC_PER_SEC 1000000000L -static const unsigned int mtk_pwm_reg_offset[] = { +enum mtk_pwm_reg_ver { + PWM_REG_V1, + PWM_REG_V2, +}; + +static const unsigned int mtk_pwm_reg_offset_v1[] = { 0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220 }; +static const unsigned int mtk_pwm_reg_offset_v2[] = { + 0x0080, 0x00c0, 0x0100, 0x0140, 0x0180, 0x01c0, 0x0200, 0x0240 +}; + struct mtk_pwm_soc { unsigned int num_pwms; bool pwm45_fixup; + enum mtk_pwm_reg_ver reg_ver; }; struct mtk_pwm_priv { @@ -49,7 +59,16 @@ struct mtk_pwm_priv { static void mtk_pwm_w32(struct udevice *dev, uint channel, uint reg, uint val) { struct mtk_pwm_priv *priv = dev_get_priv(dev); - u32 offset = mtk_pwm_reg_offset[channel]; + u32 offset; + + switch (priv->soc->reg_ver) { + case PWM_REG_V2: + offset = mtk_pwm_reg_offset_v2[channel]; + break; + + default: + offset = mtk_pwm_reg_offset_v1[channel]; + } writel(val, priv->base + offset + reg); } @@ -159,22 +178,39 @@ static const struct pwm_ops mtk_pwm_ops = { static const struct mtk_pwm_soc mt7622_data = { .num_pwms = 6, .pwm45_fixup = false, + .reg_ver = PWM_REG_V1, }; static const struct mtk_pwm_soc mt7623_data = { .num_pwms = 5, .pwm45_fixup = true, + .reg_ver = PWM_REG_V1, }; static const struct mtk_pwm_soc mt7629_data = { .num_pwms = 1, .pwm45_fixup = false, + .reg_ver = PWM_REG_V1, +}; + +static const struct mtk_pwm_soc mt7981_data = { + .num_pwms = 2, + .pwm45_fixup = false, + .reg_ver = PWM_REG_V2, +}; + +static const struct mtk_pwm_soc mt7986_data = { + .num_pwms = 2, + .pwm45_fixup = false, + .reg_ver = PWM_REG_V1, }; static const struct udevice_id mtk_pwm_ids[] = { { .compatible = "mediatek,mt7622-pwm", .data = (ulong)&mt7622_data }, { .compatible = "mediatek,mt7623-pwm", .data = (ulong)&mt7623_data }, { .compatible = "mediatek,mt7629-pwm", .data = (ulong)&mt7629_data }, + { .compatible = "mediatek,mt7981-pwm", .data = (ulong)&mt7981_data }, + { .compatible = "mediatek,mt7986-pwm", .data = (ulong)&mt7986_data }, { } }; diff --git a/drivers/ram/stm32mp1/stm32mp1_tests.c b/drivers/ram/stm32mp1/stm32mp1_tests.c index 64262f1aa9..c5f3354414 100644 --- a/drivers/ram/stm32mp1/stm32mp1_tests.c +++ b/drivers/ram/stm32mp1/stm32mp1_tests.c @@ -169,7 +169,7 @@ static int test_loop_end(u32 *loop, u32 nb_loop, u32 progress) return 1; } printf("loop #%d\n", *loop); - WATCHDOG_RESET(); + schedule(); return 0; } diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 69a7b4ccba..4cb0ba0850 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -156,13 +156,12 @@ config RESET_IMX7 help Support for reset controller on i.MX7/8 SoCs. -config RESET_IPQ419 - bool "Reset driver for Qualcomm IPQ40xx SoCs" - depends on DM_RESET && ARCH_IPQ40XX +config RESET_QCOM + bool "Reset driver for Qualcomm SoCs" + depends on DM_RESET && (ARCH_SNAPDRAGON || ARCH_IPQ40XX) default y help - Support for reset controller on Qualcomm - IPQ40xx SoCs. + Support for reset controller on Qualcomm SoCs. config RESET_SIFIVE bool "Reset Driver for SiFive SoC's" diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 97e3a782c0..0620b62809 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -24,7 +24,7 @@ obj-$(CONFIG_RESET_MTMIPS) += reset-mtmips.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o -obj-$(CONFIG_RESET_IPQ419) += reset-ipq4019.o +obj-$(CONFIG_RESET_QCOM) += reset-qcom.o obj-$(CONFIG_RESET_SIFIVE) += reset-sifive.o obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o diff --git a/drivers/reset/reset-ipq4019.c b/drivers/reset/reset-qcom.c similarity index 64% rename from drivers/reset/reset-ipq4019.c rename to drivers/reset/reset-qcom.c index 7f0bd85ad6..94315e76d5 100644 --- a/drivers/reset/reset-ipq4019.c +++ b/drivers/reset/reset-qcom.c @@ -1,8 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2020 Sartura Ltd. + * Copyright (c) 2022 Linaro Ltd. * * Author: Robert Marko + * Sumit Garg * * Based on Linux driver */ @@ -10,12 +12,11 @@ #include #include #include -#include #include #include #include -struct ipq4019_reset_priv { +struct qcom_reset_priv { phys_addr_t base; }; @@ -24,7 +25,9 @@ struct qcom_reset_map { u8 bit; }; -static const struct qcom_reset_map gcc_ipq4019_resets[] = { +#ifdef CONFIG_ARCH_IPQ40XX +#include +static const struct qcom_reset_map gcc_qcom_resets[] = { [WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 }, [WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 }, [WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 }, @@ -97,11 +100,41 @@ static const struct qcom_reset_map gcc_ipq4019_resets[] = { [GCC_MPM_BCR] = {0x24000, 0}, [GCC_SPDM_BCR] = {0x25000, 0}, }; +#endif -static int ipq4019_reset_assert(struct reset_ctl *rst) +#ifdef CONFIG_TARGET_QCS404EVB +#include +static const struct qcom_reset_map gcc_qcom_resets[] = { + [GCC_GENI_IR_BCR] = { 0x0F000 }, + [GCC_CDSP_RESTART] = { 0x18000 }, + [GCC_USB_HS_BCR] = { 0x41000 }, + [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, + [GCC_QUSB2_PHY_BCR] = { 0x4103c }, + [GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 }, + [GCC_USB2A_PHY_BCR] = { 0x0000c, 0 }, + [GCC_USB3_PHY_BCR] = { 0x39004 }, + [GCC_USB_30_BCR] = { 0x39000 }, + [GCC_USB3PHY_PHY_BCR] = { 0x39008 }, + [GCC_PCIE_0_BCR] = { 0x3e000 }, + [GCC_PCIE_0_PHY_BCR] = { 0x3e004 }, + [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 }, + [GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c }, + [GCC_PCIE_0_AXI_MASTER_STICKY_ARES] = { 0x3e040, 6}, + [GCC_PCIE_0_AHB_ARES] = { 0x3e040, 5 }, + [GCC_PCIE_0_AXI_SLAVE_ARES] = { 0x3e040, 4 }, + [GCC_PCIE_0_AXI_MASTER_ARES] = { 0x3e040, 3 }, + [GCC_PCIE_0_CORE_STICKY_ARES] = { 0x3e040, 2 }, + [GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 }, + [GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 }, + [GCC_EMAC_BCR] = { 0x4e000 }, + [GCC_WDSP_RESTART] = {0x19000}, +}; +#endif + +static int qcom_reset_assert(struct reset_ctl *rst) { - struct ipq4019_reset_priv *priv = dev_get_priv(rst->dev); - const struct qcom_reset_map *reset_map = gcc_ipq4019_resets; + struct qcom_reset_priv *priv = dev_get_priv(rst->dev); + const struct qcom_reset_map *reset_map = gcc_qcom_resets; const struct qcom_reset_map *map; u32 value; @@ -114,10 +147,10 @@ static int ipq4019_reset_assert(struct reset_ctl *rst) return 0; } -static int ipq4019_reset_deassert(struct reset_ctl *rst) +static int qcom_reset_deassert(struct reset_ctl *rst) { - struct ipq4019_reset_priv *priv = dev_get_priv(rst->dev); - const struct qcom_reset_map *reset_map = gcc_ipq4019_resets; + struct qcom_reset_priv *priv = dev_get_priv(rst->dev); + const struct qcom_reset_map *reset_map = gcc_qcom_resets; const struct qcom_reset_map *map; u32 value; @@ -130,19 +163,20 @@ static int ipq4019_reset_deassert(struct reset_ctl *rst) return 0; } -static const struct reset_ops ipq4019_reset_ops = { - .rst_assert = ipq4019_reset_assert, - .rst_deassert = ipq4019_reset_deassert, +static const struct reset_ops qcom_reset_ops = { + .rst_assert = qcom_reset_assert, + .rst_deassert = qcom_reset_deassert, }; -static const struct udevice_id ipq4019_reset_ids[] = { +static const struct udevice_id qcom_reset_ids[] = { { .compatible = "qcom,gcc-reset-ipq4019" }, + { .compatible = "qcom,gcc-reset-qcs404" }, { } }; -static int ipq4019_reset_probe(struct udevice *dev) +static int qcom_reset_probe(struct udevice *dev) { - struct ipq4019_reset_priv *priv = dev_get_priv(dev); + struct qcom_reset_priv *priv = dev_get_priv(dev); priv->base = dev_read_addr(dev); if (priv->base == FDT_ADDR_T_NONE) @@ -151,11 +185,11 @@ static int ipq4019_reset_probe(struct udevice *dev) return 0; } -U_BOOT_DRIVER(ipq4019_reset) = { - .name = "ipq4019_reset", +U_BOOT_DRIVER(qcom_reset) = { + .name = "qcom_reset", .id = UCLASS_RESET, - .of_match = ipq4019_reset_ids, - .ops = &ipq4019_reset_ops, - .probe = ipq4019_reset_probe, - .priv_auto = sizeof(struct ipq4019_reset_priv), + .of_match = qcom_reset_ids, + .ops = &qcom_reset_ops, + .probe = qcom_reset_probe, + .priv_auto = sizeof(struct qcom_reset_priv), }; diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c index 52c08c4722..87b4df5bf8 100644 --- a/drivers/reset/reset-zynqmp.c +++ b/drivers/reset/reset-zynqmp.c @@ -80,6 +80,7 @@ const struct reset_ops zynqmp_reset_ops = { static const struct udevice_id zynqmp_reset_ids[] = { { .compatible = "xlnx,zynqmp-reset" }, { .compatible = "xlnx,versal-reset" }, + { .compatible = "xlnx,versal-net-reset" }, { } }; diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig index 16143681da..5dcf68176a 100644 --- a/drivers/rng/Kconfig +++ b/drivers/rng/Kconfig @@ -41,6 +41,7 @@ config RNG_NPCM config RNG_OPTEE bool "OP-TEE based Random Number Generator support" depends on DM_RNG && OPTEE + default y if OPTEE_SERVICE_DISCOVERY help This driver provides support for the OP-TEE based Random Number Generator on ARM SoCs where hardware entropy sources are not diff --git a/drivers/rng/optee_rng.c b/drivers/rng/optee_rng.c index aa8ce864d3..410dfc053f 100644 --- a/drivers/rng/optee_rng.c +++ b/drivers/rng/optee_rng.c @@ -11,6 +11,9 @@ #include #include #include +#include + +#define DRIVER_NAME "optee-rng" #define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 @@ -35,6 +38,8 @@ #define TA_HWRNG_UUID { 0xab7a617c, 0xb8e7, 0x4d8f, \ { 0x83, 0x01, 0xd0, 0x9b, 0x61, 0x03, 0x6b, 0x64 } } +OPTEE_SERVICE_DRIVER(optee_rng, TA_HWRNG_UUID, DRIVER_NAME); + /** open_session_ta_hwrng() - Open session with hwrng Trusted App * * @dev: device @@ -177,7 +182,7 @@ static const struct dm_rng_ops optee_rng_ops = { }; U_BOOT_DRIVER(optee_rng) = { - .name = "optee-rng", + .name = DRIVER_NAME, .id = UCLASS_RNG, .ops = &optee_rng_ops, .probe = optee_rng_probe, diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index c400e2de16..ad484ce8e8 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1,6 +1,5 @@ config SCSI bool "Support SCSI controllers" - select HAVE_BLOCK_DEVICE help This enables support for SCSI (Small Computer System Interface), a parallel interface widely used with storage peripherals such as @@ -10,7 +9,6 @@ config SCSI config DM_SCSI bool "Support SCSI controllers with driver model" - depends on BLK help This option enables the SCSI (Small Computer System Interface) uclass which supports SCSI and SATA HDDs. For every device configuration diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 25194eeec1..d1b40c6140 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -17,4 +17,5 @@ endif ifdef CONFIG_SCSI obj-$(CONFIG_SANDBOX) += sandbox_scsi.o +obj-$(CONFIG_SANDBOX) += scsi_emul.o endif diff --git a/drivers/scsi/sandbox_scsi.c b/drivers/scsi/sandbox_scsi.c index 39b969a4b2..a7ac33cb1c 100644 --- a/drivers/scsi/sandbox_scsi.c +++ b/drivers/scsi/sandbox_scsi.c @@ -7,19 +7,145 @@ * that CONFIG_SCSI can be enabled for sandbox. */ +#define LOG_CATEGORY UCLASS_SCSI + #include +#include +#include +#include #include +#include -int scsi_bus_reset(struct udevice *dev) +enum { + SANDBOX_SCSI_BLOCK_LEN = 512, + SANDBOX_SCSI_BUF_SIZE = 512, +}; + +/** + * struct sandbox_scsi_priv + * + * @eminfo: emulator state + * @pathanme: Path to the backing file, e.g. 'scsi.img' + * @fd: File descriptor of backing file + */ +struct sandbox_scsi_priv { + struct scsi_emul_info eminfo; + const char *pathname; + int fd; +}; + +static int sandbox_scsi_exec(struct udevice *dev, struct scsi_cmd *req) { + struct sandbox_scsi_priv *priv = dev_get_priv(dev); + struct scsi_emul_info *info = &priv->eminfo; + int ret; + + if (req->lun || req->target) + return -EIO; + ret = sb_scsi_emul_command(info, req, req->cmdlen); + if (ret < 0) { + log_debug("SCSI command 0x%02x ret errno %d\n", req->cmd[0], + ret); + return ret; + } else if (ret == SCSI_EMUL_DO_READ && priv->fd != -1) { + long bytes_read; + + log_debug("read %x %x\n", info->seek_block, info->read_len); + os_lseek(priv->fd, info->seek_block * info->block_size, + OS_SEEK_SET); + bytes_read = os_read(priv->fd, req->pdata, info->buff_used); + if (bytes_read < 0) + return bytes_read; + if (bytes_read != info->buff_used) + return -EIO; + } else if (!ret) { + req->pdata = info->buff; + info->phase = SCSIPH_STATUS; + log_debug("sending buf\n"); + } else { + log_debug("error\n"); + return -EIO; + } + return 0; } -void scsi_init(void) +static int sandbox_scsi_bus_reset(struct udevice *dev) { -} + /* Not implemented */ -int scsi_exec(struct udevice *dev, struct scsi_cmd *pccb) -{ return 0; } + +static int sandbox_scsi_of_to_plat(struct udevice *dev) +{ + struct sandbox_scsi_priv *priv = dev_get_priv(dev); + + priv->pathname = dev_read_string(dev, "sandbox,filepath"); + + return 0; +} + +static int sandbox_scsi_probe(struct udevice *dev) +{ + struct scsi_plat *scsi_plat = dev_get_uclass_plat(dev); + struct sandbox_scsi_priv *priv = dev_get_priv(dev); + struct scsi_emul_info *info = &priv->eminfo; + int ret; + + scsi_plat->max_id = 2; + scsi_plat->max_lun = 3; + scsi_plat->max_bytes_per_req = 1 << 20; + + info->vendor = "SANDBOX"; + info->product = "FAKE DISK"; + info->buff = malloc(SANDBOX_SCSI_BUF_SIZE); + if (!info->buff) + return log_ret(-ENOMEM); + info->block_size = SANDBOX_SCSI_BLOCK_LEN; + + if (priv->pathname) { + priv->fd = os_open(priv->pathname, OS_O_RDONLY); + if (priv->fd != -1) { + ret = os_get_filesize(priv->pathname, &info->file_size); + if (ret) + return log_msg_ret("sz", ret); + } + } else { + priv->fd = -1; + } + log_debug("filename: %s, fd %d\n", priv->pathname, priv->fd); + + return 0; +} + +static int sandbox_scsi_remove(struct udevice *dev) +{ + struct sandbox_scsi_priv *priv = dev_get_priv(dev); + struct scsi_emul_info *info = &priv->eminfo; + + free(info->buff); + + return 0; +} + +struct scsi_ops sandbox_scsi_ops = { + .exec = sandbox_scsi_exec, + .bus_reset = sandbox_scsi_bus_reset, +}; + +static const struct udevice_id sanbox_scsi_ids[] = { + { .compatible = "sandbox,scsi" }, + { } +}; + +U_BOOT_DRIVER(sandbox_scsi) = { + .name = "sandbox_scsi", + .id = UCLASS_SCSI, + .ops = &sandbox_scsi_ops, + .of_match = sanbox_scsi_ids, + .of_to_plat = sandbox_scsi_of_to_plat, + .probe = sandbox_scsi_probe, + .remove = sandbox_scsi_remove, + .priv_auto = sizeof(struct sandbox_scsi_priv), +}; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 78d729d809..3e769b0843 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -456,7 +456,7 @@ static void scsi_init_dev_desc(struct blk_desc *dev_desc, int devnum) { dev_desc->lba = 0; dev_desc->blksz = 0; - dev_desc->if_type = IF_TYPE_SCSI; + dev_desc->uclass_id = UCLASS_SCSI; dev_desc->devnum = devnum; dev_desc->part_type = PART_TYPE_UNKNOWN; @@ -574,8 +574,8 @@ static int do_scsi_scan_one(struct udevice *dev, int id, int lun, bool verbose) * block devices created */ snprintf(str, sizeof(str), "id%dlun%d", id, lun); - ret = blk_create_devicef(dev, "scsi_blk", str, IF_TYPE_SCSI, -1, - bd.blksz, bd.lba, &bdev); + ret = blk_create_devicef(dev, "scsi_blk", str, UCLASS_SCSI, -1, + bd.blksz, bd.lba, &bdev); if (ret) { debug("Can't create device\n"); return ret; @@ -638,7 +638,7 @@ int scsi_scan(bool verbose) if (verbose) printf("scanning bus for devices...\n"); - blk_unbind_all(IF_TYPE_SCSI); + blk_unbind_all(UCLASS_SCSI); ret = uclass_get(UCLASS_SCSI, &uc); if (ret) @@ -706,8 +706,8 @@ U_BOOT_DRIVER(scsi_blk) = { }; #else U_BOOT_LEGACY_BLK(scsi) = { - .if_typename = "scsi", - .if_type = IF_TYPE_SCSI, + .uclass_idname = "scsi", + .uclass_id = UCLASS_SCSI, .max_devs = SCSI_MAX_DEVICE, .desc = scsi_dev_desc, }; diff --git a/drivers/scsi/scsi_emul.c b/drivers/scsi/scsi_emul.c new file mode 100644 index 0000000000..5ba364bdac --- /dev/null +++ b/drivers/scsi/scsi_emul.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Emulation of enough SCSI commands to find and read from a unit + * + * Copyright 2022 Google LLC + * Written by Simon Glass + * + * implementation of SCSI functions required so that CONFIG_SCSI can be enabled + * for sandbox. + */ + +#define LOG_CATEGORY UCLASS_SCSI + +#include +#include +#include +#include +#include + +int sb_scsi_emul_command(struct scsi_emul_info *info, + const struct scsi_cmd *req, int len) +{ + int ret = 0; + + info->buff_used = 0; + log_debug("emul %x\n", *req->cmd); + switch (*req->cmd) { + case SCSI_INQUIRY: { + struct scsi_inquiry_resp *resp = (void *)info->buff; + + info->alloc_len = req->cmd[4]; + memset(resp, '\0', sizeof(*resp)); + resp->data_format = 1; + resp->additional_len = 0x1f; + strncpy(resp->vendor, info->vendor, sizeof(resp->vendor)); + strncpy(resp->product, info->product, sizeof(resp->product)); + strncpy(resp->revision, "1.0", sizeof(resp->revision)); + info->buff_used = sizeof(*resp); + break; + } + case SCSI_TST_U_RDY: + break; + case SCSI_RD_CAPAC: { + struct scsi_read_capacity_resp *resp = (void *)info->buff; + uint blocks; + + if (info->file_size) + blocks = info->file_size / info->block_size - 1; + else + blocks = 0; + resp->last_block_addr = cpu_to_be32(blocks); + resp->block_len = cpu_to_be32(info->block_size); + info->buff_used = sizeof(*resp); + break; + } + case SCSI_READ10: { + const struct scsi_read10_req *read_req = (void *)req; + + info->seek_block = be32_to_cpu(read_req->lba); + info->read_len = be16_to_cpu(read_req->xfer_len); + info->buff_used = info->read_len * info->block_size; + ret = SCSI_EMUL_DO_READ; + break; + } + default: + debug("Command not supported: %x\n", req->cmd[0]); + ret = -EPROTONOSUPPORT; + } + if (ret >= 0) + info->phase = info->transfer_len ? SCSIPH_DATA : SCSIPH_STATUS; + log_debug(" - done %x: ret=%d\n", *req->cmd, ret); + + return ret; +} diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c index 1fb9ee5cc9..90ccdf6b29 100644 --- a/drivers/serial/atmel_usart.c +++ b/drivers/serial/atmel_usart.c @@ -103,7 +103,7 @@ static int atmel_serial_getc(void) atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE; while (!(readl(&usart->csr) & USART3_BIT(RXRDY))) - WATCHDOG_RESET(); + schedule(); return readl(&usart->rhr); } diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 47bad6f8e2..7592979cab 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -296,7 +296,7 @@ void ns16550_putc(struct ns16550 *com_port, char c) * in puts(). */ if (c == '\n') - WATCHDOG_RESET(); + schedule(); } #ifndef CONFIG_NS16550_MIN_FUNCTIONS @@ -307,7 +307,7 @@ char ns16550_getc(struct ns16550 *com_port) extern void usbtty_poll(void); usbtty_poll(); #endif - WATCHDOG_RESET(); + schedule(); } return serial_in(&com_port->rbr); } @@ -395,7 +395,7 @@ static int ns16550_serial_putc(struct udevice *dev, const char ch) * in puts(). */ if (ch == '\n') - WATCHDOG_RESET(); + schedule(); return 0; } diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 30650e37b0..da3e1eb3ab 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -238,6 +238,18 @@ static void _serial_puts(struct udevice *dev, const char *str) } while (*str); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void _serial_flush(struct udevice *dev) +{ + struct dm_serial_ops *ops = serial_get_ops(dev); + + if (!ops->pending) + return; + while (ops->pending(dev, false) > 0) + ; +} +#endif + static int __serial_getc(struct udevice *dev) { struct dm_serial_ops *ops = serial_get_ops(dev); @@ -246,7 +258,7 @@ static int __serial_getc(struct udevice *dev) do { err = ops->getc(dev); if (err == -EAGAIN) - WATCHDOG_RESET(); + schedule(); } while (err == -EAGAIN); return err >= 0 ? err : 0; @@ -315,6 +327,16 @@ void serial_puts(const char *str) _serial_puts(gd->cur_serial_dev, str); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void serial_flush(void) +{ + if (!gd->cur_serial_dev) + return; + + _serial_flush(gd->cur_serial_dev); +} +#endif + int serial_getc(void) { if (!gd->cur_serial_dev) @@ -398,6 +420,13 @@ static void serial_stub_puts(struct stdio_dev *sdev, const char *str) _serial_puts(sdev->priv, str); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void serial_stub_flush(struct stdio_dev *sdev) +{ + _serial_flush(sdev->priv); +} +#endif + static int serial_stub_getc(struct stdio_dev *sdev) { return _serial_getc(sdev->priv); @@ -447,6 +476,7 @@ static int on_baudrate(const char *name, const char *value, enum env_op op, printf("## Switch baudrate to %d bps and press ENTER ...\n", baudrate); udelay(50000); + flush(); } gd->baudrate = baudrate; @@ -520,6 +550,7 @@ static int serial_post_probe(struct udevice *dev) sdev.priv = dev; sdev.putc = serial_stub_putc; sdev.puts = serial_stub_puts; + STDIO_DEV_ASSIGN_FLUSH(&sdev, serial_stub_flush); sdev.getc = serial_stub_getc; sdev.tstc = serial_stub_tstc; diff --git a/drivers/serial/serial_bcm283x_mu.c b/drivers/serial/serial_bcm283x_mu.c index f0756c37c8..493a42b4cc 100644 --- a/drivers/serial/serial_bcm283x_mu.c +++ b/drivers/serial/serial_bcm283x_mu.c @@ -114,7 +114,7 @@ static int bcm283x_mu_serial_pending(struct udevice *dev, bool input) lsr = readl(®s->lsr); if (input) { - WATCHDOG_RESET(); + schedule(); return (lsr & BCM283X_MU_LSR_RX_READY) ? 1 : 0; } else { return (lsr & BCM283X_MU_LSR_TX_IDLE) ? 0 : 1; diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c index ca49ef7372..ff576da516 100644 --- a/drivers/serial/serial_lpuart.c +++ b/drivers/serial/serial_lpuart.c @@ -169,7 +169,7 @@ static int _lpuart_serial_getc(struct lpuart_serial_plat *plat) { struct lpuart_fsl *base = plat->reg; while (!(__raw_readb(&base->us1) & (US1_RDRF | US1_OR))) - WATCHDOG_RESET(); + schedule(); barrier(); @@ -182,7 +182,7 @@ static void _lpuart_serial_putc(struct lpuart_serial_plat *plat, struct lpuart_fsl *base = plat->reg; while (!(__raw_readb(&base->us1) & US1_TDRE)) - WATCHDOG_RESET(); + schedule(); __raw_writeb(c, &base->ud); } @@ -330,7 +330,7 @@ static int _lpuart32_serial_getc(struct lpuart_serial_plat *plat) lpuart_read32(plat->flags, &base->stat, &stat); while ((stat & STAT_RDRF) == 0) { lpuart_write32(plat->flags, &base->stat, STAT_FLAGS); - WATCHDOG_RESET(); + schedule(); lpuart_read32(plat->flags, &base->stat, &stat); } @@ -358,7 +358,7 @@ static void _lpuart32_serial_putc(struct lpuart_serial_plat *plat, if ((stat & STAT_TDRE)) break; - WATCHDOG_RESET(); + schedule(); } lpuart_write32(plat->flags, &base->data, c); diff --git a/drivers/serial/serial_mpc8xx.c b/drivers/serial/serial_mpc8xx.c index 0978930dcd..aeae6ae6cd 100644 --- a/drivers/serial/serial_mpc8xx.c +++ b/drivers/serial/serial_mpc8xx.c @@ -187,7 +187,7 @@ static int serial_mpc8xx_putc(struct udevice *dev, const char c) setbits_be16(&rtx->txbd.cbd_sc, BD_SC_READY); while (in_be16(&rtx->txbd.cbd_sc) & BD_SC_READY) - WATCHDOG_RESET(); + schedule(); return 0; } @@ -204,7 +204,7 @@ static int serial_mpc8xx_getc(struct udevice *dev) /* Wait for character to show up. */ while (in_be16(&rtx->rxbd.cbd_sc) & BD_SC_EMPTY) - WATCHDOG_RESET(); + schedule(); /* the characters are read one by one, * use the rxindex to know the next char to deliver diff --git a/drivers/serial/serial_mt7620.c b/drivers/serial/serial_mt7620.c index 5c5264bc96..b00e2f2c36 100644 --- a/drivers/serial/serial_mt7620.c +++ b/drivers/serial/serial_mt7620.c @@ -102,7 +102,7 @@ static int mt7620_serial_putc(struct udevice *dev, const char ch) writel(ch, &plat->regs->thr); if (ch == '\n') - WATCHDOG_RESET(); + schedule(); return 0; } diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c index a84f39b3fa..03b9e86bfc 100644 --- a/drivers/serial/serial_mtk.c +++ b/drivers/serial/serial_mtk.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -70,27 +71,37 @@ struct mtk_serial_regs { #define BAUD_ALLOW_MAX(baud) ((baud) + (baud) * 3 / 100) #define BAUD_ALLOW_MIX(baud) ((baud) - (baud) * 3 / 100) +/* struct mtk_serial_priv - Structure holding all information used by the + * driver + * @regs: Register base of the serial port + * @clk: The baud clock device + * @fixed_clk_rate: Fallback fixed baud clock rate if baud clock + * device is not specified + * @force_highspeed: Force using high-speed mode + */ struct mtk_serial_priv { struct mtk_serial_regs __iomem *regs; - u32 clock; + struct clk clk; + u32 fixed_clk_rate; bool force_highspeed; }; -static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud) +static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud, + uint clk_rate) { u32 quot, realbaud, samplecount = 1; /* Special case for low baud clock */ - if (baud <= 115200 && priv->clock <= 12000000) { + if (baud <= 115200 && clk_rate == 12000000) { writel(3, &priv->regs->highspeed); - quot = DIV_ROUND_CLOSEST(priv->clock, 256 * baud); + quot = DIV_ROUND_CLOSEST(clk_rate, 256 * baud); if (quot == 0) quot = 1; - samplecount = DIV_ROUND_CLOSEST(priv->clock, quot * baud); + samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud); - realbaud = priv->clock / samplecount / quot; + realbaud = clk_rate / samplecount / quot; if (realbaud > BAUD_ALLOW_MAX(baud) || realbaud < BAUD_ALLOW_MIX(baud)) { pr_info("baud %d can't be handled\n", baud); @@ -104,7 +115,7 @@ static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud) if (baud <= 115200) { writel(0, &priv->regs->highspeed); - quot = DIV_ROUND_CLOSEST(priv->clock, 16 * baud); + quot = DIV_ROUND_CLOSEST(clk_rate, 16 * baud); } else if (baud <= 576000) { writel(2, &priv->regs->highspeed); @@ -112,13 +123,13 @@ static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud) if ((baud == 500000) || (baud == 576000)) baud = 460800; - quot = DIV_ROUND_UP(priv->clock, 4 * baud); + quot = DIV_ROUND_UP(clk_rate, 4 * baud); } else { use_hs3: writel(3, &priv->regs->highspeed); - quot = DIV_ROUND_UP(priv->clock, 256 * baud); - samplecount = DIV_ROUND_CLOSEST(priv->clock, quot * baud); + quot = DIV_ROUND_UP(clk_rate, 256 * baud); + samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud); } set_baud: @@ -141,7 +152,7 @@ static int _mtk_serial_putc(struct mtk_serial_priv *priv, const char ch) writel(ch, &priv->regs->thr); if (ch == '\n') - WATCHDOG_RESET(); + schedule(); return 0; } @@ -167,8 +178,13 @@ static int _mtk_serial_pending(struct mtk_serial_priv *priv, bool input) static int mtk_serial_setbrg(struct udevice *dev, int baudrate) { struct mtk_serial_priv *priv = dev_get_priv(dev); + u32 clk_rate; - _mtk_serial_setbrg(priv, baudrate); + clk_rate = clk_get_rate(&priv->clk); + if (IS_ERR_VALUE(clk_rate) || clk_rate == 0) + clk_rate = priv->fixed_clk_rate; + + _mtk_serial_setbrg(priv, baudrate, clk_rate); return 0; } @@ -211,7 +227,6 @@ static int mtk_serial_of_to_plat(struct udevice *dev) { struct mtk_serial_priv *priv = dev_get_priv(dev); fdt_addr_t addr; - struct clk clk; int err; addr = dev_read_addr(dev); @@ -220,22 +235,19 @@ static int mtk_serial_of_to_plat(struct udevice *dev) priv->regs = map_physmem(addr, 0, MAP_NOCACHE); - err = clk_get_by_index(dev, 0, &clk); - if (!err) { - err = clk_get_rate(&clk); - if (!IS_ERR_VALUE(err)) - priv->clock = err; - } else if (err != -ENOENT && err != -ENODEV && err != -ENOSYS) { - debug("mtk_serial: failed to get clock\n"); - return err; - } - - if (!priv->clock) - priv->clock = dev_read_u32_default(dev, "clock-frequency", 0); - - if (!priv->clock) { - debug("mtk_serial: clock not defined\n"); - return -EINVAL; + err = clk_get_by_index(dev, 0, &priv->clk); + if (err) { + err = dev_read_u32(dev, "clock-frequency", &priv->fixed_clk_rate); + if (err) { + dev_err(dev, "baud clock not defined\n"); + return -EINVAL; + } + } else { + err = clk_get_rate(&priv->clk); + if (IS_ERR_VALUE(err)) { + dev_err(dev, "invalid baud clock\n"); + return -EINVAL; + } } priv->force_highspeed = dev_read_bool(dev, "mediatek,force-highspeed"); @@ -273,7 +285,7 @@ DECLARE_GLOBAL_DATA_PTR; #define DECLARE_HSUART_PRIV(port) \ static struct mtk_serial_priv mtk_hsuart##port = { \ .regs = (struct mtk_serial_regs *)CONFIG_SYS_NS16550_COM##port, \ - .clock = CONFIG_SYS_NS16550_CLK \ + .fixed_clk_rate = CONFIG_SYS_NS16550_CLK \ }; #define DECLARE_HSUART_FUNCTIONS(port) \ @@ -282,12 +294,14 @@ DECLARE_GLOBAL_DATA_PTR; writel(0, &mtk_hsuart##port.regs->ier); \ writel(UART_MCRVAL, &mtk_hsuart##port.regs->mcr); \ writel(UART_FCRVAL, &mtk_hsuart##port.regs->fcr); \ - _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \ + _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \ + mtk_hsuart##port.fixed_clk_rate); \ return 0 ; \ } \ static void mtk_serial##port##_setbrg(void) \ { \ - _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \ + _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \ + mtk_hsuart##port.fixed_clk_rate); \ } \ static int mtk_serial##port##_getc(void) \ { \ @@ -295,7 +309,7 @@ DECLARE_GLOBAL_DATA_PTR; do { \ err = _mtk_serial_getc(&mtk_hsuart##port); \ if (err == -EAGAIN) \ - WATCHDOG_RESET(); \ + schedule(); \ } while (err == -EAGAIN); \ return err >= 0 ? err : 0; \ } \ @@ -427,13 +441,13 @@ static inline void _debug_uart_init(void) struct mtk_serial_priv priv; priv.regs = (void *) CONFIG_VAL(DEBUG_UART_BASE); - priv.clock = CONFIG_DEBUG_UART_CLOCK; + priv.fixed_clk_rate = CONFIG_DEBUG_UART_CLOCK; writel(0, &priv.regs->ier); writel(UART_MCRVAL, &priv.regs->mcr); writel(UART_FCRVAL, &priv.regs->fcr); - _mtk_serial_setbrg(&priv, CONFIG_BAUDRATE); + _mtk_serial_setbrg(&priv, CONFIG_BAUDRATE, priv.fixed_clk_rate); } static inline void _debug_uart_putc(int ch) diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c index af1fd1ea9b..4cf79c1ca2 100644 --- a/drivers/serial/serial_mxc.c +++ b/drivers/serial/serial_mxc.c @@ -213,7 +213,7 @@ static void mxc_serial_setbrg(void) static int mxc_serial_getc(void) { while (readl(&mxc_base->ts) & UTS_RXEMPTY) - WATCHDOG_RESET(); + schedule(); return (readl(&mxc_base->rxd) & URXD_RX_DATA); /* mask out status from upper word */ } @@ -227,7 +227,7 @@ static void mxc_serial_putc(const char c) /* wait for transmitter to be ready */ while (!(readl(&mxc_base->ts) & UTS_TXEMPTY)) - WATCHDOG_RESET(); + schedule(); } /* Test whether a character is in the RX buffer */ @@ -397,7 +397,7 @@ static inline void _debug_uart_putc(int ch) struct mxc_uart *base = (struct mxc_uart *)CONFIG_VAL(DEBUG_UART_BASE); while (!(readl(&base->ts) & UTS_TXEMPTY)) - WATCHDOG_RESET(); + schedule(); writel(ch, &base->txd); } diff --git a/drivers/serial/serial_octeon_bootcmd.c b/drivers/serial/serial_octeon_bootcmd.c index 4bcff77eb8..eff5c43e2a 100644 --- a/drivers/serial/serial_octeon_bootcmd.c +++ b/drivers/serial/serial_octeon_bootcmd.c @@ -98,7 +98,7 @@ static int octeon_bootcmd_getc(struct udevice *dev) } while (!octeon_bootcmd_pending(dev, true)) { - WATCHDOG_RESET(); + schedule(); /* * ToDo: * The original code calls octeon_board_poll() here. We may diff --git a/drivers/serial/serial_octeon_pcie_console.c b/drivers/serial/serial_octeon_pcie_console.c index c76e787d03..b0eafe7ad8 100644 --- a/drivers/serial/serial_octeon_pcie_console.c +++ b/drivers/serial/serial_octeon_pcie_console.c @@ -134,7 +134,7 @@ static int octeon_pcie_console_read(struct udevice *dev, cons_ptr->input_write_index, cons_ptr->input_read_index))) { mdelay(10); - WATCHDOG_RESET(); + schedule(); } } @@ -210,7 +210,7 @@ static int octeon_pcie_console_write(struct udevice *dev, if (flags & OCT_PCI_CON_FLAG_NONBLOCK) goto done; - WATCHDOG_RESET(); + schedule(); mdelay(10); /* Delay if we are spinning */ } else { bytes_written = -1; diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index 9b0d16f164..d3c3d3e2d1 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -70,7 +70,7 @@ static int pl01x_getc(struct pl01x_regs *regs) static int pl01x_tstc(struct pl01x_regs *regs) { - WATCHDOG_RESET(); + schedule(); return !(readl(®s->fr) & UART_PL01x_FR_RXFE); } @@ -227,7 +227,7 @@ static int pl01x_serial_getc(void) int ch = pl01x_getc(base_regs); if (ch == -EAGAIN) { - WATCHDOG_RESET(); + schedule(); continue; } @@ -247,9 +247,9 @@ static void pl01x_serial_setbrg(void) * crap in console */ while (!(readl(&base_regs->fr) & UART_PL01x_FR_TXFE)) - WATCHDOG_RESET(); + schedule(); while (readl(&base_regs->fr) & UART_PL01x_FR_BUSY) - WATCHDOG_RESET(); + schedule(); pl01x_serial_init_baud(gd->baudrate); } diff --git a/drivers/serial/serial_sifive.c b/drivers/serial/serial_sifive.c index 4af1ff5060..c449f3fd02 100644 --- a/drivers/serial/serial_sifive.c +++ b/drivers/serial/serial_sifive.c @@ -225,7 +225,7 @@ static inline void _debug_uart_putc(int ch) (struct uart_sifive *)CONFIG_VAL(DEBUG_UART_BASE); while (_sifive_serial_putc(regs, ch) == -EAGAIN) - WATCHDOG_RESET(); + schedule(); } DEBUG_UART_FUNCS diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c index 295337a817..4b1818313a 100644 --- a/drivers/serial/serial_zynq.c +++ b/drivers/serial/serial_zynq.c @@ -307,7 +307,7 @@ static inline void _debug_uart_putc(int ch) struct uart_zynq *regs = (struct uart_zynq *)CONFIG_VAL(DEBUG_UART_BASE); while (_uart_zynq_serial_putc(regs, ch) == -EAGAIN) - WATCHDOG_RESET(); + schedule(); } DEBUG_UART_FUNCS diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 75b794548b..2f12081f88 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -40,6 +40,16 @@ config SPI_MEM This extension is meant to simplify interaction with SPI memories by providing an high-level interface to send memory-like commands. +config SPI_DIRMAP + bool "SPI direct mapping" + depends on SPI_MEM + help + Enable the SPI direct mapping API. Most modern SPI controllers can + directly map a SPI memory (or a portion of the SPI memory) in the CPU + address space. Most of the time this brings significant performance + improvements as it automates the whole process of sending SPI memory + operations every time a new region is accessed. + if DM_SPI config ALTERA_SPI @@ -138,7 +148,7 @@ config CQSPI_REF_CLK config CADENCE_OSPI_VERSAL bool "Configure Versal OSPI" - depends on ARCH_VERSAL && CADENCE_QSPI + depends on (ARCH_VERSAL || ARCH_VERSAL_NET) && CADENCE_QSPI imply DM_GPIO help This option is used to enable Versal OSPI DMA operations which @@ -276,6 +286,14 @@ config MTK_SNFI_SPI used to access SPI memory devices like SPI-NOR or SPI-NAND on platforms embedding this IP core, like MT7622/M7629. +config MTK_SPIM + bool "Mediatek SPI-MEM master controller driver" + depends on SPI_MEM + help + Enable MediaTek SPI-MEM master controller driver. This driver mainly + supports SPI flashes. You can use single, dual or quad mode + transmission on this controller. + config MVEBU_A3700_SPI bool "Marvell Armada 3700 SPI driver" select CLK_ARMADA_3720 @@ -401,6 +419,14 @@ config SANDBOX_SPI }; }; +config SPI_ASPEED_SMC + bool "ASPEED SPI flash controller driver" + depends on DM_SPI && SPI_MEM + default n + help + Enable ASPEED SPI flash controller driver for AST2500 + and AST2600 SoCs. + config SPI_SIFIVE bool "SiFive SPI driver" help diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 4de77c260a..50ba43550b 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o obj-$(CONFIG_CADENCE_OSPI_VERSAL) += cadence_ospi_versal.o obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o obj-$(CONFIG_SOFT_SPI) += soft_spi.o +obj-$(CONFIG_SPI_ASPEED_SMC) += spi-aspeed-smc.o obj-$(CONFIG_SPI_MEM) += spi-mem.o obj-$(CONFIG_TI_QSPI) += ti_qspi.o obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o @@ -43,6 +44,7 @@ obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o obj-$(CONFIG_MTK_SNFI_SPI) += mtk_snfi_spi.o obj-$(CONFIG_MTK_SNOR) += mtk_snor.o +obj-$(CONFIG_MTK_SPIM) += mtk_spim.o obj-$(CONFIG_MT7620_SPI) += mt7620_spi.o obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o obj-$(CONFIG_MSCC_BB_SPI) += mscc_bb_spi.o diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index 52bcad053f..a9547a8200 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -21,7 +21,7 @@ #define CMD_4BYTE_READ 0x13 #define CMD_4BYTE_FAST_READ 0x0C -int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat, +int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data; @@ -34,86 +34,86 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat, if (bytes_to_dma) { cadence_qspi_apb_enable_linear_mode(false); - reg = readl(plat->regbase + CQSPI_REG_CONFIG); + reg = readl(priv->regbase + CQSPI_REG_CONFIG); reg |= CQSPI_REG_CONFIG_ENBL_DMA; - writel(reg, plat->regbase + CQSPI_REG_CONFIG); + writel(reg, priv->regbase + CQSPI_REG_CONFIG); - writel(bytes_to_dma, plat->regbase + CQSPI_REG_INDIRECTRDBYTES); + writel(bytes_to_dma, priv->regbase + CQSPI_REG_INDIRECTRDBYTES); writel(CQSPI_DFLT_INDIR_TRIG_ADDR_RANGE, - plat->regbase + CQSPI_REG_INDIR_TRIG_ADDR_RANGE); + priv->regbase + CQSPI_REG_INDIR_TRIG_ADDR_RANGE); writel(CQSPI_DFLT_DMA_PERIPH_CFG, - plat->regbase + CQSPI_REG_DMA_PERIPH_CFG); - writel((unsigned long)rxbuf, plat->regbase + + priv->regbase + CQSPI_REG_DMA_PERIPH_CFG); + writel((unsigned long)rxbuf, priv->regbase + CQSPI_DMA_DST_ADDR_REG); - writel(plat->trigger_address, plat->regbase + + writel(priv->trigger_address, priv->regbase + CQSPI_DMA_SRC_RD_ADDR_REG); - writel(bytes_to_dma, plat->regbase + + writel(bytes_to_dma, priv->regbase + CQSPI_DMA_DST_SIZE_REG); flush_dcache_range((unsigned long)rxbuf, (unsigned long)rxbuf + bytes_to_dma); writel(CQSPI_DFLT_DST_CTRL_REG_VAL, - plat->regbase + CQSPI_DMA_DST_CTRL_REG); + priv->regbase + CQSPI_DMA_DST_CTRL_REG); /* Start the indirect read transfer */ - writel(CQSPI_REG_INDIRECTRD_START, plat->regbase + + writel(CQSPI_REG_INDIRECTRD_START, priv->regbase + CQSPI_REG_INDIRECTRD); /* Wait for dma to complete transfer */ - ret = cadence_qspi_apb_wait_for_dma_cmplt(plat); + ret = cadence_qspi_apb_wait_for_dma_cmplt(priv); if (ret) return ret; /* Clear indirect completion status */ - writel(CQSPI_REG_INDIRECTRD_DONE, plat->regbase + + writel(CQSPI_REG_INDIRECTRD_DONE, priv->regbase + CQSPI_REG_INDIRECTRD); rxbuf += bytes_to_dma; } if (rx_rem) { - reg = readl(plat->regbase + CQSPI_REG_CONFIG); + reg = readl(priv->regbase + CQSPI_REG_CONFIG); reg &= ~CQSPI_REG_CONFIG_ENBL_DMA; - writel(reg, plat->regbase + CQSPI_REG_CONFIG); + writel(reg, priv->regbase + CQSPI_REG_CONFIG); - reg = readl(plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR); + reg = readl(priv->regbase + CQSPI_REG_INDIRECTRDSTARTADDR); reg += bytes_to_dma; - writel(reg, plat->regbase + CQSPI_REG_CMDADDRESS); + writel(reg, priv->regbase + CQSPI_REG_CMDADDRESS); - addr_bytes = readl(plat->regbase + CQSPI_REG_SIZE) & + addr_bytes = readl(priv->regbase + CQSPI_REG_SIZE) & CQSPI_REG_SIZE_ADDRESS_MASK; opcode = CMD_4BYTE_FAST_READ; dummy_cycles = 8; writel((dummy_cycles << CQSPI_REG_RD_INSTR_DUMMY_LSB) | opcode, - plat->regbase + CQSPI_REG_RD_INSTR); + priv->regbase + CQSPI_REG_RD_INSTR); reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB; reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB); reg |= (addr_bytes & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) << CQSPI_REG_CMDCTRL_ADD_BYTES_LSB; reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB); - dummy_cycles = (readl(plat->regbase + CQSPI_REG_RD_INSTR) >> + dummy_cycles = (readl(priv->regbase + CQSPI_REG_RD_INSTR) >> CQSPI_REG_RD_INSTR_DUMMY_LSB) & CQSPI_REG_RD_INSTR_DUMMY_MASK; reg |= (dummy_cycles & CQSPI_REG_CMDCTRL_DUMMY_MASK) << CQSPI_REG_CMDCTRL_DUMMY_LSB; reg |= (((rx_rem - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK) << CQSPI_REG_CMDCTRL_RD_BYTES_LSB); - ret = cadence_qspi_apb_exec_flash_cmd(plat->regbase, reg); + ret = cadence_qspi_apb_exec_flash_cmd(priv->regbase, reg); if (ret) return ret; - data = readl(plat->regbase + CQSPI_REG_CMDREADDATALOWER); + data = readl(priv->regbase + CQSPI_REG_CMDREADDATALOWER); memcpy(rxbuf, &data, rx_rem); } return 0; } -int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_plat *plat) +int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_priv *priv) { u32 timeout = CQSPI_DMA_TIMEOUT; - while (!(readl(plat->regbase + CQSPI_DMA_DST_I_STS_REG) & + while (!(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG) & CQSPI_DMA_DST_I_STS_DONE) && timeout--) udelay(1); @@ -122,14 +122,15 @@ int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_plat *plat) return -ETIMEDOUT; } - writel(readl(plat->regbase + CQSPI_DMA_DST_I_STS_REG), - plat->regbase + CQSPI_DMA_DST_I_STS_REG); + writel(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG), + priv->regbase + CQSPI_DMA_DST_I_STS_REG); return 0; } #if defined(CONFIG_DM_GPIO) -int cadence_spi_versal_flash_reset(struct udevice *dev) +int cadence_qspi_versal_flash_reset(struct udevice *dev) { +#ifndef CONFIG_ARCH_VERSAL_NET struct gpio_desc gpio; u32 reset_gpio; int ret; @@ -165,11 +166,11 @@ int cadence_spi_versal_flash_reset(struct udevice *dev) /* Set value 1 to pin */ dm_gpio_set_value(&gpio, 1); udelay(1); - +#endif return 0; } #else -int cadence_spi_versal_flash_reset(struct udevice *dev) +int cadence_qspi_versal_flash_reset(struct udevice *dev) { /* CRP WPROT */ writel(0, WPROT_CRP); diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index 907f5dadc4..ab0a681c83 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -29,7 +29,7 @@ #define CQSPI_READ 2 #define CQSPI_WRITE 3 -__weak int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat, +__weak int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { return 0; @@ -42,36 +42,40 @@ __weak int cadence_qspi_versal_flash_reset(struct udevice *dev) static int cadence_spi_write_speed(struct udevice *bus, uint hz) { - struct cadence_spi_plat *plat = dev_get_plat(bus); struct cadence_spi_priv *priv = dev_get_priv(bus); cadence_qspi_apb_config_baudrate_div(priv->regbase, - plat->ref_clk_hz, hz); + priv->ref_clk_hz, hz); /* Reconfigure delay timing if speed is changed. */ - cadence_qspi_apb_delay(priv->regbase, plat->ref_clk_hz, hz, - plat->tshsl_ns, plat->tsd2d_ns, - plat->tchsh_ns, plat->tslch_ns); + cadence_qspi_apb_delay(priv->regbase, priv->ref_clk_hz, hz, + priv->tshsl_ns, priv->tsd2d_ns, + priv->tchsh_ns, priv->tslch_ns); return 0; } -static int cadence_spi_read_id(struct cadence_spi_plat *plat, u8 len, +static int cadence_spi_read_id(struct cadence_spi_priv *priv, u8 len, u8 *idcode) { + int err; + struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0x9F, 1), SPI_MEM_OP_NO_ADDR, SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_IN(len, idcode, 1)); - return cadence_qspi_apb_command_read(plat, &op); + err = cadence_qspi_apb_command_read_setup(priv, &op); + if (!err) + err = cadence_qspi_apb_command_read(priv, &op); + + return err; } /* Calibration sequence to determine the read data capture delay register */ static int spi_calibration(struct udevice *bus, uint hz) { struct cadence_spi_priv *priv = dev_get_priv(bus); - struct cadence_spi_plat *plat = dev_get_plat(bus); void *base = priv->regbase; unsigned int idcode = 0, temp = 0; int err = 0, i, range_lo = -1, range_hi = -1; @@ -86,7 +90,7 @@ static int spi_calibration(struct udevice *bus, uint hz) cadence_qspi_apb_controller_enable(base); /* read the ID which will be our golden value */ - err = cadence_spi_read_id(plat, 3, (u8 *)&idcode); + err = cadence_spi_read_id(priv, 3, (u8 *)&idcode); if (err) { puts("SF: Calibration failed (read)\n"); return err; @@ -105,7 +109,7 @@ static int spi_calibration(struct udevice *bus, uint hz) cadence_qspi_apb_controller_enable(base); /* issue a RDID to get the ID value */ - err = cadence_spi_read_id(plat, 3, (u8 *)&temp); + err = cadence_spi_read_id(priv, 3, (u8 *)&temp); if (err) { puts("SF: Calibration failed (read)\n"); return err; @@ -147,13 +151,11 @@ static int spi_calibration(struct udevice *bus, uint hz) static int cadence_spi_set_speed(struct udevice *bus, uint hz) { - struct cadence_spi_plat *plat = dev_get_plat(bus); struct cadence_spi_priv *priv = dev_get_priv(bus); int err; - if (!hz || hz > plat->max_hz) - hz = plat->max_hz; - + if (!hz || hz > priv->max_hz) + hz = priv->max_hz; /* Disable QSPI */ cadence_qspi_apb_controller_disable(priv->regbase); @@ -161,10 +163,10 @@ static int cadence_spi_set_speed(struct udevice *bus, uint hz) * If the device tree already provides a read delay value, use that * instead of calibrating. */ - if (plat->read_delay >= 0) { + if (priv->read_delay >= 0) { cadence_spi_write_speed(bus, hz); cadence_qspi_apb_readdata_capture(priv->regbase, 1, - plat->read_delay); + priv->read_delay); } else if (priv->previous_hz != hz || priv->qspi_calibrated_hz != hz || priv->qspi_calibrated_cs != spi_chip_select(bus)) { @@ -195,29 +197,44 @@ static int cadence_spi_probe(struct udevice *bus) struct clk clk; int ret; - priv->regbase = plat->regbase; - priv->ahbbase = plat->ahbbase; + priv->regbase = plat->regbase; + priv->ahbbase = plat->ahbbase; + priv->is_dma = plat->is_dma; + priv->is_decoded_cs = plat->is_decoded_cs; + priv->fifo_depth = plat->fifo_depth; + priv->fifo_width = plat->fifo_width; + priv->trigger_address = plat->trigger_address; + priv->read_delay = plat->read_delay; + priv->ahbsize = plat->ahbsize; + priv->max_hz = plat->max_hz; + + priv->page_size = plat->page_size; + priv->block_size = plat->block_size; + priv->tshsl_ns = plat->tshsl_ns; + priv->tsd2d_ns = plat->tsd2d_ns; + priv->tchsh_ns = plat->tchsh_ns; + priv->tslch_ns = plat->tslch_ns; if (CONFIG_IS_ENABLED(ZYNQMP_FIRMWARE)) xilinx_pm_request(PM_REQUEST_NODE, PM_DEV_OSPI, ZYNQMP_PM_CAPABILITY_ACCESS, ZYNQMP_PM_MAX_QOS, ZYNQMP_PM_REQUEST_ACK_NO, NULL); - if (plat->ref_clk_hz == 0) { + if (priv->ref_clk_hz == 0) { ret = clk_get_by_index(bus, 0, &clk); if (ret) { #ifdef CONFIG_HAS_CQSPI_REF_CLK - plat->ref_clk_hz = CONFIG_CQSPI_REF_CLK; + priv->ref_clk_hz = CONFIG_CQSPI_REF_CLK; #elif defined(CONFIG_ARCH_SOCFPGA) - plat->ref_clk_hz = cm_get_qspi_controller_clk_hz(); + priv->ref_clk_hz = cm_get_qspi_controller_clk_hz(); #else return ret; #endif } else { - plat->ref_clk_hz = clk_get_rate(&clk); + priv->ref_clk_hz = clk_get_rate(&clk); clk_free(&clk); - if (IS_ERR_VALUE(plat->ref_clk_hz)) - return plat->ref_clk_hz; + if (IS_ERR_VALUE(priv->ref_clk_hz)) + return priv->ref_clk_hz; } } @@ -226,16 +243,16 @@ static int cadence_spi_probe(struct udevice *bus) reset_deassert_bulk(priv->resets); if (!priv->qspi_is_init) { - cadence_qspi_apb_controller_init(plat); + cadence_qspi_apb_controller_init(priv); priv->qspi_is_init = 1; } - plat->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC, plat->ref_clk_hz); + priv->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC, priv->ref_clk_hz); if (CONFIG_IS_ENABLED(ARCH_VERSAL)) { /* Versal platform uses spi calibration to set read delay */ - if (plat->read_delay >= 0) - plat->read_delay = -1; + if (priv->read_delay >= 0) + priv->read_delay = -1; /* Reset ospi flash device */ ret = cadence_qspi_versal_flash_reset(bus); if (ret) @@ -258,7 +275,6 @@ static int cadence_spi_remove(struct udevice *dev) static int cadence_spi_set_mode(struct udevice *bus, uint mode) { - struct cadence_spi_plat *plat = dev_get_plat(bus); struct cadence_spi_priv *priv = dev_get_priv(bus); /* Disable QSPI */ @@ -268,7 +284,7 @@ static int cadence_spi_set_mode(struct udevice *bus, uint mode) cadence_qspi_apb_set_clk_mode(priv->regbase, mode); /* Enable Direct Access Controller */ - if (plat->use_dac_mode) + if (priv->use_dac_mode) cadence_qspi_apb_dac_mode_enable(priv->regbase); /* Enable QSPI */ @@ -281,7 +297,6 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi, const struct spi_mem_op *op) { struct udevice *bus = spi->dev->parent; - struct cadence_spi_plat *plat = dev_get_plat(bus); struct cadence_spi_priv *priv = dev_get_priv(bus); void *base = priv->regbase; int err = 0; @@ -289,7 +304,7 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi, /* Set Chip select */ cadence_qspi_apb_chipselect(base, spi_chip_select(spi->dev), - plat->is_decoded_cs); + priv->is_decoded_cs); if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) { if (!op->addr.nbytes) @@ -305,28 +320,28 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi, switch (mode) { case CQSPI_STIG_READ: - err = cadence_qspi_apb_command_read_setup(plat, op); + err = cadence_qspi_apb_command_read_setup(priv, op); if (!err) - err = cadence_qspi_apb_command_read(plat, op); + err = cadence_qspi_apb_command_read(priv, op); break; case CQSPI_STIG_WRITE: - err = cadence_qspi_apb_command_write_setup(plat, op); + err = cadence_qspi_apb_command_write_setup(priv, op); if (!err) - err = cadence_qspi_apb_command_write(plat, op); + err = cadence_qspi_apb_command_write(priv, op); break; case CQSPI_READ: - err = cadence_qspi_apb_read_setup(plat, op); + err = cadence_qspi_apb_read_setup(priv, op); if (!err) { - if (plat->is_dma) - err = cadence_qspi_apb_dma_read(plat, op); + if (priv->is_dma) + err = cadence_qspi_apb_dma_read(priv, op); else - err = cadence_qspi_apb_read_execute(plat, op); + err = cadence_qspi_apb_read_execute(priv, op); } break; case CQSPI_WRITE: - err = cadence_qspi_apb_write_setup(plat, op); + err = cadence_qspi_apb_write_setup(priv, op); if (!err) - err = cadence_qspi_apb_write_execute(plat, op); + err = cadence_qspi_apb_write_execute(priv, op); break; default: err = -1; @@ -359,6 +374,7 @@ static bool cadence_spi_mem_supports_op(struct spi_slave *slave, static int cadence_spi_of_to_plat(struct udevice *bus) { struct cadence_spi_plat *plat = dev_get_plat(bus); + struct cadence_spi_priv *priv = dev_get_priv(bus); ofnode subnode; plat->regbase = (void *)devfdt_get_addr_index(bus, 0); @@ -372,7 +388,7 @@ static int cadence_spi_of_to_plat(struct udevice *bus) 0); /* Use DAC mode only when MMIO window is at least 8M wide */ if (plat->ahbsize >= SZ_8M) - plat->use_dac_mode = true; + priv->use_dac_mode = true; plat->is_dma = dev_read_bool(bus, "cdns,is-dma"); diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index c8d16bb0e4..1c59d1a9d9 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -198,7 +198,6 @@ CQSPI_REG_SDRAMLEVEL_WR_LSB) & CQSPI_REG_SDRAMLEVEL_WR_MASK) struct cadence_spi_plat { - unsigned int ref_clk_hz; unsigned int max_hz; void *regbase; void *ahbbase; @@ -209,7 +208,6 @@ struct cadence_spi_plat { fdt_addr_t ahbsize; bool use_dac_mode; int read_delay; - u32 wr_delay; /* Flash parameters */ u32 page_size; @@ -219,17 +217,18 @@ struct cadence_spi_plat { u32 tchsh_ns; u32 tslch_ns; - /* Transaction protocol parameters. */ - u8 inst_width; - u8 addr_width; - u8 data_width; - bool dtr; bool is_dma; }; struct cadence_spi_priv { + unsigned int ref_clk_hz; + unsigned int max_hz; void *regbase; void *ahbbase; + unsigned int fifo_depth; + unsigned int fifo_width; + unsigned int trigger_address; + fdt_addr_t ahbsize; size_t cmd_len; u8 cmd_buf[32]; size_t data_len; @@ -238,32 +237,53 @@ struct cadence_spi_priv { unsigned int qspi_calibrated_hz; unsigned int qspi_calibrated_cs; unsigned int previous_hz; + u32 wr_delay; + int read_delay; struct reset_ctl_bulk *resets; + u32 page_size; + u32 block_size; + u32 tshsl_ns; + u32 tsd2d_ns; + u32 tchsh_ns; + u32 tslch_ns; + u8 edge_mode; + u8 dll_mode; + bool extra_dummy; + bool ddr_init; + bool is_decoded_cs; + bool use_dac_mode; + bool is_dma; + + /* Transaction protocol parameters. */ + u8 inst_width; + u8 addr_width; + u8 data_width; + bool dtr; }; /* Functions call declaration */ -void cadence_qspi_apb_controller_init(struct cadence_spi_plat *plat); +void cadence_qspi_apb_controller_init(struct cadence_spi_priv *priv); void cadence_qspi_apb_controller_enable(void *reg_base_addr); void cadence_qspi_apb_controller_disable(void *reg_base_addr); void cadence_qspi_apb_dac_mode_enable(void *reg_base); -int cadence_qspi_apb_command_read_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_read_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_command_write_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_write_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_write(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_read_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_read_execute(struct cadence_spi_plat *plat, +int cadence_qspi_apb_read_execute(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_write_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_write_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_write_execute(struct cadence_spi_plat *plat, +int cadence_qspi_apb_write_execute(struct cadence_spi_priv *priv, const struct spi_mem_op *op); void cadence_qspi_apb_chipselect(void *reg_base, @@ -279,9 +299,9 @@ void cadence_qspi_apb_enter_xip(void *reg_base, char xip_dummy); void cadence_qspi_apb_readdata_capture(void *reg_base, unsigned int bypass, unsigned int delay); unsigned int cm_get_qspi_controller_clk_hz(void); -int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat, +int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_plat *plat); +int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_priv *priv); int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg); int cadence_qspi_versal_flash_reset(struct udevice *dev); void cadence_qspi_apb_enable_linear_mode(bool enable); diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index c00755050e..cfae5dcbda 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -83,13 +83,13 @@ static unsigned int cadence_qspi_calc_dummy(const struct spi_mem_op *op, return dummy_clk; } -static u32 cadence_qspi_calc_rdreg(struct cadence_spi_plat *plat) +static u32 cadence_qspi_calc_rdreg(struct cadence_spi_priv *priv) { u32 rdreg = 0; - rdreg |= plat->inst_width << CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB; - rdreg |= plat->addr_width << CQSPI_REG_RD_INSTR_TYPE_ADDR_LSB; - rdreg |= plat->data_width << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB; + rdreg |= priv->inst_width << CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB; + rdreg |= priv->addr_width << CQSPI_REG_RD_INSTR_TYPE_ADDR_LSB; + rdreg |= priv->data_width << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB; return rdreg; } @@ -115,27 +115,27 @@ static int cadence_qspi_buswidth_to_inst_type(u8 buswidth) } } -static int cadence_qspi_set_protocol(struct cadence_spi_plat *plat, +static int cadence_qspi_set_protocol(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { int ret; - plat->dtr = op->data.dtr && op->cmd.dtr && op->addr.dtr; + priv->dtr = op->data.dtr && op->cmd.dtr && op->addr.dtr; ret = cadence_qspi_buswidth_to_inst_type(op->cmd.buswidth); if (ret < 0) return ret; - plat->inst_width = ret; + priv->inst_width = ret; ret = cadence_qspi_buswidth_to_inst_type(op->addr.buswidth); if (ret < 0) return ret; - plat->addr_width = ret; + priv->addr_width = ret; ret = cadence_qspi_buswidth_to_inst_type(op->data.buswidth); if (ret < 0) return ret; - plat->data_width = ret; + priv->data_width = ret; return 0; } @@ -314,31 +314,31 @@ void cadence_qspi_apb_delay(void *reg_base, cadence_qspi_apb_controller_enable(reg_base); } -void cadence_qspi_apb_controller_init(struct cadence_spi_plat *plat) +void cadence_qspi_apb_controller_init(struct cadence_spi_priv *priv) { unsigned reg; - cadence_qspi_apb_controller_disable(plat->regbase); + cadence_qspi_apb_controller_disable(priv->regbase); /* Configure the device size and address bytes */ - reg = readl(plat->regbase + CQSPI_REG_SIZE); + reg = readl(priv->regbase + CQSPI_REG_SIZE); /* Clear the previous value */ reg &= ~(CQSPI_REG_SIZE_PAGE_MASK << CQSPI_REG_SIZE_PAGE_LSB); reg &= ~(CQSPI_REG_SIZE_BLOCK_MASK << CQSPI_REG_SIZE_BLOCK_LSB); - reg |= (plat->page_size << CQSPI_REG_SIZE_PAGE_LSB); - reg |= (plat->block_size << CQSPI_REG_SIZE_BLOCK_LSB); - writel(reg, plat->regbase + CQSPI_REG_SIZE); + reg |= (priv->page_size << CQSPI_REG_SIZE_PAGE_LSB); + reg |= (priv->block_size << CQSPI_REG_SIZE_BLOCK_LSB); + writel(reg, priv->regbase + CQSPI_REG_SIZE); /* Configure the remap address register, no remap */ - writel(0, plat->regbase + CQSPI_REG_REMAP); + writel(0, priv->regbase + CQSPI_REG_REMAP); /* Indirect mode configurations */ - writel(plat->fifo_depth / 2, plat->regbase + CQSPI_REG_SRAMPARTITION); + writel(priv->fifo_depth / 2, priv->regbase + CQSPI_REG_SRAMPARTITION); /* Disable all interrupts */ - writel(0, plat->regbase + CQSPI_REG_IRQMASK); + writel(0, priv->regbase + CQSPI_REG_IRQMASK); - cadence_qspi_apb_controller_enable(plat->regbase); + cadence_qspi_apb_controller_enable(priv->regbase); } int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg) @@ -370,7 +370,7 @@ int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg) return 0; } -static int cadence_qspi_setup_opcode_ext(struct cadence_spi_plat *plat, +static int cadence_qspi_setup_opcode_ext(struct cadence_spi_priv *priv, const struct spi_mem_op *op, unsigned int shift) { @@ -383,15 +383,15 @@ static int cadence_qspi_setup_opcode_ext(struct cadence_spi_plat *plat, /* Opcode extension is the LSB. */ ext = op->cmd.opcode & 0xff; - reg = readl(plat->regbase + CQSPI_REG_OP_EXT_LOWER); + reg = readl(priv->regbase + CQSPI_REG_OP_EXT_LOWER); reg &= ~(0xff << shift); reg |= ext << shift; - writel(reg, plat->regbase + CQSPI_REG_OP_EXT_LOWER); + writel(reg, priv->regbase + CQSPI_REG_OP_EXT_LOWER); return 0; } -static int cadence_qspi_enable_dtr(struct cadence_spi_plat *plat, +static int cadence_qspi_enable_dtr(struct cadence_spi_priv *priv, const struct spi_mem_op *op, unsigned int shift, bool enable) @@ -399,14 +399,14 @@ static int cadence_qspi_enable_dtr(struct cadence_spi_plat *plat, unsigned int reg; int ret; - reg = readl(plat->regbase + CQSPI_REG_CONFIG); + reg = readl(priv->regbase + CQSPI_REG_CONFIG); if (enable) { reg |= CQSPI_REG_CONFIG_DTR_PROTO; reg |= CQSPI_REG_CONFIG_DUAL_OPCODE; /* Set up command opcode extension. */ - ret = cadence_qspi_setup_opcode_ext(plat, op, shift); + ret = cadence_qspi_setup_opcode_ext(priv, op, shift); if (ret) return ret; } else { @@ -414,37 +414,37 @@ static int cadence_qspi_enable_dtr(struct cadence_spi_plat *plat, reg &= ~CQSPI_REG_CONFIG_DUAL_OPCODE; } - writel(reg, plat->regbase + CQSPI_REG_CONFIG); + writel(reg, priv->regbase + CQSPI_REG_CONFIG); return 0; } -int cadence_qspi_apb_command_read_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_read_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { int ret; unsigned int reg; - ret = cadence_qspi_set_protocol(plat, op); + ret = cadence_qspi_set_protocol(priv, op); if (ret) return ret; - ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_STIG_LSB, - plat->dtr); + ret = cadence_qspi_enable_dtr(priv, op, CQSPI_REG_OP_EXT_STIG_LSB, + priv->dtr); if (ret) return ret; - reg = cadence_qspi_calc_rdreg(plat); - writel(reg, plat->regbase + CQSPI_REG_RD_INSTR); + reg = cadence_qspi_calc_rdreg(priv); + writel(reg, priv->regbase + CQSPI_REG_RD_INSTR); return 0; } /* For command RDID, RDSR. */ -int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { - void *reg_base = plat->regbase; + void *reg_base = priv->regbase; unsigned int reg; unsigned int read_len; int status; @@ -458,7 +458,7 @@ int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat, return -EINVAL; } - if (plat->dtr) + if (priv->dtr) opcode = op->cmd.opcode >> 8; else opcode = op->cmd.opcode; @@ -466,7 +466,7 @@ int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat, reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB; /* Set up dummy cycles. */ - dummy_clk = cadence_qspi_calc_dummy(op, plat->dtr); + dummy_clk = cadence_qspi_calc_dummy(op, priv->dtr); if (dummy_clk > CQSPI_DUMMY_CLKS_MAX) return -ENOTSUPP; @@ -499,29 +499,29 @@ int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat, return 0; } -int cadence_qspi_apb_command_write_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_write_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { int ret; unsigned int reg; - ret = cadence_qspi_set_protocol(plat, op); + ret = cadence_qspi_set_protocol(priv, op); if (ret) return ret; - ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_STIG_LSB, - plat->dtr); + ret = cadence_qspi_enable_dtr(priv, op, CQSPI_REG_OP_EXT_STIG_LSB, + priv->dtr); if (ret) return ret; - reg = cadence_qspi_calc_rdreg(plat); - writel(reg, plat->regbase + CQSPI_REG_RD_INSTR); + reg = cadence_qspi_calc_rdreg(priv); + writel(reg, priv->regbase + CQSPI_REG_RD_INSTR); return 0; } /* For commands: WRSR, WREN, WRDI, CHIP_ERASE, BE, etc. */ -int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_write(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { unsigned int reg = 0; @@ -529,7 +529,7 @@ int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat, unsigned int wr_len; unsigned int txlen = op->data.nbytes; const void *txbuf = op->data.buf.out; - void *reg_base = plat->regbase; + void *reg_base = priv->regbase; u32 addr; u8 opcode; @@ -547,7 +547,7 @@ int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat, return -EINVAL; } - if (plat->dtr) + if (priv->dtr) opcode = op->cmd.opcode >> 8; else opcode = op->cmd.opcode; @@ -579,7 +579,7 @@ int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat, } /* Opcode + Address (3/4 bytes) + dummy bytes (0-4 bytes) */ -int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_read_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { unsigned int reg; @@ -589,33 +589,33 @@ int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat, int ret; u8 opcode; - ret = cadence_qspi_set_protocol(plat, op); + ret = cadence_qspi_set_protocol(priv, op); if (ret) return ret; - ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_READ_LSB, - plat->dtr); + ret = cadence_qspi_enable_dtr(priv, op, CQSPI_REG_OP_EXT_READ_LSB, + priv->dtr); if (ret) return ret; /* Setup the indirect trigger address */ - writel(plat->trigger_address, - plat->regbase + CQSPI_REG_INDIRECTTRIGGER); + writel(priv->trigger_address, + priv->regbase + CQSPI_REG_INDIRECTTRIGGER); /* Configure the opcode */ - if (plat->dtr) + if (priv->dtr) opcode = op->cmd.opcode >> 8; else opcode = op->cmd.opcode; rd_reg = opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB; - rd_reg |= cadence_qspi_calc_rdreg(plat); + rd_reg |= cadence_qspi_calc_rdreg(priv); - writel(op->addr.val, plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR); + writel(op->addr.val, priv->regbase + CQSPI_REG_INDIRECTRDSTARTADDR); if (dummy_bytes) { /* Convert to clock cycles. */ - dummy_clk = cadence_qspi_calc_dummy(op, plat->dtr); + dummy_clk = cadence_qspi_calc_dummy(op, priv->dtr); if (dummy_clk > CQSPI_DUMMY_CLKS_MAX) return -ENOTSUPP; @@ -625,30 +625,30 @@ int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat, << CQSPI_REG_RD_INSTR_DUMMY_LSB; } - writel(rd_reg, plat->regbase + CQSPI_REG_RD_INSTR); + writel(rd_reg, priv->regbase + CQSPI_REG_RD_INSTR); /* set device size */ - reg = readl(plat->regbase + CQSPI_REG_SIZE); + reg = readl(priv->regbase + CQSPI_REG_SIZE); reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; reg |= (op->addr.nbytes - 1); - writel(reg, plat->regbase + CQSPI_REG_SIZE); + writel(reg, priv->regbase + CQSPI_REG_SIZE); return 0; } -static u32 cadence_qspi_get_rd_sram_level(struct cadence_spi_plat *plat) +static u32 cadence_qspi_get_rd_sram_level(struct cadence_spi_priv *priv) { - u32 reg = readl(plat->regbase + CQSPI_REG_SDRAMLEVEL); + u32 reg = readl(priv->regbase + CQSPI_REG_SDRAMLEVEL); reg >>= CQSPI_REG_SDRAMLEVEL_RD_LSB; return reg & CQSPI_REG_SDRAMLEVEL_RD_MASK; } -static int cadence_qspi_wait_for_data(struct cadence_spi_plat *plat) +static int cadence_qspi_wait_for_data(struct cadence_spi_priv *priv) { unsigned int timeout = 10000; u32 reg; while (timeout--) { - reg = cadence_qspi_get_rd_sram_level(plat); + reg = cadence_qspi_get_rd_sram_level(priv); if (reg) return reg; udelay(1); @@ -658,21 +658,21 @@ static int cadence_qspi_wait_for_data(struct cadence_spi_plat *plat) } static int -cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat, +cadence_qspi_apb_indirect_read_execute(struct cadence_spi_priv *priv, unsigned int n_rx, u8 *rxbuf) { unsigned int remaining = n_rx; unsigned int bytes_to_read = 0; int ret; - writel(n_rx, plat->regbase + CQSPI_REG_INDIRECTRDBYTES); + writel(n_rx, priv->regbase + CQSPI_REG_INDIRECTRDBYTES); /* Start the indirect read transfer */ writel(CQSPI_REG_INDIRECTRD_START, - plat->regbase + CQSPI_REG_INDIRECTRD); + priv->regbase + CQSPI_REG_INDIRECTRD); while (remaining > 0) { - ret = cadence_qspi_wait_for_data(plat); + ret = cadence_qspi_wait_for_data(priv); if (ret < 0) { printf("Indirect write timed out (%i)\n", ret); goto failrd; @@ -681,7 +681,7 @@ cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat, bytes_to_read = ret; while (bytes_to_read != 0) { - bytes_to_read *= plat->fifo_width; + bytes_to_read *= priv->fifo_width; bytes_to_read = bytes_to_read > remaining ? remaining : bytes_to_read; /* @@ -689,18 +689,18 @@ cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat, * data abort. */ if (((uintptr_t)rxbuf % 4) || (bytes_to_read % 4)) - readsb(plat->ahbbase, rxbuf, bytes_to_read); + readsb(priv->ahbbase, rxbuf, bytes_to_read); else - readsl(plat->ahbbase, rxbuf, + readsl(priv->ahbbase, rxbuf, bytes_to_read >> 2); rxbuf += bytes_to_read; remaining -= bytes_to_read; - bytes_to_read = cadence_qspi_get_rd_sram_level(plat); + bytes_to_read = cadence_qspi_get_rd_sram_level(priv); } } /* Check indirect done status */ - ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTRD, + ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_INDIRECTRD, CQSPI_REG_INDIRECTRD_DONE, 1, 10, 0); if (ret) { printf("Indirect read completion error (%i)\n", ret); @@ -709,10 +709,10 @@ cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat, /* Clear indirect completion status */ writel(CQSPI_REG_INDIRECTRD_DONE, - plat->regbase + CQSPI_REG_INDIRECTRD); + priv->regbase + CQSPI_REG_INDIRECTRD); /* Check indirect done status */ - ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTRD, + ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_INDIRECTRD, CQSPI_REG_INDIRECTRD_DONE, 0, 10, 0); if (ret) { printf("Indirect read clear completion error (%i)\n", ret); @@ -724,11 +724,11 @@ cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat, failrd: /* Cancel the indirect read */ writel(CQSPI_REG_INDIRECTRD_CANCEL, - plat->regbase + CQSPI_REG_INDIRECTRD); + priv->regbase + CQSPI_REG_INDIRECTRD); return ret; } -int cadence_qspi_apb_read_execute(struct cadence_spi_plat *plat, +int cadence_qspi_apb_read_execute(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { u64 from = op->addr.val; @@ -738,57 +738,57 @@ int cadence_qspi_apb_read_execute(struct cadence_spi_plat *plat, if (CONFIG_IS_ENABLED(ARCH_VERSAL)) cadence_qspi_apb_enable_linear_mode(true); - if (plat->use_dac_mode && (from + len < plat->ahbsize)) { + if (priv->use_dac_mode && (from + len < priv->ahbsize)) { if (len < 256 || - dma_memcpy(buf, plat->ahbbase + from, len) < 0) { - memcpy_fromio(buf, plat->ahbbase + from, len); + dma_memcpy(buf, priv->ahbbase + from, len) < 0) { + memcpy_fromio(buf, priv->ahbbase + from, len); } - if (!cadence_qspi_wait_idle(plat->regbase)) + if (!cadence_qspi_wait_idle(priv->regbase)) return -EIO; return 0; } - return cadence_qspi_apb_indirect_read_execute(plat, len, buf); + return cadence_qspi_apb_indirect_read_execute(priv, len, buf); } /* Opcode + Address (3/4 bytes) */ -int cadence_qspi_apb_write_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_write_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { unsigned int reg; int ret; u8 opcode; - ret = cadence_qspi_set_protocol(plat, op); + ret = cadence_qspi_set_protocol(priv, op); if (ret) return ret; - ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_WRITE_LSB, - plat->dtr); + ret = cadence_qspi_enable_dtr(priv, op, CQSPI_REG_OP_EXT_WRITE_LSB, + priv->dtr); if (ret) return ret; /* Setup the indirect trigger address */ - writel(plat->trigger_address, - plat->regbase + CQSPI_REG_INDIRECTTRIGGER); + writel(priv->trigger_address, + priv->regbase + CQSPI_REG_INDIRECTTRIGGER); /* Configure the opcode */ - if (plat->dtr) + if (priv->dtr) opcode = op->cmd.opcode >> 8; else opcode = op->cmd.opcode; reg = opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB; - reg |= plat->data_width << CQSPI_REG_WR_INSTR_TYPE_DATA_LSB; - reg |= plat->addr_width << CQSPI_REG_WR_INSTR_TYPE_ADDR_LSB; - writel(reg, plat->regbase + CQSPI_REG_WR_INSTR); + reg |= priv->data_width << CQSPI_REG_WR_INSTR_TYPE_DATA_LSB; + reg |= priv->addr_width << CQSPI_REG_WR_INSTR_TYPE_ADDR_LSB; + writel(reg, priv->regbase + CQSPI_REG_WR_INSTR); - reg = cadence_qspi_calc_rdreg(plat); - writel(reg, plat->regbase + CQSPI_REG_RD_INSTR); + reg = cadence_qspi_calc_rdreg(priv); + writel(reg, priv->regbase + CQSPI_REG_RD_INSTR); - writel(op->addr.val, plat->regbase + CQSPI_REG_INDIRECTWRSTARTADDR); + writel(op->addr.val, priv->regbase + CQSPI_REG_INDIRECTWRSTARTADDR); - if (plat->dtr) { + if (priv->dtr) { /* * Some flashes like the cypress Semper flash expect a 4-byte * dummy address with the Read SR command in DTR mode, but this @@ -797,23 +797,23 @@ int cadence_qspi_apb_write_setup(struct cadence_spi_plat *plat, * controller's side. spi-nor will take care of polling the * status register. */ - reg = readl(plat->regbase + CQSPI_REG_WR_COMPLETION_CTRL); + reg = readl(priv->regbase + CQSPI_REG_WR_COMPLETION_CTRL); reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL; - writel(reg, plat->regbase + CQSPI_REG_WR_COMPLETION_CTRL); + writel(reg, priv->regbase + CQSPI_REG_WR_COMPLETION_CTRL); } - reg = readl(plat->regbase + CQSPI_REG_SIZE); + reg = readl(priv->regbase + CQSPI_REG_SIZE); reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; reg |= (op->addr.nbytes - 1); - writel(reg, plat->regbase + CQSPI_REG_SIZE); + writel(reg, priv->regbase + CQSPI_REG_SIZE); return 0; } static int -cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat, +cadence_qspi_apb_indirect_write_execute(struct cadence_spi_priv *priv, unsigned int n_tx, const u8 *txbuf) { - unsigned int page_size = plat->page_size; + unsigned int page_size = priv->page_size; unsigned int remaining = n_tx; const u8 *bb_txbuf = txbuf; void *bounce_buf = NULL; @@ -833,27 +833,27 @@ cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat, } /* Configure the indirect read transfer bytes */ - writel(n_tx, plat->regbase + CQSPI_REG_INDIRECTWRBYTES); + writel(n_tx, priv->regbase + CQSPI_REG_INDIRECTWRBYTES); /* Start the indirect write transfer */ writel(CQSPI_REG_INDIRECTWR_START, - plat->regbase + CQSPI_REG_INDIRECTWR); + priv->regbase + CQSPI_REG_INDIRECTWR); /* * Some delay is required for the above bit to be internally * synchronized by the QSPI module. */ - ndelay(plat->wr_delay); + ndelay(priv->wr_delay); while (remaining > 0) { write_bytes = remaining > page_size ? page_size : remaining; - writesl(plat->ahbbase, bb_txbuf, write_bytes >> 2); + writesl(priv->ahbbase, bb_txbuf, write_bytes >> 2); if (write_bytes % 4) - writesb(plat->ahbbase, + writesb(priv->ahbbase, bb_txbuf + rounddown(write_bytes, 4), write_bytes % 4); - ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_SDRAMLEVEL, + ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_SDRAMLEVEL, CQSPI_REG_SDRAMLEVEL_WR_MASK << CQSPI_REG_SDRAMLEVEL_WR_LSB, 0, 10, 0); if (ret) { @@ -866,7 +866,7 @@ cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat, } /* Check indirect done status */ - ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTWR, + ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_INDIRECTWR, CQSPI_REG_INDIRECTWR_DONE, 1, 10, 0); if (ret) { printf("Indirect write completion error (%i)\n", ret); @@ -875,10 +875,10 @@ cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat, /* Clear indirect completion status */ writel(CQSPI_REG_INDIRECTWR_DONE, - plat->regbase + CQSPI_REG_INDIRECTWR); + priv->regbase + CQSPI_REG_INDIRECTWR); /* Check indirect done status */ - ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTWR, + ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_INDIRECTWR, CQSPI_REG_INDIRECTWR_DONE, 0, 10, 0); if (ret) { printf("Indirect write clear completion error (%i)\n", ret); @@ -892,13 +892,13 @@ cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat, failwr: /* Cancel the indirect write */ writel(CQSPI_REG_INDIRECTWR_CANCEL, - plat->regbase + CQSPI_REG_INDIRECTWR); + priv->regbase + CQSPI_REG_INDIRECTWR); if (bounce_buf) free(bounce_buf); return ret; } -int cadence_qspi_apb_write_execute(struct cadence_spi_plat *plat, +int cadence_qspi_apb_write_execute(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { u32 to = op->addr.val; @@ -916,14 +916,15 @@ int cadence_qspi_apb_write_execute(struct cadence_spi_plat *plat, * mode. So, we can not use direct mode when in DTR mode for writing * data. */ - if (!plat->dtr && plat->use_dac_mode && (to + len < plat->ahbsize)) { - memcpy_toio(plat->ahbbase + to, buf, len); - if (!cadence_qspi_wait_idle(plat->regbase)) + cadence_qspi_apb_enable_linear_mode(true); + if (!priv->dtr && priv->use_dac_mode && (to + len < priv->ahbsize)) { + memcpy_toio(priv->ahbbase + to, buf, len); + if (!cadence_qspi_wait_idle(priv->regbase)) return -EIO; return 0; } - return cadence_qspi_apb_indirect_write_execute(plat, len, buf); + return cadence_qspi_apb_indirect_write_execute(priv, len, buf); } void cadence_qspi_apb_enter_xip(void *reg_base, char xip_dummy) diff --git a/drivers/spi/mtk_snfi_spi.c b/drivers/spi/mtk_snfi_spi.c index 65d0ce0981..5ea62776b4 100644 --- a/drivers/spi/mtk_snfi_spi.c +++ b/drivers/spi/mtk_snfi_spi.c @@ -202,7 +202,7 @@ static int mtk_snfi_exec_op(struct spi_slave *slave, int addr_sh; int ret; - WATCHDOG_RESET(); + schedule(); ret = mtk_snfi_mac_reset(priv); if (ret) diff --git a/drivers/spi/mtk_spim.c b/drivers/spi/mtk_spim.c new file mode 100644 index 0000000000..b45ef529a5 --- /dev/null +++ b/drivers/spi/mtk_spim.c @@ -0,0 +1,701 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All Rights Reserved. + * + * Author: SkyLake.Huang + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPI_CFG0_REG 0x0000 +#define SPI_CFG1_REG 0x0004 +#define SPI_TX_SRC_REG 0x0008 +#define SPI_RX_DST_REG 0x000c +#define SPI_TX_DATA_REG 0x0010 +#define SPI_RX_DATA_REG 0x0014 +#define SPI_CMD_REG 0x0018 +#define SPI_IRQ_REG 0x001c +#define SPI_STATUS_REG 0x0020 +#define SPI_PAD_SEL_REG 0x0024 +#define SPI_CFG2_REG 0x0028 +#define SPI_TX_SRC_REG_64 0x002c +#define SPI_RX_DST_REG_64 0x0030 +#define SPI_CFG3_IPM_REG 0x0040 + +#define SPI_CFG0_SCK_HIGH_OFFSET 0 +#define SPI_CFG0_SCK_LOW_OFFSET 8 +#define SPI_CFG0_CS_HOLD_OFFSET 16 +#define SPI_CFG0_CS_SETUP_OFFSET 24 +#define SPI_ADJUST_CFG0_CS_HOLD_OFFSET 0 +#define SPI_ADJUST_CFG0_CS_SETUP_OFFSET 16 + +#define SPI_CFG1_CS_IDLE_OFFSET 0 +#define SPI_CFG1_PACKET_LOOP_OFFSET 8 +#define SPI_CFG1_PACKET_LENGTH_OFFSET 16 +#define SPI_CFG1_GET_TICKDLY_OFFSET 29 + +#define SPI_CFG1_GET_TICKDLY_MASK GENMASK(31, 29) +#define SPI_CFG1_CS_IDLE_MASK 0xff +#define SPI_CFG1_PACKET_LOOP_MASK 0xff00 +#define SPI_CFG1_PACKET_LENGTH_MASK 0x3ff0000 +#define SPI_CFG1_IPM_PACKET_LENGTH_MASK GENMASK(31, 16) +#define SPI_CFG2_SCK_HIGH_OFFSET 0 +#define SPI_CFG2_SCK_LOW_OFFSET 16 +#define SPI_CFG2_SCK_HIGH_MASK GENMASK(15, 0) +#define SPI_CFG2_SCK_LOW_MASK GENMASK(31, 16) + +#define SPI_CMD_ACT BIT(0) +#define SPI_CMD_RESUME BIT(1) +#define SPI_CMD_RST BIT(2) +#define SPI_CMD_PAUSE_EN BIT(4) +#define SPI_CMD_DEASSERT BIT(5) +#define SPI_CMD_SAMPLE_SEL BIT(6) +#define SPI_CMD_CS_POL BIT(7) +#define SPI_CMD_CPHA BIT(8) +#define SPI_CMD_CPOL BIT(9) +#define SPI_CMD_RX_DMA BIT(10) +#define SPI_CMD_TX_DMA BIT(11) +#define SPI_CMD_TXMSBF BIT(12) +#define SPI_CMD_RXMSBF BIT(13) +#define SPI_CMD_RX_ENDIAN BIT(14) +#define SPI_CMD_TX_ENDIAN BIT(15) +#define SPI_CMD_FINISH_IE BIT(16) +#define SPI_CMD_PAUSE_IE BIT(17) +#define SPI_CMD_IPM_NONIDLE_MODE BIT(19) +#define SPI_CMD_IPM_SPIM_LOOP BIT(21) +#define SPI_CMD_IPM_GET_TICKDLY_OFFSET 22 + +#define SPI_CMD_IPM_GET_TICKDLY_MASK GENMASK(24, 22) + +#define PIN_MODE_CFG(x) ((x) / 2) + +#define SPI_CFG3_IPM_PIN_MODE_OFFSET 0 +#define SPI_CFG3_IPM_HALF_DUPLEX_DIR BIT(2) +#define SPI_CFG3_IPM_HALF_DUPLEX_EN BIT(3) +#define SPI_CFG3_IPM_XMODE_EN BIT(4) +#define SPI_CFG3_IPM_NODATA_FLAG BIT(5) +#define SPI_CFG3_IPM_CMD_BYTELEN_OFFSET 8 +#define SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET 12 +#define SPI_CFG3_IPM_DUMMY_BYTELEN_OFFSET 16 + +#define SPI_CFG3_IPM_CMD_PIN_MODE_MASK GENMASK(1, 0) +#define SPI_CFG3_IPM_CMD_BYTELEN_MASK GENMASK(11, 8) +#define SPI_CFG3_IPM_ADDR_BYTELEN_MASK GENMASK(15, 12) +#define SPI_CFG3_IPM_DUMMY_BYTELEN_MASK GENMASK(19, 16) + +#define MT8173_SPI_MAX_PAD_SEL 3 + +#define MTK_SPI_PAUSE_INT_STATUS 0x2 + +#define MTK_SPI_IDLE 0 +#define MTK_SPI_PAUSED 1 + +#define MTK_SPI_MAX_FIFO_SIZE 32U +#define MTK_SPI_PACKET_SIZE 1024 +#define MTK_SPI_IPM_PACKET_SIZE SZ_64K +#define MTK_SPI_IPM_PACKET_LOOP SZ_256 + +#define MTK_SPI_32BITS_MASK 0xffffffff + +#define DMA_ADDR_EXT_BITS 36 +#define DMA_ADDR_DEF_BITS 32 + +#define CLK_TO_US(freq, clkcnt) DIV_ROUND_UP((clkcnt), (freq) / 1000000) + +/* struct mtk_spim_capability + * @enhance_timing: Some IC design adjust cfg register to enhance time accuracy + * @dma_ext: Some IC support DMA addr extension + * @ipm_design: The IPM IP design improves some features, and supports dual/quad mode + * @support_quad: Whether quad mode is supported + */ +struct mtk_spim_capability { + bool enhance_timing; + bool dma_ext; + bool ipm_design; + bool support_quad; +}; + +/* struct mtk_spim_priv + * @base: Base address of the spi controller + * @state: Controller state + * @sel_clk: Pad clock + * @spi_clk: Core clock + * @xfer_len: Current length of data for transfer + * @hw_cap: Controller capabilities + * @tick_dly: Used to postpone SPI sampling time + * @sample_sel: Sample edge of MISO + * @dev: udevice of this spi controller + * @tx_dma: Tx DMA address + * @rx_dma: Rx DMA address + */ +struct mtk_spim_priv { + void __iomem *base; + u32 state; + struct clk sel_clk, spi_clk; + u32 xfer_len; + struct mtk_spim_capability hw_cap; + u32 tick_dly; + u32 sample_sel; + + struct device *dev; + dma_addr_t tx_dma; + dma_addr_t rx_dma; +}; + +static void mtk_spim_reset(struct mtk_spim_priv *priv) +{ + /* set the software reset bit in SPI_CMD_REG. */ + setbits_le32(priv->base + SPI_CMD_REG, SPI_CMD_RST); + clrbits_le32(priv->base + SPI_CMD_REG, SPI_CMD_RST); +} + +static int mtk_spim_hw_init(struct spi_slave *slave) +{ + struct udevice *bus = dev_get_parent(slave->dev); + struct mtk_spim_priv *priv = dev_get_priv(bus); + u16 cpha, cpol; + u32 reg_val; + + cpha = slave->mode & SPI_CPHA ? 1 : 0; + cpol = slave->mode & SPI_CPOL ? 1 : 0; + + if (priv->hw_cap.enhance_timing) { + if (priv->hw_cap.ipm_design) { + /* CFG3 reg only used for spi-mem, + * here write to default value + */ + writel(0x0, priv->base + SPI_CFG3_IPM_REG); + clrsetbits_le32(priv->base + SPI_CMD_REG, + SPI_CMD_IPM_GET_TICKDLY_MASK, + priv->tick_dly << + SPI_CMD_IPM_GET_TICKDLY_OFFSET); + } else { + clrsetbits_le32(priv->base + SPI_CFG1_REG, + SPI_CFG1_GET_TICKDLY_MASK, + priv->tick_dly << + SPI_CFG1_GET_TICKDLY_OFFSET); + } + } + + reg_val = readl(priv->base + SPI_CMD_REG); + if (priv->hw_cap.ipm_design) { + /* SPI transfer without idle time until packet length done */ + reg_val |= SPI_CMD_IPM_NONIDLE_MODE; + if (slave->mode & SPI_LOOP) + reg_val |= SPI_CMD_IPM_SPIM_LOOP; + else + reg_val &= ~SPI_CMD_IPM_SPIM_LOOP; + } + + if (cpha) + reg_val |= SPI_CMD_CPHA; + else + reg_val &= ~SPI_CMD_CPHA; + if (cpol) + reg_val |= SPI_CMD_CPOL; + else + reg_val &= ~SPI_CMD_CPOL; + + /* set the mlsbx and mlsbtx */ + if (slave->mode & SPI_LSB_FIRST) { + reg_val &= ~SPI_CMD_TXMSBF; + reg_val &= ~SPI_CMD_RXMSBF; + } else { + reg_val |= SPI_CMD_TXMSBF; + reg_val |= SPI_CMD_RXMSBF; + } + + /* do not reverse tx/rx endian */ + reg_val &= ~SPI_CMD_TX_ENDIAN; + reg_val &= ~SPI_CMD_RX_ENDIAN; + + if (priv->hw_cap.enhance_timing) { + /* set CS polarity */ + if (slave->mode & SPI_CS_HIGH) + reg_val |= SPI_CMD_CS_POL; + else + reg_val &= ~SPI_CMD_CS_POL; + + if (priv->sample_sel) + reg_val |= SPI_CMD_SAMPLE_SEL; + else + reg_val &= ~SPI_CMD_SAMPLE_SEL; + } + + /* disable dma mode */ + reg_val &= ~(SPI_CMD_TX_DMA | SPI_CMD_RX_DMA); + + /* disable deassert mode */ + reg_val &= ~SPI_CMD_DEASSERT; + + writel(reg_val, priv->base + SPI_CMD_REG); + + return 0; +} + +static void mtk_spim_prepare_transfer(struct mtk_spim_priv *priv, + u32 speed_hz) +{ + u32 spi_clk_hz, div, sck_time, cs_time, reg_val; + + spi_clk_hz = clk_get_rate(&priv->spi_clk); + if (speed_hz <= spi_clk_hz / 4) + div = DIV_ROUND_UP(spi_clk_hz, speed_hz); + else + div = 4; + + sck_time = (div + 1) / 2; + cs_time = sck_time * 2; + + if (priv->hw_cap.enhance_timing) { + reg_val = ((sck_time - 1) & 0xffff) + << SPI_CFG2_SCK_HIGH_OFFSET; + reg_val |= ((sck_time - 1) & 0xffff) + << SPI_CFG2_SCK_LOW_OFFSET; + writel(reg_val, priv->base + SPI_CFG2_REG); + + reg_val = ((cs_time - 1) & 0xffff) + << SPI_ADJUST_CFG0_CS_HOLD_OFFSET; + reg_val |= ((cs_time - 1) & 0xffff) + << SPI_ADJUST_CFG0_CS_SETUP_OFFSET; + writel(reg_val, priv->base + SPI_CFG0_REG); + } else { + reg_val = ((sck_time - 1) & 0xff) + << SPI_CFG0_SCK_HIGH_OFFSET; + reg_val |= ((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET; + reg_val |= ((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET; + reg_val |= ((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET; + writel(reg_val, priv->base + SPI_CFG0_REG); + } + + reg_val = readl(priv->base + SPI_CFG1_REG); + reg_val &= ~SPI_CFG1_CS_IDLE_MASK; + reg_val |= ((cs_time - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET; + writel(reg_val, priv->base + SPI_CFG1_REG); +} + +/** + * mtk_spim_setup_packet() - setup packet format. + * @priv: controller priv + * + * This controller sents/receives data in packets. The packet size is + * configurable. + * + * This function calculates the maximum packet size available for current + * data, and calculates the number of packets required to sent/receive data + * as much as possible. + */ +static void mtk_spim_setup_packet(struct mtk_spim_priv *priv) +{ + u32 packet_size, packet_loop, reg_val; + + /* Calculate maximum packet size */ + if (priv->hw_cap.ipm_design) + packet_size = min_t(u32, + priv->xfer_len, + MTK_SPI_IPM_PACKET_SIZE); + else + packet_size = min_t(u32, + priv->xfer_len, + MTK_SPI_PACKET_SIZE); + + /* Calculates number of packets to sent/receive */ + packet_loop = priv->xfer_len / packet_size; + + reg_val = readl(priv->base + SPI_CFG1_REG); + if (priv->hw_cap.ipm_design) + reg_val &= ~SPI_CFG1_IPM_PACKET_LENGTH_MASK; + else + reg_val &= ~SPI_CFG1_PACKET_LENGTH_MASK; + + reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET; + + reg_val &= ~SPI_CFG1_PACKET_LOOP_MASK; + + reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET; + + writel(reg_val, priv->base + SPI_CFG1_REG); +} + +static void mtk_spim_enable_transfer(struct mtk_spim_priv *priv) +{ + u32 cmd; + + cmd = readl(priv->base + SPI_CMD_REG); + if (priv->state == MTK_SPI_IDLE) + cmd |= SPI_CMD_ACT; + else + cmd |= SPI_CMD_RESUME; + writel(cmd, priv->base + SPI_CMD_REG); +} + +static bool mtk_spim_supports_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + struct udevice *bus = dev_get_parent(slave->dev); + struct mtk_spim_priv *priv = dev_get_priv(bus); + + if (op->cmd.buswidth == 0 || op->cmd.buswidth > 4 || + op->addr.buswidth > 4 || op->dummy.buswidth > 4 || + op->data.buswidth > 4) + return false; + + if (!priv->hw_cap.support_quad && (op->cmd.buswidth > 2 || + op->addr.buswidth > 2 || op->dummy.buswidth > 2 || + op->data.buswidth > 2)) + return false; + + if (op->addr.nbytes && op->dummy.nbytes && + op->addr.buswidth != op->dummy.buswidth) + return false; + + if (op->addr.nbytes + op->dummy.nbytes > 16) + return false; + + if (op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) { + if (op->data.nbytes / MTK_SPI_IPM_PACKET_SIZE > + MTK_SPI_IPM_PACKET_LOOP || + op->data.nbytes % MTK_SPI_IPM_PACKET_SIZE != 0) + return false; + } + + return true; +} + +static void mtk_spim_setup_dma_xfer(struct mtk_spim_priv *priv, + const struct spi_mem_op *op) +{ + writel((u32)(priv->tx_dma & MTK_SPI_32BITS_MASK), + priv->base + SPI_TX_SRC_REG); + + if (priv->hw_cap.dma_ext) + writel((u32)(priv->tx_dma >> 32), + priv->base + SPI_TX_SRC_REG_64); + + if (op->data.dir == SPI_MEM_DATA_IN) { + writel((u32)(priv->rx_dma & MTK_SPI_32BITS_MASK), + priv->base + SPI_RX_DST_REG); + + if (priv->hw_cap.dma_ext) + writel((u32)(priv->rx_dma >> 32), + priv->base + SPI_RX_DST_REG_64); + } +} + +static int mtk_spim_transfer_wait(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + struct udevice *bus = dev_get_parent(slave->dev); + struct mtk_spim_priv *priv = dev_get_priv(bus); + u32 sck_l, sck_h, spi_bus_clk, clk_count, reg; + ulong us = 1; + int ret = 0; + + if (op->data.dir == SPI_MEM_NO_DATA) + clk_count = 32; + else + clk_count = op->data.nbytes; + + spi_bus_clk = clk_get_rate(&priv->spi_clk); + sck_l = readl(priv->base + SPI_CFG2_REG) >> SPI_CFG2_SCK_LOW_OFFSET; + sck_h = readl(priv->base + SPI_CFG2_REG) & SPI_CFG2_SCK_HIGH_MASK; + do_div(spi_bus_clk, sck_l + sck_h + 2); + + us = CLK_TO_US(spi_bus_clk, clk_count * 8); + us += 1000 * 1000; /* 1s tolerance */ + + if (us > UINT_MAX) + us = UINT_MAX; + + ret = readl_poll_timeout(priv->base + SPI_STATUS_REG, reg, + reg & 0x1, us); + if (ret < 0) { + dev_err(priv->dev, "transfer timeout, val: 0x%lx\n", us); + return -ETIMEDOUT; + } + + return 0; +} + +static int mtk_spim_exec_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + struct udevice *bus = dev_get_parent(slave->dev); + struct mtk_spim_priv *priv = dev_get_priv(bus); + u32 reg_val, nio = 1, tx_size; + char *tx_tmp_buf; + char *rx_tmp_buf; + int i, ret = 0; + + mtk_spim_reset(priv); + mtk_spim_hw_init(slave); + mtk_spim_prepare_transfer(priv, slave->max_hz); + + reg_val = readl(priv->base + SPI_CFG3_IPM_REG); + /* opcode byte len */ + reg_val &= ~SPI_CFG3_IPM_CMD_BYTELEN_MASK; + reg_val |= 1 << SPI_CFG3_IPM_CMD_BYTELEN_OFFSET; + + /* addr & dummy byte len */ + if (op->addr.nbytes || op->dummy.nbytes) + reg_val |= (op->addr.nbytes + op->dummy.nbytes) << + SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET; + + /* data byte len */ + if (!op->data.nbytes) { + reg_val |= SPI_CFG3_IPM_NODATA_FLAG; + writel(0, priv->base + SPI_CFG1_REG); + } else { + reg_val &= ~SPI_CFG3_IPM_NODATA_FLAG; + priv->xfer_len = op->data.nbytes; + mtk_spim_setup_packet(priv); + } + + if (op->addr.nbytes || op->dummy.nbytes) { + if (op->addr.buswidth == 1 || op->dummy.buswidth == 1) + reg_val |= SPI_CFG3_IPM_XMODE_EN; + else + reg_val &= ~SPI_CFG3_IPM_XMODE_EN; + } + + if (op->addr.buswidth == 2 || + op->dummy.buswidth == 2 || + op->data.buswidth == 2) + nio = 2; + else if (op->addr.buswidth == 4 || + op->dummy.buswidth == 4 || + op->data.buswidth == 4) + nio = 4; + + reg_val &= ~SPI_CFG3_IPM_CMD_PIN_MODE_MASK; + reg_val |= PIN_MODE_CFG(nio) << SPI_CFG3_IPM_PIN_MODE_OFFSET; + + reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_EN; + if (op->data.dir == SPI_MEM_DATA_IN) + reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_DIR; + else + reg_val &= ~SPI_CFG3_IPM_HALF_DUPLEX_DIR; + writel(reg_val, priv->base + SPI_CFG3_IPM_REG); + + tx_size = 1 + op->addr.nbytes + op->dummy.nbytes; + if (op->data.dir == SPI_MEM_DATA_OUT) + tx_size += op->data.nbytes; + + tx_size = max(tx_size, (u32)32); + + /* Fill up tx data */ + tx_tmp_buf = kzalloc(tx_size, GFP_KERNEL); + if (!tx_tmp_buf) { + ret = -ENOMEM; + goto exit; + } + + tx_tmp_buf[0] = op->cmd.opcode; + + if (op->addr.nbytes) { + for (i = 0; i < op->addr.nbytes; i++) + tx_tmp_buf[i + 1] = op->addr.val >> + (8 * (op->addr.nbytes - i - 1)); + } + + if (op->dummy.nbytes) + memset(tx_tmp_buf + op->addr.nbytes + 1, 0xff, + op->dummy.nbytes); + + if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT) + memcpy(tx_tmp_buf + op->dummy.nbytes + op->addr.nbytes + 1, + op->data.buf.out, op->data.nbytes); + /* Finish filling up tx data */ + + priv->tx_dma = dma_map_single(tx_tmp_buf, tx_size, DMA_TO_DEVICE); + if (dma_mapping_error(priv->dev, priv->tx_dma)) { + ret = -ENOMEM; + goto tx_free; + } + + if (op->data.dir == SPI_MEM_DATA_IN) { + if (!IS_ALIGNED((size_t)op->data.buf.in, 4)) { + rx_tmp_buf = kzalloc(op->data.nbytes, GFP_KERNEL); + if (!rx_tmp_buf) { + ret = -ENOMEM; + goto tx_unmap; + } + } else { + rx_tmp_buf = op->data.buf.in; + } + + priv->rx_dma = dma_map_single(rx_tmp_buf, op->data.nbytes, + DMA_FROM_DEVICE); + if (dma_mapping_error(priv->dev, priv->rx_dma)) { + ret = -ENOMEM; + goto rx_free; + } + } + + reg_val = readl(priv->base + SPI_CMD_REG); + reg_val |= SPI_CMD_TX_DMA; + if (op->data.dir == SPI_MEM_DATA_IN) + reg_val |= SPI_CMD_RX_DMA; + + writel(reg_val, priv->base + SPI_CMD_REG); + + mtk_spim_setup_dma_xfer(priv, op); + + mtk_spim_enable_transfer(priv); + + /* Wait for the interrupt. */ + ret = mtk_spim_transfer_wait(slave, op); + if (ret) + goto rx_unmap; + + if (op->data.dir == SPI_MEM_DATA_IN && + !IS_ALIGNED((size_t)op->data.buf.in, 4)) + memcpy(op->data.buf.in, rx_tmp_buf, op->data.nbytes); + +rx_unmap: + /* spi disable dma */ + reg_val = readl(priv->base + SPI_CMD_REG); + reg_val &= ~SPI_CMD_TX_DMA; + if (op->data.dir == SPI_MEM_DATA_IN) + reg_val &= ~SPI_CMD_RX_DMA; + writel(reg_val, priv->base + SPI_CMD_REG); + + writel(0, priv->base + SPI_TX_SRC_REG); + writel(0, priv->base + SPI_RX_DST_REG); + + if (op->data.dir == SPI_MEM_DATA_IN) + dma_unmap_single(priv->rx_dma, + op->data.nbytes, DMA_FROM_DEVICE); +rx_free: + if (op->data.dir == SPI_MEM_DATA_IN && + !IS_ALIGNED((size_t)op->data.buf.in, 4)) + kfree(rx_tmp_buf); +tx_unmap: + dma_unmap_single(priv->tx_dma, + tx_size, DMA_TO_DEVICE); +tx_free: + kfree(tx_tmp_buf); +exit: + return ret; +} + +static int mtk_spim_adjust_op_size(struct spi_slave *slave, + struct spi_mem_op *op) +{ + int opcode_len; + + if (!op->data.nbytes) + return 0; + + if (op->data.dir != SPI_MEM_NO_DATA) { + opcode_len = 1 + op->addr.nbytes + op->dummy.nbytes; + if (opcode_len + op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) { + op->data.nbytes = MTK_SPI_IPM_PACKET_SIZE - opcode_len; + /* force data buffer dma-aligned. */ + op->data.nbytes -= op->data.nbytes % 4; + } + } + + return 0; +} + +static int mtk_spim_get_attr(struct mtk_spim_priv *priv, struct udevice *dev) +{ + int ret; + + priv->hw_cap.enhance_timing = dev_read_bool(dev, "enhance_timing"); + priv->hw_cap.dma_ext = dev_read_bool(dev, "dma_ext"); + priv->hw_cap.ipm_design = dev_read_bool(dev, "ipm_design"); + priv->hw_cap.support_quad = dev_read_bool(dev, "support_quad"); + + ret = dev_read_u32(dev, "tick_dly", &priv->tick_dly); + if (ret < 0) + dev_err(priv->dev, "tick dly not set.\n"); + + ret = dev_read_u32(dev, "sample_sel", &priv->sample_sel); + if (ret < 0) + dev_err(priv->dev, "sample sel not set.\n"); + + return ret; +} + +static int mtk_spim_probe(struct udevice *dev) +{ + struct mtk_spim_priv *priv = dev_get_priv(dev); + int ret; + + priv->base = (void __iomem *)devfdt_get_addr(dev); + if (!priv->base) + return -EINVAL; + + mtk_spim_get_attr(priv, dev); + + ret = clk_get_by_name(dev, "sel-clk", &priv->sel_clk); + if (ret < 0) { + dev_err(dev, "failed to get sel-clk\n"); + return ret; + } + + ret = clk_get_by_name(dev, "spi-clk", &priv->spi_clk); + if (ret < 0) { + dev_err(dev, "failed to get spi-clk\n"); + return ret; + } + + clk_enable(&priv->sel_clk); + clk_enable(&priv->spi_clk); + + return 0; +} + +static int mtk_spim_set_speed(struct udevice *dev, uint speed) +{ + return 0; +} + +static int mtk_spim_set_mode(struct udevice *dev, uint mode) +{ + return 0; +} + +static const struct spi_controller_mem_ops mtk_spim_mem_ops = { + .adjust_op_size = mtk_spim_adjust_op_size, + .supports_op = mtk_spim_supports_op, + .exec_op = mtk_spim_exec_op +}; + +static const struct dm_spi_ops mtk_spim_ops = { + .mem_ops = &mtk_spim_mem_ops, + .set_speed = mtk_spim_set_speed, + .set_mode = mtk_spim_set_mode, +}; + +static const struct udevice_id mtk_spim_ids[] = { + { .compatible = "mediatek,ipm-spi" }, + {} +}; + +U_BOOT_DRIVER(mtk_spim) = { + .name = "mtk_spim", + .id = UCLASS_SPI, + .of_match = mtk_spim_ids, + .ops = &mtk_spim_ops, + .priv_auto = sizeof(struct mtk_spim_priv), + .probe = mtk_spim_probe, +}; diff --git a/drivers/spi/octeon_spi.c b/drivers/spi/octeon_spi.c index c2a7ee232b..4bc38beaa6 100644 --- a/drivers/spi/octeon_spi.c +++ b/drivers/spi/octeon_spi.c @@ -126,7 +126,7 @@ static void octeon_spi_wait_ready(struct udevice *dev) do { mpi_sts = readq(base + MPI_STS); - WATCHDOG_RESET(); + schedule(); } while (mpi_sts & MPI_STS_BUSY); debug("%s(%s)\n", __func__, dev->name); diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c new file mode 100644 index 0000000000..a3c9633382 --- /dev/null +++ b/drivers/spi/spi-aspeed-smc.c @@ -0,0 +1,1218 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * ASPEED FMC/SPI Controller driver + * + * Copyright (c) 2022 ASPEED Corporation. + * Copyright (c) 2022 IBM Corporation. + * + * Author: + * Chin-Ting Kuo + * Cedric Le Goater + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ASPEED_SPI_MAX_CS 5 + +#define CTRL_IO_SINGLE_DATA 0 +#define CTRL_IO_QUAD_DATA BIT(30) +#define CTRL_IO_DUAL_DATA BIT(29) + +#define CTRL_IO_MODE_USER GENMASK(1, 0) +#define CTRL_IO_MODE_CMD_READ BIT(0) +#define CTRL_IO_MODE_CMD_WRITE BIT(1) +#define CTRL_STOP_ACTIVE BIT(2) + +struct aspeed_spi_regs { + u32 conf; /* 0x00 CE Type Setting */ + u32 ctrl; /* 0x04 CE Control */ + u32 intr_ctrl; /* 0x08 Interrupt Control and Status */ + u32 cmd_ctrl; /* 0x0c Command Control */ + u32 ce_ctrl[ASPEED_SPI_MAX_CS]; /* 0x10 .. 0x20 CEx Control */ + u32 _reserved0[3]; /* .. */ + u32 segment_addr[ASPEED_SPI_MAX_CS]; /* 0x30 .. 0x40 Segment Address */ + u32 _reserved1[3]; /* .. */ + u32 soft_rst_cmd_ctrl; /* 0x50 Auto Soft-Reset Command Control */ + u32 _reserved2[11]; /* .. */ + u32 dma_ctrl; /* 0x80 DMA Control/Status */ + u32 dma_flash_addr; /* 0x84 DMA Flash Side Address */ + u32 dma_dram_addr; /* 0x88 DMA DRAM Side Address */ + u32 dma_len; /* 0x8c DMA Length Register */ + u32 dma_checksum; /* 0x90 Checksum Calculation Result */ + u32 timings[ASPEED_SPI_MAX_CS]; /* 0x94 Read Timing Compensation */ +}; + +struct aspeed_spi_plat { + u8 max_cs; + void __iomem *ahb_base; /* AHB address base for all flash devices. */ + fdt_size_t ahb_sz; /* Overall AHB window size for all flash device. */ + u32 hclk_rate; /* AHB clock rate */ +}; + +struct aspeed_spi_flash { + void __iomem *ahb_base; + u32 ahb_decoded_sz; + u32 ce_ctrl_user; + u32 ce_ctrl_read; + u32 max_freq; +}; + +struct aspeed_spi_priv { + u32 num_cs; + struct aspeed_spi_regs *regs; + struct aspeed_spi_info *info; + struct aspeed_spi_flash flashes[ASPEED_SPI_MAX_CS]; + bool fixed_decoded_range; +}; + +struct aspeed_spi_info { + u32 io_mode_mask; + u32 max_bus_width; + u32 min_decoded_sz; + u32 clk_ctrl_mask; + void (*set_4byte)(struct udevice *bus, u32 cs); + u32 (*segment_start)(struct udevice *bus, u32 reg); + u32 (*segment_end)(struct udevice *bus, u32 reg); + u32 (*segment_reg)(u32 start, u32 end); + int (*adjust_decoded_sz)(struct udevice *bus); + u32 (*get_clk_setting)(struct udevice *dev, uint hz); +}; + +struct aspeed_spi_decoded_range { + u32 cs; + u32 ahb_base; + u32 sz; +}; + +static const struct aspeed_spi_info ast2400_spi_info; +static const struct aspeed_spi_info ast2500_fmc_info; +static const struct aspeed_spi_info ast2500_spi_info; +static int aspeed_spi_decoded_range_config(struct udevice *bus); +static int aspeed_spi_trim_decoded_size(struct udevice *bus); + +static u32 aspeed_spi_get_io_mode(u32 bus_width) +{ + switch (bus_width) { + case 1: + return CTRL_IO_SINGLE_DATA; + case 2: + return CTRL_IO_DUAL_DATA; + case 4: + return CTRL_IO_QUAD_DATA; + default: + /* keep in default value */ + return CTRL_IO_SINGLE_DATA; + } +} + +static u32 ast2400_spi_segment_start(struct udevice *bus, u32 reg) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + u32 start_offset = ((reg >> 16) & 0xff) << 23; + + if (start_offset == 0) + return (u32)plat->ahb_base; + + return (u32)plat->ahb_base + start_offset; +} + +static u32 ast2400_spi_segment_end(struct udevice *bus, u32 reg) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + u32 end_offset = ((reg >> 24) & 0xff) << 23; + + /* Meaningless end_offset, set to physical ahb base. */ + if (end_offset == 0) + return (u32)plat->ahb_base; + + return (u32)plat->ahb_base + end_offset; +} + +static u32 ast2400_spi_segment_reg(u32 start, u32 end) +{ + if (start == end) + return 0; + + return ((((start) >> 23) & 0xff) << 16) | ((((end) >> 23) & 0xff) << 24); +} + +static void ast2400_fmc_chip_set_4byte(struct udevice *bus, u32 cs) +{ + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 reg_val; + + reg_val = readl(&priv->regs->ctrl); + reg_val |= 0x1 << cs; + writel(reg_val, &priv->regs->ctrl); +} + +static void ast2400_spi_chip_set_4byte(struct udevice *bus, u32 cs) +{ + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct aspeed_spi_flash *flash = &priv->flashes[cs]; + + flash->ce_ctrl_read |= BIT(13); + writel(flash->ce_ctrl_read, &priv->regs->ctrl); +} + +/* Transfer maximum clock frequency to register setting */ +static u32 ast2400_get_clk_setting(struct udevice *dev, uint max_hz) +{ + struct aspeed_spi_plat *plat = dev_get_plat(dev->parent); + struct aspeed_spi_priv *priv = dev_get_priv(dev->parent); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + u32 hclk_clk = plat->hclk_rate; + u32 hclk_div = 0x0000; /* default value */ + u32 i; + bool found = false; + /* HCLK/1 .. HCLK/16 */ + u32 hclk_masks[] = {15, 7, 14, 6, 13, 5, 12, 4, + 11, 3, 10, 2, 9, 1, 8, 0}; + + /* FMC/SPIR10[11:8] */ + for (i = 0; i < ARRAY_SIZE(hclk_masks); i++) { + if (hclk_clk / (i + 1) <= max_hz) { + found = true; + break; + } + } + + if (found) { + hclk_div = hclk_masks[i] << 8; + priv->flashes[slave_plat->cs].max_freq = hclk_clk / (i + 1); + } + + dev_dbg(dev, "found: %s, hclk: %d, max_clk: %d\n", found ? "yes" : "no", + hclk_clk, max_hz); + + if (found) { + dev_dbg(dev, "h_div: %d (mask %x), speed: %d\n", + i + 1, hclk_masks[i], priv->flashes[slave_plat->cs].max_freq); + } + + return hclk_div; +} + +static u32 ast2500_spi_segment_start(struct udevice *bus, u32 reg) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + u32 start_offset = ((reg >> 16) & 0xff) << 23; + + if (start_offset == 0) + return (u32)plat->ahb_base; + + return (u32)plat->ahb_base + start_offset; +} + +static u32 ast2500_spi_segment_end(struct udevice *bus, u32 reg) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + u32 end_offset = ((reg >> 24) & 0xff) << 23; + + /* Meaningless end_offset, set to physical ahb base. */ + if (end_offset == 0) + return (u32)plat->ahb_base; + + return (u32)plat->ahb_base + end_offset; +} + +static u32 ast2500_spi_segment_reg(u32 start, u32 end) +{ + if (start == end) + return 0; + + return ((((start) >> 23) & 0xff) << 16) | ((((end) >> 23) & 0xff) << 24); +} + +static void ast2500_spi_chip_set_4byte(struct udevice *bus, u32 cs) +{ + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 reg_val; + + reg_val = readl(&priv->regs->ctrl); + reg_val |= 0x1 << cs; + writel(reg_val, &priv->regs->ctrl); +} + +/* + * For AST2500, the minimum address decoded size for each CS + * is 8MB instead of zero. This address decoded size is + * mandatory for each CS no matter whether it will be used. + * This is a HW limitation. + */ +static int ast2500_adjust_decoded_size(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct aspeed_spi_flash *flashes = &priv->flashes[0]; + int ret; + int i; + int cs; + u32 pre_sz; + u32 lack_sz; + + /* Assign min_decoded_sz to unused CS. */ + for (cs = priv->num_cs; cs < plat->max_cs; cs++) + flashes[cs].ahb_decoded_sz = priv->info->min_decoded_sz; + + /* + * If commnad mode or normal mode is used, the start address of a + * decoded range should be multiple of its related flash size. + * Namely, the total decoded size from flash 0 to flash N should + * be multiple of the size of flash (N + 1). + */ + for (cs = priv->num_cs - 1; cs >= 0; cs--) { + pre_sz = 0; + for (i = 0; i < cs; i++) + pre_sz += flashes[i].ahb_decoded_sz; + + if (flashes[cs].ahb_decoded_sz != 0 && + (pre_sz % flashes[cs].ahb_decoded_sz) != 0) { + lack_sz = flashes[cs].ahb_decoded_sz - + (pre_sz % flashes[cs].ahb_decoded_sz); + flashes[0].ahb_decoded_sz += lack_sz; + } + } + + ret = aspeed_spi_trim_decoded_size(bus); + if (ret != 0) + return ret; + + return 0; +} + +static u32 ast2500_get_clk_setting(struct udevice *dev, uint max_hz) +{ + struct aspeed_spi_plat *plat = dev_get_plat(dev->parent); + struct aspeed_spi_priv *priv = dev_get_priv(dev->parent); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + u32 hclk_clk = plat->hclk_rate; + u32 hclk_div = 0x0000; /* default value */ + u32 i; + bool found = false; + /* HCLK/1 .. HCLK/16 */ + u32 hclk_masks[] = {15, 7, 14, 6, 13, 5, 12, 4, + 11, 3, 10, 2, 9, 1, 8, 0}; + + /* FMC/SPIR10[11:8] */ + for (i = 0; i < ARRAY_SIZE(hclk_masks); i++) { + if (hclk_clk / (i + 1) <= max_hz) { + found = true; + priv->flashes[slave_plat->cs].max_freq = + hclk_clk / (i + 1); + break; + } + } + + if (found) { + hclk_div = hclk_masks[i] << 8; + goto end; + } + + for (i = 0; i < ARRAY_SIZE(hclk_masks); i++) { + if (hclk_clk / ((i + 1) * 4) <= max_hz) { + found = true; + priv->flashes[slave_plat->cs].max_freq = + hclk_clk / ((i + 1) * 4); + break; + } + } + + if (found) + hclk_div = BIT(13) | (hclk_masks[i] << 8); + +end: + dev_dbg(dev, "found: %s, hclk: %d, max_clk: %d\n", found ? "yes" : "no", + hclk_clk, max_hz); + + if (found) { + dev_dbg(dev, "h_div: %d (mask %x), speed: %d\n", + i + 1, hclk_masks[i], priv->flashes[slave_plat->cs].max_freq); + } + + return hclk_div; +} + +static u32 ast2600_spi_segment_start(struct udevice *bus, u32 reg) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + u32 start_offset = (reg << 16) & 0x0ff00000; + + if (start_offset == 0) + return (u32)plat->ahb_base; + + return (u32)plat->ahb_base + start_offset; +} + +static u32 ast2600_spi_segment_end(struct udevice *bus, u32 reg) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + u32 end_offset = reg & 0x0ff00000; + + /* Meaningless end_offset, set to physical ahb base. */ + if (end_offset == 0) + return (u32)plat->ahb_base; + + return (u32)plat->ahb_base + end_offset + 0x100000; +} + +static u32 ast2600_spi_segment_reg(u32 start, u32 end) +{ + if (start == end) + return 0; + + return ((start & 0x0ff00000) >> 16) | ((end - 0x100000) & 0x0ff00000); +} + +static void ast2600_spi_chip_set_4byte(struct udevice *bus, u32 cs) +{ + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 reg_val; + + reg_val = readl(&priv->regs->ctrl); + reg_val |= 0x11 << cs; + writel(reg_val, &priv->regs->ctrl); +} + +static int ast2600_adjust_decoded_size(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct aspeed_spi_flash *flashes = &priv->flashes[0]; + int ret; + int i; + int cs; + u32 pre_sz; + u32 lack_sz; + + /* Close unused CS. */ + for (cs = priv->num_cs; cs < plat->max_cs; cs++) + flashes[cs].ahb_decoded_sz = 0; + + /* + * If commnad mode or normal mode is used, the start address of a + * decoded range should be multiple of its related flash size. + * Namely, the total decoded size from flash 0 to flash N should + * be multiple of the size of flash (N + 1). + */ + for (cs = priv->num_cs - 1; cs >= 0; cs--) { + pre_sz = 0; + for (i = 0; i < cs; i++) + pre_sz += flashes[i].ahb_decoded_sz; + + if (flashes[cs].ahb_decoded_sz != 0 && + (pre_sz % flashes[cs].ahb_decoded_sz) != 0) { + lack_sz = flashes[cs].ahb_decoded_sz - + (pre_sz % flashes[cs].ahb_decoded_sz); + flashes[0].ahb_decoded_sz += lack_sz; + } + } + + ret = aspeed_spi_trim_decoded_size(bus); + if (ret != 0) + return ret; + + return 0; +} + +static u32 ast2600_get_clk_setting(struct udevice *dev, uint max_hz) +{ + struct aspeed_spi_plat *plat = dev_get_plat(dev->parent); + struct aspeed_spi_priv *priv = dev_get_priv(dev->parent); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + u32 hclk_clk = plat->hclk_rate; + u32 hclk_div = 0x0400; /* default value */ + u32 i, j; + bool found = false; + /* HCLK/1 .. HCLK/16 */ + u32 hclk_masks[] = {15, 7, 14, 6, 13, 5, 12, 4, + 11, 3, 10, 2, 9, 1, 8, 0}; + + /* FMC/SPIR10[27:24] */ + for (j = 0; j < 0xf; j++) { + /* FMC/SPIR10[11:8] */ + for (i = 0; i < ARRAY_SIZE(hclk_masks); i++) { + if (i == 0 && j == 0) + continue; + + if (hclk_clk / (i + 1 + (j * 16)) <= max_hz) { + found = true; + break; + } + } + + if (found) { + hclk_div = ((j << 24) | hclk_masks[i] << 8); + priv->flashes[slave_plat->cs].max_freq = + hclk_clk / (i + 1 + j * 16); + break; + } + } + + dev_dbg(dev, "found: %s, hclk: %d, max_clk: %d\n", found ? "yes" : "no", + hclk_clk, max_hz); + + if (found) { + dev_dbg(dev, "base_clk: %d, h_div: %d (mask %x), speed: %d\n", + j, i + 1, hclk_masks[i], priv->flashes[slave_plat->cs].max_freq); + } + + return hclk_div; +} + +/* + * As the flash size grows up, we need to trim some decoded + * size if needed for the sake of conforming the maximum + * decoded size. We trim the decoded size from the largest + * CS in order to avoid affecting the default boot up sequence + * from CS0 where command mode or normal mode is used. + * Notice, if a CS decoded size is trimmed, command mode may + * not work perfectly on that CS. + */ +static int aspeed_spi_trim_decoded_size(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct aspeed_spi_flash *flashes = &priv->flashes[0]; + u32 total_sz; + int cs = plat->max_cs - 1; + u32 i; + + do { + total_sz = 0; + for (i = 0; i < plat->max_cs; i++) + total_sz += flashes[i].ahb_decoded_sz; + + if (flashes[cs].ahb_decoded_sz <= priv->info->min_decoded_sz) + cs--; + + if (cs < 0) + return -ENOMEM; + + if (total_sz > plat->ahb_sz) { + flashes[cs].ahb_decoded_sz -= + priv->info->min_decoded_sz; + total_sz -= priv->info->min_decoded_sz; + } + } while (total_sz > plat->ahb_sz); + + return 0; +} + +static int aspeed_spi_read_from_ahb(void __iomem *ahb_base, void *buf, + size_t len) +{ + size_t offset = 0; + + if (IS_ALIGNED((uintptr_t)ahb_base, sizeof(uintptr_t)) && + IS_ALIGNED((uintptr_t)buf, sizeof(uintptr_t))) { + readsl(ahb_base, buf, len >> 2); + offset = len & ~0x3; + len -= offset; + } + + readsb(ahb_base, (u8 *)buf + offset, len); + + return 0; +} + +static int aspeed_spi_write_to_ahb(void __iomem *ahb_base, const void *buf, + size_t len) +{ + size_t offset = 0; + + if (IS_ALIGNED((uintptr_t)ahb_base, sizeof(uintptr_t)) && + IS_ALIGNED((uintptr_t)buf, sizeof(uintptr_t))) { + writesl(ahb_base, buf, len >> 2); + offset = len & ~0x3; + len -= offset; + } + + writesb(ahb_base, (u8 *)buf + offset, len); + + return 0; +} + +/* + * Currently, only support 1-1-1, 1-1-2 or 1-1-4 + * SPI NOR flash operation format. + */ +static bool aspeed_spi_supports_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + struct udevice *bus = slave->dev->parent; + struct aspeed_spi_priv *priv = dev_get_priv(bus); + + if (op->cmd.buswidth > 1) + return false; + + if (op->addr.nbytes != 0) { + if (op->addr.buswidth > 1) + return false; + if (op->addr.nbytes < 3 || op->addr.nbytes > 4) + return false; + } + + if (op->dummy.nbytes != 0) { + if (op->dummy.buswidth > 1 || op->dummy.nbytes > 7) + return false; + } + + if (op->data.nbytes != 0 && + op->data.buswidth > priv->info->max_bus_width) + return false; + + if (!spi_mem_default_supports_op(slave, op)) + return false; + + return true; +} + +static int aspeed_spi_exec_op_user_mode(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + struct udevice *dev = slave->dev; + struct udevice *bus = dev->parent; + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(slave->dev); + u32 cs = slave_plat->cs; + u32 ce_ctrl_reg = (u32)&priv->regs->ce_ctrl[cs]; + u32 ce_ctrl_val; + struct aspeed_spi_flash *flash = &priv->flashes[cs]; + u8 dummy_data[16] = {0}; + u8 addr[4] = {0}; + int i; + + dev_dbg(dev, "cmd:%x(%d),addr:%llx(%d),dummy:%d(%d),data_len:0x%x(%d)\n", + op->cmd.opcode, op->cmd.buswidth, op->addr.val, + op->addr.buswidth, op->dummy.nbytes, op->dummy.buswidth, + op->data.nbytes, op->data.buswidth); + + if (priv->info == &ast2400_spi_info) + ce_ctrl_reg = (u32)&priv->regs->ctrl; + + /* + * Set controller to 4-byte address mode + * if flash is in 4-byte address mode. + */ + if (op->cmd.opcode == SPINOR_OP_EN4B) + priv->info->set_4byte(bus, cs); + + /* Start user mode */ + ce_ctrl_val = flash->ce_ctrl_user; + writel(ce_ctrl_val, ce_ctrl_reg); + ce_ctrl_val &= (~CTRL_STOP_ACTIVE); + writel(ce_ctrl_val, ce_ctrl_reg); + + /* Send command */ + aspeed_spi_write_to_ahb(flash->ahb_base, &op->cmd.opcode, 1); + + /* Send address */ + for (i = op->addr.nbytes; i > 0; i--) { + addr[op->addr.nbytes - i] = + ((u32)op->addr.val >> ((i - 1) * 8)) & 0xff; + } + + /* Change io_mode */ + ce_ctrl_val &= ~priv->info->io_mode_mask; + ce_ctrl_val |= aspeed_spi_get_io_mode(op->addr.buswidth); + writel(ce_ctrl_val, ce_ctrl_reg); + aspeed_spi_write_to_ahb(flash->ahb_base, addr, op->addr.nbytes); + + /* Send dummy cycles */ + aspeed_spi_write_to_ahb(flash->ahb_base, dummy_data, op->dummy.nbytes); + + /* Change io_mode */ + ce_ctrl_val &= ~priv->info->io_mode_mask; + ce_ctrl_val |= aspeed_spi_get_io_mode(op->data.buswidth); + writel(ce_ctrl_val, ce_ctrl_reg); + + /* Send data */ + if (op->data.dir == SPI_MEM_DATA_OUT) { + aspeed_spi_write_to_ahb(flash->ahb_base, op->data.buf.out, + op->data.nbytes); + } else { + aspeed_spi_read_from_ahb(flash->ahb_base, op->data.buf.in, + op->data.nbytes); + } + + ce_ctrl_val |= CTRL_STOP_ACTIVE; + writel(ce_ctrl_val, ce_ctrl_reg); + + /* Restore controller setting. */ + writel(flash->ce_ctrl_read, ce_ctrl_reg); + + return 0; +} + +static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc) +{ + int ret = 0; + struct udevice *dev = desc->slave->dev; + struct udevice *bus = dev->parent; + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + const struct aspeed_spi_info *info = priv->info; + struct spi_mem_op op_tmpl = desc->info.op_tmpl; + u32 i; + u32 cs = slave_plat->cs; + u32 cmd_io_conf; + u32 ce_ctrl_reg; + + if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) { + /* + * dirmap_write is not supported currently due to a HW + * limitation for command write mode: The written data + * length should be multiple of 4-byte. + */ + return -EOPNOTSUPP; + } + + ce_ctrl_reg = (u32)&priv->regs->ce_ctrl[cs]; + if (info == &ast2400_spi_info) + ce_ctrl_reg = (u32)&priv->regs->ctrl; + + if (desc->info.length > 0x1000000) + priv->info->set_4byte(bus, cs); + + /* AST2400 SPI1 doesn't have decoded address segment register. */ + if (info != &ast2400_spi_info) { + priv->flashes[cs].ahb_decoded_sz = desc->info.length; + + for (i = 0; i < priv->num_cs; i++) { + dev_dbg(dev, "cs: %d, sz: 0x%x\n", i, + priv->flashes[cs].ahb_decoded_sz); + } + + ret = aspeed_spi_decoded_range_config(bus); + if (ret) + return ret; + } + + cmd_io_conf = aspeed_spi_get_io_mode(op_tmpl.data.buswidth) | + op_tmpl.cmd.opcode << 16 | + ((op_tmpl.dummy.nbytes) & 0x3) << 6 | + ((op_tmpl.dummy.nbytes) & 0x4) << 14 | + CTRL_IO_MODE_CMD_READ; + + priv->flashes[cs].ce_ctrl_read &= priv->info->clk_ctrl_mask; + priv->flashes[cs].ce_ctrl_read |= cmd_io_conf; + + writel(priv->flashes[cs].ce_ctrl_read, ce_ctrl_reg); + + dev_dbg(dev, "read bus width: %d ce_ctrl_val: 0x%08x\n", + op_tmpl.data.buswidth, priv->flashes[cs].ce_ctrl_read); + + return ret; +} + +static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf) +{ + struct udevice *dev = desc->slave->dev; + struct aspeed_spi_priv *priv = dev_get_priv(dev->parent); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + u32 cs = slave_plat->cs; + int ret; + + dev_dbg(dev, "read op:0x%x, addr:0x%llx, len:0x%x\n", + desc->info.op_tmpl.cmd.opcode, offs, len); + + if (priv->flashes[cs].ahb_decoded_sz < offs + len || + (offs % 4) != 0) { + ret = aspeed_spi_exec_op_user_mode(desc->slave, + &desc->info.op_tmpl); + if (ret != 0) + return 0; + } else { + memcpy_fromio(buf, priv->flashes[cs].ahb_base + offs, len); + } + + return len; +} + +static struct aspeed_spi_flash *aspeed_spi_get_flash(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 cs = slave_plat->cs; + + if (cs >= plat->max_cs) { + dev_err(dev, "invalid CS %u\n", cs); + return NULL; + } + + return &priv->flashes[cs]; +} + +static void aspeed_spi_decoded_base_calculate(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 cs; + + if (priv->fixed_decoded_range) + return; + + priv->flashes[0].ahb_base = plat->ahb_base; + + for (cs = 1; cs < plat->max_cs; cs++) { + priv->flashes[cs].ahb_base = + priv->flashes[cs - 1].ahb_base + + priv->flashes[cs - 1].ahb_decoded_sz; + } +} + +static void aspeed_spi_decoded_range_set(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 decoded_reg_val; + u32 start_addr, end_addr; + u32 cs; + + for (cs = 0; cs < plat->max_cs; cs++) { + start_addr = (u32)priv->flashes[cs].ahb_base; + end_addr = (u32)priv->flashes[cs].ahb_base + + priv->flashes[cs].ahb_decoded_sz; + + decoded_reg_val = priv->info->segment_reg(start_addr, end_addr); + + writel(decoded_reg_val, &priv->regs->segment_addr[cs]); + + dev_dbg(bus, "cs: %d, decoded_reg: 0x%x, start: 0x%x, end: 0x%x\n", + cs, decoded_reg_val, start_addr, end_addr); + } +} + +static int aspeed_spi_decoded_range_config(struct udevice *bus) +{ + int ret = 0; + struct aspeed_spi_priv *priv = dev_get_priv(bus); + + if (priv->info->adjust_decoded_sz && + !priv->fixed_decoded_range) { + ret = priv->info->adjust_decoded_sz(bus); + if (ret != 0) + return ret; + } + + aspeed_spi_decoded_base_calculate(bus); + aspeed_spi_decoded_range_set(bus); + + return ret; +} + +static int aspeed_spi_decoded_ranges_sanity(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 cs; + u32 total_sz = 0; + + /* Check overall size. */ + for (cs = 0; cs < plat->max_cs; cs++) + total_sz += priv->flashes[cs].ahb_decoded_sz; + + if (total_sz > plat->ahb_sz) { + dev_err(bus, "invalid total size 0x%08x\n", total_sz); + return -EINVAL; + } + + /* Check each decoded range size for AST2500. */ + if (priv->info == &ast2500_fmc_info || + priv->info == &ast2500_spi_info) { + for (cs = 0; cs < plat->max_cs; cs++) { + if (priv->flashes[cs].ahb_decoded_sz < + priv->info->min_decoded_sz) { + dev_err(bus, "insufficient decoded range.\n"); + return -EINVAL; + } + } + } + + /* + * Check overlay. Here, we assume the deccded ranges and + * address base are monotonic increasing with CE#. + */ + for (cs = plat->max_cs - 1; cs > 0; cs--) { + if ((u32)priv->flashes[cs].ahb_base != 0 && + (u32)priv->flashes[cs].ahb_base < + (u32)priv->flashes[cs - 1].ahb_base + + priv->flashes[cs - 1].ahb_decoded_sz) { + dev_err(bus, "decoded range overlay 0x%08x 0x%08x\n", + (u32)priv->flashes[cs].ahb_base, + (u32)priv->flashes[cs - 1].ahb_base); + return -EINVAL; + } + } + + return 0; +} + +static int aspeed_spi_read_fixed_decoded_ranges(struct udevice *bus) +{ + int ret = 0; + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + const char *range_prop = "decoded-ranges"; + struct aspeed_spi_decoded_range ranges[ASPEED_SPI_MAX_CS]; + const struct property *prop; + u32 prop_sz; + u32 count; + u32 i; + + priv->fixed_decoded_range = false; + + prop = dev_read_prop(bus, range_prop, &prop_sz); + if (!prop) + return 0; + + count = prop_sz / sizeof(struct aspeed_spi_decoded_range); + if (count > plat->max_cs || count < priv->num_cs) { + dev_err(bus, "invalid '%s' property %d %d\n", + range_prop, count, priv->num_cs); + return -EINVAL; + } + + ret = dev_read_u32_array(bus, range_prop, (u32 *)ranges, count * 3); + if (ret) + return ret; + + for (i = 0; i < count; i++) { + priv->flashes[ranges[i].cs].ahb_base = + (void __iomem *)ranges[i].ahb_base; + priv->flashes[ranges[i].cs].ahb_decoded_sz = + ranges[i].sz; + } + + for (i = 0; i < plat->max_cs; i++) { + dev_dbg(bus, "ahb_base: 0x%p, size: 0x%08x\n", + priv->flashes[i].ahb_base, + priv->flashes[i].ahb_decoded_sz); + } + + ret = aspeed_spi_decoded_ranges_sanity(bus); + if (ret != 0) + return ret; + + priv->fixed_decoded_range = true; + + return 0; +} + +/* + * Initialize SPI controller for each chip select. + * Here, only the minimum decode range is configured + * in order to get device (SPI NOR flash) information + * at the early stage. + */ +static int aspeed_spi_ctrl_init(struct udevice *bus) +{ + int ret; + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 cs; + u32 reg_val; + u32 decoded_sz; + + /* Enable write capability for all CS. */ + reg_val = readl(&priv->regs->conf); + if (priv->info == &ast2400_spi_info) { + writel(reg_val | BIT(0), &priv->regs->conf); + } else { + writel(reg_val | (GENMASK(plat->max_cs - 1, 0) << 16), + &priv->regs->conf); + } + + memset(priv->flashes, 0x0, + sizeof(struct aspeed_spi_flash) * ASPEED_SPI_MAX_CS); + + /* Initial user mode. */ + for (cs = 0; cs < priv->num_cs; cs++) { + priv->flashes[cs].ce_ctrl_user &= priv->info->clk_ctrl_mask; + priv->flashes[cs].ce_ctrl_user |= + (CTRL_STOP_ACTIVE | CTRL_IO_MODE_USER); + } + + /* + * SPI1 on AST2400 only supports CS0. + * It is unnecessary to configure segment address register. + */ + if (priv->info == &ast2400_spi_info) { + priv->flashes[cs].ahb_base = plat->ahb_base; + priv->flashes[cs].ahb_decoded_sz = 0x10000000; + return 0; + } + + + ret = aspeed_spi_read_fixed_decoded_ranges(bus); + if (ret != 0) + return ret; + + if (!priv->fixed_decoded_range) { + /* Assign basic AHB decoded size for each CS. */ + for (cs = 0; cs < plat->max_cs; cs++) { + reg_val = readl(&priv->regs->segment_addr[cs]); + decoded_sz = priv->info->segment_end(bus, reg_val) - + priv->info->segment_start(bus, reg_val); + + if (decoded_sz < priv->info->min_decoded_sz) + decoded_sz = priv->info->min_decoded_sz; + + priv->flashes[cs].ahb_decoded_sz = decoded_sz; + } + } + + ret = aspeed_spi_decoded_range_config(bus); + + return ret; +} + +static const struct aspeed_spi_info ast2400_fmc_info = { + .io_mode_mask = 0x70000000, + .max_bus_width = 2, + .min_decoded_sz = 0x800000, + .clk_ctrl_mask = 0x00002f00, + .set_4byte = ast2400_fmc_chip_set_4byte, + .segment_start = ast2400_spi_segment_start, + .segment_end = ast2400_spi_segment_end, + .segment_reg = ast2400_spi_segment_reg, + .get_clk_setting = ast2400_get_clk_setting, +}; + +static const struct aspeed_spi_info ast2400_spi_info = { + .io_mode_mask = 0x70000000, + .max_bus_width = 2, + .min_decoded_sz = 0x800000, + .clk_ctrl_mask = 0x00000f00, + .set_4byte = ast2400_spi_chip_set_4byte, + .segment_start = ast2400_spi_segment_start, + .segment_end = ast2400_spi_segment_end, + .segment_reg = ast2400_spi_segment_reg, + .get_clk_setting = ast2400_get_clk_setting, +}; + +static const struct aspeed_spi_info ast2500_fmc_info = { + .io_mode_mask = 0x70000000, + .max_bus_width = 2, + .min_decoded_sz = 0x800000, + .clk_ctrl_mask = 0x00002f00, + .set_4byte = ast2500_spi_chip_set_4byte, + .segment_start = ast2500_spi_segment_start, + .segment_end = ast2500_spi_segment_end, + .segment_reg = ast2500_spi_segment_reg, + .adjust_decoded_sz = ast2500_adjust_decoded_size, + .get_clk_setting = ast2500_get_clk_setting, +}; + +/* + * There are some different between FMC and SPI controllers. + * For example, DMA operation, but this isn't implemented currently. + */ +static const struct aspeed_spi_info ast2500_spi_info = { + .io_mode_mask = 0x70000000, + .max_bus_width = 2, + .min_decoded_sz = 0x800000, + .clk_ctrl_mask = 0x00002f00, + .set_4byte = ast2500_spi_chip_set_4byte, + .segment_start = ast2500_spi_segment_start, + .segment_end = ast2500_spi_segment_end, + .segment_reg = ast2500_spi_segment_reg, + .adjust_decoded_sz = ast2500_adjust_decoded_size, + .get_clk_setting = ast2500_get_clk_setting, +}; + +static const struct aspeed_spi_info ast2600_fmc_info = { + .io_mode_mask = 0xf0000000, + .max_bus_width = 4, + .min_decoded_sz = 0x200000, + .clk_ctrl_mask = 0x0f000f00, + .set_4byte = ast2600_spi_chip_set_4byte, + .segment_start = ast2600_spi_segment_start, + .segment_end = ast2600_spi_segment_end, + .segment_reg = ast2600_spi_segment_reg, + .adjust_decoded_sz = ast2600_adjust_decoded_size, + .get_clk_setting = ast2600_get_clk_setting, +}; + +static const struct aspeed_spi_info ast2600_spi_info = { + .io_mode_mask = 0xf0000000, + .max_bus_width = 4, + .min_decoded_sz = 0x200000, + .clk_ctrl_mask = 0x0f000f00, + .set_4byte = ast2600_spi_chip_set_4byte, + .segment_start = ast2600_spi_segment_start, + .segment_end = ast2600_spi_segment_end, + .segment_reg = ast2600_spi_segment_reg, + .adjust_decoded_sz = ast2600_adjust_decoded_size, + .get_clk_setting = ast2600_get_clk_setting, +}; + +static int aspeed_spi_claim_bus(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + struct aspeed_spi_priv *priv = dev_get_priv(dev->parent); + struct aspeed_spi_flash *flash = &priv->flashes[slave_plat->cs]; + u32 clk_setting; + + dev_dbg(bus, "%s: claim bus CS%u\n", bus->name, slave_plat->cs); + + if (flash->max_freq == 0) { + clk_setting = priv->info->get_clk_setting(dev, slave_plat->max_hz); + flash->ce_ctrl_user &= ~(priv->info->clk_ctrl_mask); + flash->ce_ctrl_user |= clk_setting; + flash->ce_ctrl_read &= ~(priv->info->clk_ctrl_mask); + flash->ce_ctrl_read |= clk_setting; + } + + return 0; +} + +static int aspeed_spi_release_bus(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + + dev_dbg(bus, "%s: release bus CS%u\n", bus->name, slave_plat->cs); + + if (!aspeed_spi_get_flash(dev)) + return -ENODEV; + + return 0; +} + +static int aspeed_spi_set_mode(struct udevice *bus, uint mode) +{ + dev_dbg(bus, "%s: setting mode to %x\n", bus->name, mode); + + return 0; +} + +static int aspeed_spi_set_speed(struct udevice *bus, uint hz) +{ + dev_dbg(bus, "%s: setting speed to %u\n", bus->name, hz); + /* + * ASPEED SPI controller supports multiple CS with different + * clock frequency. We cannot distinguish which CS here. + * Thus, the related implementation is postponed to claim_bus. + */ + + return 0; +} + +static int apseed_spi_of_to_plat(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + int ret; + struct clk hclk; + + priv->regs = (void __iomem *)devfdt_get_addr_index(bus, 0); + if ((u32)priv->regs == FDT_ADDR_T_NONE) { + dev_err(bus, "wrong ctrl base\n"); + return -ENODEV; + } + + plat->ahb_base = + (void __iomem *)devfdt_get_addr_size_index(bus, 1, &plat->ahb_sz); + if ((u32)plat->ahb_base == FDT_ADDR_T_NONE) { + dev_err(bus, "wrong AHB base\n"); + return -ENODEV; + } + + plat->max_cs = dev_read_u32_default(bus, "num-cs", ASPEED_SPI_MAX_CS); + if (plat->max_cs > ASPEED_SPI_MAX_CS) + return -EINVAL; + + ret = clk_get_by_index(bus, 0, &hclk); + if (ret < 0) { + dev_err(bus, "%s could not get clock: %d\n", bus->name, ret); + return ret; + } + + plat->hclk_rate = clk_get_rate(&hclk); + clk_free(&hclk); + + dev_dbg(bus, "ctrl_base = 0x%x, ahb_base = 0x%p, size = 0x%lx\n", + (u32)priv->regs, plat->ahb_base, plat->ahb_sz); + dev_dbg(bus, "hclk = %dMHz, max_cs = %d\n", + plat->hclk_rate / 1000000, plat->max_cs); + + return 0; +} + +static int aspeed_spi_probe(struct udevice *bus) +{ + int ret; + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct udevice *dev; + + priv->info = (struct aspeed_spi_info *)dev_get_driver_data(bus); + + priv->num_cs = 0; + for (device_find_first_child(bus, &dev); dev; + device_find_next_child(&dev)) { + priv->num_cs++; + } + + if (priv->num_cs > ASPEED_SPI_MAX_CS) + return -EINVAL; + + ret = aspeed_spi_ctrl_init(bus); + + return ret; +} + +static const struct spi_controller_mem_ops aspeed_spi_mem_ops = { + .supports_op = aspeed_spi_supports_op, + .exec_op = aspeed_spi_exec_op_user_mode, + .dirmap_create = aspeed_spi_dirmap_create, + .dirmap_read = aspeed_spi_dirmap_read, +}; + +static const struct dm_spi_ops aspeed_spi_ops = { + .claim_bus = aspeed_spi_claim_bus, + .release_bus = aspeed_spi_release_bus, + .set_speed = aspeed_spi_set_speed, + .set_mode = aspeed_spi_set_mode, + .mem_ops = &aspeed_spi_mem_ops, +}; + +static const struct udevice_id aspeed_spi_ids[] = { + { .compatible = "aspeed,ast2400-fmc", .data = (ulong)&ast2400_fmc_info, }, + { .compatible = "aspeed,ast2400-spi", .data = (ulong)&ast2400_spi_info, }, + { .compatible = "aspeed,ast2500-fmc", .data = (ulong)&ast2500_fmc_info, }, + { .compatible = "aspeed,ast2500-spi", .data = (ulong)&ast2500_spi_info, }, + { .compatible = "aspeed,ast2600-fmc", .data = (ulong)&ast2600_fmc_info, }, + { .compatible = "aspeed,ast2600-spi", .data = (ulong)&ast2600_spi_info, }, + { } +}; + +U_BOOT_DRIVER(aspeed_spi) = { + .name = "aspeed_spi_smc", + .id = UCLASS_SPI, + .of_match = aspeed_spi_ids, + .ops = &aspeed_spi_ops, + .of_to_plat = apseed_spi_of_to_plat, + .plat_auto = sizeof(struct aspeed_spi_plat), + .priv_auto = sizeof(struct aspeed_spi_priv), + .probe = aspeed_spi_probe, +}; diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 9c1ede1b61..8e8995fc53 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #endif #ifndef __UBOOT__ @@ -491,6 +493,272 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, struct spi_mem_op *op) } EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size); +static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf) +{ + struct spi_mem_op op = desc->info.op_tmpl; + int ret; + + op.addr.val = desc->info.offset + offs; + op.data.buf.in = buf; + op.data.nbytes = len; + ret = spi_mem_adjust_op_size(desc->slave, &op); + if (ret) + return ret; + + ret = spi_mem_exec_op(desc->slave, &op); + if (ret) + return ret; + + return op.data.nbytes; +} + +static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, const void *buf) +{ + struct spi_mem_op op = desc->info.op_tmpl; + int ret; + + op.addr.val = desc->info.offset + offs; + op.data.buf.out = buf; + op.data.nbytes = len; + ret = spi_mem_adjust_op_size(desc->slave, &op); + if (ret) + return ret; + + ret = spi_mem_exec_op(desc->slave, &op); + if (ret) + return ret; + + return op.data.nbytes; +} + +/** + * spi_mem_dirmap_create() - Create a direct mapping descriptor + * @mem: SPI mem device this direct mapping should be created for + * @info: direct mapping information + * + * This function is creating a direct mapping descriptor which can then be used + * to access the memory using spi_mem_dirmap_read() or spi_mem_dirmap_write(). + * If the SPI controller driver does not support direct mapping, this function + * falls back to an implementation using spi_mem_exec_op(), so that the caller + * doesn't have to bother implementing a fallback on his own. + * + * Return: a valid pointer in case of success, and ERR_PTR() otherwise. + */ +struct spi_mem_dirmap_desc * +spi_mem_dirmap_create(struct spi_slave *slave, + const struct spi_mem_dirmap_info *info) +{ + struct udevice *bus = slave->dev->parent; + struct dm_spi_ops *ops = spi_get_ops(bus); + struct spi_mem_dirmap_desc *desc; + int ret = -EOPNOTSUPP; + + /* Make sure the number of address cycles is between 1 and 8 bytes. */ + if (!info->op_tmpl.addr.nbytes || info->op_tmpl.addr.nbytes > 8) + return ERR_PTR(-EINVAL); + + /* data.dir should either be SPI_MEM_DATA_IN or SPI_MEM_DATA_OUT. */ + if (info->op_tmpl.data.dir == SPI_MEM_NO_DATA) + return ERR_PTR(-EINVAL); + + desc = kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) + return ERR_PTR(-ENOMEM); + + desc->slave = slave; + desc->info = *info; + if (ops->mem_ops && ops->mem_ops->dirmap_create) + ret = ops->mem_ops->dirmap_create(desc); + + if (ret) { + desc->nodirmap = true; + if (!spi_mem_supports_op(desc->slave, &desc->info.op_tmpl)) + ret = -EOPNOTSUPP; + else + ret = 0; + } + + if (ret) { + kfree(desc); + return ERR_PTR(ret); + } + + return desc; +} +EXPORT_SYMBOL_GPL(spi_mem_dirmap_create); + +/** + * spi_mem_dirmap_destroy() - Destroy a direct mapping descriptor + * @desc: the direct mapping descriptor to destroy + * + * This function destroys a direct mapping descriptor previously created by + * spi_mem_dirmap_create(). + */ +void spi_mem_dirmap_destroy(struct spi_mem_dirmap_desc *desc) +{ + struct udevice *bus = desc->slave->dev->parent; + struct dm_spi_ops *ops = spi_get_ops(bus); + + if (!desc->nodirmap && ops->mem_ops && ops->mem_ops->dirmap_destroy) + ops->mem_ops->dirmap_destroy(desc); + + kfree(desc); +} +EXPORT_SYMBOL_GPL(spi_mem_dirmap_destroy); + +#ifndef __UBOOT__ +static void devm_spi_mem_dirmap_release(struct udevice *dev, void *res) +{ + struct spi_mem_dirmap_desc *desc = *(struct spi_mem_dirmap_desc **)res; + + spi_mem_dirmap_destroy(desc); +} + +/** + * devm_spi_mem_dirmap_create() - Create a direct mapping descriptor and attach + * it to a device + * @dev: device the dirmap desc will be attached to + * @mem: SPI mem device this direct mapping should be created for + * @info: direct mapping information + * + * devm_ variant of the spi_mem_dirmap_create() function. See + * spi_mem_dirmap_create() for more details. + * + * Return: a valid pointer in case of success, and ERR_PTR() otherwise. + */ +struct spi_mem_dirmap_desc * +devm_spi_mem_dirmap_create(struct udevice *dev, struct spi_slave *slave, + const struct spi_mem_dirmap_info *info) +{ + struct spi_mem_dirmap_desc **ptr, *desc; + + ptr = devres_alloc(devm_spi_mem_dirmap_release, sizeof(*ptr), + GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + desc = spi_mem_dirmap_create(slave, info); + if (IS_ERR(desc)) { + devres_free(ptr); + } else { + *ptr = desc; + devres_add(dev, ptr); + } + + return desc; +} +EXPORT_SYMBOL_GPL(devm_spi_mem_dirmap_create); + +static int devm_spi_mem_dirmap_match(struct udevice *dev, void *res, void *data) +{ + struct spi_mem_dirmap_desc **ptr = res; + + if (WARN_ON(!ptr || !*ptr)) + return 0; + + return *ptr == data; +} + +/** + * devm_spi_mem_dirmap_destroy() - Destroy a direct mapping descriptor attached + * to a device + * @dev: device the dirmap desc is attached to + * @desc: the direct mapping descriptor to destroy + * + * devm_ variant of the spi_mem_dirmap_destroy() function. See + * spi_mem_dirmap_destroy() for more details. + */ +void devm_spi_mem_dirmap_destroy(struct udevice *dev, + struct spi_mem_dirmap_desc *desc) +{ + devres_release(dev, devm_spi_mem_dirmap_release, + devm_spi_mem_dirmap_match, desc); +} +EXPORT_SYMBOL_GPL(devm_spi_mem_dirmap_destroy); +#endif /* __UBOOT__ */ + +/** + * spi_mem_dirmap_read() - Read data through a direct mapping + * @desc: direct mapping descriptor + * @offs: offset to start reading from. Note that this is not an absolute + * offset, but the offset within the direct mapping which already has + * its own offset + * @len: length in bytes + * @buf: destination buffer. This buffer must be DMA-able + * + * This function reads data from a memory device using a direct mapping + * previously instantiated with spi_mem_dirmap_create(). + * + * Return: the amount of data read from the memory device or a negative error + * code. Note that the returned size might be smaller than @len, and the caller + * is responsible for calling spi_mem_dirmap_read() again when that happens. + */ +ssize_t spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf) +{ + struct udevice *bus = desc->slave->dev->parent; + struct dm_spi_ops *ops = spi_get_ops(bus); + ssize_t ret; + + if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN) + return -EINVAL; + + if (!len) + return 0; + + if (desc->nodirmap) + ret = spi_mem_no_dirmap_read(desc, offs, len, buf); + else if (ops->mem_ops && ops->mem_ops->dirmap_read) + ret = ops->mem_ops->dirmap_read(desc, offs, len, buf); + else + ret = -EOPNOTSUPP; + + return ret; +} +EXPORT_SYMBOL_GPL(spi_mem_dirmap_read); + +/** + * spi_mem_dirmap_write() - Write data through a direct mapping + * @desc: direct mapping descriptor + * @offs: offset to start writing from. Note that this is not an absolute + * offset, but the offset within the direct mapping which already has + * its own offset + * @len: length in bytes + * @buf: source buffer. This buffer must be DMA-able + * + * This function writes data to a memory device using a direct mapping + * previously instantiated with spi_mem_dirmap_create(). + * + * Return: the amount of data written to the memory device or a negative error + * code. Note that the returned size might be smaller than @len, and the caller + * is responsible for calling spi_mem_dirmap_write() again when that happens. + */ +ssize_t spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, const void *buf) +{ + struct udevice *bus = desc->slave->dev->parent; + struct dm_spi_ops *ops = spi_get_ops(bus); + ssize_t ret; + + if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_OUT) + return -EINVAL; + + if (!len) + return 0; + + if (desc->nodirmap) + ret = spi_mem_no_dirmap_write(desc, offs, len, buf); + else if (ops->mem_ops && ops->mem_ops->dirmap_write) + ret = ops->mem_ops->dirmap_write(desc, offs, len, buf); + else + ret = -EOPNOTSUPP; + + return ret; +} +EXPORT_SYMBOL_GPL(spi_mem_dirmap_write); + #ifndef __UBOOT__ static inline struct spi_mem_driver *to_spi_mem_drv(struct device_driver *drv) { diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c index ceba413727..90c207d518 100644 --- a/drivers/spi/stm32_qspi.c +++ b/drivers/spi/stm32_qspi.c @@ -172,7 +172,7 @@ static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv *priv, static void _stm32_qspi_read_fifo(u8 *val, void __iomem *addr) { *val = readb(addr); - WATCHDOG_RESET(); + schedule(); } static void _stm32_qspi_write_fifo(u8 *val, void __iomem *addr) diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c index c772bae3cc..d3cc8554b8 100644 --- a/drivers/spi/zynqmp_gqspi.c +++ b/drivers/spi/zynqmp_gqspi.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #define GQSPI_GFIFO_STRT_MODE_MASK BIT(29) #define GQSPI_CONFIG_MODE_EN_MASK (3 << 30) @@ -102,8 +104,10 @@ #define TAP_DLY_BYPASS_LQSPI_RX_VALUE 0x1 #define TAP_DLY_BYPASS_LQSPI_RX_SHIFT 2 #define GQSPI_DATA_DLY_ADJ_OFST 0x000001F8 -#define IOU_TAPDLY_BYPASS_OFST 0xFF180390 +#define IOU_TAPDLY_BYPASS_OFST !IS_ENABLED(CONFIG_ARCH_VERSAL) ? \ + 0xFF180390 : 0xF103003C #define GQSPI_LPBK_DLY_ADJ_LPBK_MASK 0x00000020 +#define GQSPI_FREQ_37_5MHZ 37500000 #define GQSPI_FREQ_40MHZ 40000000 #define GQSPI_FREQ_100MHZ 100000000 #define GQSPI_FREQ_150MHZ 150000000 @@ -163,6 +167,7 @@ struct zynqmp_qspi_plat { struct zynqmp_qspi_dma_regs *dma_regs; u32 frequency; u32 speed_hz; + unsigned int io_mode; }; struct zynqmp_qspi_priv { @@ -171,6 +176,7 @@ struct zynqmp_qspi_priv { const void *tx_buf; void *rx_buf; unsigned int len; + unsigned int io_mode; int bytes_to_transfer; int bytes_to_receive; const struct spi_mem_op *op; @@ -187,6 +193,8 @@ static int zynqmp_qspi_of_to_plat(struct udevice *bus) plat->dma_regs = (struct zynqmp_qspi_dma_regs *) (dev_read_addr(bus) + GQSPI_DMA_REG_OFFSET); + plat->io_mode = dev_read_bool(bus, "has-io-mode"); + return 0; } @@ -206,8 +214,11 @@ static void zynqmp_qspi_init_hw(struct zynqmp_qspi_priv *priv) config_reg = readl(®s->confr); config_reg &= ~(GQSPI_GFIFO_STRT_MODE_MASK | GQSPI_CONFIG_MODE_EN_MASK); - config_reg |= GQSPI_CONFIG_DMA_MODE | GQSPI_GFIFO_WP_HOLD | - GQSPI_DFLT_BAUD_RATE_DIV | GQSPI_GFIFO_STRT_MODE_MASK; + config_reg |= GQSPI_GFIFO_WP_HOLD | GQSPI_DFLT_BAUD_RATE_DIV; + config_reg |= GQSPI_GFIFO_STRT_MODE_MASK; + if (!priv->io_mode) + config_reg |= GQSPI_CONFIG_DMA_MODE; + writel(config_reg, ®s->confr); writel(GQSPI_ENABLE_ENABLE_MASK, ®s->enbr); @@ -297,28 +308,42 @@ void zynqmp_qspi_set_tapdelay(struct udevice *bus, u32 baudrateval) debug("%s, req_hz:%d, clk_rate:%d, baudrateval:%d\n", __func__, reqhz, clk_rate, baudrateval); - if (reqhz < GQSPI_FREQ_40MHZ) { - zynqmp_mmio_read(IOU_TAPDLY_BYPASS_OFST, &tapdlybypass); - tapdlybypass |= (TAP_DLY_BYPASS_LQSPI_RX_VALUE << - TAP_DLY_BYPASS_LQSPI_RX_SHIFT); - } else if (reqhz <= GQSPI_FREQ_100MHZ) { - zynqmp_mmio_read(IOU_TAPDLY_BYPASS_OFST, &tapdlybypass); - tapdlybypass |= (TAP_DLY_BYPASS_LQSPI_RX_VALUE << - TAP_DLY_BYPASS_LQSPI_RX_SHIFT); - lpbkdlyadj = readl(®s->lpbkdly); - lpbkdlyadj |= (GQSPI_LPBK_DLY_ADJ_LPBK_MASK); - datadlyadj = readl(®s->gqspidlyadj); - datadlyadj |= ((GQSPI_USE_DATA_DLY << GQSPI_USE_DATA_DLY_SHIFT) - | (GQSPI_DATA_DLY_ADJ_VALUE << - GQSPI_DATA_DLY_ADJ_SHIFT)); - } else if (reqhz <= GQSPI_FREQ_150MHZ) { - lpbkdlyadj = readl(®s->lpbkdly); - lpbkdlyadj |= ((GQSPI_LPBK_DLY_ADJ_LPBK_MASK) | - GQSPI_LPBK_DLY_ADJ_DLY_0); + if (!(IS_ENABLED(CONFIG_ARCH_VERSAL) || + IS_ENABLED(CONFIG_ARCH_VERSAL_NET))) { + if (reqhz <= GQSPI_FREQ_40MHZ) { + tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE << + TAP_DLY_BYPASS_LQSPI_RX_SHIFT; + } else if (reqhz <= GQSPI_FREQ_100MHZ) { + tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE << + TAP_DLY_BYPASS_LQSPI_RX_SHIFT; + lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK; + datadlyadj = (GQSPI_USE_DATA_DLY << + GQSPI_USE_DATA_DLY_SHIFT) | + (GQSPI_DATA_DLY_ADJ_VALUE << + GQSPI_DATA_DLY_ADJ_SHIFT); + } else if (reqhz <= GQSPI_FREQ_150MHZ) { + lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK | + GQSPI_LPBK_DLY_ADJ_DLY_0; + } + zynqmp_mmio_write(IOU_TAPDLY_BYPASS_OFST, + IOU_TAPDLY_BYPASS_MASK, tapdlybypass); + } else { + if (reqhz <= GQSPI_FREQ_37_5MHZ) { + tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE << + TAP_DLY_BYPASS_LQSPI_RX_SHIFT; + } else if (reqhz <= GQSPI_FREQ_100MHZ) { + tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE << + TAP_DLY_BYPASS_LQSPI_RX_SHIFT; + lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK; + datadlyadj = GQSPI_USE_DATA_DLY << + GQSPI_USE_DATA_DLY_SHIFT; + } else if (reqhz <= GQSPI_FREQ_150MHZ) { + lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK | + (GQSPI_LPBK_DLY_ADJ_DLY_1 << + GQSPI_LPBK_DLY_ADJ_DLY_1_SHIFT); + } + writel(tapdlybypass, IOU_TAPDLY_BYPASS_OFST); } - - zynqmp_mmio_write(IOU_TAPDLY_BYPASS_OFST, IOU_TAPDLY_BYPASS_MASK, - tapdlybypass); writel(lpbkdlyadj, ®s->lpbkdly); writel(datadlyadj, ®s->gqspidlyadj); } @@ -372,6 +397,7 @@ static int zynqmp_qspi_probe(struct udevice *bus) priv->regs = plat->regs; priv->dma_regs = plat->dma_regs; + priv->io_mode = plat->io_mode; ret = clk_get_by_index(bus, 0, &clk); if (ret < 0) { @@ -409,8 +435,7 @@ static int zynqmp_qspi_set_mode(struct udevice *bus, uint mode) debug("%s\n", __func__); /* Set the SPI Clock phase and polarities */ confr = readl(®s->confr); - confr &= ~(GQSPI_CONFIG_CPHA_MASK | - GQSPI_CONFIG_CPOL_MASK); + confr &= ~(GQSPI_CONFIG_CPHA_MASK | GQSPI_CONFIG_CPOL_MASK); if (mode & SPI_CPHA) confr |= GQSPI_CONFIG_CPHA_MASK; @@ -554,8 +579,7 @@ static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv) gen_fifo_cmd = zynqmp_qspi_bus_select(priv); gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(priv->op->data.buswidth); - gen_fifo_cmd |= GQSPI_GFIFO_TX | - GQSPI_GFIFO_DATA_XFR_MASK; + gen_fifo_cmd |= GQSPI_GFIFO_TX | GQSPI_GFIFO_DATA_XFR_MASK; while (priv->len) { len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd); @@ -564,11 +588,9 @@ static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv) debug("GFIFO_CMD_TX:0x%x\n", gen_fifo_cmd); if (gen_fifo_cmd & GQSPI_GFIFO_EXP_MASK) - ret = zynqmp_qspi_fill_tx_fifo(priv, - 1 << len); + ret = zynqmp_qspi_fill_tx_fifo(priv, 1 << len); else - ret = zynqmp_qspi_fill_tx_fifo(priv, - len); + ret = zynqmp_qspi_fill_tx_fifo(priv, len); if (ret) return ret; @@ -576,45 +598,120 @@ static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv) return ret; } +static int zynqmp_qspi_start_io(struct zynqmp_qspi_priv *priv, + u32 gen_fifo_cmd, u32 *buf) +{ + u32 len; + u32 actuallen = priv->len; + u32 config_reg, ier, isr; + u32 timeout = GQSPI_TIMEOUT; + struct zynqmp_qspi_regs *regs = priv->regs; + u32 last_bits; + u32 *traverse = buf; + + while (priv->len) { + len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd); + /* If exponent bit is set, reset immediate to be 2^len */ + if (gen_fifo_cmd & GQSPI_GFIFO_EXP_MASK) + priv->bytes_to_receive = (1 << len); + else + priv->bytes_to_receive = len; + zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd); + debug("GFIFO_CMD_RX:0x%x\n", gen_fifo_cmd); + /* Manual start */ + config_reg = readl(®s->confr); + config_reg |= GQSPI_STRT_GEN_FIFO; + writel(config_reg, ®s->confr); + /* Enable RX interrupts for IO mode */ + ier = readl(®s->ier); + ier |= GQSPI_IXR_ALL_MASK; + writel(ier, ®s->ier); + while (priv->bytes_to_receive && timeout) { + isr = readl(®s->isr); + if (isr & GQSPI_IXR_RXNEMTY_MASK) { + if (priv->bytes_to_receive >= 4) { + *traverse = readl(®s->drxr); + traverse++; + priv->bytes_to_receive -= 4; + } else { + last_bits = readl(®s->drxr); + memcpy(traverse, &last_bits, + priv->bytes_to_receive); + priv->bytes_to_receive = 0; + } + timeout = GQSPI_TIMEOUT; + } else { + udelay(1); + timeout--; + } + } + + debug("buf:0x%lx, rxbuf:0x%lx, *buf:0x%x len: 0x%x\n", + (unsigned long)buf, (unsigned long)priv->rx_buf, + *buf, actuallen); + if (!timeout) { + printf("IO timeout: %d\n", readl(®s->isr)); + return -1; + } + } + + return 0; +} + static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv, u32 gen_fifo_cmd, u32 *buf) { u32 addr; u32 size; u32 actuallen = priv->len; + u32 totallen = priv->len; int ret = 0; struct zynqmp_qspi_dma_regs *dma_regs = priv->dma_regs; - writel((unsigned long)buf, &dma_regs->dmadst); - writel(roundup(priv->len, GQSPI_DMA_ALIGN), &dma_regs->dmasize); - writel(GQSPI_DMA_DST_I_STS_MASK, &dma_regs->dmaier); - addr = (unsigned long)buf; - size = roundup(priv->len, GQSPI_DMA_ALIGN); - flush_dcache_range(addr, addr + size); + while (totallen) { + if (totallen >= SZ_512M) + priv->len = SZ_256M; + else + priv->len = totallen; - while (priv->len) { - zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd); - zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd); + totallen -= priv->len; /* Save remaining bytes length to read */ + actuallen = priv->len; /* Actual number of bytes reading */ - debug("GFIFO_CMD_RX:0x%x\n", gen_fifo_cmd); + writel((unsigned long)buf, &dma_regs->dmadst); + writel(roundup(priv->len, GQSPI_DMA_ALIGN), &dma_regs->dmasize); + writel(GQSPI_DMA_DST_I_STS_MASK, &dma_regs->dmaier); + addr = (unsigned long)buf; + size = roundup(priv->len, GQSPI_DMA_ALIGN); + flush_dcache_range(addr, addr + size); + + while (priv->len) { + zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd); + zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd); + + debug("GFIFO_CMD_RX:0x%x\n", gen_fifo_cmd); + } + + ret = wait_for_bit_le32(&dma_regs->dmaisr, + GQSPI_DMA_DST_I_STS_DONE, 1, + GQSPI_TIMEOUT, 1); + if (ret) { + printf("DMA Timeout:0x%x\n", readl(&dma_regs->dmaisr)); + return -ETIMEDOUT; + } + + writel(GQSPI_DMA_DST_I_STS_DONE, &dma_regs->dmaisr); + + debug("buf:0x%lx, rxbuf:0x%lx, *buf:0x%x len: 0x%x\n", + (unsigned long)buf, (unsigned long)priv->rx_buf, *buf, + actuallen); + + if (buf != priv->rx_buf) + memcpy(priv->rx_buf, buf, actuallen); + + buf = (u32 *)((u8 *)buf + actuallen); + priv->rx_buf = (u8 *)priv->rx_buf + actuallen; } - ret = wait_for_bit_le32(&dma_regs->dmaisr, GQSPI_DMA_DST_I_STS_DONE, - 1, GQSPI_TIMEOUT, 1); - if (ret) { - printf("DMA Timeout:0x%x\n", readl(&dma_regs->dmaisr)); - return -ETIMEDOUT; - } - - writel(GQSPI_DMA_DST_I_STS_DONE, &dma_regs->dmaisr); - - debug("buf:0x%lx, rxbuf:0x%lx, *buf:0x%x len: 0x%x\n", - (unsigned long)buf, (unsigned long)priv->rx_buf, *buf, - actuallen); - - if (buf != priv->rx_buf) - memcpy(priv->rx_buf, buf, actuallen); - return 0; } @@ -626,21 +723,22 @@ static int zynqmp_qspi_genfifo_fill_rx(struct zynqmp_qspi_priv *priv) gen_fifo_cmd = zynqmp_qspi_bus_select(priv); gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(priv->op->data.buswidth); - gen_fifo_cmd |= GQSPI_GFIFO_RX | - GQSPI_GFIFO_DATA_XFR_MASK; + gen_fifo_cmd |= GQSPI_GFIFO_RX | GQSPI_GFIFO_DATA_XFR_MASK; /* * Check if receive buffer is aligned to 4 byte and length * is multiples of four byte as we are using dma to receive. */ - if (!((unsigned long)priv->rx_buf & (GQSPI_DMA_ALIGN - 1)) && - !(actuallen % GQSPI_DMA_ALIGN)) { + if ((!((unsigned long)priv->rx_buf & (GQSPI_DMA_ALIGN - 1)) && + !(actuallen % GQSPI_DMA_ALIGN)) || priv->io_mode) { buf = (u32 *)priv->rx_buf; - return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf); + if (priv->io_mode) + return zynqmp_qspi_start_io(priv, gen_fifo_cmd, buf); + else + return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf); } - ALLOC_CACHE_ALIGN_BUFFER(u8, tmp, roundup(priv->len, - GQSPI_DMA_ALIGN)); + ALLOC_CACHE_ALIGN_BUFFER(u8, tmp, roundup(priv->len, GQSPI_DMA_ALIGN)); buf = (u32 *)tmp; return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf); } diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig index d03028070b..9dc65b0501 100644 --- a/drivers/tee/optee/Kconfig +++ b/drivers/tee/optee/Kconfig @@ -37,6 +37,14 @@ config OPTEE_TA_SCP03 help Enables support for controlling (enabling, provisioning) the Secure Channel Protocol 03 operation in the OP-TEE SCP03 TA. + +config OPTEE_SERVICE_DISCOVERY + bool "OP-TEE service discovery" + default y + help + This implements automated driver binding of OP-TEE service drivers by + requesting OP-TEE firmware to enumerate its hosted services. + endmenu endif diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index a89d62aaf0..9240277579 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "optee_smc.h" #include "optee_msg.h" @@ -22,6 +23,25 @@ #define PAGELIST_ENTRIES_PER_PAGE \ ((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1) +/* + * PTA_DEVICE_ENUM interface exposed by OP-TEE to discover enumerated services + */ +#define PTA_DEVICE_ENUM { 0x7011a688, 0xddde, 0x4053, \ + { 0xa5, 0xa9, 0x7b, 0x3c, 0x4d, 0xdf, 0x13, 0xb8 } } +/* + * PTA_CMD_GET_DEVICES - List services without supplicant dependencies + * + * [out] memref[0]: List of the UUIDs of service enumerated by OP-TEE + */ +#define PTA_CMD_GET_DEVICES 0x0 + +/* + * PTA_CMD_GET_DEVICES_SUPP - List services depending on tee supplicant + * + * [out] memref[0]: List of the UUIDs of service enumerated by OP-TEE + */ +#define PTA_CMD_GET_DEVICES_SUPP 0x1 + typedef void (optee_invoke_fn)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, @@ -42,6 +62,134 @@ struct rpc_param { u32 a7; }; +static struct optee_service *find_service_driver(const struct tee_optee_ta_uuid *uuid) +{ + struct optee_service *service; + u8 loc_uuid[TEE_UUID_LEN]; + size_t service_cnt, idx; + + service_cnt = ll_entry_count(struct optee_service, optee_service); + service = ll_entry_start(struct optee_service, optee_service); + + for (idx = 0; idx < service_cnt; idx++, service++) { + tee_optee_ta_uuid_to_octets(loc_uuid, &service->uuid); + if (!memcmp(uuid, loc_uuid, sizeof(uuid))) + return service; + } + + return NULL; +} + +static int bind_service_list(struct udevice *dev, struct tee_shm *service_list, size_t count) +{ + const struct tee_optee_ta_uuid *service_uuid = (const void *)service_list->addr; + struct optee_service *service; + size_t idx; + int ret; + + for (idx = 0; idx < count; idx++) { + service = find_service_driver(service_uuid + idx); + if (!service) + continue; + + ret = device_bind_driver(dev, service->driver_name, service->driver_name, NULL); + if (ret) { + dev_warn(dev, "%s was not bound: %d, ignored\n", service->driver_name, ret); + continue; + } + } + + return 0; +} + +static int __enum_services(struct udevice *dev, struct tee_shm *shm, size_t *shm_size, u32 tee_sess) +{ + struct tee_invoke_arg arg = { }; + struct tee_param param = { }; + int ret = 0; + + arg.func = PTA_CMD_GET_DEVICES; + arg.session = tee_sess; + + /* Fill invoke cmd params */ + param.attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT; + param.u.memref.shm = shm; + param.u.memref.size = *shm_size; + + ret = tee_invoke_func(dev, &arg, 1, ¶m); + if (ret || (arg.ret && arg.ret != TEE_ERROR_SHORT_BUFFER)) { + dev_err(dev, "PTA_CMD_GET_DEVICES invoke function err: 0x%x\n", arg.ret); + return -EINVAL; + } + + *shm_size = param.u.memref.size; + + return 0; +} + +static int enum_services(struct udevice *dev, struct tee_shm **shm, size_t *count, u32 tee_sess) +{ + size_t shm_size = 0; + int ret; + + ret = __enum_services(dev, NULL, &shm_size, tee_sess); + if (ret) + return ret; + + ret = tee_shm_alloc(dev, shm_size, 0, shm); + if (ret) { + dev_err(dev, "Failed to allocated shared memory: %d\n", ret); + return ret; + } + + ret = __enum_services(dev, *shm, &shm_size, tee_sess); + if (!ret) + *count = shm_size / sizeof(struct tee_optee_ta_uuid); + + return ret; +} + +static int open_enum_session(struct udevice *dev, u32 *tee_sess) +{ + const struct tee_optee_ta_uuid pta_uuid = PTA_DEVICE_ENUM; + struct tee_open_session_arg arg = { }; + int ret; + + tee_optee_ta_uuid_to_octets(arg.uuid, &pta_uuid); + + ret = tee_open_session(dev, &arg, 0, NULL); + if (ret || arg.ret) { + if (!ret) + ret = -EIO; + return ret; + } + + *tee_sess = arg.session; + + return 0; +} + +static int bind_service_drivers(struct udevice *dev) +{ + struct tee_shm *service_list = NULL; + size_t service_count; + u32 tee_sess; + int ret; + + ret = open_enum_session(dev, &tee_sess); + if (ret) + return ret; + + ret = enum_services(dev, &service_list, &service_count, tee_sess); + if (!ret) + ret = bind_service_list(dev, service_list, service_count); + + tee_shm_free(service_list); + tee_close_session(dev, tee_sess); + + return ret; +} + /** * reg_pair_to_ptr() - Make a pointer of 2 32-bit values * @reg0: High bits of the pointer @@ -638,11 +786,18 @@ static int optee_of_to_plat(struct udevice *dev) return 0; } +static int optee_bind(struct udevice *dev) +{ + if (IS_ENABLED(CONFIG_OPTEE_SERVICE_DISCOVERY)) + dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND); + + return 0; +} + static int optee_probe(struct udevice *dev) { struct optee_pdata *pdata = dev_get_plat(dev); u32 sec_caps; - struct udevice *child; int ret; if (!is_optee_api(pdata->invoke_fn)) { @@ -668,12 +823,16 @@ static int optee_probe(struct udevice *dev) return -ENOENT; } - /* - * in U-Boot, the discovery of TA on the TEE bus is not supported: - * only bind the drivers associated to the supported OP-TEE TA - */ - if (IS_ENABLED(CONFIG_RNG_OPTEE)) { - ret = device_bind_driver(dev, "optee-rng", "optee-rng", &child); + if (IS_ENABLED(CONFIG_OPTEE_SERVICE_DISCOVERY)) { + ret = bind_service_drivers(dev); + if (ret) + return ret; + } else if (IS_ENABLED(CONFIG_RNG_OPTEE)) { + /* + * Discovery of TAs on the TEE bus is not supported in U-Boot: + * only bind the drivers associated to the supported OP-TEE TA + */ + ret = device_bind_driver(dev, "optee-rng", "optee-rng", NULL); if (ret) return ret; } @@ -692,6 +851,7 @@ U_BOOT_DRIVER(optee) = { .of_match = optee_match, .of_to_plat = optee_of_to_plat, .probe = optee_probe, + .bind = optee_bind, .ops = &optee_ops, .plat_auto = sizeof(struct optee_pdata), .priv_auto = sizeof(struct optee_private), diff --git a/drivers/tee/optee/rpmb.c b/drivers/tee/optee/rpmb.c index cf5e0a08e6..5bc13757ea 100644 --- a/drivers/tee/optee/rpmb.c +++ b/drivers/tee/optee/rpmb.c @@ -48,7 +48,7 @@ static void release_mmc(struct optee_private *priv) if (!priv->rpmb_mmc) return; - rc = blk_select_hwpart_devnum(IF_TYPE_MMC, priv->rpmb_dev_id, + rc = blk_select_hwpart_devnum(UCLASS_MMC, priv->rpmb_dev_id, priv->rpmb_original_part); if (rc) debug("%s: blk_select_hwpart_devnum() failed: %d\n", @@ -88,7 +88,7 @@ static struct mmc *get_mmc(struct optee_private *priv, int dev_id) priv->rpmb_original_part = mmc_get_blk_desc(mmc)->hwpart; - rc = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_id, MMC_PART_RPMB); + rc = blk_select_hwpart_devnum(UCLASS_MMC, dev_id, MMC_PART_RPMB); if (rc) { debug("Device id %d: cannot select RPMB partition: %d\n", dev_id, rc); diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 4049290148..fd8745ffc2 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -73,6 +73,12 @@ config ARC_TIMER usually at least one of them exists. Either of them is supported in U-Boot. +config ARM_TWD_TIMER + bool "ARM timer watchdog (TWD) timer support" + depends on TIMER && CLK + help + Select this to enable support for the ARM global timer watchdog timer. + config AST_TIMER bool "Aspeed ast2400/ast2500 timer support" depends on TIMER @@ -197,8 +203,11 @@ config OMAP_TIMER config ORION_TIMER bool "Orion timer support" depends on TIMER + default y if ARCH_KIRKWOOD || (ARCH_MVEBU && ARMADA_32BIT) + select TIMER_EARLY if ARCH_MVEBU help - Select this to enable an timer for Orion devices. + Select this to enable an timer for Orion and Armada devices + like Armada XP etc. config RISCV_TIMER bool "RISC-V timer support" diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile index 560e2d27e1..7bfb7749e9 100644 --- a/drivers/timer/Makefile +++ b/drivers/timer/Makefile @@ -6,6 +6,7 @@ obj-y += timer-uclass.o obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o obj-$(CONFIG_ANDES_PLMT_TIMER) += andes_plmt_timer.o obj-$(CONFIG_ARC_TIMER) += arc_timer.o +obj-$(CONFIG_ARM_TWD_TIMER) += arm_twd_timer.o obj-$(CONFIG_AST_TIMER) += ast_timer.o obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o obj-$(CONFIG_$(SPL_)ATMEL_PIT_TIMER) += atmel_pit_timer.o diff --git a/drivers/timer/arm_twd_timer.c b/drivers/timer/arm_twd_timer.c new file mode 100644 index 0000000000..40ccd16587 --- /dev/null +++ b/drivers/timer/arm_twd_timer.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017-2022 Weidmüller Interface GmbH & Co. KG + * Stefan Herbrechtsmeier + * + * Copyright (C) 2012 Michal Simek + * Copyright (C) 2011-2017 Xilinx, Inc. All rights reserved. + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2003 + * Texas Instruments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + */ + +#include +#include +#include +#include +#include + +#include + +#define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */ +#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002 /* Auto-reload */ +#define SCUTIMER_CONTROL_ENABLE_MASK 0x00000001 /* Timer enable */ + +#define TIMER_LOAD_VAL 0xFFFFFFFF + +struct arm_twd_timer_regs { + u32 load; /* Timer Load Register */ + u32 counter; /* Timer Counter Register */ + u32 control; /* Timer Control Register */ +}; + +struct arm_twd_timer_priv { + struct arm_twd_timer_regs *base; +}; + +static u64 arm_twd_timer_get_count(struct udevice *dev) +{ + struct arm_twd_timer_priv *priv = dev_get_priv(dev); + struct arm_twd_timer_regs *regs = priv->base; + u32 count = TIMER_LOAD_VAL - readl(®s->counter); + + return timer_conv_64(count); +} + +static int arm_twd_timer_probe(struct udevice *dev) +{ + struct arm_twd_timer_priv *priv = dev_get_priv(dev); + struct arm_twd_timer_regs *regs; + fdt_addr_t addr; + + addr = dev_read_addr(dev); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->base = (struct arm_twd_timer_regs *)addr; + + regs = priv->base; + + /* Load the timer counter register */ + writel(0xFFFFFFFF, ®s->load); + + /* + * Start the A9Timer device + * Enable Auto reload mode, Clear prescaler control bits + * Set prescaler value, Enable the decrementer + */ + clrsetbits_le32(®s->control, SCUTIMER_CONTROL_PRESCALER_MASK, + SCUTIMER_CONTROL_AUTO_RELOAD_MASK | + SCUTIMER_CONTROL_ENABLE_MASK); + + return 0; +} + +static const struct timer_ops arm_twd_timer_ops = { + .get_count = arm_twd_timer_get_count, +}; + +static const struct udevice_id arm_twd_timer_ids[] = { + { .compatible = "arm,cortex-a9-twd-timer" }, + {} +}; + +U_BOOT_DRIVER(arm_twd_timer) = { + .name = "arm_twd_timer", + .id = UCLASS_TIMER, + .of_match = arm_twd_timer_ids, + .priv_auto = sizeof(struct arm_twd_timer_priv), + .probe = arm_twd_timer_probe, + .ops = &arm_twd_timer_ops, +}; diff --git a/drivers/timer/mpc83xx_timer.c b/drivers/timer/mpc83xx_timer.c index 952293195f..410bf723d6 100644 --- a/drivers/timer/mpc83xx_timer.c +++ b/drivers/timer/mpc83xx_timer.c @@ -176,7 +176,7 @@ void timer_interrupt(struct pt_regs *regs) #if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG) if (CONFIG_SYS_WATCHDOG_FREQ && (priv->timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0) - WATCHDOG_RESET(); + schedule(); #endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ #ifdef CONFIG_LED_STATUS @@ -189,7 +189,7 @@ void wait_ticks(ulong ticks) ulong end = get_ticks() + ticks; while (end > get_ticks()) - WATCHDOG_RESET(); + schedule(); } static u64 mpc83xx_timer_get_count(struct udevice *dev) diff --git a/drivers/timer/mtk_timer.c b/drivers/timer/mtk_timer.c index f6b97f868c..223e63f6c1 100644 --- a/drivers/timer/mtk_timer.c +++ b/drivers/timer/mtk_timer.c @@ -13,24 +13,32 @@ #include #include -#define MTK_GPT4_CTRL 0x40 -#define MTK_GPT4_CLK 0x44 -#define MTK_GPT4_CNT 0x48 +#define MTK_GPT4_OFFSET_V1 0x40 +#define MTK_GPT4_OFFSET_V2 0x80 -#define GPT4_ENABLE BIT(0) -#define GPT4_CLEAR BIT(1) -#define GPT4_FREERUN GENMASK(5, 4) -#define GPT4_CLK_SYS 0x0 -#define GPT4_CLK_DIV1 0x0 +#define MTK_GPT_CON 0x0 +#define MTK_GPT_V1_CLK 0x4 +#define MTK_GPT_CNT 0x8 + +#define GPT_ENABLE BIT(0) +#define GPT_CLEAR BIT(1) +#define GPT_V1_FREERUN GENMASK(5, 4) +#define GPT_V2_FREERUN GENMASK(6, 5) + +enum mtk_gpt_ver { + MTK_GPT_V1, + MTK_GPT_V2 +}; struct mtk_timer_priv { void __iomem *base; + unsigned int gpt4_offset; }; static u64 mtk_timer_get_count(struct udevice *dev) { struct mtk_timer_priv *priv = dev_get_priv(dev); - u32 val = readl(priv->base + MTK_GPT4_CNT); + u32 val = readl(priv->base + priv->gpt4_offset + MTK_GPT_CNT); return timer_conv_64(val); } @@ -40,12 +48,27 @@ static int mtk_timer_probe(struct udevice *dev) struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct mtk_timer_priv *priv = dev_get_priv(dev); struct clk clk, parent; - int ret; + int ret, gpt_ver; priv->base = dev_read_addr_ptr(dev); + gpt_ver = dev_get_driver_data(dev); + if (!priv->base) return -ENOENT; + if (gpt_ver == MTK_GPT_V2) { + priv->gpt4_offset = MTK_GPT4_OFFSET_V2; + + writel(GPT_V2_FREERUN | GPT_CLEAR | GPT_ENABLE, + priv->base + priv->gpt4_offset + MTK_GPT_CON); + } else { + priv->gpt4_offset = MTK_GPT4_OFFSET_V1; + + writel(GPT_V1_FREERUN | GPT_CLEAR | GPT_ENABLE, + priv->base + priv->gpt4_offset + MTK_GPT_CON); + writel(0, priv->base + priv->gpt4_offset + MTK_GPT_V1_CLK); + } + ret = clk_get_by_index(dev, 0, &clk); if (ret) return ret; @@ -61,16 +84,6 @@ static int mtk_timer_probe(struct udevice *dev) if (!uc_priv->clock_rate) return -EINVAL; - /* - * Initialize the timer: - * 1. set clock source to system clock with clock divider setting to 1 - * 2. set timer mode to free running - * 3. reset timer counter to 0 then enable the timer - */ - writel(GPT4_CLK_SYS | GPT4_CLK_DIV1, priv->base + MTK_GPT4_CLK); - writel(GPT4_FREERUN | GPT4_CLEAR | GPT4_ENABLE, - priv->base + MTK_GPT4_CTRL); - return 0; } @@ -79,8 +92,10 @@ static const struct timer_ops mtk_timer_ops = { }; static const struct udevice_id mtk_timer_ids[] = { - { .compatible = "mediatek,timer" }, - { .compatible = "mediatek,mt6577-timer" }, + { .compatible = "mediatek,timer", .data = MTK_GPT_V1 }, + { .compatible = "mediatek,mt6577-timer", .data = MTK_GPT_V1 }, + { .compatible = "mediatek,mt7981-timer", .data = MTK_GPT_V2 }, + { .compatible = "mediatek,mt7986-timer", .data = MTK_GPT_V2 }, { } }; diff --git a/drivers/timer/orion-timer.c b/drivers/timer/orion-timer.c index d7d1a1b244..cd63ea9162 100644 --- a/drivers/timer/orion-timer.c +++ b/drivers/timer/orion-timer.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ #include #include +#include #include #include #include @@ -11,20 +12,100 @@ #define TIMER0_RELOAD 0x10 #define TIMER0_VAL 0x14 +enum input_clock_type { + INPUT_CLOCK_NON_FIXED, + INPUT_CLOCK_25MHZ, /* input clock rate is fixed to 25MHz */ +}; + struct orion_timer_priv { void *base; }; -static uint64_t orion_timer_get_count(struct udevice *dev) +#define MVEBU_TIMER_FIXED_RATE_25MHZ 25000000 + +static bool early_init_done __section(".data") = false; + +/* Common functions for early (boot) and DM based timer */ +static void orion_timer_init(void *base, enum input_clock_type type) +{ + writel(~0, base + TIMER0_VAL); + writel(~0, base + TIMER0_RELOAD); + + if (type == INPUT_CLOCK_25MHZ) { + /* + * On Armada XP / 38x ..., the 25MHz clock source needs to + * be enabled + */ + setbits_le32(base + TIMER_CTRL, BIT(11)); + } + + /* enable timer */ + setbits_le32(base + TIMER_CTRL, TIMER0_EN | TIMER0_RELOAD_EN); +} + +static uint64_t orion_timer_get_count(void *base) +{ + return timer_conv_64(~readl(base + TIMER0_VAL)); +} + +/* Early (e.g. bootstage etc) timer functions */ +static void notrace timer_early_init(void) +{ + /* Only init the timer once */ + if (early_init_done) + return; + early_init_done = true; + + if (IS_ENABLED(CONFIG_ARCH_MVEBU)) + orion_timer_init((void *)MVEBU_TIMER_BASE, INPUT_CLOCK_25MHZ); + else + orion_timer_init((void *)MVEBU_TIMER_BASE, INPUT_CLOCK_NON_FIXED); +} + +/** + * timer_early_get_rate() - Get the timer rate before driver model + */ +unsigned long notrace timer_early_get_rate(void) +{ + timer_early_init(); + + if (IS_ENABLED(CONFIG_ARCH_MVEBU)) + return MVEBU_TIMER_FIXED_RATE_25MHZ; + else + return CONFIG_SYS_TCLK; +} + +/** + * timer_early_get_count() - Get the timer count before driver model + * + */ +u64 notrace timer_early_get_count(void) +{ + timer_early_init(); + + return orion_timer_get_count((void *)MVEBU_TIMER_BASE); +} + +ulong timer_get_boot_us(void) +{ + u64 ticks; + + ticks = timer_early_get_count(); + return lldiv(ticks * 1000, timer_early_get_rate()); +} + +/* DM timer functions */ +static uint64_t dm_orion_timer_get_count(struct udevice *dev) { struct orion_timer_priv *priv = dev_get_priv(dev); - return timer_conv_64(~readl(priv->base + TIMER0_VAL)); + return orion_timer_get_count(priv->base); } static int orion_timer_probe(struct udevice *dev) { struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + enum input_clock_type type = dev_get_driver_data(dev); struct orion_timer_priv *priv = dev_get_priv(dev); priv->base = devfdt_remap_addr_index(dev, 0); @@ -33,23 +114,23 @@ static int orion_timer_probe(struct udevice *dev) return -ENOMEM; } - uc_priv->clock_rate = CONFIG_SYS_TCLK; - - writel(~0, priv->base + TIMER0_VAL); - writel(~0, priv->base + TIMER0_RELOAD); - - /* enable timer */ - setbits_le32(priv->base + TIMER_CTRL, TIMER0_EN | TIMER0_RELOAD_EN); + if (type == INPUT_CLOCK_25MHZ) + uc_priv->clock_rate = MVEBU_TIMER_FIXED_RATE_25MHZ; + else + uc_priv->clock_rate = CONFIG_SYS_TCLK; + orion_timer_init(priv->base, type); return 0; } static const struct timer_ops orion_timer_ops = { - .get_count = orion_timer_get_count, + .get_count = dm_orion_timer_get_count, }; static const struct udevice_id orion_timer_ids[] = { - { .compatible = "marvell,orion-timer" }, + { .compatible = "marvell,orion-timer", .data = INPUT_CLOCK_NON_FIXED }, + { .compatible = "marvell,armada-370-timer", .data = INPUT_CLOCK_25MHZ }, + { .compatible = "marvell,armada-xp-timer", .data = INPUT_CLOCK_25MHZ }, {} }; diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c index 01b2b41cce..2589c708d8 100644 --- a/drivers/usb/emul/sandbox_flash.c +++ b/drivers/usb/emul/sandbox_flash.c @@ -7,8 +7,10 @@ #include #include #include +#include #include #include +#include #include /* @@ -21,12 +23,7 @@ enum { SANDBOX_FLASH_EP_OUT = 1, /* endpoints */ SANDBOX_FLASH_EP_IN = 2, SANDBOX_FLASH_BLOCK_LEN = 512, -}; - -enum cmd_phase { - PHASE_START, - PHASE_DATA, - PHASE_STATUS, + SANDBOX_FLASH_BUF_SIZE = 512, }; enum { @@ -40,29 +37,19 @@ enum { /** * struct sandbox_flash_priv - private state for this driver * + * @eminfo: emulator state * @error: true if there is an error condition - * @alloc_len: Allocation length from the last incoming command - * @transfer_len: Transfer length from CBW header - * @read_len: Number of blocks of data left in the current read command * @tag: Tag value from last command * @fd: File descriptor of backing file * @file_size: Size of file in bytes * @status_buff: Data buffer for outgoing status - * @buff_used: Number of bytes ready to transfer back to host - * @buff: Data buffer for outgoing data */ struct sandbox_flash_priv { + struct scsi_emul_info eminfo; bool error; - int alloc_len; - int transfer_len; - int read_len; - enum cmd_phase phase; u32 tag; int fd; - loff_t file_size; struct umass_bbb_csw status; - int buff_used; - u8 buff[512]; }; struct sandbox_flash_plat { @@ -70,32 +57,6 @@ struct sandbox_flash_plat { struct usb_string flash_strings[STRINGID_COUNT]; }; -struct scsi_inquiry_resp { - u8 type; - u8 flags; - u8 version; - u8 data_format; - u8 additional_len; - u8 spare[3]; - char vendor[8]; - char product[16]; - char revision[4]; -}; - -struct scsi_read_capacity_resp { - u32 last_block_addr; - u32 block_len; -}; - -struct __packed scsi_read10_req { - u8 cmd; - u8 lun_flags; - u32 lba; - u8 spare; - u16 transfer_len; - u8 spare2[3]; -}; - static struct usb_device_descriptor flash_device_desc = { .bLength = sizeof(flash_device_desc), .bDescriptorType = USB_DT_DEVICE, @@ -200,7 +161,6 @@ static void setup_fail_response(struct sandbox_flash_priv *priv) csw->dCSWTag = priv->tag; csw->dCSWDataResidue = 0; csw->bCSWStatus = CSWSTATUS_FAILED; - priv->buff_used = 0; } /** @@ -210,8 +170,7 @@ static void setup_fail_response(struct sandbox_flash_priv *priv) * @resp: Response to send, or NULL if none * @size: Size of response */ -static void setup_response(struct sandbox_flash_priv *priv, void *resp, - int size) +static void setup_response(struct sandbox_flash_priv *priv) { struct umass_bbb_csw *csw = &priv->status; @@ -219,97 +178,45 @@ static void setup_response(struct sandbox_flash_priv *priv, void *resp, csw->dCSWTag = priv->tag; csw->dCSWDataResidue = 0; csw->bCSWStatus = CSWSTATUS_GOOD; - - assert(!resp || resp == priv->buff); - priv->buff_used = size; } -static void handle_read(struct sandbox_flash_priv *priv, ulong lba, - ulong transfer_len) +static int handle_ufi_command(struct sandbox_flash_priv *priv, const void *buff, + int len) { - debug("%s: lba=%lx, transfer_len=%lx\n", __func__, lba, transfer_len); - priv->read_len = transfer_len; - if (priv->fd != -1) { - os_lseek(priv->fd, lba * SANDBOX_FLASH_BLOCK_LEN, OS_SEEK_SET); - setup_response(priv, priv->buff, - transfer_len * SANDBOX_FLASH_BLOCK_LEN); + struct scsi_emul_info *info = &priv->eminfo; + const struct scsi_cmd *req = buff; + int ret; + + ret = sb_scsi_emul_command(info, req, len); + if (!ret) { + setup_response(priv); + } else if (ret == SCSI_EMUL_DO_READ && priv->fd != -1) { + os_lseek(priv->fd, info->seek_block * info->block_size, + OS_SEEK_SET); + setup_response(priv); } else { setup_fail_response(priv); } -} -static int handle_ufi_command(struct sandbox_flash_plat *plat, - struct sandbox_flash_priv *priv, const void *buff, - int len) -{ - const struct scsi_cmd *req = buff; - - switch (*req->cmd) { - case SCSI_INQUIRY: { - struct scsi_inquiry_resp *resp = (void *)priv->buff; - - priv->alloc_len = req->cmd[4]; - memset(resp, '\0', sizeof(*resp)); - resp->data_format = 1; - resp->additional_len = 0x1f; - strncpy(resp->vendor, - plat->flash_strings[STRINGID_MANUFACTURER - 1].s, - sizeof(resp->vendor)); - strncpy(resp->product, - plat->flash_strings[STRINGID_PRODUCT - 1].s, - sizeof(resp->product)); - strncpy(resp->revision, "1.0", sizeof(resp->revision)); - setup_response(priv, resp, sizeof(*resp)); - break; - } - case SCSI_TST_U_RDY: - setup_response(priv, NULL, 0); - break; - case SCSI_RD_CAPAC: { - struct scsi_read_capacity_resp *resp = (void *)priv->buff; - uint blocks; - - if (priv->file_size) - blocks = priv->file_size / SANDBOX_FLASH_BLOCK_LEN - 1; - else - blocks = 0; - resp->last_block_addr = cpu_to_be32(blocks); - resp->block_len = cpu_to_be32(SANDBOX_FLASH_BLOCK_LEN); - setup_response(priv, resp, sizeof(*resp)); - break; - } - case SCSI_READ10: { - struct scsi_read10_req *req = (void *)buff; - - handle_read(priv, be32_to_cpu(req->lba), - be16_to_cpu(req->transfer_len)); - break; - } - default: - debug("Command not supported: %x\n", req->cmd[0]); - return -EPROTONOSUPPORT; - } - - priv->phase = priv->transfer_len ? PHASE_DATA : PHASE_STATUS; return 0; } static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, unsigned long pipe, void *buff, int len) { - struct sandbox_flash_plat *plat = dev_get_plat(dev); struct sandbox_flash_priv *priv = dev_get_priv(dev); + struct scsi_emul_info *info = &priv->eminfo; int ep = usb_pipeendpoint(pipe); struct umass_bbb_cbw *cbw = buff; debug("%s: dev=%s, pipe=%lx, ep=%x, len=%x, phase=%d\n", __func__, - dev->name, pipe, ep, len, priv->phase); + dev->name, pipe, ep, len, info->phase); switch (ep) { case SANDBOX_FLASH_EP_OUT: - switch (priv->phase) { - case PHASE_START: - priv->alloc_len = 0; - priv->read_len = 0; + switch (info->phase) { + case SCSIPH_START: + info->alloc_len = 0; + info->read_len = 0; if (priv->error || len != UMASS_BBB_CBW_SIZE || cbw->dCBWSignature != CBWSIGNATURE) goto err; @@ -318,22 +225,22 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, goto err; if (cbw->bCDBLength < 1 || cbw->bCDBLength >= 0x10) goto err; - priv->transfer_len = cbw->dCBWDataTransferLength; + info->transfer_len = cbw->dCBWDataTransferLength; priv->tag = cbw->dCBWTag; - return handle_ufi_command(plat, priv, cbw->CBWCDB, + return handle_ufi_command(priv, cbw->CBWCDB, cbw->bCDBLength); - case PHASE_DATA: + case SCSIPH_DATA: debug("data out\n"); break; default: break; } case SANDBOX_FLASH_EP_IN: - switch (priv->phase) { - case PHASE_DATA: - debug("data in, len=%x, alloc_len=%x, priv->read_len=%x\n", - len, priv->alloc_len, priv->read_len); - if (priv->read_len) { + switch (info->phase) { + case SCSIPH_DATA: + debug("data in, len=%x, alloc_len=%x, info->read_len=%x\n", + len, info->alloc_len, info->read_len); + if (info->read_len) { ulong bytes_read; if (priv->fd == -1) @@ -342,24 +249,24 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, bytes_read = os_read(priv->fd, buff, len); if (bytes_read != len) return -EIO; - priv->read_len -= len / SANDBOX_FLASH_BLOCK_LEN; - if (!priv->read_len) - priv->phase = PHASE_STATUS; + info->read_len -= len / info->block_size; + if (!info->read_len) + info->phase = SCSIPH_STATUS; } else { - if (priv->alloc_len && len > priv->alloc_len) - len = priv->alloc_len; - if (len > sizeof(priv->buff)) - len = sizeof(priv->buff); - memcpy(buff, priv->buff, len); - priv->phase = PHASE_STATUS; + if (info->alloc_len && len > info->alloc_len) + len = info->alloc_len; + if (len > SANDBOX_FLASH_BUF_SIZE) + len = SANDBOX_FLASH_BUF_SIZE; + memcpy(buff, info->buff, len); + info->phase = SCSIPH_STATUS; } return len; - case PHASE_STATUS: + case SCSIPH_STATUS: debug("status in, len=%x\n", len); if (len > sizeof(priv->status)) len = sizeof(priv->status); memcpy(buff, &priv->status, len); - priv->phase = PHASE_START; + info->phase = SCSIPH_START; return len; default: break; @@ -400,10 +307,31 @@ static int sandbox_flash_probe(struct udevice *dev) { struct sandbox_flash_plat *plat = dev_get_plat(dev); struct sandbox_flash_priv *priv = dev_get_priv(dev); + struct scsi_emul_info *info = &priv->eminfo; + int ret; priv->fd = os_open(plat->pathname, OS_O_RDONLY); - if (priv->fd != -1) - return os_get_filesize(plat->pathname, &priv->file_size); + if (priv->fd != -1) { + ret = os_get_filesize(plat->pathname, &info->file_size); + if (ret) + return log_msg_ret("sz", ret); + } + info->buff = malloc(SANDBOX_FLASH_BUF_SIZE); + if (!info->buff) + return log_ret(-ENOMEM); + info->vendor = plat->flash_strings[STRINGID_MANUFACTURER - 1].s; + info->product = plat->flash_strings[STRINGID_PRODUCT - 1].s; + info->block_size = SANDBOX_FLASH_BLOCK_LEN; + + return 0; +} + +static int sandbox_flash_remove(struct udevice *dev) +{ + struct sandbox_flash_priv *priv = dev_get_priv(dev); + struct scsi_emul_info *info = &priv->eminfo; + + free(info->buff); return 0; } @@ -424,6 +352,7 @@ U_BOOT_DRIVER(usb_sandbox_flash) = { .of_match = sandbox_usb_flash_ids, .bind = sandbox_flash_bind, .probe = sandbox_flash_probe, + .remove = sandbox_flash_remove, .of_to_plat = sandbox_flash_of_to_plat, .ops = &sandbox_usb_flash_ops, .priv_auto = sizeof(struct sandbox_flash_priv), diff --git a/drivers/usb/eth/lan7x.h b/drivers/usb/eth/lan7x.h index f71e8c7268..9480f4f6d1 100644 --- a/drivers/usb/eth/lan7x.h +++ b/drivers/usb/eth/lan7x.h @@ -157,7 +157,7 @@ static inline int lan7x_wait_for_bit(struct usb_device *udev, } udelay(1); - WATCHDOG_RESET(); + schedule(); } debug("%s: Timeout (reg=0x%x mask=%08x wait_set=%i)\n", prefix, reg, @@ -199,7 +199,7 @@ static inline int lan7x_mdio_wait_for_bit(struct usb_device *udev, } udelay(1); - WATCHDOG_RESET(); + schedule(); } debug("%s: Timeout (reg=0x%x mask=%08x wait_set=%i)\n", prefix, reg, diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 388f73d1bc..b2ddd1ada8 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -579,7 +579,7 @@ static int acm_stdio_getc(struct stdio_dev *dev) /* Wait for a character to arrive. */ while (!acm_stdio_tstc(dev)) - WATCHDOG_RESET(); + schedule(); buf_pop(&f_acm->rx_buf, &c, 1); @@ -639,7 +639,7 @@ static int acm_stdio_start(struct stdio_dev *dev) if (ctrlc()) return -ECANCELED; - WATCHDOG_RESET(); + schedule(); } return 0; diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c index 0fa7230b99..af4b167e17 100644 --- a/drivers/usb/gadget/f_sdp.c +++ b/drivers/usb/gadget/f_sdp.c @@ -711,7 +711,7 @@ int sdp_init(int controller_index) return 1; } - WATCHDOG_RESET(); + schedule(); usb_gadget_handle_interrupts(controller_index); } @@ -835,7 +835,7 @@ static int sdp_handle_in_ep(struct spl_image_info *spl_image, printf("Found header at 0x%08x\n", sdp_func->jmp_address); - image_header_t *header = + struct legacy_img_hdr *header = sdp_ptr(sdp_func->jmp_address); #ifdef CONFIG_SPL_LOAD_FIT if (image_get_magic(header) == FDT_MAGIC) { @@ -927,7 +927,7 @@ int spl_sdp_handle(int controller_index, struct spl_image_info *spl_image, if (flag == SDP_EXIT) return 0; - WATCHDOG_RESET(); + schedule(); usb_gadget_handle_interrupts(controller_index); #ifdef CONFIG_SPL_BUILD diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f033198a7c..d30f2a0d13 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -641,7 +641,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, token = hc32_to_cpu(vtd->qt_token); if (!(QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)) break; - WATCHDOG_RESET(); + schedule(); } while (get_timer(ts) < timeout); qhtoken = hc32_to_cpu(qh->qh_overlay.qt_token); diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c index d186facc7e..62c5e8e5fa 100644 --- a/drivers/usb/musb-new/musb_uboot.c +++ b/drivers/usb/musb-new/musb_uboot.c @@ -378,7 +378,7 @@ static struct musb *gadget; int usb_gadget_handle_interrupts(int index) { - WATCHDOG_RESET(); + schedule(); if (!gadget || !gadget->isr) return -EINVAL; diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c index 4d2d961696..082895a50e 100644 --- a/drivers/video/video_bmp.c +++ b/drivers/video/video_bmp.c @@ -329,7 +329,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, byte_width = width; for (i = 0; i < height; ++i) { - WATCHDOG_RESET(); + schedule(); for (j = 0; j < width; j++) { write_pix8(fb, bpix, eformat, palette, bmap); bmap++; @@ -342,7 +342,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, case 16: if (IS_ENABLED(CONFIG_BMP_16BPP)) { for (i = 0; i < height; ++i) { - WATCHDOG_RESET(); + schedule(); for (j = 0; j < width; j++) { *fb++ = *bmap++; *fb++ = *bmap++; diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index 586263ec88..852f6735b6 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -64,7 +64,6 @@ config VIRTIO_NET config VIRTIO_BLK bool "virtio block driver" depends on VIRTIO - depends on BLK help This is the virtual block driver for virtio. It can be used with QEMU based targets. diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c index 3ff74f4a97..30cfc56725 100644 --- a/drivers/virtio/virtio_blk.c +++ b/drivers/virtio/virtio_blk.c @@ -75,14 +75,14 @@ static int virtio_blk_bind(struct udevice *dev) struct blk_desc *desc = dev_get_uclass_plat(dev); int devnum; - desc->if_type = IF_TYPE_VIRTIO; + desc->uclass_id = UCLASS_VIRTIO; /* * Initialize the devnum to -ENODEV. This is to make sure that * blk_next_free_devnum() works as expected, since the default * value 0 is a valid devnum. */ desc->devnum = -ENODEV; - devnum = blk_next_free_devnum(IF_TYPE_VIRTIO); + devnum = blk_next_free_devnum(UCLASS_VIRTIO); if (devnum < 0) return devnum; desc->devnum = devnum; diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c index 880a12cc28..cfde4007f5 100644 --- a/drivers/virtio/virtio_pci_modern.c +++ b/drivers/virtio/virtio_pci_modern.c @@ -466,7 +466,7 @@ static void __iomem *virtio_pci_map_capability(struct udevice *udev, unsigned long mask = PCI_REGION_TYPE | PCI_REGION_SYS_MEMORY | PCI_REGION_RO; unsigned long flags = PCI_REGION_MEM; - u8 *p = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0 + cap->bar, cap->offset, + u8 *p = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0 + 4 * cap->bar, cap->offset, cap->length, mask, flags); return (void __iomem *)p; diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 50e6a1efba..e55deaf906 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -3,6 +3,7 @@ menu "Watchdog Timer Support" config WATCHDOG bool "Enable U-Boot watchdog reset" depends on !HW_WATCHDOG + select CYCLIC help This option enables U-Boot watchdog support where U-Boot is using watchdog_reset function to service watchdog device in U-Boot. Enable @@ -74,6 +75,7 @@ config WDT bool "Enable driver model for watchdog timer drivers" depends on DM imply WATCHDOG + select CYCLIC help Enable driver model for watchdog timer. At the moment the API is very simple and only supports four operations: diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c index b098b2e3cf..368b36849c 100644 --- a/drivers/watchdog/mtk_wdt.c +++ b/drivers/watchdog/mtk_wdt.c @@ -145,6 +145,7 @@ static const struct wdt_ops mtk_wdt_ops = { static const struct udevice_id mtk_wdt_ids[] = { { .compatible = "mediatek,wdt"}, { .compatible = "mediatek,mt6589-wdt"}, + { .compatible = "mediatek,mt7986-wdt" }, {} }; diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c index dbf556467d..3f342cd99f 100644 --- a/drivers/watchdog/wdt-uclass.c +++ b/drivers/watchdog/wdt-uclass.c @@ -6,6 +6,7 @@ #define LOG_CATEGORY UCLASS_WDT #include +#include #include #include #include @@ -38,8 +39,25 @@ struct wdt_priv { bool running; /* No autostart */ bool noautostart; + + struct cyclic_info *cyclic; }; +static void wdt_cyclic(void *ctx) +{ + struct udevice *dev = ctx; + struct wdt_priv *priv; + + if (!device_active(dev)) + return; + + priv = dev_get_uclass_priv(dev); + if (!priv->running) + return; + + wdt_reset(dev); +} + static void init_watchdog_dev(struct udevice *dev) { struct wdt_priv *priv; @@ -64,9 +82,6 @@ static void init_watchdog_dev(struct udevice *dev) printf("WDT: Failed to start %s\n", dev->name); return; } - - printf("WDT: Started %s with%s servicing (%ds timeout)\n", dev->name, - IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out", priv->timeout); } int initr_watchdog(void) @@ -105,8 +120,29 @@ int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) ret = ops->start(dev, timeout_ms, flags); if (ret == 0) { struct wdt_priv *priv = dev_get_uclass_priv(dev); + char str[16]; priv->running = true; + + memset(str, 0, 16); + if (IS_ENABLED(CONFIG_WATCHDOG)) { + /* Register the watchdog driver as a cyclic function */ + priv->cyclic = cyclic_register(wdt_cyclic, + priv->reset_period * 1000, + dev->name, dev); + if (!priv->cyclic) { + printf("cyclic_register for %s failed\n", + dev->name); + return -ENODEV; + } else { + snprintf(str, 16, "every %ldms", + priv->reset_period); + } + } + + printf("WDT: Started %s with%s servicing %s (%ds timeout)\n", + dev->name, IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out", + str, priv->timeout); } return ret; @@ -194,37 +230,10 @@ int wdt_expire_now(struct udevice *dev, ulong flags) */ void watchdog_reset(void) { - struct wdt_priv *priv; - struct udevice *dev; - struct uclass *uc; - ulong now; - - /* Exit if GD is not ready or watchdog is not initialized yet */ - if (!gd || !(gd->flags & GD_FLG_WDT_READY)) - return; - - if (uclass_get(UCLASS_WDT, &uc)) - return; - /* - * All devices bound to the wdt uclass should have been probed - * in initr_watchdog(). But just in case something went wrong, - * check device_active() before accessing the uclass private - * data. + * Empty function for now. The actual WDT handling is now done in + * the cyclic function instead. */ - uclass_foreach_dev(dev, uc) { - if (!device_active(dev)) - continue; - priv = dev_get_uclass_priv(dev); - if (!priv->running) - continue; - /* Do not reset the watchdog too often */ - now = get_timer(0); - if (time_after_eq(now, priv->next_reset)) { - priv->next_reset = now + priv->reset_period; - wdt_reset(dev); - } - } } #endif diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 6ad2a93668..0ee74d036c 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -2,7 +2,6 @@ config PVBLOCK bool "Xen para-virtualized block device" depends on DM select BLK - select HAVE_BLOCK_DEVICE help This driver implements the front-end of the Xen virtual block device driver. It communicates with a back-end driver diff --git a/drivers/xen/pvblock.c b/drivers/xen/pvblock.c index c25c3ea4ff..970182cd90 100644 --- a/drivers/xen/pvblock.c +++ b/drivers/xen/pvblock.c @@ -665,14 +665,14 @@ static int pvblock_blk_bind(struct udevice *udev) struct blk_desc *desc = dev_get_uclass_plat(udev); int devnum; - desc->if_type = IF_TYPE_PVBLOCK; + desc->uclass_id = UCLASS_PVBLOCK; /* * Initialize the devnum to -ENODEV. This is to make sure that * blk_next_free_devnum() works as expected, since the default * value 0 is a valid devnum. */ desc->devnum = -ENODEV; - devnum = blk_next_free_devnum(IF_TYPE_PVBLOCK); + devnum = blk_next_free_devnum(UCLASS_PVBLOCK); if (devnum < 0) return devnum; desc->devnum = devnum; @@ -804,7 +804,7 @@ static void print_pvblock_devices(void) const char *class_name; class_name = uclass_get_name(UCLASS_PVBLOCK); - for (blk_first_device(IF_TYPE_PVBLOCK, &udev); udev; + for (blk_first_device(UCLASS_PVBLOCK, &udev); udev; blk_next_device(&udev), first = false) { struct blk_desc *desc = dev_get_uclass_plat(udev); diff --git a/env/Kconfig b/env/Kconfig index 238e4c70cf..24111dfaf4 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -558,7 +558,7 @@ config ENV_OFFSET default 0xF0000 if ARCH_SUNXI default 0xE0000 if ARCH_ZYNQ default 0x1E00000 if ARCH_ZYNQMP - default 0x7F40000 if ARCH_VERSAL + default 0x7F40000 if ARCH_VERSAL || ARCH_VERSAL_NET default 0 if ARC default 0x140000 if ARCH_AT91 default 0x260000 if ARCH_OMAP2PLUS @@ -570,6 +570,7 @@ config ENV_OFFSET_REDUND hex "Redundant environment offset" depends on (ENV_IS_IN_EEPROM || ENV_IS_IN_MMC || ENV_IS_IN_NAND || \ ENV_IS_IN_SPI_FLASH) && SYS_REDUNDAND_ENVIRONMENT + default 0x10C0000 if MICROBLAZE default 0 help Offset from the start of the device (or partition) of the redundant @@ -582,7 +583,7 @@ config ENV_SIZE default 0x10000 if ARCH_SUNXI default 0x8000 if ARCH_ROCKCHIP && ENV_IS_IN_MMC default 0x2000 if ARCH_ROCKCHIP && ENV_IS_IN_SPI_FLASH - default 0x8000 if ARCH_ZYNQMP || ARCH_VERSAL + default 0x8000 if ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET default 0x4000 if ARC default 0x1f000 help @@ -592,7 +593,7 @@ config ENV_SECT_SIZE hex "Environment Sector-Size" depends on ENV_IS_IN_FLASH || ENV_IS_IN_SPI_FLASH default 0x2000 if ARCH_ROCKCHIP - default 0x40000 if ARCH_ZYNQMP || ARCH_VERSAL + default 0x40000 if ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET default 0x20000 if ARCH_ZYNQ || ARCH_OMAP2PLUS || ARCH_AT91 default 0x20000 if MICROBLAZE && ENV_IS_IN_SPI_FLASH default 0x10000 if ARCH_SUNXI && ENV_IS_IN_SPI_FLASH diff --git a/env/common.c b/env/common.c index f9226e0690..8beb8e6aa4 100644 --- a/env/common.c +++ b/env/common.c @@ -115,7 +115,7 @@ char *env_get(const char *name) if (gd->flags & GD_FLG_ENV_READY) { /* after import into hashtable */ struct env_entry e, *ep; - WATCHDOG_RESET(); + schedule(); e.key = name; e.data = NULL; @@ -539,12 +539,12 @@ void env_import_fdt(void) return; } - for (res = ofnode_get_first_property(node, &prop); + for (res = ofnode_first_property(node, &prop); !res; - res = ofnode_get_next_property(&prop)) { + res = ofnode_next_property(&prop)) { const char *name, *val; - val = ofnode_get_property_by_prop(&prop, &name, NULL); + val = ofprop_get_property(&prop, &name, NULL); env_set(name, val); } } diff --git a/env/mmc.c b/env/mmc.c index 0c498d9a46..c28f4c6c6d 100644 --- a/env/mmc.c +++ b/env/mmc.c @@ -143,7 +143,7 @@ static int mmc_set_env_part(struct mmc *mmc, uint part) int dev = mmc_get_env_dev(); int ret = 0; - ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part); + ret = blk_select_hwpart_devnum(UCLASS_MMC, dev, part); if (ret) puts("MMC partition switch failed\n"); @@ -179,7 +179,7 @@ static void fini_mmc_for_env(struct mmc *mmc) #ifdef CONFIG_SYS_MMC_ENV_PART int dev = mmc_get_env_dev(); - blk_select_hwpart_devnum(IF_TYPE_MMC, dev, env_mmc_orig_hwpart); + blk_select_hwpart_devnum(UCLASS_MMC, dev, env_mmc_orig_hwpart); #endif } diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c index f431cc46c1..0d071b69f4 100644 --- a/fs/cramfs/uncompress.c +++ b/fs/cramfs/uncompress.c @@ -21,6 +21,7 @@ */ #include +#include #include #include #include @@ -62,7 +63,7 @@ int cramfs_uncompress_init (void) stream.avail_in = 0; #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - stream.outcb = (cb_func) WATCHDOG_RESET; + stream.outcb = (cb_func)cyclic_run; #else stream.outcb = Z_NULL; #endif /* CONFIG_HW_WATCHDOG */ diff --git a/fs/fat/fat.c b/fs/fat/fat.c index df9ea2c028..a945904785 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -1144,8 +1144,8 @@ int file_fat_detectfs(void) return 1; } - if (IS_ENABLED(CONFIG_HAVE_BLOCK_DEVICE)) { - printf("Interface: %s\n", blk_get_if_type_name(cur_dev->if_type)); + if (blk_enabled()) { + printf("Interface: %s\n", blk_get_uclass_name(cur_dev->uclass_id)); printf(" Device %d: ", cur_dev->devnum); dev_print(cur_dev); } diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index ef7b302725..49ba82ef95 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -1523,7 +1523,7 @@ jffs2_1pass_build_lists(struct part_info * part) /* Set buf_size to maximum length */ buf_size = DEFAULT_EMPTY_SCAN_SIZE; - WATCHDOG_RESET(); + schedule(); #ifdef CONFIG_JFFS2_SUMMARY buf_len = sizeof(*sm); diff --git a/include/_exports.h b/include/_exports.h index f6df8b6107..1af946fac3 100644 --- a/include/_exports.h +++ b/include/_exports.h @@ -12,6 +12,9 @@ EXPORT_FUNC(tstc, int, tstc, void) EXPORT_FUNC(putc, void, putc, const char) EXPORT_FUNC(puts, void, puts, const char *) +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT + EXPORT_FUNC(flush, void, flush, void) +#endif EXPORT_FUNC(printf, int, printf, const char*, ...) #if (defined(CONFIG_X86) && !defined(CONFIG_X86_64)) || defined(CONFIG_PPC) EXPORT_FUNC(irq_install_handler, void, install_hdlr, diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 2a747d91e1..2d55fe2ac0 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -20,6 +20,7 @@ */ #ifndef __ASSEMBLY__ +#include #include #include #include @@ -477,6 +478,12 @@ struct global_data { * @event_state: Points to the current state of events */ struct event_state event_state; +#endif +#ifdef CONFIG_CYCLIC + /** + * @cyclic: cyclic driver data + */ + struct cyclic_drv *cyclic; #endif /** * @dmtag_list: List of DM tags @@ -639,6 +646,10 @@ enum gd_flags { * @GD_FLG_SMP_READY: SMP initialization is complete */ GD_FLG_SMP_READY = 0x80000, + /** + * @GD_FLG_FDT_CHANGED: Device tree change has been detected by tests + */ + GD_FLG_FDT_CHANGED = 0x100000, }; #endif /* __ASSEMBLY__ */ diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 81f63f06f1..0fcf70983f 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -127,6 +127,7 @@ struct gpio_desc { #define GPIOD_OPEN_SOURCE BIT(6) /* GPIO is open source type */ #define GPIOD_PULL_UP BIT(7) /* GPIO has pull-up enabled */ #define GPIOD_PULL_DOWN BIT(8) /* GPIO has pull-down enabled */ +#define GPIOD_IS_AF BIT(9) /* GPIO is an alternate function */ /* Flags for updating the above */ #define GPIOD_MASK_DIR (GPIOD_IS_OUT | GPIOD_IS_IN | \ diff --git a/include/blk.h b/include/blk.h index 9503369db8..8806c382d4 100644 --- a/include/blk.h +++ b/include/blk.h @@ -7,6 +7,7 @@ #ifndef BLK_H #define BLK_H +#include #include #ifdef CONFIG_SYS_64BIT_LBA @@ -21,26 +22,10 @@ typedef ulong lbaint_t; struct udevice; -/* Interface types: */ -enum if_type { - IF_TYPE_UNKNOWN = 0, - IF_TYPE_IDE, - IF_TYPE_SCSI, - IF_TYPE_ATAPI, - IF_TYPE_USB, - IF_TYPE_DOC, - IF_TYPE_MMC, - IF_TYPE_SD, - IF_TYPE_SATA, - IF_TYPE_HOST, - IF_TYPE_NVME, - IF_TYPE_EFI_LOADER, - IF_TYPE_PVBLOCK, - IF_TYPE_VIRTIO, - IF_TYPE_EFI_MEDIA, - - IF_TYPE_COUNT, /* Number of interface types */ -}; +static inline bool blk_enabled(void) +{ + return CONFIG_IS_ENABLED(BLK) || IS_ENABLED(CONFIG_SPL_LEGACY_BLOCK); +} #define BLK_VEN_SIZE 40 #define BLK_PRD_SIZE 20 @@ -69,7 +54,7 @@ struct blk_desc { * TODO: With driver model we should be able to use the parent * device's uclass instead. */ - enum if_type if_type; /* type of the interface */ + enum uclass_id uclass_id; /* type of the interface */ int devnum; /* device number */ unsigned char part_type; /* partition type */ unsigned char target; /* target SCSI ID */ @@ -129,7 +114,7 @@ int blkcache_init(void); /** * blkcache_read() - attempt to read a set of blocks from cache * - * @param iftype - IF_TYPE_x for type of device + * @param iftype - uclass_id_x for type of device * @param dev - device index of particular type * @param start - starting block number * @param blkcnt - number of blocks to read @@ -146,7 +131,7 @@ int blkcache_read(int iftype, int dev, * blkcache_fill() - make data read from a block device available * to the block cache * - * @param iftype - IF_TYPE_x for type of device + * @param iftype - uclass_id_x for type of device * @param dev - device index of particular type * @param start - starting block number * @param blkcnt - number of blocks available @@ -162,7 +147,7 @@ void blkcache_fill(int iftype, int dev, * blkcache_invalidate() - discard the cache for a set of blocks * because of a write or device (re)initialization. * - * @param iftype - IF_TYPE_x for type of device + * @param iftype - uclass_id_x for type of device * @param dev - device index of particular type */ void blkcache_invalidate(int iftype, int dev); @@ -294,22 +279,22 @@ unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start, * This function does not activate the device. The device will be returned * whether or not it is activated. * - * @if_type: Interface type (enum if_type_t) + * @uclass_id: Interface type (enum uclass_id_t) * @devnum: Device number (specific to each interface type) * @devp: the device, if found * Return: 0 if found, -ENODEV if no device found, or other -ve error value */ -int blk_find_device(int if_type, int devnum, struct udevice **devp); +int blk_find_device(int uclass_id, int devnum, struct udevice **devp); /** * blk_get_device() - Find and probe a block device ready for use * - * @if_type: Interface type (enum if_type_t) + * @uclass_id: Interface type (enum uclass_id_t) * @devnum: Device number (specific to each interface type) * @devp: the device, if found * Return: 0 if found, -ENODEV if no device found, or other -ve error value */ -int blk_get_device(int if_type, int devnum, struct udevice **devp); +int blk_get_device(int uclass_id, int devnum, struct udevice **devp); /** * blk_first_device() - Find the first device for a given interface @@ -320,7 +305,7 @@ int blk_get_device(int if_type, int devnum, struct udevice **devp); * @devp: the device, if found * Return: 0 if found, -ENODEV if no device, or other -ve error value */ -int blk_first_device(int if_type, struct udevice **devp); +int blk_first_device(int uclass_id, struct udevice **devp); /** * blk_next_device() - Find the next device for a given interface @@ -342,7 +327,7 @@ int blk_next_device(struct udevice **devp); * @parent: Parent of the new device * @drv_name: Driver name to use for the block device * @name: Name for the device - * @if_type: Interface type (enum if_type_t) + * @uclass_id: Interface type (enum uclass_id_t) * @devnum: Device number, specific to the interface type, or -1 to * allocate the next available number * @blksz: Block size of the device in bytes (typically 512) @@ -350,7 +335,7 @@ int blk_next_device(struct udevice **devp); * @devp: the new device (which has not been probed) */ int blk_create_device(struct udevice *parent, const char *drv_name, - const char *name, int if_type, int devnum, int blksz, + const char *name, int uclass_id, int devnum, int blksz, lbaint_t lba, struct udevice **devp); /** @@ -359,7 +344,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name, * @parent: Parent of the new device * @drv_name: Driver name to use for the block device * @name: Name for the device (parent name is prepended) - * @if_type: Interface type (enum if_type_t) + * @uclass_id: Interface type (enum uclass_id_t) * @devnum: Device number, specific to the interface type, or -1 to * allocate the next available number * @blksz: Block size of the device in bytes (typically 512) @@ -367,7 +352,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name, * @devp: the new device (which has not been probed) */ int blk_create_devicef(struct udevice *parent, const char *drv_name, - const char *name, int if_type, int devnum, int blksz, + const char *name, int uclass_id, int devnum, int blksz, lbaint_t lba, struct udevice **devp); /** @@ -387,33 +372,33 @@ int blk_probe_or_unbind(struct udevice *dev); * * The devices are removed and then unbound. * - * @if_type: Interface type to unbind + * @uclass_id: Interface type to unbind * Return: 0 if OK, -ve on error */ -int blk_unbind_all(int if_type); +int blk_unbind_all(int uclass_id); /** * blk_find_max_devnum() - find the maximum device number for an interface type * - * Finds the last allocated device number for an interface type @if_type. The + * Finds the last allocated device number for an interface type @uclass_id. The * next number is safe to use for a newly allocated device. * - * @if_type: Interface type to scan + * @uclass_id: Interface type to scan * Return: maximum device number found, or -ENODEV if none, or other -ve on * error */ -int blk_find_max_devnum(enum if_type if_type); +int blk_find_max_devnum(enum uclass_id uclass_id); /** * blk_next_free_devnum() - get the next device number for an interface type * * Finds the next number that is safe to use for a newly allocated device for - * an interface type @if_type. + * an interface type @uclass_id. * - * @if_type: Interface type to scan + * @uclass_id: Interface type to scan * Return: next device number safe to use, or -ve on error */ -int blk_next_free_devnum(enum if_type if_type); +int blk_next_free_devnum(enum uclass_id uclass_id); /** * blk_select_hwpart() - select a hardware partition @@ -462,7 +447,7 @@ static inline ulong blk_dread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, void *buffer) { ulong blks_read; - if (blkcache_read(block_dev->if_type, block_dev->devnum, + if (blkcache_read(block_dev->uclass_id, block_dev->devnum, start, blkcnt, block_dev->blksz, buffer)) return blkcnt; @@ -473,7 +458,7 @@ static inline ulong blk_dread(struct blk_desc *block_dev, lbaint_t start, */ blks_read = block_dev->block_read(block_dev, start, blkcnt, buffer); if (blks_read == blkcnt) - blkcache_fill(block_dev->if_type, block_dev->devnum, + blkcache_fill(block_dev->uclass_id, block_dev->devnum, start, blkcnt, block_dev->blksz, buffer); return blks_read; @@ -482,14 +467,14 @@ static inline ulong blk_dread(struct blk_desc *block_dev, lbaint_t start, static inline ulong blk_dwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, const void *buffer) { - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return block_dev->block_write(block_dev, start, blkcnt, buffer); } static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) { - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return block_dev->block_erase(block_dev, start, blkcnt); } @@ -500,15 +485,15 @@ static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start, * driver should be provided using U_BOOT_LEGACY_BLK() for each interface * type that is to be supported. * - * @if_typename: Interface type name - * @if_type: Interface type + * @uclass_idname: Interface type name + * @uclass_id: Interface type * @max_devs: Maximum number of devices supported * @desc: Pointer to list of devices for this interface type, * or NULL to use @get_dev() instead */ struct blk_driver { - const char *if_typename; - enum if_type if_type; + const char *uclass_idname; + enum uclass_id uclass_id; int max_devs; struct blk_desc *desc; /** @@ -555,33 +540,33 @@ struct blk_driver { #define U_BOOT_LEGACY_BLK(__name) \ ll_entry_declare(struct blk_driver, __name, blk_driver) -struct blk_driver *blk_driver_lookup_type(int if_type); +struct blk_driver *blk_driver_lookup_type(int uclass_id); #endif /* !CONFIG_BLK */ /** - * blk_get_devnum_by_typename() - Get a block device by type and number + * blk_get_devnum_by_uclass_idname() - Get a block device by type and number * * This looks through the available block devices of the given type, returning * the one with the given @devnum. * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * Return: point to block device descriptor, or NULL if not found */ -struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum); +struct blk_desc *blk_get_devnum_by_uclass_id(enum uclass_id uclass_id, int devnum); /** - * blk_get_devnum_by_type() - Get a block device by type name, and number + * blk_get_devnum_by_uclass_id() - Get a block device by type name, and number * - * This looks up the block device type based on @if_typename, then calls - * blk_get_devnum_by_type(). + * This looks up the block device type based on @uclass_idname, then calls + * blk_get_devnum_by_uclass_id(). * - * @if_typename: Block device type name + * @uclass_idname: Block device type name * @devnum: Device number * Return: point to block device descriptor, or NULL if not found */ -struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, +struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname, int devnum); /** @@ -600,34 +585,34 @@ int blk_dselect_hwpart(struct blk_desc *desc, int hwpart); /** * blk_list_part() - list the partitions for block devices of a given type * - * This looks up the partition type for each block device of type @if_type, + * This looks up the partition type for each block device of type @uclass_id, * then displays a list of partitions. * - * @if_type: Block device type + * @uclass_id: Block device type * Return: 0 if OK, -ENODEV if there is none of that type */ -int blk_list_part(enum if_type if_type); +int blk_list_part(enum uclass_id uclass_id); /** * blk_list_devices() - list the block devices of a given type * - * This lists each block device of the type @if_type, showing the capacity + * This lists each block device of the type @uclass_id, showing the capacity * as well as type-specific information. * - * @if_type: Block device type + * @uclass_id: Block device type */ -void blk_list_devices(enum if_type if_type); +void blk_list_devices(enum uclass_id uclass_id); /** * blk_show_device() - show information about a given block device * * This shows the block device capacity as well as type-specific information. * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * Return: 0 if OK, -ENODEV for invalid device number */ -int blk_show_device(enum if_type if_type, int devnum); +int blk_show_device(enum uclass_id uclass_id, int devnum); /** * blk_print_device_num() - show information about a given block device @@ -635,45 +620,45 @@ int blk_show_device(enum if_type if_type, int devnum); * This is similar to blk_show_device() but returns an error if the block * device type is unknown. * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * Return: 0 if OK, -ENODEV for invalid device number, -ENOENT if the block * device is not connected */ -int blk_print_device_num(enum if_type if_type, int devnum); +int blk_print_device_num(enum uclass_id uclass_id, int devnum); /** * blk_print_part_devnum() - print the partition information for a device * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * Return: 0 if OK, -ENOENT if the block device is not connected, -ENOSYS if * the interface type is not supported, other -ve on other error */ -int blk_print_part_devnum(enum if_type if_type, int devnum); +int blk_print_part_devnum(enum uclass_id uclass_id, int devnum); /** * blk_read_devnum() - read blocks from a device * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * @blkcnt: Number of blocks to read * @buffer: Address to write data to * Return: number of blocks read, or -ve error number on error */ -ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start, +ulong blk_read_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, void *buffer); /** * blk_write_devnum() - write blocks to a device * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * @blkcnt: Number of blocks to write * @buffer: Address to read data from * Return: number of blocks written, or -ve error number on error */ -ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start, +ulong blk_write_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, const void *buffer); /** @@ -682,31 +667,31 @@ ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start, * This is similar to blk_dselect_hwpart() but it looks up the interface and * device number. * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * @hwpart: Partition number to select * Return: 0 if OK, -ve on error */ -int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart); +int blk_select_hwpart_devnum(enum uclass_id uclass_id, int devnum, int hwpart); /** - * blk_get_if_type_name() - Get the name of an interface type + * blk_get_uclass_name() - Get the name of an interface type * - * @if_type: Interface type to check + * @uclass_id: Interface type to check * Return: name of interface, or NULL if none */ -const char *blk_get_if_type_name(enum if_type if_type); +const char *blk_get_uclass_name(enum uclass_id uclass_id); /** * blk_common_cmd() - handle common commands with block devices * * @args: Number of arguments to the command (argv[0] is the command itself) * @argv: Command arguments - * @if_type: Interface type + * @uclass_id: Interface type * @cur_devnump: Current device number for this interface type * Return: 0 if OK, CMD_RET_ERROR on error */ -int blk_common_cmd(int argc, char *const argv[], enum if_type if_type, +int blk_common_cmd(int argc, char *const argv[], enum uclass_id uclass_id, int *cur_devnump); enum blk_flag_t { diff --git a/include/bootm.h b/include/bootm.h index 7ed5650fca..044a4797ed 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -33,7 +33,7 @@ struct cmd_tbl; * not return. */ typedef int boot_os_fn(int flag, int argc, char *const argv[], - bootm_headers_t *images); + struct bootm_headers *images); extern boot_os_fn do_bootm_linux; extern boot_os_fn do_bootm_vxworks; @@ -47,7 +47,7 @@ int bootm_host_load_images(const void *fit, int cfg_noffset); #endif int boot_selected_os(int argc, char *const argv[], int state, - bootm_headers_t *images, boot_os_fn *boot_fn); + struct bootm_headers *images, boot_os_fn *boot_fn); ulong bootm_disable_interrupts(void); @@ -56,7 +56,7 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, ulong size); int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], int states, bootm_headers_t *images, + char *const argv[], int states, struct bootm_headers *images, int boot_progress); void arch_preboot_os(void); diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index 5506f3168f..fcb319a20a 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -162,11 +162,13 @@ "scan_dev_for_efi=" \ "setenv efi_fdtfile ${fdtfile}; " \ BOOTENV_EFI_SET_FDTFILE_FALLBACK \ + BOOTENV_RUN_EXTENSION_INIT \ "for prefix in ${efi_dtb_prefixes}; do " \ "if test -e ${devtype} " \ "${devnum}:${distro_bootpart} " \ "${prefix}${efi_fdtfile}; then " \ "run load_efi_dtb; " \ + BOOTENV_RUN_EXTENSION_APPLY \ "fi;" \ "done;" \ "run boot_efi_bootmgr;" \ @@ -418,6 +420,34 @@ BOOT_TARGET_DEVICES_references_PXE_without_CONFIG_CMD_DHCP_or_PXE #endif +#if defined(CONFIG_CMD_EXTENSION) +#define BOOTENV_RUN_EXTENSION_INIT "run extension_init; " +#define BOOTENV_RUN_EXTENSION_APPLY "run extension_apply; " +#define BOOTENV_SET_EXTENSION_NEED_INIT \ + "extension_need_init=; " \ + "setenv extension_overlay_addr ${fdtoverlay_addr_r}; " +#define BOOTENV_SHARED_EXTENSION \ + "extension_init=" \ + "echo Extension init...; " \ + "if ${extension_need_init}; then " \ + "extension_need_init=false; " \ + "extension scan; " \ + "fi\0" \ + \ + "extension_overlay_cmd=" \ + "load ${devtype} ${devnum}:${distro_bootpart} " \ + "${extension_overlay_addr} ${prefix}${extension_overlay_name}\0" \ + "extension_apply=" \ + "if fdt addr -q ${fdt_addr_r}; then " \ + "extension apply all; " \ + "fi\0" +#else +#define BOOTENV_RUN_EXTENSION_INIT +#define BOOTENV_RUN_EXTENSION_APPLY +#define BOOTENV_SET_EXTENSION_NEED_INIT +#define BOOTENV_SHARED_EXTENSION +#endif + #define BOOTENV_DEV_NAME(devtypeu, devtypel, instance, ...) \ BOOTENV_DEV_NAME_##devtypeu(devtypeu, devtypel, instance, ## __VA_ARGS__) #define BOOTENV_BOOT_TARGETS \ @@ -437,6 +467,7 @@ BOOTENV_SHARED_UBIFS \ BOOTENV_SHARED_EFI \ BOOTENV_SHARED_VIRTIO \ + BOOTENV_SHARED_EXTENSION \ "boot_prefixes=/ /boot/\0" \ "boot_scripts=boot.scr.uimg boot.scr\0" \ "boot_script_dhcp=boot.scr.uimg\0" \ @@ -501,6 +532,7 @@ BOOTENV_SET_NVME_NEED_INIT \ BOOTENV_SET_IDE_NEED_INIT \ BOOTENV_SET_VIRTIO_NEED_INIT \ + BOOTENV_SET_EXTENSION_NEED_INIT \ "for target in ${boot_targets}; do " \ "run bootcmd_${target}; " \ "done\0" diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h index 0c710ef886..eb7a835179 100644 --- a/include/configs/MPC8548CDS.h +++ b/include/configs/MPC8548CDS.h @@ -255,9 +255,6 @@ #define CONFIG_SYS_I2C_NOPROBES { {0, 0x69} } #endif -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_CCID - /* * General PCI * Memory space is mapped 1-1, but I/O space must start from 0. diff --git a/include/configs/P1010RDB.h b/include/configs/P1010RDB.h index 7f5eaf88aa..8492a64d43 100644 --- a/include/configs/P1010RDB.h +++ b/include/configs/P1010RDB.h @@ -351,10 +351,6 @@ extern unsigned long get_sdram_size(void); /* I2C EEPROM */ #if defined(CONFIG_TARGET_P1010RDB_PB) -#ifdef CONFIG_ID_EEPROM -#define CONFIG_SYS_I2C_EEPROM_NXID -#endif -#define CONFIG_SYS_EEPROM_BUS_NUM 0 #define MAX_NUM_PORTS 9 /* for 128Bytes EEPROM */ #endif /* enable read and write access to EEPROM */ diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h index 11a3db5902..925720d234 100644 --- a/include/configs/P2041RDB.h +++ b/include/configs/P2041RDB.h @@ -67,10 +67,6 @@ #define CONFIG_SYS_DCSRBAR_PHYS 0xf00000000ull #endif -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * DDR Setup */ diff --git a/include/configs/T102xRDB.h b/include/configs/T102xRDB.h index a5461d7fc6..e0aa2b9598 100644 --- a/include/configs/T102xRDB.h +++ b/include/configs/T102xRDB.h @@ -112,10 +112,6 @@ #define CONFIG_SYS_DCSRBAR_PHYS 0xf00000000ull #endif -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * DDR Setup */ diff --git a/include/configs/T104xRDB.h b/include/configs/T104xRDB.h index 560083c5b3..918aabcbb5 100644 --- a/include/configs/T104xRDB.h +++ b/include/configs/T104xRDB.h @@ -292,11 +292,6 @@ #if defined(CONFIG_TARGET_T1042RDB_PI) || \ defined(CONFIG_TARGET_T1040D4RDB) || \ defined(CONFIG_TARGET_T1042D4RDB) -/* LDI/DVI Encoder for display */ -#define CONFIG_SYS_I2C_LDI_ADDR 0x38 -#define CONFIG_SYS_I2C_DVI_ADDR 0x75 -#define CONFIG_SYS_I2C_DVI_BUS_NUM 0 - /* * RTC configuration */ diff --git a/include/configs/T208xQDS.h b/include/configs/T208xQDS.h index fc068c94a9..e852fc4cdc 100644 --- a/include/configs/T208xQDS.h +++ b/include/configs/T208xQDS.h @@ -82,10 +82,6 @@ #define CONFIG_SYS_DCSRBAR 0xf0000000 #define CONFIG_SYS_DCSRBAR_PHYS 0xf00000000ull -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * DDR Setup */ diff --git a/include/configs/T208xRDB.h b/include/configs/T208xRDB.h index 056e2d1925..68cf13581a 100644 --- a/include/configs/T208xRDB.h +++ b/include/configs/T208xRDB.h @@ -77,10 +77,6 @@ #define CONFIG_SYS_DCSRBAR 0xf0000000 #define CONFIG_SYS_DCSRBAR_PHYS 0xf00000000ull -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * DDR Setup */ diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h index 87d3a27099..fc82a8c003 100644 --- a/include/configs/am43xx_evm.h +++ b/include/configs/am43xx_evm.h @@ -29,7 +29,6 @@ /* SPL defines. */ /* Enabling L2 Cache */ -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE 0x48242000 /* diff --git a/include/configs/brppt1.h b/include/configs/brppt1.h index 6cb1a10600..2c5236aa58 100644 --- a/include/configs/brppt1.h +++ b/include/configs/brppt1.h @@ -27,44 +27,18 @@ * the Linux kernel. */ -#ifdef CONFIG_SPL_OS_BOOT -/* RAW SD card / eMMC */ - -#endif /* CONFIG_SPL_OS_BOOT */ - -#ifdef CONFIG_MTD_RAW_NAND -#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE -#endif /* CONFIG_MTD_RAW_NAND */ - -#ifdef CONFIG_MTD_RAW_NAND -#define NANDTGTS \ -"cfgscr=mw ${dtbaddr} 0; nand read ${cfgaddr} cfgscr && source ${cfgaddr};" \ -" fdt addr ${dtbaddr} || cp ${fdtcontroladdr} ${dtbaddr} 4000\0" \ -"nandargs=setenv bootargs console=${console} ${optargs} ${optargs_rot} " \ - "root=mtd6 rootfstype=jffs2 b_mode=${b_mode}\0" \ -"b_nand=nand read ${loadaddr} kernel; nand read ${dtbaddr} dtb; " \ - "run nandargs; run cfgscr; bootz ${loadaddr} - ${dtbaddr}\0" \ -"b_tgts_std=usb0 nand net\0" \ -"b_tgts_rcy=net usb0 nand\0" \ -"b_tgts_pme=usb0 nand net\0" -#else -#define NANDTGTS "" -#endif /* CONFIG_MTD_RAW_NAND */ - -#define MMCSPI_TGTS \ +#define MMC_TGTS \ "t30args#0=setenv bootargs ${optargs_rot} ${optargs} console=${console} " \ - "b_mode=${b_mode} root=/dev/mmcblk0p2 rootfstype=ext4\0" \ + "b_mode=${b_mode} root=${root_dev} rootfstype=ext4 rootwait\0" \ "b_t30lgcy#0=" \ - "load ${loaddev}:2 ${loadaddr} /boot/PPTImage.md5 && " \ "load ${loaddev}:2 ${loadaddr} /boot/zImage && " \ - "load ${loaddev}:2 ${dtbaddr} /boot/am335x-ppt30.dtb || " \ - "load ${loaddev}:1 ${dtbaddr} am335x-ppt30-legacy.dtb; "\ + "run load_dtb && " \ "run t30args#0; run cfgscr; bootz ${loadaddr} - ${dtbaddr}\0" \ "t30args#1=setenv bootargs ${optargs_rot} ${optargs} console=${console} " \ "b_mode=${b_mode}\0" \ "b_t30lgcy#1=" \ "load ${loaddev}:1 ${loadaddr} zImage && " \ - "load ${loaddev}:1 ${dtbaddr} am335x-ppt30.dtb && " \ + "load ${loaddev}:1 ${dtbaddr} am335x-brppt30.dtb && " \ "load ${loaddev}:1 ${ramaddr} rootfsPPT30.uboot && " \ "run t30args#1; run cfgscr; bootz ${loadaddr} ${ramaddr} ${dtbaddr}\0" \ "b_mmc0=load ${loaddev}:1 ${scraddr} bootscr.img && source ${scraddr}\0" \ @@ -72,28 +46,25 @@ "b_tgts_std=mmc0 mmc1 t30lgcy#0 t30lgcy#1 usb0 net\0" \ "b_tgts_rcy=t30lgcy#1 usb0 net\0" \ "b_tgts_pme=net usb0 mmc0 mmc1\0" \ -"loaddev=mmc 1\0" +"loaddev=mmc 1\0" \ +"root_dev=/dev/mmcblk0p2\0" \ +"load_dtb=load ${loaddev}:2 ${dtbaddr} /boot/am335x-brppt30.dtb; " \ + "if test $? -eq 0; then " \ + "setenv root_dev /dev/mmcblk1p2; " \ + "else; " \ + "load ${loaddev}:1 ${dtbaddr} am335x-brppt30-legacy.dtb; " \ + "fi;\0" #ifdef CONFIG_ENV_IS_IN_MMC #define MMCTGTS \ -MMCSPI_TGTS \ -"cfgscr=mw ${dtbaddr} 0;" \ +MMC_TGTS \ +"cfgscr=mw ${cfgaddr} 0;" \ " mmc dev 1; mmc read ${cfgaddr} 200 80; source ${cfgaddr};" \ " fdt addr ${dtbaddr} || cp ${fdtcontroladdr} ${dtbaddr} 4000\0" #else #define MMCTGTS "" #endif /* CONFIG_MMC */ -#ifdef CONFIG_SPI -#define SPITGTS \ -MMCSPI_TGTS \ -"cfgscr=mw ${dtbaddr} 0;" \ -" sf probe; sf read ${cfgaddr} 0xC0000 10000; source ${cfgaddr};" \ -" fdt addr ${dtbaddr} || cp ${fdtcontroladdr} ${dtbaddr} 4000\0" -#else -#define SPITGTS "" -#endif /* CONFIG_SPI */ - #define LOAD_OFFSET(x) 0x8##x #define CONFIG_EXTRA_ENV_SETTINGS \ @@ -110,8 +81,6 @@ BUR_COMMON_ENV \ "b_usb0=usb start && load usb 0 ${scraddr} bootscr.img && source ${scraddr}\0" \ "b_net=tftp ${scraddr} netscript.img && source ${scraddr}\0" \ MMCTGTS \ -SPITGTS \ -NANDTGTS \ "b_deftgts=if test ${b_mode} = 12; then setenv b_tgts ${b_tgts_pme};" \ " elif test ${b_mode} = 0; then setenv b_tgts ${b_tgts_rcy};" \ " else setenv b_tgts ${b_tgts_std}; fi\0" \ @@ -119,28 +88,4 @@ NANDTGTS \ " do echo \"### booting ${target} ###\"; run b_${target};" \ " if test ${b_break} = 1; then; exit; fi; done\0" -#ifdef CONFIG_MTD_RAW_NAND -/* - * GPMC block. We support 1 device and the physical address to - * access CS0 at is 0x8000000. - */ -#define CONFIG_SYS_MAX_NAND_DEVICE 1 -#define CONFIG_SYS_NAND_BASE 0x8000000 -/* don't change OMAP_ELM, ECCSCHEME. ROM code only supports this */ -#define CONFIG_SYS_NAND_ECCPOS {2, 3, 4, 5, 6, 7, 8, 9, \ - 10, 11, 12, 13, 14, 15, 16, 17, \ - 18, 19, 20, 21, 22, 23, 24, 25, \ - 26, 27, 28, 29, 30, 31, 32, 33, \ - 34, 35, 36, 37, 38, 39, 40, 41, \ - 42, 43, 44, 45, 46, 47, 48, 49, \ - 50, 51, 52, 53, 54, 55, 56, 57, } - -#define CONFIG_SYS_NAND_ECCSIZE 512 -#define CONFIG_SYS_NAND_ECCBYTES 14 - -#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE - -#define CONFIG_NAND_OMAP_GPMC_WSCFG 1 -#endif /* CONFIG_MTD_RAW_NAND */ - #endif /* ! __CONFIG_BRPPT1_H__ */ diff --git a/include/configs/brppt2.h b/include/configs/brppt2.h index adaba410ce..0c7fe5f3ab 100644 --- a/include/configs/brppt2.h +++ b/include/configs/brppt2.h @@ -13,7 +13,6 @@ /* -- i.mx6 specifica -- */ #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE L2_PL310_BASE #endif /* !CONFIG_SYS_L2CACHE_OFF */ diff --git a/include/configs/cm_t43.h b/include/configs/cm_t43.h index 07c5cb8ded..50cb2a4718 100644 --- a/include/configs/cm_t43.h +++ b/include/configs/cm_t43.h @@ -36,7 +36,6 @@ #define CONFIG_POWER_TPS65218 /* Enabling L2 Cache */ -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE 0x48242000 /* diff --git a/include/configs/ls1012aqds.h b/include/configs/ls1012aqds.h index 48fe8288aa..9ad3a12011 100644 --- a/include/configs/ls1012aqds.h +++ b/include/configs/ls1012aqds.h @@ -49,10 +49,6 @@ #define RTC #define CONFIG_SYS_I2C_RTC_ADDR 0x51 /* Channel 3*/ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* Voltage monitor on channel 2*/ #define I2C_VOL_MONITOR_ADDR 0x40 diff --git a/include/configs/ls1021aiot.h b/include/configs/ls1021aiot.h index ec688741a0..f418c8ccf7 100644 --- a/include/configs/ls1021aiot.h +++ b/include/configs/ls1021aiot.h @@ -59,10 +59,6 @@ * I2C */ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * MMC */ diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h index aaf28a346d..d383b6c655 100644 --- a/include/configs/ls1021aqds.h +++ b/include/configs/ls1021aqds.h @@ -246,10 +246,6 @@ /* GPIO */ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * I2C bus multiplexer */ diff --git a/include/configs/ls1021atsn.h b/include/configs/ls1021atsn.h index f318eb5860..157f218a8e 100644 --- a/include/configs/ls1021atsn.h +++ b/include/configs/ls1021atsn.h @@ -71,10 +71,6 @@ /* I2C */ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* PCIe */ #define FSL_PCIE_COMPAT "fsl,ls1021a-pcie" diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h index 5f3e8d5b71..83c74b66d3 100644 --- a/include/configs/ls1021atwr.h +++ b/include/configs/ls1021atwr.h @@ -161,10 +161,6 @@ /* GPIO */ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 1 - #define CONFIG_PEN_ADDR_BIG_ENDIAN #define CONFIG_SMP_PEN_ADDR 0x01ee0200 diff --git a/include/configs/ls1028a_common.h b/include/configs/ls1028a_common.h index 8413e68f3a..24422665e8 100644 --- a/include/configs/ls1028a_common.h +++ b/include/configs/ls1028a_common.h @@ -63,10 +63,6 @@ #define I2C_MUX_PCA_ADDR_PRI 0x77 /* Primary Mux*/ #define I2C_MUX_CH_DEFAULT 0x8 -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* DisplayPort */ #define DP_PWD_EN_DEFAULT_MASK 0x8 diff --git a/include/configs/ls1043aqds.h b/include/configs/ls1043aqds.h index 49f6cd6be1..4158d15cc0 100644 --- a/include/configs/ls1043aqds.h +++ b/include/configs/ls1043aqds.h @@ -37,10 +37,6 @@ /* SATA */ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - #define CONFIG_SYS_SATA AHCI_BASE_ADDR /* diff --git a/include/configs/ls1043ardb.h b/include/configs/ls1043ardb.h index ff5da5d275..4bfe4e3ecd 100644 --- a/include/configs/ls1043ardb.h +++ b/include/configs/ls1043ardb.h @@ -184,12 +184,6 @@ #define CONFIG_SYS_CS2_FTIM2 CONFIG_SYS_CPLD_FTIM2 #define CONFIG_SYS_CS2_FTIM3 CONFIG_SYS_CPLD_FTIM3 -/* EEPROM */ -#ifndef SPL_NO_EEPROM -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 -#endif - /* * Environment */ diff --git a/include/configs/ls1046afrwy.h b/include/configs/ls1046afrwy.h index 43717cdd4e..2df5f3f6c0 100644 --- a/include/configs/ls1046afrwy.h +++ b/include/configs/ls1046afrwy.h @@ -59,8 +59,6 @@ #define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NAND_FTIM3 /* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 #define I2C_RETIMER_ADDR 0x18 /* I2C bus multiplexer */ diff --git a/include/configs/ls1046aqds.h b/include/configs/ls1046aqds.h index 869bbd7634..1f54e51645 100644 --- a/include/configs/ls1046aqds.h +++ b/include/configs/ls1046aqds.h @@ -54,10 +54,6 @@ #define CFG_LPUART_EN 0x2 #endif -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * IFC Definitions */ diff --git a/include/configs/ls1046ardb.h b/include/configs/ls1046ardb.h index 382d5c7646..5d329577a6 100644 --- a/include/configs/ls1046ardb.h +++ b/include/configs/ls1046ardb.h @@ -98,8 +98,6 @@ #define CONFIG_SYS_CS2_FTIM3 CONFIG_SYS_CPLD_FTIM3 /* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 #define I2C_RETIMER_ADDR 0x18 /* PMIC */ diff --git a/include/configs/ls1088aqds.h b/include/configs/ls1088aqds.h index 747ee9d442..2d3351e6b4 100644 --- a/include/configs/ls1088aqds.h +++ b/include/configs/ls1088aqds.h @@ -287,10 +287,6 @@ #define RTC #define CONFIG_SYS_I2C_RTC_ADDR 0x51 /* Channel 3*/ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - #ifdef CONFIG_FSL_DSPI #if !defined(CONFIG_TFABOOT) && \ !defined(CONFIG_QSPI_BOOT) && !defined(CONFIG_SD_BOOT_QSPI) diff --git a/include/configs/ls1088ardb.h b/include/configs/ls1088ardb.h index 3e829ea865..d98ed39812 100644 --- a/include/configs/ls1088ardb.h +++ b/include/configs/ls1088ardb.h @@ -198,10 +198,6 @@ #define CONFIG_SYS_I2C_RTC_ADDR 0x51 /* Channel 3*/ #endif -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - #ifndef SPL_NO_ENV /* Initial environment variables */ #ifdef CONFIG_TFABOOT diff --git a/include/configs/ls2080aqds.h b/include/configs/ls2080aqds.h index 6487397f65..d02d7fc588 100644 --- a/include/configs/ls2080aqds.h +++ b/include/configs/ls2080aqds.h @@ -235,10 +235,6 @@ #define CONFIG_RTC_DS3231 1 #define CONFIG_SYS_I2C_RTC_ADDR 0x68 -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* Initial environment variables */ #undef CONFIG_EXTRA_ENV_SETTINGS #ifdef CONFIG_NXP_ESBC diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h index 87d07b765c..09484dc609 100644 --- a/include/configs/ls2080ardb.h +++ b/include/configs/ls2080ardb.h @@ -222,10 +222,6 @@ #define CONFIG_SYS_I2C_RTC_ADDR 0x68 #endif -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - #define BOOT_TARGET_DEVICES(func) \ func(USB, usb, 0) \ func(MMC, mmc, 0) \ diff --git a/include/configs/lx2160a_common.h b/include/configs/lx2160a_common.h index d39c0032c4..ed69b85758 100644 --- a/include/configs/lx2160a_common.h +++ b/include/configs/lx2160a_common.h @@ -78,10 +78,6 @@ #define RTC #define CONFIG_SYS_I2C_RTC_ADDR 0x51 /* Channel 3*/ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* Qixis */ #define CONFIG_SYS_I2C_FPGA_ADDR 0x66 diff --git a/include/configs/lx2160aqds.h b/include/configs/lx2160aqds.h index 585aab26bf..4e8a904859 100644 --- a/include/configs/lx2160aqds.h +++ b/include/configs/lx2160aqds.h @@ -13,10 +13,6 @@ /* MAC/PHY configuration */ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* Initial environment variables */ #define CONFIG_EXTRA_ENV_SETTINGS \ EXTRA_ENV_SETTINGS \ diff --git a/include/configs/lx2160ardb.h b/include/configs/lx2160ardb.h index 5c4ea27787..bb9239cc59 100644 --- a/include/configs/lx2160ardb.h +++ b/include/configs/lx2160ardb.h @@ -17,10 +17,6 @@ #define I2C_EMC2305_CMD 0x40 #define I2C_EMC2305_PWM 0x80 -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* Initial environment variables */ #define CONFIG_EXTRA_ENV_SETTINGS \ EXTRA_ENV_SETTINGS \ diff --git a/include/configs/lx2162aqds.h b/include/configs/lx2162aqds.h index d1ae403473..b70abb013f 100644 --- a/include/configs/lx2162aqds.h +++ b/include/configs/lx2162aqds.h @@ -13,10 +13,6 @@ /* RTC */ #define CONFIG_SYS_RTC_BUS_NUM 0 -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* Initial environment variables */ #define CONFIG_EXTRA_ENV_SETTINGS \ EXTRA_ENV_SETTINGS \ diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 8eaac4f8bc..dfae8cea7b 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -97,10 +97,4 @@ #define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE -/* SP location before relocation, must use scratch RAM */ -/* BRAM start */ -#define CONFIG_SYS_INIT_RAM_ADDR 0x0 -/* BRAM size - will be generated */ -#define CONFIG_SYS_INIT_RAM_SIZE 0x100000 - #endif /* __CONFIG_H */ diff --git a/include/configs/mt7981.h b/include/configs/mt7981.h new file mode 100644 index 0000000000..01ad309608 --- /dev/null +++ b/include/configs/mt7981.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Configuration for MediaTek MT7981 SoC + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#ifndef __MT7981_H +#define __MT7981_H + +#include + +#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M + +/* Uboot definition */ +#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE + +/* SPL -> Uboot */ +#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE + +/* DRAM */ +#define CONFIG_SYS_SDRAM_BASE 0x40000000 + +#endif diff --git a/include/configs/mt7986.h b/include/configs/mt7986.h new file mode 100644 index 0000000000..ccdd6abdb1 --- /dev/null +++ b/include/configs/mt7986.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Configuration for MediaTek MT7986 SoC + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#ifndef __MT7986_H +#define __MT7986_H + +#include + +#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M + +/* Uboot definition */ +#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE + +/* SPL -> Uboot */ +#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE + +/* DRAM */ +#define CONFIG_SYS_SDRAM_BASE 0x40000000 + +#endif diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h index e416f81e43..4314556754 100644 --- a/include/configs/mx6_common.h +++ b/include/configs/mx6_common.h @@ -12,7 +12,6 @@ #define CONFIG_SC_TIMER_CLK 8000000 /* 8Mhz */ #else #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE L2_PL310_BASE #endif diff --git a/include/configs/odroid.h b/include/configs/odroid.h index 7448cc9520..babd3ca963 100644 --- a/include/configs/odroid.h +++ b/include/configs/odroid.h @@ -14,7 +14,6 @@ #include #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE 0x10502000 #endif diff --git a/include/configs/poleg.h b/include/configs/poleg.h index f1c259f476..05253d59ef 100644 --- a/include/configs/poleg.h +++ b/include/configs/poleg.h @@ -7,7 +7,6 @@ #define __CONFIG_POLEG_H #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 1 #define CONFIG_SYS_PL310_BASE 0xF03FC000 /* L2 - Cache Regs Base (4k Space)*/ #endif diff --git a/include/configs/sifive-unmatched.h b/include/configs/sifive-unmatched.h index 9923f3d9c3..85fab92719 100644 --- a/include/configs/sifive-unmatched.h +++ b/include/configs/sifive-unmatched.h @@ -51,6 +51,4 @@ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ BOOTENV -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - #endif /* __SIFIVE_UNMATCHED_H */ diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h index 4a7da76e51..c3f30afe2b 100644 --- a/include/configs/socfpga_common.h +++ b/include/configs/socfpga_common.h @@ -48,7 +48,6 @@ /* * Cache */ -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE SOCFPGA_MPUL2_ADDRESS /* diff --git a/include/configs/stemmy.h b/include/configs/stemmy.h index 71b25c23b1..3c70856fc7 100644 --- a/include/configs/stemmy.h +++ b/include/configs/stemmy.h @@ -15,7 +15,6 @@ */ /* FIXME: This should be loaded from device tree... */ -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE 0xa0412000 /* Linux does not boot if FDT / initrd is loaded to end of RAM */ diff --git a/include/configs/stm32f746-disco.h b/include/configs/stm32f746-disco.h index 64c1bc7d43..b0ec226114 100644 --- a/include/configs/stm32f746-disco.h +++ b/include/configs/stm32f746-disco.h @@ -34,7 +34,6 @@ BOOTENV #define CONFIG_SYS_MONITOR_LEN (512 * 1024) -#define CONFIG_SYS_UBOOT_START 0x080083FD #define CONFIG_SYS_UBOOT_BASE (CONFIG_SYS_FLASH_BASE + \ CONFIG_SPL_PAD_TO) diff --git a/include/configs/stm32mp13_common.h b/include/configs/stm32mp13_common.h index 3ca65ea2a3..78089b965a 100644 --- a/include/configs/stm32mp13_common.h +++ b/include/configs/stm32mp13_common.h @@ -21,8 +21,6 @@ */ #define CONFIG_SYS_BOOTMAPSZ SZ_256M -/* Extend size of kernel image for uncompression */ - /*MMC SD*/ #define CONFIG_SYS_MMC_MAX_DEVICE 2 diff --git a/include/configs/stm32mp15_common.h b/include/configs/stm32mp15_common.h index c5412ffeb3..bd8e16bc1b 100644 --- a/include/configs/stm32mp15_common.h +++ b/include/configs/stm32mp15_common.h @@ -21,8 +21,6 @@ */ #define CONFIG_SYS_BOOTMAPSZ SZ_256M -/* Extend size of kernel image for uncompression */ - /*MMC SD*/ #define CONFIG_SYS_MMC_MAX_DEVICE 3 diff --git a/include/configs/ti_omap4_common.h b/include/configs/ti_omap4_common.h index 3d78972bfe..0568946fc8 100644 --- a/include/configs/ti_omap4_common.h +++ b/include/configs/ti_omap4_common.h @@ -12,7 +12,6 @@ #define __CONFIG_TI_OMAP4_COMMON_H #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 1 #define CONFIG_SYS_PL310_BASE 0x48242000 #endif diff --git a/include/configs/tqma6.h b/include/configs/tqma6.h index a782e3d02b..9498dbeadf 100644 --- a/include/configs/tqma6.h +++ b/include/configs/tqma6.h @@ -37,10 +37,6 @@ /* I2C Configs */ #define CONFIG_I2C_MULTI_BUS -/* I2C EEPROM (M24C64) */ -#define CONFIG_SYS_I2C_EEPROM_PAGE_WRITE_BITS 5 /* 32 Bytes */ -#define CONFIG_SYS_I2C_EEPROM_PAGE_WRITE_DELAY_MS 20 - #if !defined(CONFIG_DM_PMIC) #define CONFIG_POWER_PFUZE100 #define CONFIG_POWER_PFUZE100_I2C_ADDR 0x08 diff --git a/include/configs/trats.h b/include/configs/trats.h index 53f5a6996b..530b413d5b 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -12,7 +12,6 @@ #include #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE 0x10502000 #endif diff --git a/include/configs/trats2.h b/include/configs/trats2.h index b7449dab8b..06c1fcd23e 100644 --- a/include/configs/trats2.h +++ b/include/configs/trats2.h @@ -13,7 +13,6 @@ #include #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE 0x10502000 #endif diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 15ae0844c1..d9e95abcc1 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -169,7 +169,7 @@ /* only for SPL */ -/* subtract sizeof(struct image_header) */ +/* subtract sizeof(struct legacy_img_hdr) */ #define CONFIG_SYS_UBOOT_BASE (0x130000 - 0x40) #endif /* __CONFIG_UNIPHIER_H__ */ diff --git a/include/configs/xilinx_versal.h b/include/configs/xilinx_versal.h index 971bd69dec..8caf5394ed 100644 --- a/include/configs/xilinx_versal.h +++ b/include/configs/xilinx_versal.h @@ -23,10 +23,6 @@ EFI_GUID(0x20c5fba5, 0x0171, 0x457f, 0xb9, 0xcd, \ 0xf5, 0x12, 0x9c, 0xd0, 0x72, 0x28) -/* Miscellaneous configurable options */ - -/* Console I/O Buffer Size */ - #if defined(CONFIG_CMD_DFU) #define DFU_DEFAULT_POLL_TIMEOUT 300 #define CONFIG_THOR_RESET_OFF diff --git a/include/configs/xilinx_versal_net.h b/include/configs/xilinx_versal_net.h new file mode 100644 index 0000000000..0ccd38b7e6 --- /dev/null +++ b/include/configs/xilinx_versal_net.h @@ -0,0 +1,134 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Configuration for Xilinx Versal NET + * Copyright (C) 2016 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + * + * Based on Configuration for Xilinx ZynqMP + */ + +#ifndef __XILINX_VERSAL_NET_H +#define __XILINX_VERSAL_NET_H + +/* FIXME this is causing issue at least on IPP */ +/* #define CONFIG_ARMV8_SWITCH_TO_EL1 */ + +/* Generic Interrupt Controller Definitions */ +#define GICD_BASE 0xF9000000 +#define GICR_BASE 0xF9060000 + +/* Serial setup */ +#define CONFIG_SYS_BAUDRATE_TABLE \ + { 4800, 9600, 19200, 38400, 57600, 115200 } + +#if defined(CONFIG_CMD_DFU) +#define DFU_DEFAULT_POLL_TIMEOUT 300 +#define CONFIG_THOR_RESET_OFF +#define DFU_ALT_INFO_RAM \ + "dfu_ram_info=" \ + "setenv dfu_alt_info " \ + "Image ram 80000 $kernel_size_r\\\\;" \ + "system.dtb ram $fdt_addr_r $fdt_size_r\0" \ + "dfu_ram=run dfu_ram_info && dfu 0 ram 0\0" \ + "thor_ram=run dfu_ram_info && thordown 0 ram 0\0" + +#define DFU_ALT_INFO \ + DFU_ALT_INFO_RAM +#endif + +#if !defined(DFU_ALT_INFO) +# define DFU_ALT_INFO +#endif + +/* Ethernet driver */ +#if defined(CONFIG_ZYNQ_GEM) +# define PHY_ANEG_TIMEOUT 20000 +#endif + +#define ENV_MEM_LAYOUT_SETTINGS \ + "fdt_addr_r=0x40000000\0" \ + "fdt_size_r=0x400000\0" \ + "pxefile_addr_r=0x10000000\0" \ + "kernel_addr_r=0x18000000\0" \ + "kernel_size_r=0x10000000\0" \ + "kernel_comp_addr_r=0x30000000\0" \ + "kernel_comp_size=0x3C00000\0" \ + "scriptaddr=0x20000000\0" \ + "ramdisk_addr_r=0x02100000\0" \ + "script_size_f=0x80000\0" + +#if defined(CONFIG_MMC_SDHCI_ZYNQ) +# define BOOT_TARGET_DEVICES_MMC(func) func(MMC, mmc, 0) func(MMC, mmc, 1) +#else +# define BOOT_TARGET_DEVICES_MMC(func) +#endif + +#if defined(CONFIG_CMD_PXE) && defined(CONFIG_CMD_DHCP) +# define BOOT_TARGET_DEVICES_PXE(func) func(PXE, pxe, na) +#else +# define BOOT_TARGET_DEVICES_PXE(func) +#endif + +#if defined(CONFIG_CMD_DHCP) +# define BOOT_TARGET_DEVICES_DHCP(func) func(DHCP, dhcp, na) +#else +# define BOOT_TARGET_DEVICES_DHCP(func) +#endif + +#if defined(CONFIG_ZYNQMP_GQSPI) || defined(CONFIG_CADENCE_OSPI_VERSAL_NET) +# define BOOT_TARGET_DEVICES_XSPI(func) func(XSPI, xspi, 0) +#else +# define BOOT_TARGET_DEVICES_XSPI(func) +#endif + +#define BOOTENV_DEV_XSPI(devtypeu, devtypel, instance) \ + "bootcmd_xspi0=sf probe 0 0 0 && " \ + "sf read $scriptaddr $script_offset_f $script_size_f && " \ + "echo XSPI: Trying to boot script at ${scriptaddr} && " \ + "source ${scriptaddr}; echo XSPI: SCRIPT FAILED: continuing...;\0" + +#define BOOTENV_DEV_NAME_XSPI(devtypeu, devtypel, instance) \ + "xspi0 " + +#define BOOT_TARGET_DEVICES_JTAG(func) func(JTAG, jtag, na) + +#define BOOTENV_DEV_JTAG(devtypeu, devtypel, instance) \ + "bootcmd_jtag=echo JTAG: Trying to boot script at ${scriptaddr} && " \ + "source ${scriptaddr}; echo JTAG: SCRIPT FAILED: continuing...;\0" + +#define BOOTENV_DEV_NAME_JTAG(devtypeu, devtypel, instance) \ + "jtag " + +#define BOOT_TARGET_DEVICES_DFU_USB(func) func(DFU_USB, dfu_usb, 0) + +#define BOOTENV_DEV_DFU_USB(devtypeu, devtypel, instance) \ + "bootcmd_dfu_usb=setenv dfu_alt_info boot.scr ram $scriptaddr " \ + "$script_size_f; dfu 0 ram 0 && " \ + "echo DFU: Trying to boot script at ${scriptaddr} && " \ + "source ${scriptaddr}; " \ + "echo DFU: SCRIPT FAILED: continuing...;\0" + +#define BOOTENV_DEV_NAME_DFU_USB(devtypeu, devtypel, instance) \ + "" + +#define BOOT_TARGET_DEVICES(func) \ + BOOT_TARGET_DEVICES_JTAG(func) \ + BOOT_TARGET_DEVICES_MMC(func) \ + BOOT_TARGET_DEVICES_XSPI(func) \ + BOOT_TARGET_DEVICES_DFU_USB(func) \ + BOOT_TARGET_DEVICES_PXE(func) \ + BOOT_TARGET_DEVICES_DHCP(func) + +#include + +/* Initial environment variables */ +#ifndef CONFIG_EXTRA_ENV_SETTINGS +#define CONFIG_EXTRA_ENV_SETTINGS \ + ENV_MEM_LAYOUT_SETTINGS \ + BOOTENV \ + DFU_ALT_INFO +#endif + +#endif /* __XILINX_VERSAL_NET_H */ diff --git a/include/configs/xilinx_versal_net_mini.h b/include/configs/xilinx_versal_net_mini.h new file mode 100644 index 0000000000..1939832a84 --- /dev/null +++ b/include/configs/xilinx_versal_net_mini.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Configuration for Xilinx Versal NET MINI configuration + * + * Copyright (C) 2018 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#ifndef __CONFIG_VERSAL_NET_MINI_H +#define __CONFIG_VERSAL_NET_MINI_H + +#define CONFIG_EXTRA_ENV_SETTINGS + +#include + +/* Undef unneeded configs */ +#undef CONFIG_EXTRA_ENV_SETTINGS + +#endif /* __CONFIG_VERSAL_NET_MINI_H */ diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index 75ae68766f..dc0cba0010 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -11,7 +11,6 @@ /* Cache options */ #ifndef CONFIG_SYS_L2CACHE_OFF -# define CONFIG_SYS_L2_PL310 # define CONFIG_SYS_PL310_BASE 0xf8f02000 #endif diff --git a/include/cyclic.h b/include/cyclic.h new file mode 100644 index 0000000000..7601636433 --- /dev/null +++ b/include/cyclic.h @@ -0,0 +1,150 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * A general-purpose cyclic execution infrastructure, to allow "small" + * (run-time wise) functions to be executed at a specified frequency. + * Things like LED blinking or watchdog triggering are examples for such + * tasks. + * + * Copyright (C) 2022 Stefan Roese + */ + +#ifndef __cyclic_h +#define __cyclic_h + +#include +#include + +/** + * struct cyclic_drv - Cyclic driver internal data + * + * @cyclic_list: Cylic list node + * @cyclic_ready: Flag if cyclic infrastructure is ready + * @cyclic_running: Flag if cyclic infrastructure is running + */ +struct cyclic_drv { + struct list_head cyclic_list; + bool cyclic_ready; + bool cyclic_running; +}; + +/** + * struct cyclic_info - Information about cyclic execution function + * + * @func: Function to call periodically + * @ctx: Context pointer to get passed to this function + * @name: Name of the cyclic function, e.g. shown in the commands + * @delay_ns: Delay is ns after which this function shall get executed + * @start_time_us: Start time in us, when this function started its execution + * @cpu_time_us: Total CPU time of this function + * @run_cnt: Counter of executions occurances + * @next_call: Next time in us, when the function shall be executed again + * @list: List node + */ +struct cyclic_info { + void (*func)(void *ctx); + void *ctx; + char *name; + uint64_t delay_us; + uint64_t start_time_us; + uint64_t cpu_time_us; + uint64_t run_cnt; + uint64_t next_call; + struct list_head list; +}; + +/** Function type for cyclic functions */ +typedef void (*cyclic_func_t)(void *ctx); + +#if defined(CONFIG_CYCLIC) +/** + * cyclic_register - Register a new cyclic function + * + * @func: Function to call periodically + * @delay_us: Delay is us after which this function shall get executed + * @name: Cyclic function name/id + * @ctx: Context to pass to the function + * @return: pointer to cyclic_struct if OK, NULL on error + */ +struct cyclic_info *cyclic_register(cyclic_func_t func, uint64_t delay_us, + const char *name, void *ctx); + +/** + * cyclic_unregister - Unregister a cyclic function + * + * @cyclic: Pointer to cyclic_struct of the function that shall be removed + * @return: 0 if OK, -ve on error + */ +int cyclic_unregister(struct cyclic_info *cyclic); + +/** + * cyclic_init() - Set up cyclic functions + * + * Init a list of cyclic functions, so that these can be added as needed + */ +int cyclic_init(void); + +/** + * cyclic_uninit() - Clean up cyclic functions + * + * This removes all cyclic functions + */ +int cyclic_uninit(void); + +/** + * cyclic_get_list() - Get cyclic list pointer + * + * Return the cyclic list pointer + * + * @return: pointer to cyclic_list + */ +struct list_head *cyclic_get_list(void); + +/** + * cyclic_run() - Interate over all registered cyclic functions + * + * Interate over all registered cyclic functions and if the it's function + * needs to be executed, then call into these registered functions. + */ +void cyclic_run(void); + +/** + * schedule() - Schedule all potentially waiting tasks + * + * Basically a wrapper for cyclic_run(), pontentially enhanced by some + * other parts, that need to get handled periodically. + */ +void schedule(void); +#else +static inline struct cyclic_info *cyclic_register(cyclic_func_t func, + uint64_t delay_us, + const char *name, + void *ctx) +{ + return NULL; +} + +static inline int cyclic_unregister(struct cyclic_info *cyclic) +{ + return 0; +} + +static inline void cyclic_run(void) +{ +} + +static inline void schedule(void) +{ +} + +static inline int cyclic_init(void) +{ + return 0; +} + +static inline int cyclic_uninit(void) +{ + return 0; +} +#endif + +#endif diff --git a/include/dm/device.h b/include/dm/device.h index 12c6ba37ff..f3f953c9af 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -253,7 +253,7 @@ static inline void dev_bic_flags(struct udevice *dev, u32 bic) * @dev: device to check * Return: reference of the device's DT node */ -static inline ofnode dev_ofnode(const struct udevice *dev) +static inline __attribute_const__ ofnode dev_ofnode(const struct udevice *dev) { #if CONFIG_IS_ENABLED(OF_REAL) return dev->node_; @@ -273,7 +273,7 @@ static inline ofnode dev_ofnode(const struct udevice *dev) #define dev_get_dma_offset(_dev) 0 #endif -static inline int dev_of_offset(const struct udevice *dev) +static inline __attribute_const__ int dev_of_offset(const struct udevice *dev) { #if CONFIG_IS_ENABLED(OF_REAL) return ofnode_to_offset(dev_ofnode(dev)); @@ -282,7 +282,7 @@ static inline int dev_of_offset(const struct udevice *dev) #endif } -static inline bool dev_has_ofnode(const struct udevice *dev) +static inline __attribute_const__ bool dev_has_ofnode(const struct udevice *dev) { #if CONFIG_IS_ENABLED(OF_REAL) return ofnode_valid(dev_ofnode(dev)); diff --git a/include/dm/of.h b/include/dm/of.h index 9c9065b793..fce7cef0ff 100644 --- a/include/dm/of.h +++ b/include/dm/of.h @@ -31,10 +31,21 @@ struct property { /** * struct device_node: Device tree node * - * @name: Node name + * The top of this tree is typically gd->of_root which points to the root node. + * + * The head of the list of children for the root node (and any other node) is + * in @child, with @sibling providing a link to the next child. + * + * Each child has a pointer to its parent in @parent. + * + * A node may have properties in which case the head of the list of properties + * @properties pointers to the first one, with struct property->@next pointing + * to the next one. + * + * @name: Node name, "" for the root node * @type: Node type (value of device_type property) or "" if none * @phandle: Phandle value of this none, or 0 if none - * @full_name: Full path to node, e.g. "/bus@1/spi@1100" + * @full_name: Full path to node, e.g. "/bus@1/spi@1100" ("/" for the root node) * @properties: Pointer to head of list of properties, or NULL if none * @parent: Pointer to parent node, or NULL if this is the root node * @child: Pointer to head of child node list, or NULL if no children diff --git a/include/dm/of_access.h b/include/dm/of_access.h index 5b7821d0a1..c556a18f7d 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -258,11 +258,45 @@ struct device_node *of_find_node_by_prop_value(struct device_node *from, /** * of_find_node_by_phandle() - Find a node given a phandle * + * @root: root node to start from (NULL for default device tree) * @handle: phandle of the node to find * * Return: node pointer, or NULL if not found */ -struct device_node *of_find_node_by_phandle(phandle handle); +struct device_node *of_find_node_by_phandle(struct device_node *root, + phandle handle); + +/** + * of_read_u8() - Find and read a 8-bit integer from a property + * + * Search for a property in a device node and read a 8-bit value from + * it. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @outp: pointer to return value, modified only if return value is 0. + * + * Return: 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + */ +int of_read_u8(const struct device_node *np, const char *propname, u8 *outp); + +/** + * of_read_u16() - Find and read a 16-bit integer from a property + * + * Search for a property in a device node and read a 16-bit value from + * it. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @outp: pointer to return value, modified only if return value is 0. + * + * Return: 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + */ +int of_read_u16(const struct device_node *np, const char *propname, u16 *outp); /** * of_read_u32() - Find and read a 32-bit integer from a property @@ -293,8 +327,7 @@ int of_read_u32(const struct device_node *np, const char *propname, u32 *outp); * @outp: pointer to return value, modified only if return value is 0. * * Return: - * 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the + * 0 on success, -EINVAL if the property does not exist, or -EOVERFLOW if the * property data isn't large enough. */ int of_read_u32_index(const struct device_node *np, const char *propname, @@ -311,8 +344,7 @@ int of_read_u32_index(const struct device_node *np, const char *propname, * @outp: pointer to return value, modified only if return value is 0. * * Return: - * 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the + * 0 on success, -EINVAL if the property does not exist, or -EOVERFLOW if the * property data isn't large enough. */ int of_read_u64(const struct device_node *np, const char *propname, u64 *outp); @@ -328,8 +360,8 @@ int of_read_u64(const struct device_node *np, const char *propname, u64 *outp); * @out_values: pointer to return value, modified only if return value is 0. * @sz: number of array elements to read * Return: - * 0 on success, -EINVAL if the property does not exist, -ENODATA - * if property does not have a value, and -EOVERFLOW is longer than sz. + * 0 on success, -EINVAL if the property does not exist, or -EOVERFLOW if + * longer than sz. */ int of_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values, size_t sz); @@ -531,4 +563,19 @@ struct device_node *of_get_stdout(void); int of_write_prop(struct device_node *np, const char *propname, int len, const void *value); +/** + * of_add_subnode() - add a new subnode to a node + * + * @node: parent node to add to + * @name: name of subnode + * @len: length of name (so the caller does not need to nul-terminate a + * partial string), or -1 for strlen(@name) + * @subnodep: returns pointer to new subnode (valid if the function returns 0 + * or -EEXIST) + * Returns 0 if OK, -EEXIST if already exists, -ENOMEM if out of memory, other + * -ve on other error + */ +int of_add_subnode(struct device_node *node, const char *name, int len, + struct device_node **subnodep); + #endif diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 7ce1e4c6d9..7aae2c29ef 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -27,40 +27,24 @@ struct ofnode_phandle_args { uint32_t args[OF_MAX_PHANDLE_ARGS]; }; +#if CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) /** - * ofnode_to_np() - convert an ofnode to a live DT node pointer + * oftree_reset() - reset the state of the oftree list * - * This cannot be called if the reference contains an offset. - * - * @node: Reference containing struct device_node * (possibly invalid) - * Return: pointer to device node (can be NULL) + * Reset the oftree list so it can be started again. This should be called + * once the control FDT is in place, but before the ofnode interface is used. */ -static inline const struct device_node *ofnode_to_np(ofnode node) -{ -#ifdef OF_CHECKS - if (!of_live_active()) - return NULL; -#endif - return node.np; -} +void oftree_reset(void); /** - * ofnode_to_npw() - convert an ofnode to a writeable live DT node pointer + * ofnode_to_fdt() - convert an ofnode to a flat DT pointer * - * This cannot be called if the reference contains an offset. + * This cannot be called if the reference contains a node pointer. * - * @node: Reference containing struct device_node * (possibly invalid) - * Return: pointer to device node (can be NULL) + * @node: Reference containing offset (possibly invalid) + * Return: DT offset (can be NULL) */ -static inline struct device_node *ofnode_to_npw(ofnode node) -{ -#ifdef OF_CHECKS - if (!of_live_active()) - return NULL; -#endif - /* Drop constant */ - return (struct device_node *)node.np; -} +__attribute_const__ void *ofnode_to_fdt(ofnode node); /** * ofnode_to_offset() - convert an ofnode to a flat DT offset @@ -70,7 +54,40 @@ static inline struct device_node *ofnode_to_npw(ofnode node) * @node: Reference containing offset (possibly invalid) * Return: DT offset (can be -1) */ -static inline int ofnode_to_offset(ofnode node) +__attribute_const__ int ofnode_to_offset(ofnode node); + +/** + * oftree_from_fdt() - Returns an oftree from a flat device tree pointer + * + * @fdt: Device tree to use + * + * Returns: reference to the given node + */ +oftree oftree_from_fdt(void *fdt); + +/** + * noffset_to_ofnode() - convert a DT offset to an ofnode + * + * @other_node: Node in the same tree to use as a reference + * @of_offset: DT offset (either valid, or -1) + * Return: reference to the associated DT offset + */ +ofnode noffset_to_ofnode(ofnode other_node, int of_offset); + +#else /* !OFNODE_MULTI_TREE */ +static inline void oftree_reset(void) {} + +static inline void *ofnode_to_fdt(ofnode node) +{ +#ifdef OF_CHECKS + if (of_live_active()) + return NULL; +#endif + /* Use the control FDT by default */ + return (void *)gd->fdt_blob; +} + +static inline __attribute_const__ int ofnode_to_offset(ofnode node) { #ifdef OF_CHECKS if (of_live_active()) @@ -79,11 +96,55 @@ static inline int ofnode_to_offset(ofnode node) return node.of_offset; } +static inline oftree oftree_from_fdt(void *fdt) +{ + oftree tree; + + /* we cannot access other trees without OFNODE_MULTI_TREE */ + if (fdt == gd->fdt_blob) + tree.fdt = fdt; + else + tree.fdt = NULL; + + return tree; +} + +static inline ofnode noffset_to_ofnode(ofnode other_node, int of_offset) +{ + ofnode node; + + if (of_live_active()) + node.np = NULL; + else + node.of_offset = of_offset; + + return node; +} + +#endif /* OFNODE_MULTI_TREE */ + +/** + * ofnode_to_np() - convert an ofnode to a live DT node pointer + * + * This cannot be called if the reference contains an offset. + * + * @node: Reference containing struct device_node * (possibly invalid) + * Return: pointer to device node (can be NULL) + */ +static inline struct device_node *ofnode_to_np(ofnode node) +{ +#ifdef OF_CHECKS + if (!of_live_active()) + return NULL; +#endif + return node.np; +} + /** * ofnode_valid() - check if an ofnode is valid * * @node: Reference containing offset (possibly invalid) - * Return: true if the reference contains a valid ofnode, false if it is NULL + * Return: true if the reference contains a valid ofnode, false if not */ static inline bool ofnode_valid(ofnode node) { @@ -93,6 +154,22 @@ static inline bool ofnode_valid(ofnode node) return node.of_offset >= 0; } +/** + * oftree_lookup_fdt() - obtain the FDT pointer from an oftree + * + * This can only be called when flat tree is enabled + * + * @tree: Tree to look at + * @return FDT pointer from the tree + */ +static inline void *oftree_lookup_fdt(oftree tree) +{ + if (of_live_active()) + return NULL; + else + return tree.fdt; +} + /** * offset_to_ofnode() - convert a DT offset to an ofnode * @@ -117,7 +194,7 @@ static inline ofnode offset_to_ofnode(int of_offset) * @np: Live node pointer (can be NULL) * Return: reference to the associated node pointer */ -static inline ofnode np_to_ofnode(const struct device_node *np) +static inline ofnode np_to_ofnode(struct device_node *np) { ofnode node; @@ -164,6 +241,38 @@ static inline bool ofnode_equal(ofnode ref1, ofnode ref2) return ref1.of_offset == ref2.of_offset; } +/** + * oftree_valid() - check if an oftree is valid + * + * @tree: Reference containing oftree + * Return: true if the reference contains a valid oftree, false if node + */ +static inline bool oftree_valid(oftree tree) +{ + if (of_live_active()) + return tree.np; + else + return tree.fdt; +} + +/** + * oftree_null() - Obtain a null oftree + * + * This returns an oftree which points to no tree. It works both with the flat + * tree and livetree. + */ +static inline oftree oftree_null(void) +{ + oftree tree; + + if (of_live_active()) + tree.np = NULL; + else + tree.fdt = NULL; + + return tree; +} + /** * ofnode_null() - Obtain a null ofnode * @@ -194,6 +303,20 @@ static inline ofnode ofnode_root(void) return node; } +/** + * ofprop_valid() - check if an ofprop is valid + * + * @prop: Pointer to ofprop to check + * Return: true if the reference contains a valid ofprop, false if not + */ +static inline bool ofprop_valid(struct ofprop *prop) +{ + if (of_live_active()) + return prop->prop; + else + return prop->offset >= 0; +} + /** * oftree_default() - Returns the default device tree (U-Boot's control FDT) * @@ -211,6 +334,21 @@ static inline oftree oftree_default(void) return tree; } +/** + * oftree_from_np() - Returns an oftree from a node pointer + * + * @root: Root node of the tree + * Returns: reference to the given node + */ +static inline oftree oftree_from_np(struct device_node *root) +{ + oftree tree; + + tree.np = root; + + return tree; +} + /** * ofnode_name_eq() - Check if the node name is equivalent to a given name * ignoring the unit address @@ -221,6 +359,46 @@ static inline oftree oftree_default(void) */ bool ofnode_name_eq(ofnode node, const char *name); +/** + * ofnode_read_u8() - Read a 8-bit integer from a property + * + * @node: valid node reference to read property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * Return: 0 if OK, -ve on error + */ +int ofnode_read_u8(ofnode node, const char *propname, u8 *outp); + +/** + * ofnode_read_u8_default() - Read a 8-bit integer from a property + * + * @node: valid node reference to read property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * Return: property value, or @def if not found + */ +u8 ofnode_read_u8_default(ofnode node, const char *propname, u8 def); + +/** + * ofnode_read_u16() - Read a 16-bit integer from a property + * + * @node: valid node reference to read property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * Return: 0 if OK, -ve on error + */ +int ofnode_read_u16(ofnode node, const char *propname, u16 *outp); + +/** + * ofnode_read_u16_default() - Read a 16-bit integer from a property + * + * @node: valid node reference to read property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * Return: property value, or @def if not found + */ +u16 ofnode_read_u16_default(ofnode node, const char *propname, u16 def); + /** * ofnode_read_u32() - Read a 32-bit integer from a property * @@ -337,12 +515,12 @@ const char *ofnode_read_string(ofnode node, const char *propname); * @propname: name of the property to read * @out_values: pointer to return value, modified only if return value is 0 * @sz: number of array elements to read - * Return: 0 if OK, -ve on error + * Return: 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough * * Search for a property in a device node and read 32-bit value(s) from - * it. Returns 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the - * property data isn't large enough. + * it. * * The out_values is modified only if a valid u32 value can be decoded. */ @@ -444,7 +622,7 @@ ofnode ofnode_get_parent(ofnode node); * ofnode_get_name() - get the name of a node * * @node: valid node to look up - * Return: name of node + * Return: name of node (for the root node this is "") */ const char *ofnode_get_name(ofnode node); @@ -461,11 +639,22 @@ int ofnode_get_path(ofnode node, char *buf, int buflen); /** * ofnode_get_by_phandle() - get ofnode from phandle * + * This uses the default (control) device tree + * * @phandle: phandle to look up * Return: ofnode reference to the phandle */ ofnode ofnode_get_by_phandle(uint phandle); +/** + * oftree_get_by_phandle() - get ofnode from phandle + * + * @tree: tree to use + * @phandle: phandle to look up + * Return: ofnode reference to the phandle + */ +ofnode oftree_get_by_phandle(oftree tree, uint phandle); + /** * ofnode_read_size() - read the size of a property * @@ -683,18 +872,28 @@ int ofnode_count_phandle_with_args(ofnode node, const char *list_name, ofnode ofnode_path(const char *path); /** - * ofnode_path_root() - find a node by full path from a root node + * oftree_path() - find a node by full path from a root node * * @tree: Device tree to use * @path: Full path to node, e.g. "/bus/spi@1" * Return: reference to the node found. Use ofnode_valid() to check if it exists */ -ofnode ofnode_path_root(oftree tree, const char *path); +ofnode oftree_path(oftree tree, const char *path); + +/** + * oftree_root() - get the root node of a tree + * + * @tree: Device tree to use + * Return: reference to the root node + */ +ofnode oftree_root(oftree tree); /** * ofnode_read_chosen_prop() - get the value of a chosen property * - * This looks for a property within the /chosen node and returns its value + * This looks for a property within the /chosen node and returns its value. + * + * This only works with the control FDT. * * @propname: Property name to look for * @sizep: Returns size of property, or `FDT_ERR_...` error code if function @@ -709,6 +908,8 @@ const void *ofnode_read_chosen_prop(const char *propname, int *sizep); * This looks for a property within the /chosen node and returns its value, * checking that it is a valid nul-terminated string * + * This only works with the control FDT. + * * @propname: Property name to look for * Return: string value if found, else NULL */ @@ -720,6 +921,8 @@ const char *ofnode_read_chosen_string(const char *propname); * This looks up a named property in the chosen node and uses that as a path to * look up a code. * + * This only works with the control FDT. + * * @propname: Property name to look for * Return: the referenced node if present, else ofnode_null() */ @@ -730,6 +933,8 @@ ofnode ofnode_get_chosen_node(const char *propname); * * This looks for a property within the /aliases node and returns its value * + * This only works with the control FDT. + * * @propname: Property name to look for * @sizep: Returns size of property, or `FDT_ERR_...` error code if function * returns NULL @@ -743,6 +948,8 @@ const void *ofnode_read_aliases_prop(const char *propname, int *sizep); * This looks up a named property in the aliases node and uses that as a path to * look up a code. * + * This only works with the control FDT. + * * @propname: Property name to look for * Return: the referenced node if present, else ofnode_null() */ @@ -775,48 +982,64 @@ int ofnode_decode_display_timing(ofnode node, int index, const void *ofnode_get_property(ofnode node, const char *propname, int *lenp); /** - * ofnode_get_first_property()- get the reference of the first property + * ofnode_first_property()- get the reference of the first property * * Get reference to the first property of the node, it is used to iterate - * and read all the property with ofnode_get_property_by_prop(). + * and read all the property with ofprop_get_property(). * * @node: node to read * @prop: place to put argument reference * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found */ -int ofnode_get_first_property(ofnode node, struct ofprop *prop); +int ofnode_first_property(ofnode node, struct ofprop *prop); /** - * ofnode_get_next_property() - get the reference of the next property + * ofnode_next_property() - get the reference of the next property * * Get reference to the next property of the node, it is used to iterate - * and read all the property with ofnode_get_property_by_prop(). + * and read all the property with ofprop_get_property(). * * @prop: reference of current argument and place to put reference of next one * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found */ -int ofnode_get_next_property(struct ofprop *prop); +int ofnode_next_property(struct ofprop *prop); /** - * ofnode_get_property_by_prop() - get a pointer to the value of a property + * ofnode_for_each_prop() - iterate over all properties of a node + * + * @prop: struct ofprop + * @node: node (lvalue, ofnode) + * + * This is a wrapper around a for loop and is used like this:: + * + * ofnode node; + * struct ofprop prop; + * + * ofnode_for_each_prop(prop, node) { + * ...use prop... + * } + * + * Note that this is implemented as a macro and @prop is used as + * iterator in the loop. The parent variable can be a constant or even a + * literal. + */ +#define ofnode_for_each_prop(prop, node) \ + for (ofnode_first_property(node, &prop); \ + ofprop_valid(&prop); \ + ofnode_next_property(&prop)) + +/** + * ofprop_get_property() - get a pointer to the value of a property * * Get value for the property identified by the provided reference. * * @prop: reference on property * @propname: If non-NULL, place to property name on success, - * @lenp: If non-NULL, place to put length on success - * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found + * @lenp: If non-NULL, place to put length on success, or error code on failure + * Return: pointer to property, or NULL if not found */ -const void *ofnode_get_property_by_prop(const struct ofprop *prop, - const char **propname, int *lenp); - -/** - * ofnode_is_available() - check if a node is marked available - * - * @node: node to check - * Return: true if node's 'status' property is "okay" (or is missing) - */ -bool ofnode_is_available(ofnode node); +const void *ofprop_get_property(const struct ofprop *prop, + const char **propname, int *lenp); /** * ofnode_get_addr_size() - get address and size from a property @@ -1006,8 +1229,9 @@ ofnode ofnode_by_compatible(ofnode from, const char *compat); * Find the next node after @from that has a @propname with a value * @propval and a length @proplen. * - * @from: ofnode to start from (use ofnode_null() to start at the - * beginning) + * @from: ofnode to start from. Use ofnode_null() to start at the + * beginning, or the return value from oftree_root() to start at the first + * child of the root * @propname: property name to check * @propval: property value to search for * @proplen: length of the value in propval @@ -1126,19 +1350,23 @@ int ofnode_device_is_compatible(ofnode node, const char *compat); /** * ofnode_write_prop() - Set a property of a ofnode * - * Note that the value passed to the function is *not* allocated by the - * function itself, but must be allocated by the caller if necessary. However - * it does allocate memory for the property struct and name. + * Note that if @copy is false, the value passed to the function is *not* + * allocated by the function itself, but must be allocated by the caller if + * necessary. However it does allocate memory for the property struct and name. * * @node: The node for whose property should be set * @propname: The name of the property to set * @value: The new value of the property (must be valid prior to calling * the function) * @len: The length of the new value of the property + * @copy: true to allocate memory for the value. This only has any effect with + * live tree, since flat tree handles this automatically. It allows a + * node's value to be written to the tree, without requiring that the + * caller allocate it * Return: 0 if successful, -ve on error */ int ofnode_write_prop(ofnode node, const char *propname, const void *value, - int len); + int len, bool copy); /** * ofnode_write_string() - Set a string property of a ofnode @@ -1211,7 +1439,9 @@ phy_interface_t ofnode_read_phy_mode(ofnode mac_node); * * This reads a property from the /config node of the devicetree. * - * See doc/config.txt for bindings + * This only works with the control FDT. + * + * See doc/device-tree-bindings/config.txt for bindings * * @prop_name: property name to look up * Return: true, if it exists, false if not @@ -1223,7 +1453,7 @@ bool ofnode_conf_read_bool(const char *prop_name); * * This reads a property from the /config node of the devicetree. * - * See doc/config.txt for bindings + * See doc/device-tree-bindings/config.txt for bindings * * @prop_name: property name to look up * @default_val: default value to return if the property is not found @@ -1236,7 +1466,9 @@ int ofnode_conf_read_int(const char *prop_name, int default_val); * * This reads a property from the /config node of the devicetree. * - * See doc/config.txt for bindings + * This only works with the control FDT. + * + * See doc/device-tree-bindings/config.txt for bindings * * @prop_name: property name to look up * Return: string value, if found, or NULL if not @@ -1258,6 +1490,35 @@ static inline const char *ofnode_conf_read_str(const char *prop_name) { return NULL; } + #endif /* CONFIG_DM */ +/** + * of_add_subnode() - add a new subnode to a node + * + * @parent: parent node to add to + * @name: name of subnode + * @nodep: returns pointer to new subnode (valid if the function returns 0 + * or -EEXIST) + * Returns 0 if OK, -EEXIST if already exists, -ENOMEM if out of memory, other + * -ve on other error + */ +int ofnode_add_subnode(ofnode parent, const char *name, ofnode *nodep); + +/** + * ofnode_copy_props() - copy all properties from one node to another + * + * Makes a copy of all properties from the source note in the destination node. + * Existing properties in the destination node remain unchanged, except that + * any with the same name are overwritten, including changing the size of the + * property. + * + * For livetree, properties are copied / allocated, so the source tree does not + * need to be present afterwards. + * + * @src: Source node to read properties from + * @dst: Destination node to write properties too + */ +int ofnode_copy_props(ofnode src, ofnode dst); + #endif diff --git a/include/dm/ofnode_decl.h b/include/dm/ofnode_decl.h index 266253d5e3..5c2115aab0 100644 --- a/include/dm/ofnode_decl.h +++ b/include/dm/ofnode_decl.h @@ -31,18 +31,47 @@ * this increases code size slightly due to the subtraction. Since it offers no * real benefit, the approach described here seems best. * - * For now these points use constant types, since we don't allow writing - * the DT. + * Where multiple trees are in use, this works without any trouble with live + * tree, except for aliases, such as ofnode_path("mmc0"), which only work on the + * control FDT. When the flat tree is in use, the trees are registered and a + * 'tree ID' is encoded into the top bits of @of_offset - see immediately below + * for the associated macro definitions. Note that 64-bit machines use the same + * encoding, even though there is more space available. This is partly because + * the FDT format contains 32-bit values for things like the string-table + * offset, therefore 64-bit offsets cannot be supported anyway. + * + * For the multiple-tree case, an invalid offset (i.e. with of_offset < 0) is + * still invalid. It does not contain a tree ID. So there is no way of knowing + * which tree produced the invalid offset. * * @np: Pointer to device node, used for live tree * @of_offset: Pointer into flat device tree, used for flat tree. Note that this * is not a really a pointer to a node: it is an offset value. See above. */ typedef union ofnode_union { - const struct device_node *np; + struct device_node *np; long of_offset; } ofnode; +/* shift for the tree ID within of_offset */ +#define OF_TREE_SHIFT 28 + +/* mask to obtain the device tree offset from of_offset */ +#define OF_TREE_MASK ((1 << OF_TREE_SHIFT) - 1) + +/* encode a tree ID and node offset into an of_offset value */ +#define OFTREE_NODE(tree_id, offs) ((tree_id) << OF_TREE_SHIFT | (offs)) + +/* decode the node offset from an of_offset value */ +#define OFTREE_OFFSET(of_offs) ((of_offs) & OF_TREE_MASK) + +/* decode the tree ID from an of_offset value */ +#define OFTREE_TREE_ID(of_offs) ((of_offs) >> OF_TREE_SHIFT) + +/* encode a node offset in the tree given by another node's of_offset value */ +#define OFTREE_MAKE_NODE(other_of_offset, offs) \ + (((offs) & OF_TREE_MASK) | ((other_of_offset) & ~OF_TREE_MASK)) + /** * struct ofprop - reference to a property of a device tree node * @@ -57,7 +86,7 @@ typedef union ofnode_union { * * @node: Pointer to device node * @offset: Pointer into flat device tree, used for flat tree. - * @prop: Pointer to property, used for live treee. + * @prop: Pointer to property, used for live tree. */ struct ofprop { diff --git a/include/dm/read.h b/include/dm/read.h index 1b54b69acf..cc4f16196f 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -31,6 +31,47 @@ static inline const struct device_node *dev_np(const struct udevice *dev) #endif #if !defined(CONFIG_DM_DEV_READ_INLINE) || CONFIG_IS_ENABLED(OF_PLATDATA) +/** + * dev_read_u8() - read a 8-bit integer from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * Return: 0 if OK, -ve on error + */ +int dev_read_u8(const struct udevice *dev, const char *propname, u8 *outp); + +/** + * dev_read_u8_default() - read a 8-bit integer from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * Return: property value, or @def if not found + */ +u8 dev_read_u8_default(const struct udevice *dev, const char *propname, u8 def); + +/** + * dev_read_u16() - read a 16-bit integer from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * Return: 0 if OK, -ve on error + */ +int dev_read_u16(const struct udevice *dev, const char *propname, u16 *outp); + +/** + * dev_read_u16_default() - read a 16-bit integer from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * Return: property value, or @def if not found + */ +u16 dev_read_u16_default(const struct udevice *dev, const char *propname, + u16 def); + /** * dev_read_u32() - read a 32-bit integer from a device's DT property * @@ -528,7 +569,7 @@ const void *dev_read_prop(const struct udevice *dev, const char *propname, int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop); /** - * ofnode_get_next_property() - get the reference of the next property + * ofnode_next_property() - get the reference of the next property * * Get reference to the next property of the node, it is used to iterate * and read all the property with dev_read_prop_by_prop(). @@ -772,6 +813,30 @@ phy_interface_t dev_read_phy_mode(const struct udevice *dev); #else /* CONFIG_DM_DEV_READ_INLINE is enabled */ #include +static inline int dev_read_u8(const struct udevice *dev, + const char *propname, u8 *outp) +{ + return ofnode_read_u8(dev_ofnode(dev), propname, outp); +} + +static inline int dev_read_u8_default(const struct udevice *dev, + const char *propname, u8 def) +{ + return ofnode_read_u8_default(dev_ofnode(dev), propname, def); +} + +static inline int dev_read_u16(const struct udevice *dev, + const char *propname, u16 *outp) +{ + return ofnode_read_u16(dev_ofnode(dev), propname, outp); +} + +static inline int dev_read_u16_default(const struct udevice *dev, + const char *propname, u16 def) +{ + return ofnode_read_u16_default(dev_ofnode(dev), propname, def); +} + static inline int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp) { @@ -1014,19 +1079,19 @@ static inline const void *dev_read_prop(const struct udevice *dev, static inline int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop) { - return ofnode_get_first_property(dev_ofnode(dev), prop); + return ofnode_first_property(dev_ofnode(dev), prop); } static inline int dev_read_next_prop(struct ofprop *prop) { - return ofnode_get_next_property(prop); + return ofnode_next_property(prop); } static inline const void *dev_read_prop_by_prop(struct ofprop *prop, const char **propname, int *lenp) { - return ofnode_get_property_by_prop(prop, propname, lenp); + return ofprop_get_property(prop, propname, lenp); } static inline int dev_read_alias_seq(const struct udevice *dev, int *devnump) diff --git a/include/dt-bindings/clock/mt7981-clk.h b/include/dt-bindings/clock/mt7981-clk.h new file mode 100644 index 0000000000..e24c759e49 --- /dev/null +++ b/include/dt-bindings/clock/mt7981-clk.h @@ -0,0 +1,267 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Sam Shih + */ + +#ifndef _DT_BINDINGS_CLK_MT7981_H +#define _DT_BINDINGS_CLK_MT7981_H + +/* INFRACFG */ + +#define CK_INFRA_CK_F26M 0 +#define CK_INFRA_UART 1 +#define CK_INFRA_ISPI0 2 +#define CK_INFRA_I2C 3 +#define CK_INFRA_ISPI1 4 +#define CK_INFRA_PWM 5 +#define CK_INFRA_66M_MCK 6 +#define CK_INFRA_CK_F32K 7 +#define CK_INFRA_PCIE_CK 8 +#define CK_INFRA_PWM_BCK 9 +#define CK_INFRA_PWM_CK1 10 +#define CK_INFRA_PWM_CK2 11 +#define CK_INFRA_133M_HCK 12 +#define CK_INFRA_66M_PHCK 13 +#define CK_INFRA_FAUD_L_CK 14 +#define CK_INFRA_FAUD_AUD_CK 15 +#define CK_INFRA_FAUD_EG2_CK 16 +#define CK_INFRA_I2CS_CK 17 +#define CK_INFRA_MUX_UART0 18 +#define CK_INFRA_MUX_UART1 19 +#define CK_INFRA_MUX_UART2 20 +#define CK_INFRA_NFI_CK 21 +#define CK_INFRA_SPINFI_CK 22 +#define CK_INFRA_MUX_SPI0 23 +#define CK_INFRA_MUX_SPI1 24 +#define CK_INFRA_MUX_SPI2 25 +#define CK_INFRA_RTC_32K 26 +#define CK_INFRA_FMSDC_CK 27 +#define CK_INFRA_FMSDC_HCK_CK 28 +#define CK_INFRA_PERI_133M 29 +#define CK_INFRA_133M_PHCK 30 +#define CK_INFRA_USB_SYS_CK 31 +#define CK_INFRA_USB_CK 32 +#define CK_INFRA_USB_XHCI_CK 33 +#define CK_INFRA_PCIE_GFMUX_TL_O_PRE 34 +#define CK_INFRA_F26M_CK0 35 +#define CK_INFRA_133M_MCK 36 +#define CLK_INFRA_NR_CLK 37 + +/* TOPCKGEN */ + +#define CK_TOP_CB_CKSQ_40M 0 +#define CK_TOP_CB_M_416M 1 +#define CK_TOP_CB_M_D2 2 +#define CK_TOP_CB_M_D3 3 +#define CK_TOP_M_D3_D2 4 +#define CK_TOP_CB_M_D4 5 +#define CK_TOP_CB_M_D8 6 +#define CK_TOP_M_D8_D2 7 +#define CK_TOP_CB_MM_720M 8 +#define CK_TOP_CB_MM_D2 9 +#define CK_TOP_CB_MM_D3 10 +#define CK_TOP_CB_MM_D3_D5 11 +#define CK_TOP_CB_MM_D4 12 +#define CK_TOP_CB_MM_D6 13 +#define CK_TOP_MM_D6_D2 14 +#define CK_TOP_CB_MM_D8 15 +#define CK_TOP_CB_APLL2_196M 16 +#define CK_TOP_APLL2_D2 17 +#define CK_TOP_APLL2_D4 18 +#define CK_TOP_NET1_2500M 19 +#define CK_TOP_CB_NET1_D4 20 +#define CK_TOP_CB_NET1_D5 21 +#define CK_TOP_NET1_D5_D2 22 +#define CK_TOP_NET1_D5_D4 23 +#define CK_TOP_CB_NET1_D8 24 +#define CK_TOP_NET1_D8_D2 25 +#define CK_TOP_NET1_D8_D4 26 +#define CK_TOP_CB_NET2_800M 27 +#define CK_TOP_CB_NET2_D2 28 +#define CK_TOP_CB_NET2_D4 29 +#define CK_TOP_NET2_D4_D2 30 +#define CK_TOP_NET2_D4_D4 31 +#define CK_TOP_CB_NET2_D6 32 +#define CK_TOP_CB_WEDMCU_208M 33 +#define CK_TOP_CB_SGM_325M 34 +#define CK_TOP_CKSQ_40M_D2 35 +#define CK_TOP_CB_RTC_32K 36 +#define CK_TOP_CB_RTC_32P7K 37 +#define CK_TOP_USB_TX250M 38 +#define CK_TOP_FAUD 39 +#define CK_TOP_NFI1X 40 +#define CK_TOP_USB_EQ_RX250M 41 +#define CK_TOP_USB_CDR_CK 42 +#define CK_TOP_USB_LN0_CK 43 +#define CK_TOP_SPINFI_BCK 44 +#define CK_TOP_SPI 45 +#define CK_TOP_SPIM_MST 46 +#define CK_TOP_UART_BCK 47 +#define CK_TOP_PWM_BCK 48 +#define CK_TOP_I2C_BCK 49 +#define CK_TOP_PEXTP_TL 50 +#define CK_TOP_EMMC_208M 51 +#define CK_TOP_EMMC_400M 52 +#define CK_TOP_DRAMC_REF 53 +#define CK_TOP_DRAMC_MD32 54 +#define CK_TOP_SYSAXI 55 +#define CK_TOP_SYSAPB 56 +#define CK_TOP_ARM_DB_MAIN 57 +#define CK_TOP_AP2CNN_HOST 58 +#define CK_TOP_NETSYS 59 +#define CK_TOP_NETSYS_500M 60 +#define CK_TOP_NETSYS_WED_MCU 61 +#define CK_TOP_NETSYS_2X 62 +#define CK_TOP_SGM_325M 63 +#define CK_TOP_SGM_REG 64 +#define CK_TOP_F26M 65 +#define CK_TOP_EIP97B 66 +#define CK_TOP_USB3_PHY 67 +#define CK_TOP_AUD 68 +#define CK_TOP_A1SYS 69 +#define CK_TOP_AUD_L 70 +#define CK_TOP_A_TUNER 71 +#define CK_TOP_U2U3_REF 72 +#define CK_TOP_U2U3_SYS 73 +#define CK_TOP_U2U3_XHCI 74 +#define CK_TOP_USB_FRMCNT 75 +#define CK_TOP_NFI1X_SEL 76 +#define CK_TOP_SPINFI_SEL 77 +#define CK_TOP_SPI_SEL 78 +#define CK_TOP_SPIM_MST_SEL 79 +#define CK_TOP_UART_SEL 80 +#define CK_TOP_PWM_SEL 81 +#define CK_TOP_I2C_SEL 82 +#define CK_TOP_PEXTP_TL_SEL 83 +#define CK_TOP_EMMC_208M_SEL 84 +#define CK_TOP_EMMC_400M_SEL 85 +#define CK_TOP_F26M_SEL 86 +#define CK_TOP_DRAMC_SEL 87 +#define CK_TOP_DRAMC_MD32_SEL 88 +#define CK_TOP_SYSAXI_SEL 89 +#define CK_TOP_SYSAPB_SEL 90 +#define CK_TOP_ARM_DB_MAIN_SEL 91 +#define CK_TOP_AP2CNN_HOST_SEL 92 +#define CK_TOP_NETSYS_SEL 93 +#define CK_TOP_NETSYS_500M_SEL 94 +#define CK_TOP_NETSYS_MCU_SEL 95 +#define CK_TOP_NETSYS_2X_SEL 96 +#define CK_TOP_SGM_325M_SEL 97 +#define CK_TOP_SGM_REG_SEL 98 +#define CK_TOP_EIP97B_SEL 99 +#define CK_TOP_USB3_PHY_SEL 100 +#define CK_TOP_AUD_SEL 101 +#define CK_TOP_A1SYS_SEL 102 +#define CK_TOP_AUD_L_SEL 103 +#define CK_TOP_A_TUNER_SEL 104 +#define CK_TOP_U2U3_SEL 105 +#define CK_TOP_U2U3_SYS_SEL 106 +#define CK_TOP_U2U3_XHCI_SEL 107 +#define CK_TOP_USB_FRMCNT_SEL 108 +#define CLK_TOP_NR_CLK 109 + +/* + * INFRACFG_AO + * clock muxes need to be append to infracfg domain, and clock gates + * need to be keep in infracgh_ao domain + */ +#define INFRACFG_AO_OFFSET 10 + +#define CK_INFRA_UART0_SEL (0 + CLK_INFRA_NR_CLK) +#define CK_INFRA_UART1_SEL (1 + CLK_INFRA_NR_CLK) +#define CK_INFRA_UART2_SEL (2 + CLK_INFRA_NR_CLK) +#define CK_INFRA_SPI0_SEL (3 + CLK_INFRA_NR_CLK) +#define CK_INFRA_SPI1_SEL (4 + CLK_INFRA_NR_CLK) +#define CK_INFRA_SPI2_SEL (5 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PWM1_SEL (6 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PWM2_SEL (7 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PWM_BSEL (8 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PCIE_SEL (9 + CLK_INFRA_NR_CLK) +#define CK_INFRA_GPT_STA (10 - INFRACFG_AO_OFFSET) +#define CK_INFRA_PWM_HCK (11 - INFRACFG_AO_OFFSET) +#define CK_INFRA_PWM_STA (12 - INFRACFG_AO_OFFSET) +#define CK_INFRA_PWM1_CK (13 - INFRACFG_AO_OFFSET) +#define CK_INFRA_PWM2_CK (14 - INFRACFG_AO_OFFSET) +#define CK_INFRA_CQ_DMA_CK (15 - INFRACFG_AO_OFFSET) +#define CK_INFRA_AUD_BUS_CK (16 - INFRACFG_AO_OFFSET) +#define CK_INFRA_AUD_26M_CK (17 - INFRACFG_AO_OFFSET) +#define CK_INFRA_AUD_L_CK (18 - INFRACFG_AO_OFFSET) +#define CK_INFRA_AUD_AUD_CK (19 - INFRACFG_AO_OFFSET) +#define CK_INFRA_AUD_EG2_CK (20 - INFRACFG_AO_OFFSET) +#define CK_INFRA_DRAMC_26M_CK (21 - INFRACFG_AO_OFFSET) +#define CK_INFRA_DBG_CK (22 - INFRACFG_AO_OFFSET) +#define CK_INFRA_AP_DMA_CK (23 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SEJ_CK (24 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SEJ_13M_CK (25 - INFRACFG_AO_OFFSET) +#define CK_INFRA_THERM_CK (26 - INFRACFG_AO_OFFSET) +#define CK_INFRA_I2CO_CK (27 - INFRACFG_AO_OFFSET) +#define CK_INFRA_UART0_CK (28 - INFRACFG_AO_OFFSET) +#define CK_INFRA_UART1_CK (29 - INFRACFG_AO_OFFSET) +#define CK_INFRA_UART2_CK (30 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPI2_CK (31 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPI2_HCK_CK (32 - INFRACFG_AO_OFFSET) +#define CK_INFRA_NFI1_CK (33 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPINFI1_CK (34 - INFRACFG_AO_OFFSET) +#define CK_INFRA_NFI_HCK_CK (35 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPI0_CK (36 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPI1_CK (37 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPI0_HCK_CK (38 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPI1_HCK_CK (39 - INFRACFG_AO_OFFSET) +#define CK_INFRA_FRTC_CK (40 - INFRACFG_AO_OFFSET) +#define CK_INFRA_MSDC_CK (41 - INFRACFG_AO_OFFSET) +#define CK_INFRA_MSDC_HCK_CK (42 - INFRACFG_AO_OFFSET) +#define CK_INFRA_MSDC_133M_CK (43 - INFRACFG_AO_OFFSET) +#define CK_INFRA_MSDC_66M_CK (44 - INFRACFG_AO_OFFSET) +#define CK_INFRA_ADC_26M_CK (45 - INFRACFG_AO_OFFSET) +#define CK_INFRA_ADC_FRC_CK (46 - INFRACFG_AO_OFFSET) +#define CK_INFRA_FBIST2FPC_CK (47 - INFRACFG_AO_OFFSET) +#define CK_INFRA_I2C_MCK_CK (48 - INFRACFG_AO_OFFSET) +#define CK_INFRA_I2C_PCK_CK (49 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IUSB_133_CK (50 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IUSB_66M_CK (51 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IUSB_SYS_CK (52 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IUSB_CK (53 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IPCIE_CK (54 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IPCIER_CK (55 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IPCIEB_CK (56 - INFRACFG_AO_OFFSET) +#define CLK_INFRA_AO_NR_CLK (57 - INFRACFG_AO_OFFSET) + +/* APMIXEDSYS */ + +#define CK_APMIXED_ARMPLL 0 +#define CK_APMIXED_NET2PLL 1 +#define CK_APMIXED_MMPLL 2 +#define CK_APMIXED_SGMPLL 3 +#define CK_APMIXED_WEDMCUPLL 4 +#define CK_APMIXED_NET1PLL 5 +#define CK_APMIXED_MPLL 6 +#define CK_APMIXED_APLL2 7 +#define CLK_APMIXED_NR_CLK 8 + +/* SGMIISYS_0 */ + +#define CK_SGM0_TX_EN 0 +#define CK_SGM0_RX_EN 1 +#define CK_SGM0_CK0_EN 2 +#define CK_SGM0_CDR_CK0_EN 3 +#define CLK_SGMII0_NR_CLK 4 + +/* SGMIISYS_1 */ + +#define CK_SGM1_TX_EN 0 +#define CK_SGM1_RX_EN 1 +#define CK_SGM1_CK1_EN 2 +#define CK_SGM1_CDR_CK1_EN 3 +#define CLK_SGMII1_NR_CLK 4 + +/* ETHSYS */ + +#define CK_ETH_FE_EN 0 +#define CK_ETH_GP2_EN 1 +#define CK_ETH_GP1_EN 2 +#define CK_ETH_WOCPU0_EN 3 +#define CLK_ETH_NR_CLK 4 + +#endif /* _DT_BINDINGS_CLK_MT7981_H */ diff --git a/include/dt-bindings/clock/mt7986-clk.h b/include/dt-bindings/clock/mt7986-clk.h new file mode 100644 index 0000000000..820f863183 --- /dev/null +++ b/include/dt-bindings/clock/mt7986-clk.h @@ -0,0 +1,249 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Sam Shih + */ + +#ifndef _DT_BINDINGS_CLK_MT7986_H +#define _DT_BINDINGS_CLK_MT7986_H + +/* INFRACFG */ + +#define CK_INFRA_CK_F26M 0 +#define CK_INFRA_UART 1 +#define CK_INFRA_ISPI0 2 +#define CK_INFRA_I2C 3 +#define CK_INFRA_ISPI1 4 +#define CK_INFRA_PWM 5 +#define CK_INFRA_66M_MCK 6 +#define CK_INFRA_CK_F32K 7 +#define CK_INFRA_PCIE_CK 8 +#define CK_INFRA_PWM_BCK 9 +#define CK_INFRA_PWM_CK1 10 +#define CK_INFRA_PWM_CK2 11 +#define CK_INFRA_133M_HCK 12 +#define CK_INFRA_EIP_CK 13 +#define CK_INFRA_66M_PHCK 14 +#define CK_INFRA_FAUD_L_CK 15 +#define CK_INFRA_FAUD_AUD_CK 17 +#define CK_INFRA_FAUD_EG2_CK 17 +#define CK_INFRA_I2CS_CK 18 +#define CK_INFRA_MUX_UART0 19 +#define CK_INFRA_MUX_UART1 20 +#define CK_INFRA_MUX_UART2 21 +#define CK_INFRA_NFI_CK 22 +#define CK_INFRA_SPINFI_CK 23 +#define CK_INFRA_MUX_SPI0 24 +#define CK_INFRA_MUX_SPI1 25 +#define CK_INFRA_RTC_32K 26 +#define CK_INFRA_FMSDC_CK 27 +#define CK_INFRA_FMSDC_HCK_CK 28 +#define CK_INFRA_PERI_133M 29 +#define CK_INFRA_133M_PHCK 30 +#define CK_INFRA_USB_SYS_CK 31 +#define CK_INFRA_USB_CK 32 +#define CK_INFRA_USB_XHCI_CK 33 +#define CK_INFRA_PCIE_GFMUX_TL_O_PRE 34 +#define CK_INFRA_F26M_CK0 35 +#define CK_INFRA_HD_133M 36 +#define CLK_INFRA_NR_CLK 37 + +/* TOPCKGEN */ + +#define CK_TOP_CB_CKSQ_40M 0 +#define CK_TOP_CB_M_416M 1 +#define CK_TOP_CB_M_D2 2 +#define CK_TOP_CB_M_D4 3 +#define CK_TOP_CB_M_D8 4 +#define CK_TOP_M_D8_D2 5 +#define CK_TOP_M_D3_D2 6 +#define CK_TOP_CB_MM_D2 7 +#define CK_TOP_CB_MM_D4 8 +#define CK_TOP_CB_MM_D8 9 +#define CK_TOP_MM_D8_D2 10 +#define CK_TOP_MM_D3_D8 11 +#define CK_TOP_CB_U2_PHYD_CK 12 +#define CK_TOP_CB_APLL2_196M 13 +#define CK_TOP_APLL2_D4 14 +#define CK_TOP_CB_NET1_D4 15 +#define CK_TOP_CB_NET1_D5 16 +#define CK_TOP_NET1_D5_D2 17 +#define CK_TOP_NET1_D5_D4 18 +#define CK_TOP_NET1_D8_D2 19 +#define CK_TOP_NET1_D8_D4 20 +#define CK_TOP_CB_NET2_800M 21 +#define CK_TOP_CB_NET2_D4 22 +#define CK_TOP_NET2_D4_D2 23 +#define CK_TOP_NET2_D3_D2 24 +#define CK_TOP_CB_WEDMCU_760M 25 +#define CK_TOP_WEDMCU_D5_D2 26 +#define CK_TOP_CB_SGM_325M 27 +#define CK_TOP_CB_CKSQ_40M_D2 28 +#define CK_TOP_CB_RTC_32K 29 +#define CK_TOP_CB_RTC_32P7K 30 +#define CK_TOP_NFI1X 31 +#define CK_TOP_USB_EQ_RX250M 32 +#define CK_TOP_USB_TX250M 33 +#define CK_TOP_USB_LN0_CK 34 +#define CK_TOP_USB_CDR_CK 35 +#define CK_TOP_SPINFI_BCK 36 +#define CK_TOP_I2C_BCK 37 +#define CK_TOP_PEXTP_TL 38 +#define CK_TOP_EMMC_250M 39 +#define CK_TOP_EMMC_416M 40 +#define CK_TOP_F_26M_ADC_CK 41 +#define CK_TOP_SYSAXI 42 +#define CK_TOP_NETSYS_WED_MCU 43 +#define CK_TOP_NETSYS_2X 44 +#define CK_TOP_SGM_325M 45 +#define CK_TOP_A1SYS 46 +#define CK_TOP_EIP_B 47 +#define CK_TOP_F26M 48 +#define CK_TOP_AUD_L 49 +#define CK_TOP_A_TUNER 50 +#define CK_TOP_U2U3_REF 51 +#define CK_TOP_U2U3_SYS 52 +#define CK_TOP_U2U3_XHCI 53 +#define CK_TOP_AP2CNN_HOST 54 +#define CK_TOP_NFI1X_SEL 55 +#define CK_TOP_SPINFI_SEL 56 +#define CK_TOP_SPI_SEL 57 +#define CK_TOP_SPIM_MST_SEL 58 +#define CK_TOP_UART_SEL 59 +#define CK_TOP_PWM_SEL 60 +#define CK_TOP_I2C_SEL 61 +#define CK_TOP_PEXTP_TL_SEL 62 +#define CK_TOP_EMMC_250M_SEL 63 +#define CK_TOP_EMMC_416M_SEL 64 +#define CK_TOP_F_26M_ADC_SEL 65 +#define CK_TOP_DRAMC_SEL 66 +#define CK_TOP_DRAMC_MD32_SEL 67 +#define CK_TOP_SYSAXI_SEL 68 +#define CK_TOP_SYSAPB_SEL 69 +#define CK_TOP_ARM_DB_MAIN_SEL 70 +#define CK_TOP_ARM_DB_JTSEL 71 +#define CK_TOP_NETSYS_SEL 72 +#define CK_TOP_NETSYS_500M_SEL 73 +#define CK_TOP_NETSYS_MCU_SEL 74 +#define CK_TOP_NETSYS_2X_SEL 75 +#define CK_TOP_SGM_325M_SEL 76 +#define CK_TOP_SGM_REG_SEL 77 +#define CK_TOP_A1SYS_SEL 78 +#define CK_TOP_CONN_MCUSYS_SEL 79 +#define CK_TOP_EIP_B_SEL 80 +#define CK_TOP_PCIE_PHY_SEL 81 +#define CK_TOP_USB3_PHY_SEL 82 +#define CK_TOP_F26M_SEL 83 +#define CK_TOP_AUD_L_SEL 84 +#define CK_TOP_A_TUNER_SEL 85 +#define CK_TOP_U2U3_SEL 86 +#define CK_TOP_U2U3_SYS_SEL 87 +#define CK_TOP_U2U3_XHCI_SEL 88 +#define CK_TOP_DA_U2_REFSEL 89 +#define CK_TOP_DA_U2_CK_1P_SEL 90 +#define CK_TOP_AP2CNN_HOST_SEL 91 +#define CLK_TOP_NR_CLK 92 + +/* + * INFRACFG_AO + * clock muxes need to be append to infracfg domain, and clock gates + * need to be keep in infracgh_ao domain + */ + +#define CK_INFRA_UART0_SEL (0 + CLK_INFRA_NR_CLK) +#define CK_INFRA_UART1_SEL (1 + CLK_INFRA_NR_CLK) +#define CK_INFRA_UART2_SEL (2 + CLK_INFRA_NR_CLK) +#define CK_INFRA_SPI0_SEL (3 + CLK_INFRA_NR_CLK) +#define CK_INFRA_SPI1_SEL (4 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PWM1_SEL (5 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PWM2_SEL (6 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PWM_BSEL (7 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PCIE_SEL (8 + CLK_INFRA_NR_CLK) +#define CK_INFRA_GPT_STA 0 +#define CK_INFRA_PWM_HCK 1 +#define CK_INFRA_PWM_STA 2 +#define CK_INFRA_PWM1_CK 3 +#define CK_INFRA_PWM2_CK 4 +#define CK_INFRA_CQ_DMA_CK 5 +#define CK_INFRA_EIP97_CK 6 +#define CK_INFRA_AUD_BUS_CK 7 +#define CK_INFRA_AUD_26M_CK 8 +#define CK_INFRA_AUD_L_CK 9 +#define CK_INFRA_AUD_AUD_CK 10 +#define CK_INFRA_AUD_EG2_CK 11 +#define CK_INFRA_DRAMC_26M_CK 12 +#define CK_INFRA_DBG_CK 13 +#define CK_INFRA_AP_DMA_CK 14 +#define CK_INFRA_SEJ_CK 15 +#define CK_INFRA_SEJ_13M_CK 16 +#define CK_INFRA_THERM_CK 17 +#define CK_INFRA_I2CO_CK 18 +#define CK_INFRA_TRNG_CK 19 +#define CK_INFRA_UART0_CK 20 +#define CK_INFRA_UART1_CK 21 +#define CK_INFRA_UART2_CK 22 +#define CK_INFRA_NFI1_CK 23 +#define CK_INFRA_SPINFI1_CK 24 +#define CK_INFRA_NFI_HCK_CK 25 +#define CK_INFRA_SPI0_CK 26 +#define CK_INFRA_SPI1_CK 27 +#define CK_INFRA_SPI0_HCK_CK 28 +#define CK_INFRA_SPI1_HCK_CK 29 +#define CK_INFRA_FRTC_CK 30 +#define CK_INFRA_MSDC_CK 31 +#define CK_INFRA_MSDC_HCK_CK 32 +#define CK_INFRA_MSDC_133M_CK 33 +#define CK_INFRA_MSDC_66M_CK 34 +#define CK_INFRA_ADC_26M_CK 35 +#define CK_INFRA_ADC_FRC_CK 36 +#define CK_INFRA_FBIST2FPC_CK 37 +#define CK_INFRA_IUSB_133_CK 38 +#define CK_INFRA_IUSB_66M_CK 39 +#define CK_INFRA_IUSB_SYS_CK 40 +#define CK_INFRA_IUSB_CK 41 +#define CK_INFRA_IPCIE_CK 42 +#define CK_INFRA_IPCIER_CK 43 +#define CK_INFRA_IPCIEB_CK 44 +#define CLK_INFRA_AO_NR_CLK 45 + +/* APMIXEDSYS */ + +#define CK_APMIXED_ARMPLL 0 +#define CK_APMIXED_NET2PLL 1 +#define CK_APMIXED_MMPLL 2 +#define CK_APMIXED_SGMPLL 3 +#define CK_APMIXED_WEDMCUPLL 4 +#define CK_APMIXED_NET1PLL 5 +#define CK_APMIXED_MPLL 6 +#define CK_APMIXED_APLL2 7 +#define CLK_APMIXED_NR_CLK 8 + +/* SGMIISYS_0 */ + +#define CK_SGM0_TX_EN 0 +#define CK_SGM0_RX_EN 1 +#define CK_SGM0_CK0_EN 2 +#define CK_SGM0_CDR_CK0_EN 3 +#define CLK_SGMII0_NR_CLK 4 + +/* SGMIISYS_1 */ + +#define CK_SGM1_TX_EN 0 +#define CK_SGM1_RX_EN 1 +#define CK_SGM1_CK1_EN 2 +#define CK_SGM1_CDR_CK1_EN 3 +#define CLK_SGMII1_NR_CLK 4 + +/* ETHSYS */ + +#define CK_ETH_FE_EN 0 +#define CK_ETH_GP2_EN 1 +#define CK_ETH_GP1_EN 2 +#define CK_ETH_WOCPU1_EN 3 +#define CK_ETH_WOCPU0_EN 4 +#define CLK_ETH_NR_CLK 5 + +#endif + +/* _DT_BINDINGS_CLK_MT7986_H */ diff --git a/include/dt-bindings/gpio/sandbox-gpio.h b/include/dt-bindings/gpio/sandbox-gpio.h index e4bfdb3ce1..05f9836583 100644 --- a/include/dt-bindings/gpio/sandbox-gpio.h +++ b/include/dt-bindings/gpio/sandbox-gpio.h @@ -21,4 +21,7 @@ /* Bit 18 express GPIO output is active */ #define GPIO_OUT_ACTIVE 0x40000 +/* Bit 19 express GPIO set as alternate function */ +#define GPIO_AF 0x80000 + #endif diff --git a/include/dt-bindings/pinctrl/mt65xx.h b/include/dt-bindings/pinctrl/mt65xx.h new file mode 100644 index 0000000000..fbea8d35bc --- /dev/null +++ b/include/dt-bindings/pinctrl/mt65xx.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Hongzhou.Yang + */ + +#ifndef _DT_BINDINGS_PINCTRL_MT65XX_H +#define _DT_BINDINGS_PINCTRL_MT65XX_H + +#define MTK_PIN_NO(x) ((x) << 8) +#define MTK_GET_PIN_NO(x) ((x) >> 8) +#define MTK_GET_PIN_FUNC(x) ((x) & 0xf) + +#define MTK_PUPD_SET_R1R0_00 100 +#define MTK_PUPD_SET_R1R0_01 101 +#define MTK_PUPD_SET_R1R0_10 102 +#define MTK_PUPD_SET_R1R0_11 103 + +#define MTK_PULL_SET_RSEL_000 200 +#define MTK_PULL_SET_RSEL_001 201 +#define MTK_PULL_SET_RSEL_010 202 +#define MTK_PULL_SET_RSEL_011 203 +#define MTK_PULL_SET_RSEL_100 204 +#define MTK_PULL_SET_RSEL_101 205 +#define MTK_PULL_SET_RSEL_110 206 +#define MTK_PULL_SET_RSEL_111 207 + +#define MTK_DRIVE_2mA 2 +#define MTK_DRIVE_4mA 4 +#define MTK_DRIVE_6mA 6 +#define MTK_DRIVE_8mA 8 +#define MTK_DRIVE_10mA 10 +#define MTK_DRIVE_12mA 12 +#define MTK_DRIVE_14mA 14 +#define MTK_DRIVE_16mA 16 +#define MTK_DRIVE_20mA 20 +#define MTK_DRIVE_24mA 24 +#define MTK_DRIVE_28mA 28 +#define MTK_DRIVE_32mA 32 + +#endif /* _DT_BINDINGS_PINCTRL_MT65XX_H */ diff --git a/include/efi_config.h b/include/efi_config.h new file mode 100644 index 0000000000..098cac2115 --- /dev/null +++ b/include/efi_config.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Menu-driven UEFI Variable maintenance + * + * Copyright (c) 2022 Masahisa Kojima, Linaro Limited + */ + +#ifndef _EFI_CONFIG_H +#define _EFI_CONFIG_H + +#include + +#define EFICONFIG_ENTRY_NUM_MAX 99 +#define EFICONFIG_VOLUME_PATH_MAX 512 +#define EFICONFIG_FILE_PATH_MAX 512 +#define EFICONFIG_FILE_PATH_BUF_SIZE (EFICONFIG_FILE_PATH_MAX * sizeof(u16)) + +typedef efi_status_t (*eficonfig_entry_func)(void *data); + +/** + * struct eficonfig_entry - menu entry structure + * + * @num: menu entry index + * @title: title of entry + * @key: unique key + * @efi_menu: pointer to the menu structure + * @func: callback function to be called when this entry is selected + * @data: data to be passed to the callback function, caller must free() this pointer + * @list: list structure + */ +struct eficonfig_entry { + u32 num; + char *title; + char key[3]; + struct efimenu *efi_menu; + eficonfig_entry_func func; + void *data; + struct list_head list; +}; + +/** + * struct efimenu - efi menu structure + * + * @delay: delay for autoboot + * @active: active menu entry index + * @count: total count of menu entry + * @menu_header: menu header string + * @list: menu entry list structure + */ +struct efimenu { + int delay; + int active; + int count; + char *menu_header; + struct list_head list; +}; + +/** + * struct eficonfig_item - structure to construct eficonfig_entry + * + * @title: title of entry + * @func: callback function to be called when this entry is selected + * @data: data to be passed to the callback function + */ +struct eficonfig_item { + char *title; + eficonfig_entry_func func; + void *data; +}; + +/** + * struct eficonfig_select_file_info - structure to be used for file selection + * + * @current_volume: pointer to the efi_simple_file_system_protocol + * @dp_volume: pointer to device path of the selected device + * @current_path: pointer to the selected file path string + * @filepath_list: list_head structure for file path list + * @file_selectred: flag indicates file selecting status + */ +struct eficonfig_select_file_info { + struct efi_simple_file_system_protocol *current_volume; + struct efi_device_path *dp_volume; + u16 *current_path; + struct list_head filepath_list; + bool file_selected; +}; + +void eficonfig_print_msg(char *msg); +void eficonfig_destroy(struct efimenu *efi_menu); +efi_status_t eficonfig_process_quit(void *data); +efi_status_t eficonfig_process_common(struct efimenu *efi_menu, char *menu_header); +efi_status_t eficonfig_select_file_handler(void *data); +efi_status_t eficonfig_get_unused_bootoption(u16 *buf, + efi_uintn_t buf_size, u32 *index); +efi_status_t eficonfig_append_bootorder(u16 index); +efi_status_t eficonfig_generate_media_device_boot_option(void); + +#endif diff --git a/include/efi_loader.h b/include/efi_loader.h index 545ba06d94..ad01395b39 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -142,6 +142,11 @@ static inline efi_status_t efi_launch_capsules(void) EFI_GUID(0x63293792, 0xadf5, 0x9325, \ 0xb9, 0x9f, 0x4e, 0x0e, 0x45, 0x5c, 0x1b, 0x1e) +/* GUID for the auto generated boot menu entry */ +#define EFICONFIG_AUTO_GENERATED_ENTRY_GUID \ + EFI_GUID(0x38c1acc1, 0x9fc0, 0x41f0, \ + 0xb9, 0x01, 0xfa, 0x74, 0xd6, 0xd6, 0xe4, 0xde) + /* Use internal device tree when starting UEFI application */ #define EFI_FDT_USE_INTERNAL NULL @@ -156,7 +161,7 @@ extern bool efi_st_keep_devices; /* EFI system partition */ extern struct efi_system_partition { - enum if_type if_type; + enum uclass_id uclass_id; int devnum; u8 part; } efi_system_partition; @@ -226,6 +231,9 @@ const char *__efi_nesting_dec(void); #define EFI_CACHELINE_SIZE 128 #endif +/* max bootmenu title size for volume selection */ +#define BOOTMENU_DEVICE_NAME_MAX 16 + /* Key identifying current memory map */ extern efi_uintn_t efi_memory_map_key; @@ -249,6 +257,9 @@ extern const struct efi_hii_string_protocol efi_hii_string; uint16_t *efi_dp_str(struct efi_device_path *dp); +/* GUID for the auto generated boot menu entry */ +extern const efi_guid_t efi_guid_bootmenu_auto_generated; + /* GUID of the U-Boot root node */ extern const efi_guid_t efi_u_boot_guid; #ifdef CONFIG_SANDBOX @@ -314,6 +325,8 @@ extern const efi_guid_t efi_guid_firmware_management_protocol; extern const efi_guid_t efi_esrt_guid; /* GUID of the SMBIOS table */ extern const efi_guid_t smbios_guid; +/*GUID of console */ +extern const efi_guid_t efi_guid_text_input_protocol; extern char __efi_runtime_start[], __efi_runtime_stop[]; extern char __efi_runtime_rel_start[], __efi_runtime_rel_stop[]; @@ -549,7 +562,7 @@ efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size, struct efi_loaded_image *loaded_image_info); /* Create handles and protocols for the partitions of a block device */ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc, - const char *if_typename, int diskid, + const char *uclass_idname, int diskid, const char *pdevname); /* Called by bootefi to make GOP (graphical) interface available */ efi_status_t efi_gop_register(void); @@ -942,6 +955,22 @@ struct efi_signature_store { struct x509_certificate; struct pkcs7_message; +/** + * struct eficonfig_media_boot_option - boot option for (removable) media device + * + * This structure is used to enumerate possible boot option + * + * @lo: Serialized load option data + * @size: Size of serialized load option data + * @exist: Flag to indicate the load option already exists + * in Non-volatile load option + */ +struct eficonfig_media_boot_option { + void *lo; + efi_uintn_t size; + bool exist; +}; + bool efi_hash_regions(struct image_region *regs, int count, void **hash, const char *hash_algo, int *len); bool efi_signature_lookup_digest(struct efi_image_regions *regs, @@ -1073,4 +1102,28 @@ efi_status_t efi_esrt_populate(void); efi_status_t efi_load_capsule_drivers(void); efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, u32 *sz); + +efi_status_t efi_locate_handle_buffer_int(enum efi_locate_search_type search_type, + const efi_guid_t *protocol, void *search_key, + efi_uintn_t *no_handles, efi_handle_t **buffer); + +efi_status_t efi_open_volume_int(struct efi_simple_file_system_protocol *this, + struct efi_file_handle **root); +efi_status_t efi_file_open_int(struct efi_file_handle *this, + struct efi_file_handle **new_handle, + u16 *file_name, u64 open_mode, + u64 attributes); +efi_status_t efi_file_close_int(struct efi_file_handle *file); +efi_status_t efi_file_read_int(struct efi_file_handle *this, + efi_uintn_t *buffer_size, void *buffer); +efi_status_t efi_file_setpos_int(struct efi_file_handle *file, u64 pos); + +typedef efi_status_t (*efi_console_filter_func)(struct efi_input_key *key); +efi_status_t efi_console_get_u16_string + (struct efi_simple_text_input_protocol *cin, + u16 *buf, efi_uintn_t count, efi_console_filter_func filer_func, + int row, int col); + +efi_status_t efi_disk_get_device_name(const efi_handle_t handle, char *buf, int size); + #endif /* _EFI_LOADER_H */ diff --git a/include/event.h b/include/event.h index e8f2f55c63..3e6dcbc3dd 100644 --- a/include/event.h +++ b/include/event.h @@ -60,9 +60,11 @@ union event_data { * struct event_ft_fixup - FDT fixup before booting * * @tree: tree to update + * @images: images which are being booted */ struct event_ft_fixup { oftree tree; + struct bootm_headers *images; } ft_fixup; }; @@ -143,8 +145,8 @@ static inline const char *event_spy_id(struct evspy_info *spy) * vbe_simple.c - so for now, make it global. */ #define EVENT_SPY(_type, _func) \ - __used ll_entry_declare(struct evspy_info, _type, evspy_info) = \ - _ESPY_REC(_type, _func) + __used ll_entry_declare(struct evspy_info, _type ## _3_ ## _func, \ + evspy_info) = _ESPY_REC(_type, _func) /** * event_register - register a new spy diff --git a/include/image.h b/include/image.h index d7d756c645..eb2513c5b7 100644 --- a/include/image.h +++ b/include/image.h @@ -263,7 +263,7 @@ enum { * Legacy format image header, * all data in network byte order (aka natural aka bigendian). */ -typedef struct image_header { +struct legacy_img_hdr { uint32_t ih_magic; /* Image Header Magic Number */ uint32_t ih_hcrc; /* Image Header CRC Checksum */ uint32_t ih_time; /* Image Creation Timestamp */ @@ -276,28 +276,28 @@ typedef struct image_header { uint8_t ih_type; /* Image Type */ uint8_t ih_comp; /* Compression Type */ uint8_t ih_name[IH_NMLEN]; /* Image Name */ -} image_header_t; +}; -typedef struct image_info { +struct image_info { ulong start, end; /* start/end of blob */ ulong image_start, image_len; /* start of image within blob, len of image */ ulong load; /* load addr for the image */ uint8_t comp, type, os; /* compression, type of image, os type */ uint8_t arch; /* CPU architecture */ -} image_info_t; +}; /* * Legacy and FIT format headers used by do_bootm() and do_bootm_() * routines. */ -typedef struct bootm_headers { +struct bootm_headers { /* * Legacy os image header, if it is a multi component image * then boot_get_ramdisk() and get_fdt() will attempt to get * data from second and third component accordingly. */ - image_header_t *legacy_hdr_os; /* image header pointer */ - image_header_t legacy_hdr_os_copy; /* header copy */ + struct legacy_img_hdr *legacy_hdr_os; /* image header pointer */ + struct legacy_img_hdr legacy_hdr_os_copy; /* header copy */ ulong legacy_hdr_valid; /* @@ -324,7 +324,7 @@ typedef struct bootm_headers { int fit_noffset_setup;/* x86 setup subimage node offset */ #ifndef USE_HOSTCC - image_info_t os; /* os image info */ + struct image_info os; /* os image info */ ulong ep; /* entry point of OS */ ulong rd_start, rd_end;/* ramdisk start/end */ @@ -341,26 +341,32 @@ typedef struct bootm_headers { int verify; /* env_get("verify")[0] != 'n' */ -#define BOOTM_STATE_START (0x00000001) -#define BOOTM_STATE_FINDOS (0x00000002) -#define BOOTM_STATE_FINDOTHER (0x00000004) -#define BOOTM_STATE_LOADOS (0x00000008) -#define BOOTM_STATE_RAMDISK (0x00000010) -#define BOOTM_STATE_FDT (0x00000020) -#define BOOTM_STATE_OS_CMDLINE (0x00000040) -#define BOOTM_STATE_OS_BD_T (0x00000080) -#define BOOTM_STATE_OS_PREP (0x00000100) -#define BOOTM_STATE_OS_FAKE_GO (0x00000200) /* 'Almost' run the OS */ -#define BOOTM_STATE_OS_GO (0x00000400) -#define BOOTM_STATE_PRE_LOAD 0x00000800 +#define BOOTM_STATE_START 0x00000001 +#define BOOTM_STATE_FINDOS 0x00000002 +#define BOOTM_STATE_FINDOTHER 0x00000004 +#define BOOTM_STATE_LOADOS 0x00000008 +#define BOOTM_STATE_RAMDISK 0x00000010 +#define BOOTM_STATE_FDT 0x00000020 +#define BOOTM_STATE_OS_CMDLINE 0x00000040 +#define BOOTM_STATE_OS_BD_T 0x00000080 +#define BOOTM_STATE_OS_PREP 0x00000100 +#define BOOTM_STATE_OS_FAKE_GO 0x00000200 /* 'Almost' run the OS */ +#define BOOTM_STATE_OS_GO 0x00000400 +#define BOOTM_STATE_PRE_LOAD 0x00000800 int state; #if defined(CONFIG_LMB) && !defined(USE_HOSTCC) struct lmb lmb; /* for memory mgmt */ #endif -} bootm_headers_t; +}; -extern bootm_headers_t images; +#ifdef CONFIG_LMB +#define images_lmb(_images) (&(_images)->lmb) +#else +#define images_lmb(_images) NULL +#endif + +extern struct bootm_headers images; /* * Some systems (for example LWMON) have very short watchdog periods; @@ -524,7 +530,7 @@ enum fit_load_op { FIT_LOAD_REQUIRED, /* Must be provided */ }; -int boot_get_setup(bootm_headers_t *images, uint8_t arch, ulong *setup_start, +int boot_get_setup(struct bootm_headers *images, uint8_t arch, ulong *setup_start, ulong *setup_len); /* Image format types, returned by _get_format() routine */ @@ -538,11 +544,11 @@ ulong genimg_get_kernel_addr_fit(char * const img_addr, const char **fit_uname_kernel); ulong genimg_get_kernel_addr(char * const img_addr); int genimg_get_format(const void *img_addr); -int genimg_has_config(bootm_headers_t *images); +int genimg_has_config(struct bootm_headers *images); -int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_fpga(int argc, char *const argv[], struct bootm_headers *images, uint8_t arch, const ulong *ld_start, ulong * const ld_len); -int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_ramdisk(int argc, char *const argv[], struct bootm_headers *images, uint8_t arch, ulong *rd_start, ulong *rd_end); /** @@ -566,10 +572,10 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, * 0, if only valid images or no images are found * error code, if an error occurs during fit_image_load */ -int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_loadable(int argc, char *const argv[], struct bootm_headers *images, uint8_t arch, const ulong *ld_start, ulong *const ld_len); -int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, +int boot_get_setup_fit(struct bootm_headers *images, uint8_t arch, ulong *setup_start, ulong *setup_len); /** @@ -593,9 +599,9 @@ int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, * * Return: node offset of base image, or -ve error code on error */ -int boot_get_fdt_fit(bootm_headers_t *images, ulong addr, - const char **fit_unamep, const char **fit_uname_configp, - int arch, ulong *datap, ulong *lenp); +int boot_get_fdt_fit(struct bootm_headers *images, ulong addr, + const char **fit_unamep, const char **fit_uname_configp, + int arch, ulong *datap, ulong *lenp); /** * fit_image_load() - load an image from a FIT @@ -627,7 +633,7 @@ int boot_get_fdt_fit(bootm_headers_t *images, ulong addr, * @param lenp Returns length of loaded image * Return: node offset of image, or -ve error code on error */ -int fit_image_load(bootm_headers_t *images, ulong addr, +int fit_image_load(struct bootm_headers *images, ulong addr, const char **fit_unamep, const char **fit_uname_configp, int arch, int image_type, int bootstage_id, enum fit_load_op load_op, ulong *datap, ulong *lenp); @@ -671,11 +677,11 @@ int image_source_script(ulong addr, const char *fit_uname); * @param prop_name Property name to look up (FIT_..._PROP) * @param addr Address of FIT in memory */ -int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name, - ulong addr); +int fit_get_node_from_config(struct bootm_headers *images, + const char *prop_name, ulong addr); int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, - bootm_headers_t *images, + struct bootm_headers *images, char **of_flat_tree, ulong *of_size); void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob); int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size); @@ -690,11 +696,11 @@ int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd); /*******************************************************************/ static inline uint32_t image_get_header_size(void) { - return (sizeof(image_header_t)); + return sizeof(struct legacy_img_hdr); } #define image_get_hdr_l(f) \ - static inline uint32_t image_get_##f(const image_header_t *hdr) \ + static inline uint32_t image_get_##f(const struct legacy_img_hdr *hdr) \ { \ return uimage_to_cpu(hdr->ih_##f); \ } @@ -707,7 +713,7 @@ image_get_hdr_l(ep) /* image_get_ep */ image_get_hdr_l(dcrc) /* image_get_dcrc */ #define image_get_hdr_b(f) \ - static inline uint8_t image_get_##f(const image_header_t *hdr) \ + static inline uint8_t image_get_##f(const struct legacy_img_hdr *hdr) \ { \ return hdr->ih_##f; \ } @@ -716,12 +722,12 @@ image_get_hdr_b(arch) /* image_get_arch */ image_get_hdr_b(type) /* image_get_type */ image_get_hdr_b(comp) /* image_get_comp */ -static inline char *image_get_name(const image_header_t *hdr) +static inline char *image_get_name(const struct legacy_img_hdr *hdr) { return (char *)hdr->ih_name; } -static inline uint32_t image_get_data_size(const image_header_t *hdr) +static inline uint32_t image_get_data_size(const struct legacy_img_hdr *hdr) { return image_get_size(hdr); } @@ -737,22 +743,23 @@ static inline uint32_t image_get_data_size(const image_header_t *hdr) * returns: * image payload data start address */ -static inline ulong image_get_data(const image_header_t *hdr) +static inline ulong image_get_data(const struct legacy_img_hdr *hdr) { return ((ulong)hdr + image_get_header_size()); } -static inline uint32_t image_get_image_size(const image_header_t *hdr) +static inline uint32_t image_get_image_size(const struct legacy_img_hdr *hdr) { return (image_get_size(hdr) + image_get_header_size()); } -static inline ulong image_get_image_end(const image_header_t *hdr) + +static inline ulong image_get_image_end(const struct legacy_img_hdr *hdr) { return ((ulong)hdr + image_get_image_size(hdr)); } #define image_set_hdr_l(f) \ - static inline void image_set_##f(image_header_t *hdr, uint32_t val) \ + static inline void image_set_##f(struct legacy_img_hdr *hdr, uint32_t val) \ { \ hdr->ih_##f = cpu_to_uimage(val); \ } @@ -765,7 +772,7 @@ image_set_hdr_l(ep) /* image_set_ep */ image_set_hdr_l(dcrc) /* image_set_dcrc */ #define image_set_hdr_b(f) \ - static inline void image_set_##f(image_header_t *hdr, uint8_t val) \ + static inline void image_set_##f(struct legacy_img_hdr *hdr, uint8_t val) \ { \ hdr->ih_##f = val; \ } @@ -774,13 +781,13 @@ image_set_hdr_b(arch) /* image_set_arch */ image_set_hdr_b(type) /* image_set_type */ image_set_hdr_b(comp) /* image_set_comp */ -static inline void image_set_name(image_header_t *hdr, const char *name) +static inline void image_set_name(struct legacy_img_hdr *hdr, const char *name) { strncpy(image_get_name(hdr), name, IH_NMLEN); } -int image_check_hcrc(const image_header_t *hdr); -int image_check_dcrc(const image_header_t *hdr); +int image_check_hcrc(const struct legacy_img_hdr *hdr); +int image_check_dcrc(const struct legacy_img_hdr *hdr); #ifndef USE_HOSTCC ulong env_get_bootm_low(void); phys_size_t env_get_bootm_size(void); @@ -788,15 +795,17 @@ phys_size_t env_get_bootm_mapsize(void); #endif void memmove_wd(void *to, void *from, size_t len, ulong chunksz); -static inline int image_check_magic(const image_header_t *hdr) +static inline int image_check_magic(const struct legacy_img_hdr *hdr) { return (image_get_magic(hdr) == IH_MAGIC); } -static inline int image_check_type(const image_header_t *hdr, uint8_t type) + +static inline int image_check_type(const struct legacy_img_hdr *hdr, uint8_t type) { return (image_get_type(hdr) == type); } -static inline int image_check_arch(const image_header_t *hdr, uint8_t arch) + +static inline int image_check_arch(const struct legacy_img_hdr *hdr, uint8_t arch) { /* Let's assume that sandbox can load any architecture */ if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX)) @@ -804,19 +813,20 @@ static inline int image_check_arch(const image_header_t *hdr, uint8_t arch) return (image_get_arch(hdr) == arch) || (image_get_arch(hdr) == IH_ARCH_ARM && arch == IH_ARCH_ARM64); } -static inline int image_check_os(const image_header_t *hdr, uint8_t os) + +static inline int image_check_os(const struct legacy_img_hdr *hdr, uint8_t os) { return (image_get_os(hdr) == os); } -ulong image_multi_count(const image_header_t *hdr); -void image_multi_getimg(const image_header_t *hdr, ulong idx, +ulong image_multi_count(const struct legacy_img_hdr *hdr); +void image_multi_getimg(const struct legacy_img_hdr *hdr, ulong idx, ulong *data, ulong *len); void image_print_contents(const void *hdr); #ifndef USE_HOSTCC -static inline int image_check_target_arch(const image_header_t *hdr) +static inline int image_check_target_arch(const struct legacy_img_hdr *hdr) { #ifndef IH_ARCH_DEFAULT # error "please define IH_ARCH_DEFAULT in your arch asm/u-boot.h" @@ -865,7 +875,7 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, * @lmb: Points to logical memory block structure * Return: 0 if ok, <0 on failure */ -int image_setup_libfdt(bootm_headers_t *images, void *blob, +int image_setup_libfdt(struct bootm_headers *images, void *blob, int of_size, struct lmb *lmb); /** @@ -877,7 +887,7 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob, * @param images Images information * Return: 0 if ok, <0 on failure */ -int image_setup_linux(bootm_headers_t *images); +int image_setup_linux(struct bootm_headers *images); /** * bootz_setup() - Extract stat and size of a Linux xImage diff --git a/include/init.h b/include/init.h index 7b8f62c121..50a8302dc5 100644 --- a/include/init.h +++ b/include/init.h @@ -291,7 +291,7 @@ int show_board_info(void); * * @param total_size Size of U-Boot (unused?) */ -ulong board_get_usable_ram_top(ulong total_size); +phys_size_t board_get_usable_ram_top(phys_size_t total_size); int board_early_init_f(void); @@ -343,6 +343,19 @@ void bdinfo_print_num_ll(const char *name, unsigned long long value); /* Print a clock speed in MHz */ void bdinfo_print_mhz(const char *name, unsigned long hz); +/** + * bdinfo_print_size - print size variables in bdinfo format + * @name: string to print before the size + * @size: size to print + * + * Helper function for displaying size variables as properly formatted bdinfo + * entries. The size is printed as "xxx Bytes", "xxx KiB", "xxx MiB", + * "xxx GiB", etc. as needed; + * + * For use in arch_print_bdinfo(). + */ +void bdinfo_print_size(const char *name, uint64_t size); + /* Show arch-specific information for the 'bd' command */ void arch_print_bdinfo(void); diff --git a/include/linux/compat.h b/include/linux/compat.h index 3d0acbd582..921e698f40 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -2,6 +2,7 @@ #define _LINUX_COMPAT_H_ #include +#include #include #include @@ -230,7 +231,6 @@ typedef unsigned long blkcnt_t; #define try_to_freeze(...) 0 #define set_current_state(...) do { } while (0) #define kthread_should_stop(...) 0 -#define schedule() do { } while (0) #define setup_timer(timer, func, data) do {} while (0) #define del_timer_sync(timer) do {} while (0) diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index aa45558b3d..fb002ae641 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -29,9 +29,8 @@ struct nand_flash_dev; struct device_node; /* Get the flash and manufacturer id and lookup if the type is supported. */ -struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, - int *maf_id, int *dev_id, - struct nand_flash_dev *type); +int nand_detect(struct nand_chip *chip, int *maf_id, int *dev_id, + struct nand_flash_dev *type); /* Scan and identify a NAND device */ int nand_scan(struct mtd_info *mtd, int max_chips); @@ -976,7 +975,7 @@ struct nand_chip { void *priv; struct { - const struct nand_manufacturers *desc; + const struct nand_manufacturer *desc; void *priv; } manufacturer; }; @@ -1124,19 +1123,19 @@ struct nand_flash_dev { }; /** - * struct nand_manufacturers - NAND Flash Manufacturer ID Structure + * struct nand_manufacturer - NAND Flash Manufacturer ID Structure * @name: Manufacturer name * @id: manufacturer ID code of device. * @ops: manufacturer operations */ -struct nand_manufacturers { +struct nand_manufacturer { int id; char *name; const struct nand_manufacturer_ops *ops; }; extern struct nand_flash_dev nand_flash_ids[]; -extern struct nand_manufacturers nand_manuf_ids[]; +extern struct nand_manufacturer nand_manuf_ids[]; extern const struct nand_manufacturer_ops toshiba_nand_manuf_ops; extern const struct nand_manufacturer_ops samsung_nand_manuf_ops; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 2595bad9df..638d807ee5 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -11,6 +11,7 @@ #include #include #include +#include /* * Manufacturer IDs @@ -522,6 +523,7 @@ struct spi_flash { * @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode * @octal_dtr_enable: [FLASH-SPECIFIC] enables SPI NOR octal DTR mode. * @ready: [FLASH-SPECIFIC] check if the flash is ready + * @dirmap: pointers to struct spi_mem_dirmap_desc for reads/writes. * @priv: the private data */ struct spi_nor { @@ -572,6 +574,11 @@ struct spi_nor { int (*octal_dtr_enable)(struct spi_nor *nor); int (*ready)(struct spi_nor *nor); + struct { + struct spi_mem_dirmap_desc *rdesc; + struct spi_mem_dirmap_desc *wdesc; + } dirmap; + void *priv; char mtd_name[MTD_NAME_SIZE(MTD_DEV_TYPE_NOR)]; /* Compatibility for spi_flash, remove once sf layer is merged with mtd */ @@ -595,6 +602,17 @@ device_node *spi_nor_get_flash_node(struct spi_nor *nor) } #endif /* __UBOOT__ */ +/** + * spi_nor_setup_op() - Set up common properties of a spi-mem op. + * @nor: pointer to a 'struct spi_nor' + * @op: pointer to the 'struct spi_mem_op' whose properties + * need to be initialized. + * @proto: the protocol from which the properties need to be set. + */ +void spi_nor_setup_op(const struct spi_nor *nor, + struct spi_mem_op *op, + const enum spi_nor_protocol proto); + /** * spi_nor_scan() - scan the SPI NOR * @nor: the spi_nor structure diff --git a/include/log.h b/include/log.h index df497bad18..8a7b961bbf 100644 --- a/include/log.h +++ b/include/log.h @@ -322,7 +322,10 @@ void __assert_fail(const char *assertion, const char *file, unsigned int line, * * or: * - * return log_msg_ret("fred failed", fred_call()); + * return log_msg_ret("get", fred_call()); + * + * It is recommended to use <= 3 characters for the name since this will only + * use 4 bytes in rodata */ #define log_ret(_ret) ({ \ int __ret = (_ret); \ diff --git a/include/malloc.h b/include/malloc.h index e8c8b254c0..161ccbd129 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -883,6 +883,18 @@ extern Void_t* sbrk(); void malloc_simple_info(void); +/** + * malloc_enable_testing() - Put malloc() into test mode + * + * This only works if UNIT_TESTING is enabled + * + * @max_allocs: return -ENOMEM after max_allocs calls to malloc() + */ +void malloc_enable_testing(int max_allocs); + +/** malloc_disable_testing() - Put malloc() into normal mode */ +void malloc_disable_testing(void); + #if CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE) #define malloc malloc_simple #define realloc realloc_simple diff --git a/include/menu.h b/include/menu.h index e74616cae8..702aacb170 100644 --- a/include/menu.h +++ b/include/menu.h @@ -48,6 +48,9 @@ enum bootmenu_key { KEY_DOWN, KEY_SELECT, KEY_QUIT, + KEY_PLUS, + KEY_MINUS, + KEY_SPACE, }; void bootmenu_autoboot_loop(struct bootmenu_data *menu, diff --git a/include/mmc.h b/include/mmc.h index f519d86972..027e8bcc73 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -767,7 +767,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv); /** * mmc_bind() - Set up a new MMC device ready for probing * - * A child block device is bound with the IF_TYPE_MMC interface type. This + * A child block device is bound with the UCLASS_MMC interface type. This * allows the device to be used with CONFIG_BLK * * @dev: MMC device to set up diff --git a/include/os.h b/include/os.h index 148178787b..5b353ae9d9 100644 --- a/include/os.h +++ b/include/os.h @@ -295,6 +295,14 @@ void os_putc(int ch); */ void os_puts(const char *str); +/** + * os_flush() - flush controlling OS terminal + * + * This bypasses the U-Boot console support and flushes directly the OS + * stdout file descriptor. + */ +void os_flush(void); + /** * os_write_ram_buf() - write the sandbox RAM buffer to a existing file * diff --git a/include/scsi.h b/include/scsi.h index b47c7463c1..94e1d8ccb2 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -15,27 +15,47 @@ struct udevice; +/** + * struct scsi_cmd - information about a SCSI command to be processed + * + * @cmd: command + * @sense_buf: for request sense + * @status: SCSI Status + * @target: Target ID + * @lun: Target LUN + * @cmdlen: command len + * @datalen: Total data length + * @pdata: pointer to data + * @msgout: Messge out buffer (NOT USED) + * @msgin: Message in buffer + * @sensecmdlen: Sense command len + * @sensedatalen: Sense data len + * @sensecmd: Sense command + * @contr_stat: Controller Status + * @trans_bytes: tranfered bytes + * @priv: Private value + * @dma_dir: Direction of data structure + */ struct scsi_cmd { - unsigned char cmd[16]; /* command */ - /* for request sense */ - unsigned char sense_buf[64] + unsigned char cmd[16]; + unsigned char sense_buf[64] __attribute__((aligned(ARCH_DMA_MINALIGN))); - unsigned char status; /* SCSI Status */ - unsigned char target; /* Target ID */ - unsigned char lun; /* Target LUN */ - unsigned char cmdlen; /* command len */ - unsigned long datalen; /* Total data length */ - unsigned char * pdata; /* pointer to data */ - unsigned char msgout[12]; /* Messge out buffer (NOT USED) */ - unsigned char msgin[12]; /* Message in buffer */ - unsigned char sensecmdlen; /* Sense command len */ - unsigned long sensedatalen; /* Sense data len */ - unsigned char sensecmd[6]; /* Sense command */ - unsigned long contr_stat; /* Controller Status */ - unsigned long trans_bytes; /* tranfered bytes */ + unsigned char status; + unsigned char target; + unsigned char lun; + unsigned char cmdlen; + unsigned long datalen; + unsigned char *pdata; + unsigned char msgout[12]; + unsigned char msgin[12]; + unsigned char sensecmdlen; + unsigned long sensedatalen; + unsigned char sensecmd[6]; + unsigned long contr_stat; + unsigned long trans_bytes; - unsigned int priv; - enum dma_data_direction dma_dir; + unsigned int priv; + enum dma_data_direction dma_dir; }; /*----------------------------------------------------------- @@ -167,6 +187,74 @@ struct scsi_cmd { #define SCSI_WRITE_LONG 0x3F /* Write Long (O) */ #define SCSI_WRITE_SAME 0x41 /* Write Same (O) */ +/** + * enum scsi_cmd_phase - current phase of the SCSI protocol + * + * @SCSIPH_START: Start phase + * @SCSIPH_DATA: Data phase + * @SCSIPH_STATUS: Status phase + */ +enum scsi_cmd_phase { + SCSIPH_START, + SCSIPH_DATA, + SCSIPH_STATUS, +}; + +/** + * struct scsi_inquiry_resp - holds a SCSI inquiry command + * + * @type; command type + * @flags; command flags + * @version; command version + * @data_format; data format + * @additional_len; additional data length + * @spare[3]; spare bytes + * @vendor[8]; vendor information + * @product[16]; production information + * @revision[4]; revision information + */ +struct scsi_inquiry_resp { + u8 type; + u8 flags; + u8 version; + u8 data_format; + u8 additional_len; + u8 spare[3]; + char vendor[8]; + char product[16]; + char revision[4]; +}; + +/** + * struct scsi_read_capacity_resp - holds the response to a read-capacity cmd + * + * @last_block_addr: Logical block address of last block + * @block_len: Length of each block in bytes + */ +struct scsi_read_capacity_resp { + u32 last_block_addr; + u32 block_len; +}; + +/** + * struct scsi_read10_req - holds a SCSI READ10 request + * + * @cmd; command type + * @lun_flags; LUN flags + * @lba; Logical block address to start reading from + * @spare; spare bytes + * @xfer_len: number of blocks to read + * @spare2: more spare bytes + */ +struct __packed scsi_read10_req { + u8 cmd; + u8 lun_flags; + u32 lba; + u8 spare; + u16 xfer_len; + u8 spare2[3]; +}; + /** * struct scsi_plat - stores information about SCSI controller * diff --git a/include/scsi_emul.h b/include/scsi_emul.h new file mode 100644 index 0000000000..13c3f860b4 --- /dev/null +++ b/include/scsi_emul.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Emulation of enough SCSI commands to find and read from a unit + * + * Copyright 2022 Google LLC + * Written by Simon Glass + * + * implementations of SCSI functions required so that CONFIG_SCSI can be enabled + * for sandbox + */ + +#ifndef __scsi_emul_h +#define __scsi_emul_h + +/** + * struct scsi_emul_info - information for emulating a SCSI device + * + * @vendor: Vendor name + * @product: Product name + * @block_size: Block size of device in bytes (normally 512) + * @file_size: Size of the backing file for this emulator, in bytes + * @seek_block: Seek position for file (block number) + * + * @phase: Current SCSI phase + * @buff_used: Number of bytes ready to transfer back to host + * @read_len: Number of bytes of data left in the current read command + * @alloc_len: Allocation length from the last incoming command + * @transfer_len: Transfer length from CBW header + * @buff: Data buffer for outgoing data + */ +struct scsi_emul_info { + /* provided by the caller: */ + void *buff; + const char *vendor; + const char *product; + int block_size; + loff_t file_size; + int seek_block; + + /* state maintained by the emulator: */ + enum scsi_cmd_phase phase; + int buff_used; + int read_len; + uint seek_pos; + int alloc_len; + uint transfer_len; +}; + +/* Indicates that a read is being started */ +#define SCSI_EMUL_DO_READ 1 + +/** + * sb_scsi_emul_command() - Process a SCSI command + * + * This sets up the response in info->buff and updates various other values + * in info. + * + * If SCSI_EMUL_DO_READ is returned then the caller should set up so that the + * backing file can be read, or return an error status if there is no file. + * + * @info: Emulation information + * @req: Request to process + * @len: Length of request in bytes + * @return SCSI_EMUL_DO_READ if a read has started, 0 if some other operation + * has started, -ve if there was an error + */ +int sb_scsi_emul_command(struct scsi_emul_info *info, + const struct scsi_cmd *req, int len); + +#endif diff --git a/include/serial.h b/include/serial.h index 8c2e7adbc3..fe01bcfadb 100644 --- a/include/serial.h +++ b/include/serial.h @@ -362,6 +362,11 @@ void serial_setbrg(void); void serial_putc(const char ch); void serial_putc_raw(const char ch); void serial_puts(const char *str); +#if defined(CONFIG_CONSOLE_FLUSH_SUPPORT) && CONFIG_IS_ENABLED(DM_SERIAL) +void serial_flush(void); +#else +static inline void serial_flush(void) {} +#endif int serial_getc(void); int serial_tstc(void); diff --git a/include/spi-mem.h b/include/spi-mem.h index 32ffdc2e0f..b07cf2ed83 100644 --- a/include/spi-mem.h +++ b/include/spi-mem.h @@ -134,6 +134,48 @@ struct spi_mem_op { .dummy = __dummy, \ .data = __data, \ } +/** + * struct spi_mem_dirmap_info - Direct mapping information + * @op_tmpl: operation template that should be used by the direct mapping when + * the memory device is accessed + * @offset: absolute offset this direct mapping is pointing to + * @length: length in byte of this direct mapping + * + * This information is used by the controller specific implementation to know + * the portion of memory that is directly mapped and the spi_mem_op that should + * be used to access the device. + * A direct mapping is only valid for one direction (read or write) and this + * direction is directly encoded in the ->op_tmpl.data.dir field. + */ +struct spi_mem_dirmap_info { + struct spi_mem_op op_tmpl; + u64 offset; + u64 length; +}; + +/** + * struct spi_mem_dirmap_desc - Direct mapping descriptor + * @mem: the SPI memory device this direct mapping is attached to + * @info: information passed at direct mapping creation time + * @nodirmap: set to 1 if the SPI controller does not implement + * ->mem_ops->dirmap_create() or when this function returned an + * error. If @nodirmap is true, all spi_mem_dirmap_{read,write}() + * calls will use spi_mem_exec_op() to access the memory. This is a + * degraded mode that allows spi_mem drivers to use the same code + * no matter whether the controller supports direct mapping or not + * @priv: field pointing to controller specific data + * + * Common part of a direct mapping descriptor. This object is created by + * spi_mem_dirmap_create() and controller implementation of ->create_dirmap() + * can create/attach direct mapping resources to the descriptor in the ->priv + * field. + */ +struct spi_mem_dirmap_desc { + struct spi_slave *slave; + struct spi_mem_dirmap_info info; + unsigned int nodirmap; + void *priv; +}; #ifndef __UBOOT__ /** @@ -183,10 +225,32 @@ static inline void *spi_mem_get_drvdata(struct spi_mem *mem) * limitations) * @supports_op: check if an operation is supported by the controller * @exec_op: execute a SPI memory operation + * @dirmap_create: create a direct mapping descriptor that can later be used to + * access the memory device. This method is optional + * @dirmap_destroy: destroy a memory descriptor previous created by + * ->dirmap_create() + * @dirmap_read: read data from the memory device using the direct mapping + * created by ->dirmap_create(). The function can return less + * data than requested (for example when the request is crossing + * the currently mapped area), and the caller of + * spi_mem_dirmap_read() is responsible for calling it again in + * this case. + * @dirmap_write: write data to the memory device using the direct mapping + * created by ->dirmap_create(). The function can return less + * data than requested (for example when the request is crossing + * the currently mapped area), and the caller of + * spi_mem_dirmap_write() is responsible for calling it again in + * this case. * * This interface should be implemented by SPI controllers providing an * high-level interface to execute SPI memory operation, which is usually the * case for QSPI controllers. + * + * Note on ->dirmap_{read,write}(): drivers should avoid accessing the direct + * mapping from the CPU because doing that can stall the CPU waiting for the + * SPI mem transaction to finish, and this will make real-time maintainers + * unhappy and might make your system less reactive. Instead, drivers should + * use DMA to access this direct mapping. */ struct spi_controller_mem_ops { int (*adjust_op_size)(struct spi_slave *slave, struct spi_mem_op *op); @@ -194,6 +258,12 @@ struct spi_controller_mem_ops { const struct spi_mem_op *op); int (*exec_op)(struct spi_slave *slave, const struct spi_mem_op *op); + int (*dirmap_create)(struct spi_mem_dirmap_desc *desc); + void (*dirmap_destroy)(struct spi_mem_dirmap_desc *desc); + ssize_t (*dirmap_read)(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf); + ssize_t (*dirmap_write)(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, const void *buf); }; #ifndef __UBOOT__ @@ -260,6 +330,15 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op); bool spi_mem_default_supports_op(struct spi_slave *mem, const struct spi_mem_op *op); +struct spi_mem_dirmap_desc * +spi_mem_dirmap_create(struct spi_slave *mem, + const struct spi_mem_dirmap_info *info); +void spi_mem_dirmap_destroy(struct spi_mem_dirmap_desc *desc); +ssize_t spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf); +ssize_t spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, const void *buf); + #ifndef __UBOOT__ int spi_mem_driver_register_with_owner(struct spi_mem_driver *drv, struct module *owner); diff --git a/include/spl.h b/include/spl.h index aac6648f94..0fc3686bbc 100644 --- a/include/spl.h +++ b/include/spl.h @@ -17,7 +17,7 @@ #include struct blk_desc; -struct image_header; +struct legacy_img_hdr; /* Value in r0 indicates we booted from U-Boot */ #define UBOOT_NOT_LOADED_FROM_SPL 0x13578642 @@ -29,7 +29,7 @@ struct image_header; #define MMCSD_MODE_EMMCBOOT 3 struct blk_desc; -struct image_header; +struct legacy_img_hdr; struct spl_boot_device; /* @@ -476,7 +476,7 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image); */ int spl_parse_image_header(struct spl_image_info *spl_image, const struct spl_boot_device *bootdev, - const struct image_header *header); + const struct legacy_img_hdr *header); void spl_board_prepare_for_linux(void); @@ -865,7 +865,7 @@ void spl_perform_fixups(struct spl_image_info *spl_image); * Returns memory area which can be populated by partial image data, * ie. uImage or fitImage header. */ -struct image_header *spl_get_load_buffer(ssize_t offset, size_t size); +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size); void spl_save_restore_data(void); #endif diff --git a/include/stdio.h b/include/stdio.h index 1939a48f0f..3241e2d493 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -15,6 +15,11 @@ int tstc(void); defined(CONFIG_SPL_SERIAL)) void putc(const char c); void puts(const char *s); +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void flush(void); +#else +static inline void flush(void) {} +#endif int __printf(1, 2) printf(const char *fmt, ...); int vprintf(const char *fmt, va_list args); #else @@ -26,6 +31,10 @@ static inline void puts(const char *s) { } +static inline void flush(void) +{ +} + static inline int __printf(1, 2) printf(const char *fmt, ...) { return 0; @@ -48,11 +57,17 @@ static inline int vprintf(const char *fmt, va_list args) /* stderr */ #define eputc(c) fputc(stderr, c) #define eputs(s) fputs(stderr, s) +#define eflush() fflush(stderr) #define eprintf(fmt, args...) fprintf(stderr, fmt, ##args) int __printf(2, 3) fprintf(int file, const char *fmt, ...); void fputs(int file, const char *s); void fputc(int file, const char c); +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void fflush(int file); +#else +static inline void fflush(int file) {} +#endif int ftstc(int file); int fgetc(int file); diff --git a/include/stdio_dev.h b/include/stdio_dev.h index 270fa2729f..3105928970 100644 --- a/include/stdio_dev.h +++ b/include/stdio_dev.h @@ -37,6 +37,13 @@ struct stdio_dev { void (*putc)(struct stdio_dev *dev, const char c); /* To put a string (accelerator) */ void (*puts)(struct stdio_dev *dev, const char *s); +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT + /* To flush output queue */ + void (*flush)(struct stdio_dev *dev); +#define STDIO_DEV_ASSIGN_FLUSH(dev, flush_func) ((dev)->flush = (flush_func)) +#else +#define STDIO_DEV_ASSIGN_FLUSH(dev, flush_func) +#endif /* INPUT functions */ diff --git a/include/tee/optee.h b/include/tee/optee.h index 5412bc7386..77729450bb 100644 --- a/include/tee/optee.h +++ b/include/tee/optee.h @@ -30,7 +30,7 @@ struct optee_header { }; static inline uint32_t -optee_image_get_entry_point(const struct image_header *hdr) +optee_image_get_entry_point(const struct legacy_img_hdr *hdr) { struct optee_header *optee_hdr = (struct optee_header *)(hdr + 1); @@ -38,7 +38,7 @@ optee_image_get_entry_point(const struct image_header *hdr) } static inline uint32_t -optee_image_get_load_addr(const struct image_header *hdr) +optee_image_get_load_addr(const struct legacy_img_hdr *hdr) { return optee_image_get_entry_point(hdr) - sizeof(struct optee_header); } diff --git a/include/tee/optee_service.h b/include/tee/optee_service.h new file mode 100644 index 0000000000..fca468af7c --- /dev/null +++ b/include/tee/optee_service.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * (C) Copyright 2022 Linaro Limited + */ + +#ifndef _OPTEE_SERVICE_H +#define _OPTEE_SERVICE_H + +/* + * struct optee_service - Discoverable OP-TEE service + * + * @driver_name - Name of the related driver + * @uuid - UUID of the OP-TEE service related to the driver + * + * Use macro OPTEE_SERVICE_DRIVER() to register a driver related to an + * OP-TEE service discovered when driver asks OP-TEE services enumaration. + */ +struct optee_service { + const char *driver_name; + const struct tee_optee_ta_uuid uuid; +}; + +#ifdef CONFIG_OPTEE_SERVICE_DISCOVERY +#define OPTEE_SERVICE_DRIVER(__name, __uuid, __drv_name) \ + ll_entry_declare(struct optee_service, __name, optee_service) = { \ + .uuid = __uuid, \ + .driver_name = __drv_name, \ + } +#else +#define OPTEE_SERVICE_DRIVER(__name, __uuid, __drv_name) \ + static int __name##__COUNTER__ __always_unused +#endif + +#endif /* _OPTEE_SERVICE_H */ diff --git a/include/test/test.h b/include/test/test.h index c888d68b1e..3bbd77c38b 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -20,6 +20,13 @@ * @testdev: Test device * @force_fail_alloc: Force all memory allocs to fail * @skip_post_probe: Skip uclass post-probe processing + * @fdt_chksum: crc8 of the device tree contents + * @fdt_copy: Copy of the device tree + * @fdt_size: Size of the device-tree copy + * @other_fdt: Buffer for the other FDT (UT_TESTF_OTHER_FDT) + * @other_fdt_size: Size of the other FDT (UT_TESTF_OTHER_FDT) + * @of_other: Live tree for the other FDT + * @runs_per_test: Number of times to run each test (typically 1) * @expect_str: Temporary string used to hold expected string value * @actual_str: Temporary string used to hold actual string value */ @@ -32,6 +39,13 @@ struct unit_test_state { struct udevice *testdev; int force_fail_alloc; int skip_post_probe; + uint fdt_chksum; + void *fdt_copy; + uint fdt_size; + void *other_fdt; + int other_fdt_size; + struct device_node *of_other; + int runs_per_test; char expect_str[512]; char actual_str[512]; }; @@ -46,8 +60,7 @@ enum { UT_TESTF_CONSOLE_REC = BIT(5), /* needs console recording */ /* do extra driver model init and uninit */ UT_TESTF_DM = BIT(6), - /* live or flat device tree, but not both in the same executable */ - UT_TESTF_LIVE_OR_FLAT = BIT(4), + UT_TESTF_OTHER_FDT = BIT(7), /* read in other device tree */ }; /** @@ -126,13 +139,24 @@ enum { */ struct udevice *testbus_get_clear_removed(void); +#ifdef CONFIG_SANDBOX +#include +#include +#endif + static inline void arch_reset_for_test(void) { #ifdef CONFIG_SANDBOX -#include - state_reset_for_test(state_get_current()); #endif } +static inline int test_load_other_fdt(struct unit_test_state *uts) +{ + int ret = 0; +#ifdef CONFIG_SANDBOX + ret = sandbox_load_other_fdt(&uts->other_fdt, &uts->other_fdt_size); +#endif + return ret; +} #endif /* __TEST_TEST_H */ diff --git a/include/test/ut.h b/include/test/ut.h index 18740f5807..f7217aa8ac 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -119,6 +119,11 @@ int ut_check_console_end(struct unit_test_state *uts); */ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); +/* Report a failure, with printf() string */ +#define ut_reportf(fmt, args...) \ + ut_failf(uts, __FILE__, __LINE__, __func__, "report", \ + fmt, ##args) + /* Assert that a condition is non-zero */ #define ut_assert(cond) \ if (!(cond)) { \ @@ -403,9 +408,10 @@ void test_set_state(struct unit_test_state *uts); * @count: Number of tests to run * @select_name: Name of a single test to run (from the list provided). If NULL * then all tests are run + * @runs_per_test: Number of times to run each test (typically 1) * Return: 0 if all tests passed, -1 if any failed */ int ut_run_list(const char *name, const char *prefix, struct unit_test *tests, - int count, const char *select_name); + int count, const char *select_name, int runs_per_test); #endif diff --git a/include/time.h b/include/time.h index 9deb2cf61c..3b2ba09124 100644 --- a/include/time.h +++ b/include/time.h @@ -83,6 +83,25 @@ uint64_t usec_to_tick(unsigned long usec); (time_after_eq(a,b) && \ time_before(a,c)) +/* Same as above, but does so with platform independent 64bit types. + * These must be used when utilizing jiffies_64 (i.e. return value of + * get_jiffies_64() */ +#define time_after64(a,b) \ + (typecheck(__u64, a) && \ + typecheck(__u64, b) && \ + ((__s64)((b) - (a)) < 0)) +#define time_before64(a,b) time_after64(b,a) + +#define time_after_eq64(a,b) \ + (typecheck(__u64, a) && \ + typecheck(__u64, b) && \ + ((__s64)((a) - (b)) >= 0)) +#define time_before_eq64(a,b) time_after_eq64(b,a) + +#define time_in_range64(a, b, c) \ + (time_after_eq64(a, b) && \ + time_before_eq64(a, c)) + /** * usec2ticks() - Convert microseconds to internal ticks * diff --git a/include/wait_bit.h b/include/wait_bit.h index dcc5c4fd39..f1d70aef87 100644 --- a/include/wait_bit.h +++ b/include/wait_bit.h @@ -63,7 +63,7 @@ static inline int wait_for_bit_##sfx(const void *reg, \ } \ \ udelay(1); \ - WATCHDOG_RESET(); \ + schedule(); \ } \ \ debug("%s: Timeout (reg=%p mask=%x wait_set=%i)\n", __func__, \ diff --git a/include/watchdog.h b/include/watchdog.h index 813cc8f2a5..ac5f11e376 100644 --- a/include/watchdog.h +++ b/include/watchdog.h @@ -10,7 +10,8 @@ #ifndef _WATCHDOG_H_ #define _WATCHDOG_H_ -#if !defined(__ASSEMBLY__) +#include + /* * Reset the watchdog timer, always returns 0 * @@ -18,7 +19,6 @@ * and the legacy arch//board.c code. */ int init_func_watchdog_reset(void); -#endif #if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG) #define INIT_FUNC_WATCHDOG_INIT init_func_watchdog_init, @@ -32,62 +32,15 @@ int init_func_watchdog_reset(void); # error "Configuration error: CONFIG_HW_WATCHDOG and CONFIG_WATCHDOG can't be used together." #endif -/* - * Hardware watchdog - */ -#ifdef CONFIG_HW_WATCHDOG - #if defined(__ASSEMBLY__) - #define WATCHDOG_RESET bl hw_watchdog_reset - #else - extern void hw_watchdog_reset(void); - - #define WATCHDOG_RESET hw_watchdog_reset - #endif /* __ASSEMBLY__ */ -#else - /* - * Maybe a software watchdog? - */ - #if defined(CONFIG_WATCHDOG) - #if defined(__ASSEMBLY__) - /* Don't require the watchdog to be enabled in SPL */ - #if defined(CONFIG_SPL_BUILD) && \ - !defined(CONFIG_SPL_WATCHDOG) - #define WATCHDOG_RESET /*XXX DO_NOT_DEL_THIS_COMMENT*/ - #else - #define WATCHDOG_RESET bl watchdog_reset - #endif - #else - /* Don't require the watchdog to be enabled in SPL */ - #if defined(CONFIG_SPL_BUILD) && \ - !defined(CONFIG_SPL_WATCHDOG) - #define WATCHDOG_RESET() {} - #else - extern void watchdog_reset(void); - - #define WATCHDOG_RESET watchdog_reset - #endif - #endif - #else - /* - * No hardware or software watchdog. - */ - #if defined(__ASSEMBLY__) - #define WATCHDOG_RESET /*XXX DO_NOT_DEL_THIS_COMMENT*/ - #else - #define WATCHDOG_RESET() {} - #endif /* __ASSEMBLY__ */ - #endif /* CONFIG_WATCHDOG && !__ASSEMBLY__ */ -#endif /* CONFIG_HW_WATCHDOG */ - /* * Prototypes from $(CPU)/cpu.c. */ -#if (defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)) && !defined(__ASSEMBLY__) +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) void hw_watchdog_init(void); #endif -#if defined(CONFIG_MPC85xx) && !defined(__ASSEMBLY__) +#if defined(CONFIG_MPC85xx) void init_85xx_watchdog(void); #endif #endif /* _WATCHDOG_H_ */ diff --git a/lib/bzip2/bzlib.c b/lib/bzip2/bzlib.c index 377b269b06..bd589aa810 100644 --- a/lib/bzip2/bzlib.c +++ b/lib/bzip2/bzlib.c @@ -844,7 +844,7 @@ int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) while (True) { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR; if (s->state == BZ_X_OUTPUT) { diff --git a/lib/bzip2/bzlib_decompress.c b/lib/bzip2/bzlib_decompress.c index 4412b8a23e..3b417d57b2 100644 --- a/lib/bzip2/bzlib_decompress.c +++ b/lib/bzip2/bzlib_decompress.c @@ -418,7 +418,7 @@ Int32 BZ2_decompress ( DState* s ) while (True) { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif if (nextSym == EOB) break; @@ -503,7 +503,7 @@ Int32 BZ2_decompress ( DState* s ) kk = MTFA_SIZE-1; for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif for (jj = MTFL_SIZE-1; jj >= 0; jj--) { s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj]; @@ -568,7 +568,7 @@ Int32 BZ2_decompress ( DState* s ) while (i != s->origPtr); #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif s->tPos = s->origPtr; s->nblock_used = 0; @@ -583,7 +583,7 @@ Int32 BZ2_decompress ( DState* s ) } else { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif /*-- compute the T^(-1) vector --*/ for (i = 0; i < nblock; i++) { diff --git a/lib/crc32.c b/lib/crc32.c index 5a3127e03a..aa94d70ef3 100644 --- a/lib/crc32.c +++ b/lib/crc32.c @@ -255,7 +255,7 @@ uint32_t crc32_wd(uint32_t crc, const unsigned char *buf, uInt len, chunk = chunk_sz; crc = crc32(crc, curr, chunk); curr += chunk; - WATCHDOG_RESET (); + schedule(); } #else crc = crc32(crc, buf, len); diff --git a/lib/display_options.c b/lib/display_options.c index 7feb446a55..80def5201f 100644 --- a/lib/display_options.c +++ b/lib/display_options.c @@ -127,6 +127,12 @@ void print_size(uint64_t size, const char *s) if (m >= 10) { m -= 10; n += 1; + + if (n == 1024 && i > 0) { + n = 1; + m = 0; + c = names[i - 1]; + } } } diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c index d57d281f85..3177ab67b8 100644 --- a/lib/efi_driver/efi_block_device.c +++ b/lib/efi_driver/efi_block_device.c @@ -128,7 +128,7 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) if (!obj) return -ENOENT; - devnum = blk_find_max_devnum(IF_TYPE_EFI_LOADER); + devnum = blk_find_max_devnum(UCLASS_EFI_LOADER); if (devnum == -ENODEV) devnum = 0; else if (devnum < 0) @@ -140,7 +140,7 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) sprintf(name, "efiblk#%d", devnum); /* Create driver model udevice for the EFI block io device */ - ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI_LOADER, + ret = blk_create_device(parent, "efi_blk", name, UCLASS_EFI_LOADER, devnum, io->media->block_size, (lbaint_t)io->media->last_block, &bdev); if (ret) diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index b8fb2701a7..41756ea539 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -20,7 +20,6 @@ config EFI_LOADER select EVENT_DYNAMIC select LIB_UUID imply PARTITION_UUIDS - select HAVE_BLOCK_DEVICE select REGEX imply FAT imply FAT_WRITE diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 234073ecb7..4b24b41047 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -19,6 +19,9 @@ static const struct efi_boot_services *bs; static const struct efi_runtime_services *rs; +const efi_guid_t efi_guid_bootmenu_auto_generated = + EFICONFIG_AUTO_GENERATED_ENTRY_GUID; + /* * bootmgr implements the logic of trying to find a payload to boot * based on the BootOrder + BootXXXX variables, and then loading it. @@ -243,6 +246,10 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle, } /* Set load options */ + if (size >= sizeof(efi_guid_t) && + !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated)) + size = 0; + if (size) { *load_options = malloc(size); if (!*load_options) { diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 6f7333638a..1bfd094e89 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -833,7 +833,7 @@ void efi_timer_check(void) efi_signal_event(evt); } efi_process_event_queue(); - WATCHDOG_RESET(); + schedule(); } /** @@ -2198,7 +2198,7 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle, /* Give the payload some time to boot */ efi_set_watchdog(0); - WATCHDOG_RESET(); + schedule(); out: if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) { if (ret != EFI_SUCCESS) @@ -2458,6 +2458,35 @@ static efi_status_t EFIAPI efi_protocols_per_handle( return EFI_EXIT(EFI_SUCCESS); } +efi_status_t efi_locate_handle_buffer_int(enum efi_locate_search_type search_type, + const efi_guid_t *protocol, void *search_key, + efi_uintn_t *no_handles, efi_handle_t **buffer) +{ + efi_status_t r; + efi_uintn_t buffer_size = 0; + + if (!no_handles || !buffer) { + r = EFI_INVALID_PARAMETER; + goto out; + } + *no_handles = 0; + *buffer = NULL; + r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, + *buffer); + if (r != EFI_BUFFER_TOO_SMALL) + goto out; + r = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, buffer_size, + (void **)buffer); + if (r != EFI_SUCCESS) + goto out; + r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, + *buffer); + if (r == EFI_SUCCESS) + *no_handles = buffer_size / sizeof(efi_handle_t); +out: + return r; +} + /** * efi_locate_handle_buffer() - locate handles implementing a protocol * @search_type: selection criterion @@ -2479,30 +2508,13 @@ efi_status_t EFIAPI efi_locate_handle_buffer( efi_uintn_t *no_handles, efi_handle_t **buffer) { efi_status_t r; - efi_uintn_t buffer_size = 0; EFI_ENTRY("%d, %pUs, %p, %p, %p", search_type, protocol, search_key, no_handles, buffer); - if (!no_handles || !buffer) { - r = EFI_INVALID_PARAMETER; - goto out; - } - *no_handles = 0; - *buffer = NULL; - r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, - *buffer); - if (r != EFI_BUFFER_TOO_SMALL) - goto out; - r = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, buffer_size, - (void **)buffer); - if (r != EFI_SUCCESS) - goto out; - r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, - *buffer); - if (r == EFI_SUCCESS) - *no_handles = buffer_size / sizeof(efi_handle_t); -out: + r = efi_locate_handle_buffer_int(search_type, protocol, search_key, + no_handles, buffer); + return EFI_EXIT(r); } diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index ee9dc6bbd8..cf9fbd9cb5 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -7,6 +7,7 @@ #define LOG_CATEGORY LOGC_EFI +#include #include #include #include @@ -1323,3 +1324,72 @@ out_of_memory: printf("ERROR: Out of memory\n"); return r; } + +/** + * efi_console_get_u16_string() - get user input string + * + * @cin: protocol interface to EFI_SIMPLE_TEXT_INPUT_PROTOCOL + * @buf: buffer to store user input string in UTF16 + * @count: number of u16 string including NULL terminator that buf has + * @filter_func: callback to filter user input + * @row: row number to locate user input form + * @col: column number to locate user input form + * Return: status code + */ +efi_status_t efi_console_get_u16_string(struct efi_simple_text_input_protocol *cin, + u16 *buf, efi_uintn_t count, + efi_console_filter_func filter_func, + int row, int col) +{ + efi_status_t ret; + efi_uintn_t len = 0; + struct efi_input_key key; + + printf(ANSI_CURSOR_POSITION + ANSI_CLEAR_LINE_TO_END + ANSI_CURSOR_SHOW, row, col); + + ret = EFI_CALL(cin->reset(cin, false)); + if (ret != EFI_SUCCESS) + return ret; + + for (;;) { + do { + ret = EFI_CALL(cin->read_key_stroke(cin, &key)); + mdelay(10); + } while (ret == EFI_NOT_READY); + + if (key.unicode_char == u'\b') { + if (len > 0) + buf[--len] = u'\0'; + + printf(ANSI_CURSOR_POSITION + "%ls" + ANSI_CLEAR_LINE_TO_END, row, col, buf); + continue; + } else if (key.unicode_char == u'\r') { + buf[len] = u'\0'; + return EFI_SUCCESS; + } else if (key.unicode_char == 0x3 || key.scan_code == 23) { + return EFI_ABORTED; + } else if (key.unicode_char < 0x20) { + /* ignore control codes other than Ctrl+C, '\r' and '\b' */ + continue; + } else if (key.scan_code != 0) { + /* only accept single ESC press for cancel */ + continue; + } + + if (filter_func) { + if (filter_func(&key) != EFI_SUCCESS) + continue; + } + + if (len >= (count - 1)) + continue; + + buf[len] = key.unicode_char; + len++; + printf(ANSI_CURSOR_POSITION "%ls", row, col, buf); + } +} diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 5feeb52ccb..39ea1a68a6 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -498,13 +498,13 @@ static efi_status_t efi_disk_add_dev( diskobj->media.last_block); /* Store first EFI system partition */ - if (part && !efi_system_partition.if_type) { + if (part && !efi_system_partition.uclass_id) { if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) { - efi_system_partition.if_type = desc->if_type; + efi_system_partition.uclass_id = desc->uclass_id; efi_system_partition.devnum = desc->devnum; efi_system_partition.part = part; EFI_PRINT("EFI system partition: %s %x:%x\n", - blk_get_if_type_name(desc->if_type), + blk_get_uclass_name(desc->uclass_id), desc->devnum, part); } } @@ -640,7 +640,7 @@ static int efi_disk_probe(void *ctx, struct event *event) * has already created an efi_disk at this moment. */ desc = dev_get_uclass_plat(dev); - if (desc->if_type != IF_TYPE_EFI_LOADER) { + if (desc->uclass_id != UCLASS_EFI_LOADER) { ret = efi_disk_create_raw(dev); if (ret) return -1; @@ -675,7 +675,7 @@ static int efi_disk_delete_raw(struct udevice *dev) return -1; desc = dev_get_uclass_plat(dev); - if (desc->if_type != IF_TYPE_EFI_LOADER) { + if (desc->uclass_id != UCLASS_EFI_LOADER) { diskobj = container_of(handle, struct efi_disk_obj, header); efi_free_pool(diskobj->dp); } @@ -761,6 +761,56 @@ efi_status_t efi_disk_init(void) return EFI_SUCCESS; } +/** + * efi_disk_get_device_name() - get U-Boot device name associated with EFI handle + * + * @handle: pointer to the EFI handle + * @buf: pointer to the buffer to store the string + * @size: size of buffer + * Return: status code + */ +efi_status_t efi_disk_get_device_name(const efi_handle_t handle, char *buf, int size) +{ + int count; + int diskid; + enum uclass_id id; + unsigned int part; + struct udevice *dev; + struct blk_desc *desc; + const char *if_typename; + bool is_partition = false; + struct disk_part *part_data; + + if (!handle || !buf || !size) + return EFI_INVALID_PARAMETER; + + dev = handle->dev; + id = device_get_uclass_id(dev); + if (id == UCLASS_BLK) { + desc = dev_get_uclass_plat(dev); + } else if (id == UCLASS_PARTITION) { + desc = dev_get_uclass_plat(dev_get_parent(dev)); + is_partition = true; + } else { + return EFI_INVALID_PARAMETER; + } + if_typename = blk_get_uclass_name(desc->uclass_id); + diskid = desc->devnum; + + if (is_partition) { + part_data = dev_get_uclass_plat(dev); + part = part_data->partnum; + count = snprintf(buf, size, "%s %d:%d", if_typename, diskid, part); + } else { + count = snprintf(buf, size, "%s %d", if_typename, diskid); + } + + if (count < 0 || (count + 1) > size) + return EFI_INVALID_PARAMETER; + + return EFI_SUCCESS; +} + /** * efi_disks_register() - ensure all block devices are available in UEFI * diff --git a/lib/efi_loader/efi_dt_fixup.c b/lib/efi_loader/efi_dt_fixup.c index d3923e5dba..838023c78f 100644 --- a/lib/efi_loader/efi_dt_fixup.c +++ b/lib/efi_loader/efi_dt_fixup.c @@ -145,7 +145,7 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb, efi_status_t ret; size_t required_size; size_t total_size; - bootm_headers_t img = { 0 }; + struct bootm_headers img = { 0 }; EFI_ENTRY("%p, %p, %p, %d", this, dtb, buffer_size, flags); diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c index 7a7077e6d0..c96a7f7ca3 100644 --- a/lib/efi_loader/efi_file.c +++ b/lib/efi_loader/efi_file.c @@ -246,10 +246,10 @@ error: return NULL; } -static efi_status_t efi_file_open_int(struct efi_file_handle *this, - struct efi_file_handle **new_handle, - u16 *file_name, u64 open_mode, - u64 attributes) +efi_status_t efi_file_open_int(struct efi_file_handle *this, + struct efi_file_handle **new_handle, + u16 *file_name, u64 open_mode, + u64 attributes) { struct file_handle *fh = to_fh(this); efi_status_t ret; @@ -369,11 +369,17 @@ static efi_status_t file_close(struct file_handle *fh) return EFI_SUCCESS; } -static efi_status_t EFIAPI efi_file_close(struct efi_file_handle *file) +efi_status_t efi_file_close_int(struct efi_file_handle *file) { struct file_handle *fh = to_fh(file); + + return file_close(fh); +} + +static efi_status_t EFIAPI efi_file_close(struct efi_file_handle *file) +{ EFI_ENTRY("%p", file); - return EFI_EXIT(file_close(fh)); + return EFI_EXIT(efi_file_close_int(file)); } static efi_status_t EFIAPI efi_file_delete(struct efi_file_handle *file) @@ -562,8 +568,8 @@ static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size, return EFI_SUCCESS; } -static efi_status_t efi_file_read_int(struct efi_file_handle *this, - efi_uintn_t *buffer_size, void *buffer) +efi_status_t efi_file_read_int(struct efi_file_handle *this, + efi_uintn_t *buffer_size, void *buffer) { struct file_handle *fh = to_fh(this); efi_status_t ret = EFI_SUCCESS; @@ -773,24 +779,11 @@ out: return EFI_EXIT(ret); } -/** - * efi_file_setpos() - set current position in file - * - * This function implements the SetPosition service of the EFI file protocol. - * See the UEFI spec for details. - * - * @file: file handle - * @pos: new file position - * Return: status code - */ -static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, - u64 pos) +efi_status_t efi_file_setpos_int(struct efi_file_handle *file, u64 pos) { struct file_handle *fh = to_fh(file); efi_status_t ret = EFI_SUCCESS; - EFI_ENTRY("%p, %llu", file, pos); - if (fh->isdir) { if (pos != 0) { ret = EFI_UNSUPPORTED; @@ -812,6 +805,28 @@ static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, fh->offset = pos; error: + return ret; +} + +/** + * efi_file_setpos() - set current position in file + * + * This function implements the SetPosition service of the EFI file protocol. + * See the UEFI spec for details. + * + * @file: file handle + * @pos: new file position + * Return: status code + */ +static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, + u64 pos) +{ + efi_status_t ret = EFI_SUCCESS; + + EFI_ENTRY("%p, %llu", file, pos); + + ret = efi_file_setpos_int(file, pos); + return EFI_EXIT(ret); } @@ -1138,17 +1153,23 @@ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp) return f; } +efi_status_t efi_open_volume_int(struct efi_simple_file_system_protocol *this, + struct efi_file_handle **root) +{ + struct file_system *fs = to_fs(this); + + *root = file_open(fs, NULL, NULL, 0, 0); + + return EFI_SUCCESS; +} + static efi_status_t EFIAPI efi_open_volume(struct efi_simple_file_system_protocol *this, struct efi_file_handle **root) { - struct file_system *fs = to_fs(this); - EFI_ENTRY("%p, %p", this, root); - *root = file_open(fs, NULL, NULL, 0, 0); - - return EFI_EXIT(EFI_SUCCESS); + return EFI_EXIT(efi_open_volume_int(this, root)); } struct efi_simple_file_system_protocol * diff --git a/lib/efi_loader/efi_var_file.c b/lib/efi_loader/efi_var_file.c index 76a2ff9e41..3d58caa13d 100644 --- a/lib/efi_loader/efi_var_file.c +++ b/lib/efi_loader/efi_var_file.c @@ -38,13 +38,13 @@ static efi_status_t __maybe_unused efi_set_blk_dev_to_system_partition(void) char part_str[PART_STR_LEN]; int r; - if (!efi_system_partition.if_type) { + if (efi_system_partition.uclass_id == UCLASS_INVALID) { log_err("No EFI system partition\n"); return EFI_DEVICE_ERROR; } snprintf(part_str, PART_STR_LEN, "%x:%x", efi_system_partition.devnum, efi_system_partition.part); - r = fs_set_blk_dev(blk_get_if_type_name(efi_system_partition.if_type), + r = fs_set_blk_dev(blk_get_uclass_name(efi_system_partition.uclass_id), part_str, FS_TYPE_ANY); if (r) { log_err("Cannot read EFI system partition\n"); diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 96b6b71a60..64c5b3da15 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -24,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -1058,7 +1059,7 @@ ofnode get_next_memory_node(ofnode mem) { do { mem = ofnode_by_prop_value(mem, "device_type", "memory", 7); - } while (!ofnode_is_available(mem)); + } while (!ofnode_is_enabled(mem)); return mem; } @@ -1668,6 +1669,8 @@ int fdtdec_setup(void) ret = fdtdec_prepare_fdt(); if (!ret) ret = fdtdec_board_setup(gd->fdt_blob); + oftree_reset(); + return ret; } diff --git a/lib/gunzip.c b/lib/gunzip.c index a8e498d98d..932e3e8036 100644 --- a/lib/gunzip.c +++ b/lib/gunzip.c @@ -251,7 +251,7 @@ int gzwrite(unsigned char *src, int len, puts("abort\n"); goto out; } - WATCHDOG_RESET(); + schedule(); } while (s.avail_out == 0); /* done when inflate() says it's done */ } while (r != Z_STREAM_END); diff --git a/lib/lzma/LzmaDec.c b/lib/lzma/LzmaDec.c index 4f45f80fe2..341149f766 100644 --- a/lib/lzma/LzmaDec.c +++ b/lib/lzma/LzmaDec.c @@ -153,7 +153,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte UInt32 range = p->range; UInt32 code = p->code; - WATCHDOG_RESET(); + schedule(); do { @@ -177,7 +177,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte state -= (state < 4) ? state : 3; symbol = 1; - WATCHDOG_RESET(); + schedule(); do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); } @@ -188,7 +188,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte state -= (state < 10) ? 3 : 6; symbol = 1; - WATCHDOG_RESET(); + schedule(); do { @@ -321,7 +321,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte UInt32 mask = 1; unsigned i = 1; - WATCHDOG_RESET(); + schedule(); do { @@ -335,7 +335,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte { numDirectBits -= kNumAlignBits; - WATCHDOG_RESET(); + schedule(); do { @@ -409,7 +409,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte const Byte *lim = dest + curLen; dicPos += curLen; - WATCHDOG_RESET(); + schedule(); do *(dest) = (Byte)*(dest + src); @@ -418,7 +418,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte else { - WATCHDOG_RESET(); + schedule(); do { @@ -433,7 +433,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte } while (dicPos < limit && buf < bufLimit); - WATCHDOG_RESET(); + schedule(); NORMALIZE; p->buf = buf; diff --git a/lib/lzma/LzmaTools.c b/lib/lzma/LzmaTools.c index af88900d31..55f64cd289 100644 --- a/lib/lzma/LzmaTools.c +++ b/lib/lzma/LzmaTools.c @@ -104,7 +104,7 @@ int lzmaBuffToBuffDecompress(unsigned char *outStream, SizeT *uncompressedSize, /* Decompress */ outProcessed = min(outSizeFull, *uncompressedSize); - WATCHDOG_RESET(); + schedule(); res = LzmaDecode( outStream, &outProcessed, diff --git a/lib/md5.c b/lib/md5.c index 9d34465564..1636ab9366 100644 --- a/lib/md5.c +++ b/lib/md5.c @@ -304,7 +304,7 @@ md5_wd(const unsigned char *input, unsigned int len, unsigned char output[16], chunk = chunk_sz; MD5Update(&context, curr, chunk); curr += chunk; - WATCHDOG_RESET (); + schedule(); } #else MD5Update(&context, input, len); diff --git a/lib/of_live.c b/lib/of_live.c index 30cae9ab88..1b5964d09a 100644 --- a/lib/of_live.c +++ b/lib/of_live.c @@ -97,6 +97,10 @@ static void *unflatten_dt_node(const void *blob, void *mem, int *poffset, char *fn; fn = (char *)np + sizeof(*np); + if (new_format) { + np->name = pathp; + has_name = 1; + } np->full_name = fn; if (new_format) { /* rebuild full path for new format */ @@ -202,7 +206,8 @@ static void *unflatten_dt_node(const void *blob, void *mem, int *poffset, } if (!dryrun) { *prev_pp = NULL; - np->name = of_get_property(np, "name", NULL); + if (!has_name) + np->name = of_get_property(np, "name", NULL); np->type = of_get_property(np, "device_type", NULL); if (!np->name) diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 1d95cfbdee..9605c37639 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -215,6 +215,8 @@ out: * @msg_len: Message length * @hash: Pointer to the expected hash * @hash_len: Length of the hash + * + * Return: 0 if padding is correct, non-zero otherwise */ int padding_pss_verify(struct image_sign_info *info, const uint8_t *msg, int msg_len, @@ -234,6 +236,9 @@ int padding_pss_verify(struct image_sign_info *info, uint8_t leftmost_mask; struct checksum_algo *checksum = info->checksum; + if (db_len <= 0) + return -EINVAL; + /* first, allocate everything */ db_mask = malloc(db_len); db = malloc(db_len); diff --git a/lib/sha1.c b/lib/sha1.c index e5e42bc9fe..8d07407893 100644 --- a/lib/sha1.c +++ b/lib/sha1.c @@ -344,7 +344,7 @@ void sha1_csum_wd(const unsigned char *input, unsigned int ilen, chunk = chunk_sz; sha1_update (&ctx, curr, chunk); curr += chunk; - WATCHDOG_RESET (); + schedule(); } #else sha1_update (&ctx, input, ilen); diff --git a/lib/sha256.c b/lib/sha256.c index 50b0b51183..4d26aea1c8 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -293,7 +293,7 @@ void sha256_csum_wd(const unsigned char *input, unsigned int ilen, chunk = chunk_sz; sha256_update(&ctx, curr, chunk); curr += chunk; - WATCHDOG_RESET(); + schedule(); } #else sha256_update(&ctx, input, ilen); diff --git a/lib/sha512.c b/lib/sha512.c index a421f249ba..fbe8d5f5bf 100644 --- a/lib/sha512.c +++ b/lib/sha512.c @@ -309,7 +309,7 @@ void sha384_csum_wd(const unsigned char *input, unsigned int ilen, chunk = chunk_sz; sha384_update(&ctx, curr, chunk); curr += chunk; - WATCHDOG_RESET(); + schedule(); } #else sha384_update(&ctx, input, ilen); @@ -372,7 +372,7 @@ void sha512_csum_wd(const unsigned char *input, unsigned int ilen, chunk = chunk_sz; sha512_update(&ctx, curr, chunk); curr += chunk; - WATCHDOG_RESET(); + schedule(); } #else sha512_update(&ctx, input, ilen); diff --git a/lib/time.c b/lib/time.c index bbf191f673..f3aaf472d1 100644 --- a/lib/time.c +++ b/lib/time.c @@ -198,7 +198,7 @@ void udelay(unsigned long usec) ulong kv; do { - WATCHDOG_RESET(); + schedule(); kv = usec > CONFIG_WD_PERIOD ? CONFIG_WD_PERIOD : usec; __udelay(kv); usec -= kv; diff --git a/lib/zlib/inflate.c b/lib/zlib/inflate.c index 6411c47932..30dfe15599 100644 --- a/lib/zlib/inflate.c +++ b/lib/zlib/inflate.c @@ -25,7 +25,7 @@ int ZEXPORT inflateReset(z_streamp strm) state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; - WATCHDOG_RESET(); + schedule(); Tracev((stderr, "inflate: reset\n")); return Z_OK; } @@ -543,7 +543,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; case TYPE: - WATCHDOG_RESET(); + schedule(); if (flush == Z_BLOCK) goto inf_leave; case TYPEDO: if (state->last) { @@ -721,7 +721,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN; case LEN: - WATCHDOG_RESET(); + schedule(); if (have >= 6 && left >= 258) { RESTORE(); inflate_fast(strm, out); @@ -933,7 +933,7 @@ int ZEXPORT inflateEnd(z_streamp strm) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->window != Z_NULL) { - WATCHDOG_RESET(); + schedule(); ZFREE(strm, state->window); } ZFREE(strm, strm->state); diff --git a/net/dsa-uclass.c b/net/dsa-uclass.c index 3bf4351c84..5b7046432f 100644 --- a/net/dsa-uclass.c +++ b/net/dsa-uclass.c @@ -432,7 +432,7 @@ static int dsa_post_bind(struct udevice *dev) * skip registration if port id not found or if the port * is explicitly disabled in DT */ - if (!ofnode_valid(pnode) || !ofnode_is_available(pnode)) + if (!ofnode_valid(pnode) || !ofnode_is_enabled(pnode)) continue; err = device_bind_driver_to_node(dev, DSA_PORT_CHILD_DRV_NAME, diff --git a/net/net.c b/net/net.c index 81905f6315..f9d11c08d2 100644 --- a/net/net.c +++ b/net/net.c @@ -559,7 +559,7 @@ restart: * someone sets `net_state' to a state that terminates. */ for (;;) { - WATCHDOG_RESET(); + schedule(); if (arp_timeout_check() > 0) time_start = get_timer(0); diff --git a/post/cpu/mpc83xx/ecc.c b/post/cpu/mpc83xx/ecc.c index f88eff8998..edd7411567 100644 --- a/post/cpu/mpc83xx/ecc.c +++ b/post/cpu/mpc83xx/ecc.c @@ -73,7 +73,7 @@ int ecc_post_test(int flags) for (addr = (u64*)CONFIG_SYS_POST_ECC_START_ADDR, errbit=0; addr < (u64*)CONFIG_SYS_POST_ECC_STOP_ADDR; addr++, errbit++ ) { - WATCHDOG_RESET(); + schedule(); ecc_clear(ddr); diff --git a/post/drivers/memory.c b/post/drivers/memory.c index 281989da6f..d249942af0 100644 --- a/post/drivers/memory.c +++ b/post/drivers/memory.c @@ -228,9 +228,8 @@ static int memory_post_dataline(unsigned long long * pmem) hi = (temp64>>32) & 0xffffffff; lo = temp64 & 0xffffffff; - post_log("Memory (data line) error at %08x, " - "wrote %08x%08x, read %08x%08x !\n", - pmem, pathi, patlo, hi, lo); + post_log("Memory (data line) error at %p, wrote %08x%08x, read %08x%08x !\n", + pmem, pathi, patlo, hi, lo); ret = -1; } } @@ -259,9 +258,8 @@ static int memory_post_addrline(ulong *testaddr, ulong *base, ulong size) } #endif if(readback == *testaddr) { - post_log("Memory (address line) error at %08x<->%08x, " - "XOR value %08x !\n", - testaddr, target, xor); + post_log("Memory (address line) error at %p<->%p, XOR value %08lx !\n", + testaddr, target, xor); ret = -1; } } @@ -281,21 +279,20 @@ static int memory_post_test1(unsigned long start, for (i = 0; i < size / sizeof (ulong); i++) { mem[i] = val; if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } for (i = 0; i < size / sizeof (ulong) && !ret; i++) { readback = mem[i]; if (readback != val) { - post_log("Memory error at %08x, " - "wrote %08x, read %08x !\n", - mem + i, val, readback); + post_log("Memory error at %p, wrote %08lx, read %08lx !\n", + mem + i, val, readback); ret = -1; break; } if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } return ret; @@ -311,21 +308,20 @@ static int memory_post_test2(unsigned long start, unsigned long size) for (i = 0; i < size / sizeof (ulong); i++) { mem[i] = 1 << (i % 32); if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } for (i = 0; i < size / sizeof (ulong) && !ret; i++) { readback = mem[i]; if (readback != (1 << (i % 32))) { - post_log("Memory error at %08x, " - "wrote %08x, read %08x !\n", - mem + i, 1 << (i % 32), readback); + post_log("Memory error at %p, wrote %08lx, read %08lx !\n", + mem + i, 1UL << (i % 32), readback); ret = -1; break; } if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } return ret; @@ -341,21 +337,20 @@ static int memory_post_test3(unsigned long start, unsigned long size) for (i = 0; i < size / sizeof (ulong); i++) { mem[i] = i; if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } for (i = 0; i < size / sizeof (ulong) && !ret; i++) { readback = mem[i]; if (readback != i) { - post_log("Memory error at %08x, " - "wrote %08x, read %08x !\n", - mem + i, i, readback); + post_log("Memory error at %p, wrote %08lx, read %08lx !\n", + mem + i, i, readback); ret = -1; break; } if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } return ret; @@ -371,21 +366,20 @@ static int memory_post_test4(unsigned long start, unsigned long size) for (i = 0; i < size / sizeof (ulong); i++) { mem[i] = ~i; if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } for (i = 0; i < size / sizeof (ulong) && !ret; i++) { readback = mem[i]; if (readback != ~i) { - post_log("Memory error at %08x, " - "wrote %08x, read %08x !\n", - mem + i, ~i, readback); + post_log("Memory error at %p, wrote %08lx, read %08lx !\n", + mem + i, ~i, readback); ret = -1; break; } if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } return ret; @@ -396,15 +390,15 @@ static int memory_post_test_lines(unsigned long start, unsigned long size) int ret = 0; ret = memory_post_dataline((unsigned long long *)start); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_addrline((ulong *)start, (ulong *)start, size); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_addrline((ulong *)(start+size-8), (ulong *)start, size); - WATCHDOG_RESET(); + schedule(); return ret; } @@ -414,25 +408,25 @@ static int memory_post_test_patterns(unsigned long start, unsigned long size) int ret = 0; ret = memory_post_test1(start, size, 0x00000000); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_test1(start, size, 0xffffffff); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_test1(start, size, 0x55555555); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_test1(start, size, 0xaaaaaaaa); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_test2(start, size); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_test3(start, size); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_test4(start, size); - WATCHDOG_RESET(); + schedule(); return ret; } diff --git a/post/lib_powerpc/cpu.c b/post/lib_powerpc/cpu.c index 8506fd6b71..1d47107342 100644 --- a/post/lib_powerpc/cpu.c +++ b/post/lib_powerpc/cpu.c @@ -61,7 +61,7 @@ int cpu_post_test (int flags) int ic = icache_status(); int ret = 0; - WATCHDOG_RESET(); + schedule(); if (ic) icache_disable(); @@ -73,7 +73,7 @@ int cpu_post_test (int flags) ret = cpu_post_test_two (); if (ret == 0) ret = cpu_post_test_twox (); - WATCHDOG_RESET(); + schedule(); if (ret == 0) ret = cpu_post_test_three (); if (ret == 0) @@ -82,7 +82,7 @@ int cpu_post_test (int flags) ret = cpu_post_test_threei (); if (ret == 0) ret = cpu_post_test_andi (); - WATCHDOG_RESET(); + schedule(); if (ret == 0) ret = cpu_post_test_srawi (); if (ret == 0) @@ -91,7 +91,7 @@ int cpu_post_test (int flags) ret = cpu_post_test_rlwinm (); if (ret == 0) ret = cpu_post_test_rlwimi (); - WATCHDOG_RESET(); + schedule(); if (ret == 0) ret = cpu_post_test_store (); if (ret == 0) @@ -100,20 +100,20 @@ int cpu_post_test (int flags) ret = cpu_post_test_cr (); if (ret == 0) ret = cpu_post_test_b (); - WATCHDOG_RESET(); + schedule(); if (ret == 0) ret = cpu_post_test_multi (); - WATCHDOG_RESET(); + schedule(); if (ret == 0) ret = cpu_post_test_string (); if (ret == 0) ret = cpu_post_test_complex (); - WATCHDOG_RESET(); + schedule(); if (ic) icache_enable(); - WATCHDOG_RESET(); + schedule(); return ret; } diff --git a/post/lib_powerpc/fpu/fpu.c b/post/lib_powerpc/fpu/fpu.c index 0de76ce051..bd65f623d5 100644 --- a/post/lib_powerpc/fpu/fpu.c +++ b/post/lib_powerpc/fpu/fpu.c @@ -43,7 +43,7 @@ int fpu_post_test (int flags) int ret = 0; - WATCHDOG_RESET (); + schedule(); if (!fpu) fpu_enable (); @@ -66,7 +66,7 @@ int fpu_post_test (int flags) if (!fpu) fpu_disable (); - WATCHDOG_RESET (); + schedule(); return ret; } diff --git a/post/post.c b/post/post.c index d67c43ed8a..b81425d8cf 100644 --- a/post/post.c +++ b/post/post.c @@ -245,7 +245,7 @@ static int post_run_single(struct post_test *test, { if ((flags & test_flags & POST_ALWAYS) && (flags & test_flags & POST_MEM)) { - WATCHDOG_RESET(); + schedule(); if (!(flags & POST_REBOOT)) { if ((test_flags & POST_REBOOT) && @@ -350,7 +350,7 @@ int post_run(char *name, int flags) } if (i < post_list_size) { - WATCHDOG_RESET(); + schedule(); return post_run_single(post_list + i, test_flags[i], flags, i); diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index 3bafeb4fe9..0b3a51da13 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -489,7 +489,7 @@ endif # Rule to link u-boot-spl # May be overridden by arch/$(ARCH)/config.mk -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) quiet_cmd_u-boot-spl ?= LTO $@ cmd_u-boot-spl ?= \ ( \ diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index f505722f6b..49e3b3847e 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -622,7 +622,6 @@ CONFIG_SYS_DPAA_PME CONFIG_SYS_DPAA_RMAN CONFIG_SYS_DRAM_TEST CONFIG_SYS_DV_NOR_BOOT_CFG -CONFIG_SYS_EEPROM_BUS_NUM CONFIG_SYS_EEPROM_WREN CONFIG_SYS_ENV_SECT_SIZE CONFIG_SYS_ETHOC_BASE @@ -786,18 +785,11 @@ CONFIG_SYS_GPIO_OUT CONFIG_SYS_GPR1 CONFIG_SYS_HZ_CLOCK CONFIG_SYS_I2C_BUSES -CONFIG_SYS_I2C_DVI_ADDR -CONFIG_SYS_I2C_DVI_BUS_NUM -CONFIG_SYS_I2C_EEPROM_CCID -CONFIG_SYS_I2C_EEPROM_NXID -CONFIG_SYS_I2C_EEPROM_PAGE_WRITE_BITS -CONFIG_SYS_I2C_EEPROM_PAGE_WRITE_DELAY_MS CONFIG_SYS_I2C_EXPANDER_ADDR CONFIG_SYS_I2C_FPGA_ADDR CONFIG_SYS_I2C_G762_ADDR CONFIG_SYS_I2C_IFDR_DIV CONFIG_SYS_I2C_INIT_BOARD -CONFIG_SYS_I2C_LDI_ADDR CONFIG_SYS_I2C_MAX_HOPS CONFIG_SYS_I2C_NOPROBES CONFIG_SYS_I2C_PCA953X_ADDR @@ -840,7 +832,6 @@ CONFIG_SYS_JFFS2_FIRST_SECTOR CONFIG_SYS_JFFS2_NUM_BANKS CONFIG_SYS_KMBEC_FPGA_BASE CONFIG_SYS_KMBEC_FPGA_SIZE -CONFIG_SYS_L2_PL310 CONFIG_SYS_L2_SIZE CONFIG_SYS_L3_SIZE CONFIG_SYS_LATCH_ADDR diff --git a/scripts/event_dump.py b/scripts/event_dump.py index 751f41b183..6aadddf28d 100755 --- a/scripts/event_dump.py +++ b/scripts/event_dump.py @@ -17,8 +17,10 @@ sys.path.insert(1, os.path.join(our_path, '../tools')) from binman import elf from patman import tools +# A typical symbol looks like this: +# _u_boot_list_2_evspy_info_2_EVT_MISC_INIT_F_3_sandbox_misc_init_f PREFIX = '_u_boot_list_2_evspy_info_2_' -RE_EVTYPE = re.compile('%s(.*)' % PREFIX) +RE_EVTYPE = re.compile('%s(.*)_3_.*' % PREFIX) def show_sym(fname, data, endian, evtype, sym): """Show information about an evspy entry diff --git a/test/boot/vbe_simple.c b/test/boot/vbe_simple.c index 2f6979cafc..8acd777f4c 100644 --- a/test/boot/vbe_simple.c +++ b/test/boot/vbe_simple.c @@ -74,29 +74,25 @@ static int vbe_simple_test_base(struct unit_test_state *uts) node_ofs = fdt_add_subnode(fdt_buf, node_ofs, "firmware0"); ut_assert(node_ofs > 0); - /* - * This can only work on the live tree, since the ofnode interface for - * flat tree assumes that ofnode points to the control FDT - */ - ut_assertok(unflatten_device_tree(fdt_buf, &np)); + if (of_live_active()) { + ut_assertok(unflatten_device_tree(fdt_buf, &np)); + fixup.tree = oftree_from_np(np); + } else { + fixup.tree = oftree_from_fdt(fdt_buf); + } /* * It would be better to call image_setup_libfdt() here, but that * function does not allow passing an ofnode. We can pass fdt_buf but - * when it comes to send the evenr, it creates an ofnode that uses the + * when it comes to send the event, it creates an ofnode that uses the * control FDT, since it has no way of accessing the live tree created * here. * - * Two fix this we need: - * - image_setup_libfdt() is updated to use ofnode - * - ofnode updated to support access to an FDT other than the control - * FDT. This is partially implemented with live tree, but not with - * flat tree + * Two fix this we need image_setup_libfdt() is updated to use ofnode */ - fixup.tree.np = np; ut_assertok(event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup))); - node = ofnode_path_root(fixup.tree, "/chosen/fwupd/firmware0"); + node = oftree_path(fixup.tree, "/chosen/fwupd/firmware0"); version = ofnode_read_string(node, "cur-version"); ut_assertnonnull(version); @@ -111,5 +107,4 @@ static int vbe_simple_test_base(struct unit_test_state *uts) return 0; } -BOOTSTD_TEST(vbe_simple_test_base, UT_TESTF_DM | UT_TESTF_SCAN_FDT | - UT_TESTF_LIVE_TREE); +BOOTSTD_TEST(vbe_simple_test_base, UT_TESTF_DM | UT_TESTF_SCAN_FDT); diff --git a/test/bootm.c b/test/bootm.c index 7d03e1e0c6..4bb3ca0655 100644 --- a/test/bootm.c +++ b/test/bootm.c @@ -208,7 +208,8 @@ BOOTM_TEST(bootm_test_silent_var, 0); /* Test substitution processing in the bootargs variable */ static int bootm_test_subst_var(struct unit_test_state *uts) { - env_set("bootargs", NULL); + ut_assertok(env_set("silent_linux", "yes")); + ut_assertok(env_set("bootargs", NULL)); ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SILENT)); ut_asserteq_str("console=ttynull", env_get("bootargs")); diff --git a/test/cmd/Makefile b/test/cmd/Makefile index c331757425..1bb02d93a2 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -5,6 +5,9 @@ ifdef CONFIG_HUSH_PARSER obj-$(CONFIG_CONSOLE_RECORD) += test_echo.o endif +ifdef CONFIG_CONSOLE_RECORD +obj-$(CONFIG_CMD_PAUSE) += test_pause.o +endif obj-y += mem.o obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o obj-$(CONFIG_CMD_FDT) += fdt.o diff --git a/test/cmd/test_pause.c b/test/cmd/test_pause.c new file mode 100644 index 0000000000..2b85cce327 --- /dev/null +++ b/test/cmd/test_pause.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Tests for pause command + * + * Copyright 2022, Samuel Dionne-Riel + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static int lib_test_hush_pause(struct unit_test_state *uts) +{ + /* Test default message */ + console_record_reset_enable(); + /* Cook a newline when the command is expected to pause */ + console_in_puts("\n"); + ut_assertok(run_command("pause", 0)); + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + ut_asserteq_str("Press any key to continue...", uts->actual_str); + ut_assertok(ut_check_console_end(uts)); + + /* Test provided message */ + console_record_reset_enable(); + /* Cook a newline when the command is expected to pause */ + console_in_puts("\n"); + ut_assertok(run_command("pause 'Prompt for pause...'", 0)); + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + ut_asserteq_str("Prompt for pause...", uts->actual_str); + ut_assertok(ut_check_console_end(uts)); + + /* Test providing more than one params */ + console_record_reset_enable(); + /* No newline cooked here since the command is expected to fail */ + ut_asserteq(1, run_command("pause a b", 0)); + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + ut_asserteq_str("pause - delay until user input", uts->actual_str); + ut_asserteq(1, ut_check_console_end(uts)); + + return 0; +} +LIB_TEST(lib_test_hush_pause, 0); diff --git a/test/cmd_ut.c b/test/cmd_ut.c index 3789c6b784..11c219b48a 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -18,10 +18,17 @@ int cmd_ut_category(const char *name, const char *prefix, struct unit_test *tests, int n_ents, int argc, char *const argv[]) { + int runs_per_text = 1; int ret; + if (argc > 1 && !strncmp("-r", argv[1], 2)) { + runs_per_text = dectoul(argv[1] + 2, NULL); + argv++; + argc++; + } + ret = ut_run_list(name, prefix, tests, n_ents, - argc > 1 ? argv[1] : NULL); + argc > 1 ? argv[1] : NULL, runs_per_text); return ret ? CMD_RET_FAILURE : 0; } @@ -168,7 +175,8 @@ static char ut_help_text[] = #ifdef CONFIG_CMD_LOADM "ut loadm [test-name]- test of parameters and load memory blob\n" #endif - ; + "All commands accept an optional [-r] flag before [test-name], to\n" + "run each test multiple times ( is in decimal)"; #endif /* CONFIG_SYS_LONGHELP */ U_BOOT_CMD( diff --git a/test/common/Makefile b/test/common/Makefile index 9087788ba6..cc918f64e5 100644 --- a/test/common/Makefile +++ b/test/common/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0+ obj-y += cmd_ut_common.o obj-$(CONFIG_AUTOBOOT) += test_autoboot.o +obj-$(CONFIG_CYCLIC) += cyclic.o obj-$(CONFIG_EVENT) += event.o diff --git a/test/common/cyclic.c b/test/common/cyclic.c new file mode 100644 index 0000000000..6e758e89db --- /dev/null +++ b/test/common/cyclic.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Stefan Roese + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Test that cyclic function is called */ +static bool cyclic_active = false; + +static void cyclic_test(void *ctx) +{ + cyclic_active = true; +} + +static int dm_test_cyclic_running(struct unit_test_state *uts) +{ + cyclic_active = false; + ut_assertnonnull(cyclic_register(cyclic_test, 10 * 1000, "cyclic_demo", + NULL)); + + /* Execute all registered cyclic functions */ + schedule(); + ut_asserteq(true, cyclic_active); + + return 0; +} +COMMON_TEST(dm_test_cyclic_running, 0); diff --git a/test/dm/Makefile b/test/dm/Makefile index 7543df8823..5178daa7cf 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_DM_REGULATOR) += regulator.o obj-$(CONFIG_DM_RNG) += rng.o obj-$(CONFIG_DM_RTC) += rtc.o obj-$(CONFIG_SCMI_FIRMWARE) += scmi.o +obj-$(CONFIG_SCSI) += scsi.o obj-$(CONFIG_DM_SERIAL) += serial.o obj-$(CONFIG_DM_SPI_FLASH) += sf.o obj-$(CONFIG_SIMPLE_BUS) += simple-bus.o diff --git a/test/dm/blk.c b/test/dm/blk.c index 85c3a3bd45..35bd5318f0 100644 --- a/test/dm/blk.c +++ b/test/dm/blk.c @@ -25,19 +25,19 @@ static int dm_test_blk_base(struct unit_test_state *uts) /* Create two, one the parent of the other */ ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test", - IF_TYPE_HOST, 1, 512, 2, &blk1)); + UCLASS_ROOT, 1, 512, 2, &blk1)); ut_assertok(blk_create_device(blk1, "sandbox_host_blk", "test", - IF_TYPE_HOST, 3, 512, 2, &blk3)); + UCLASS_ROOT, 3, 512, 2, &blk3)); /* Check we can find them */ - ut_asserteq(-ENODEV, blk_get_device(IF_TYPE_HOST, 0, &dev)); - ut_assertok(blk_get_device(IF_TYPE_HOST, 1, &dev)); + ut_asserteq(-ENODEV, blk_get_device(UCLASS_ROOT, 0, &dev)); + ut_assertok(blk_get_device(UCLASS_ROOT, 1, &dev)); ut_asserteq_ptr(blk1, dev); - ut_assertok(blk_get_device(IF_TYPE_HOST, 3, &dev)); + ut_assertok(blk_get_device(UCLASS_ROOT, 3, &dev)); ut_asserteq_ptr(blk3, dev); /* Check we can iterate */ - ut_assertok(blk_first_device(IF_TYPE_HOST, &dev)); + ut_assertok(blk_first_device(UCLASS_ROOT, &dev)); ut_asserteq_ptr(blk1, dev); ut_assertok(blk_next_device(&dev)); ut_asserteq_ptr(blk3, dev); @@ -79,7 +79,7 @@ static int dm_test_blk_usb(struct unit_test_state *uts) ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc)); /* The parent should be a block device */ - ut_assertok(blk_get_device(IF_TYPE_USB, 0, &dev)); + ut_assertok(blk_get_device(UCLASS_USB, 0, &dev)); ut_asserteq_ptr(usb_dev, dev_get_parent(dev)); /* Check we have one block device for each mass storage device */ @@ -101,14 +101,14 @@ static int dm_test_blk_find(struct unit_test_state *uts) struct udevice *blk, *dev; ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test", - IF_TYPE_HOST, 1, 512, 2, &blk)); - ut_asserteq(-ENODEV, blk_find_device(IF_TYPE_HOST, 0, &dev)); - ut_assertok(blk_find_device(IF_TYPE_HOST, 1, &dev)); + UCLASS_ROOT, 1, 512, 2, &blk)); + ut_asserteq(-ENODEV, blk_find_device(UCLASS_ROOT, 0, &dev)); + ut_assertok(blk_find_device(UCLASS_ROOT, 1, &dev)); ut_asserteq_ptr(blk, dev); ut_asserteq(false, device_active(dev)); /* Now activate it */ - ut_assertok(blk_get_device(IF_TYPE_HOST, 1, &dev)); + ut_assertok(blk_get_device(UCLASS_ROOT, 1, &dev)); ut_asserteq_ptr(blk, dev); ut_asserteq(true, device_active(dev)); @@ -134,7 +134,7 @@ static int dm_test_blk_devnum(struct unit_test_state *uts) /* Check that the bblock device is attached */ ut_assertok(uclass_get_device_by_seq(UCLASS_MMC, i, &mmc_dev)); - ut_assertok(blk_find_device(IF_TYPE_MMC, i, &dev)); + ut_assertok(blk_find_device(UCLASS_MMC, i, &dev)); parent = dev_get_parent(dev); ut_asserteq_ptr(parent, mmc_dev); ut_asserteq(trailing_strtol(mmc_dev->name), i); diff --git a/test/dm/gpio.c b/test/dm/gpio.c index 33ae98701f..a8c35d4370 100644 --- a/test/dm/gpio.c +++ b/test/dm/gpio.c @@ -778,3 +778,33 @@ static int dm_test_gpio_get_values_as_int_base3(struct unit_test_state *uts) } DM_TEST(dm_test_gpio_get_values_as_int_base3, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* Check that gpio_get_status return the label of a GPIO configured as GPIOD_AF */ +static int dm_test_gpio_function(struct unit_test_state *uts) +{ + struct gpio_desc desc; + struct udevice *dev; + ulong flags; + unsigned int offset, gpio; + char buf[80]; + + ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); + ut_asserteq_str("a-test", dev->name); + + /* request gpio_b 5 */ + ut_assertok(gpio_request_by_name(dev, "test-gpios", 2, &desc, 0)); + /* update gpio_b 5 function to GPIO_AF */ + ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_IS_AF, GPIOD_IS_AF)); + ut_assertok(dm_gpio_get_flags(&desc, &flags)); + ut_asserteq(GPIOD_IS_AF, flags); + /* check using gpio_get_status that label is displayed for a pin with GPIO_AF function */ + ut_assertok(gpio_lookup_name("b5", &dev, &offset, &gpio)); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b5: func a-test.test-gpios2", buf); + + ut_assertok(dm_gpio_free(dev, &desc)); + + return 0; +} +DM_TEST(dm_test_gpio_function, + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index f80993f892..41811ec3bb 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -1,4 +1,20 @@ // SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2022 Google LLC + * + * There are two types of tests in this file: + * - normal ones which act on the control FDT (gd->fdt_blob or gd->of_root) + * - 'other' ones which act on the 'other' FDT (other.dts) + * + * The 'other' ones have an _ot suffix. + * + * The latter are used to check behaviour with multiple device trees, + * particularly with flat tree, where a tree ID is included in ofnode as part of + * the node offset. These tests are typically just for making sure that the + * offset makes it to libfdt correctly and that the resulting return value is + * correctly turned into an ofnode. The 'other' tests do not fully check the + * behaviour of each ofnode function, since that is done by the normal ones. + */ #include #include @@ -13,6 +29,68 @@ #include #include +/** + * get_other_oftree() - Convert a flat tree into an oftree object + * + * @uts: Test state + * @return: oftree object for the 'other' FDT (see sandbox' other.dts) + */ +oftree get_other_oftree(struct unit_test_state *uts) +{ + oftree tree; + + if (of_live_active()) + tree = oftree_from_np(uts->of_other); + else + tree = oftree_from_fdt(uts->other_fdt); + + /* An invalid tree may cause failure or crashes */ + if (!oftree_valid(tree)) + ut_reportf("test needs the UT_TESTF_OTHER_FDT flag"); + + return tree; +} + +/** + * get_oftree() - Convert a flat tree into an oftree object + * + * @uts: Test state + * @fdt: Pointer to flat tree + * @treep: Returns the tree, on success + * Return: 0 if OK, 1 if the tree failed to unflatten, -EOVERFLOW if there are + * too many flat trees to allow another one to be registers (see + * oftree_ensure()) + */ +int get_oftree(struct unit_test_state *uts, void *fdt, oftree *treep) +{ + oftree tree; + + if (of_live_active()) { + struct device_node *root; + + ut_assertok(unflatten_device_tree(fdt, &root)); + tree = oftree_from_np(root); + } else { + tree = oftree_from_fdt(fdt); + if (!oftree_valid(tree)) + return -EOVERFLOW; + } + *treep = tree; + + return 0; +} + +/** + * free_oftree() - Free memory used by get_oftree() + * + * @tree: Tree to free + */ +void free_oftree(oftree tree) +{ + if (of_live_active()) + free(tree.np); +} + static int dm_test_ofnode_compatible(struct unit_test_state *uts) { ofnode root_node = ofnode_path("/"); @@ -22,7 +100,21 @@ static int dm_test_ofnode_compatible(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ofnode_compatible, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +DM_TEST(dm_test_ofnode_compatible, + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* check ofnode_device_is_compatible() with the 'other' FDT */ +static int dm_test_ofnode_compatible_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode oroot = oftree_root(otree); + + ut_assert(ofnode_valid(oroot)); + ut_assert(ofnode_device_is_compatible(oroot, "sandbox-other")); + + return 0; +} +DM_TEST(dm_test_ofnode_compatible_ot, UT_TESTF_OTHER_FDT); static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts) { @@ -36,37 +128,76 @@ static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts) /* test unknown phandle */ ut_assert(!ofnode_valid(ofnode_get_by_phandle(0x1000000))); + ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1))); + return 0; } DM_TEST(dm_test_ofnode_get_by_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); -static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts) +static int dm_test_ofnode_get_by_phandle_ot(struct unit_test_state *uts) { - const char propname[] = "compatible"; - const char propval[] = "denx,u-boot-fdt-test"; + oftree otree = get_other_oftree(uts); + ofnode node; + + ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1))); + node = oftree_get_by_phandle(otree, 1); + ut_assert(ofnode_valid(node)); + ut_asserteq_str("target", ofnode_get_name(node)); + + return 0; +} +DM_TEST(dm_test_ofnode_get_by_phandle_ot, UT_TESTF_OTHER_FDT); + +static int check_prop_values(struct unit_test_state *uts, ofnode start, + const char *propname, const char *propval, + int expect_count) +{ + int proplen = strlen(propval) + 1; const char *str; - ofnode node = ofnode_null(); + ofnode node; + int count; /* Find first matching node, there should be at least one */ - node = ofnode_by_prop_value(node, propname, propval, sizeof(propval)); + node = ofnode_by_prop_value(start, propname, propval, proplen); ut_assert(ofnode_valid(node)); str = ofnode_read_string(node, propname); ut_assert(str && !strcmp(str, propval)); /* Find the rest of the matching nodes */ + count = 1; while (true) { - node = ofnode_by_prop_value(node, propname, propval, - sizeof(propval)); + node = ofnode_by_prop_value(node, propname, propval, proplen); if (!ofnode_valid(node)) break; str = ofnode_read_string(node, propname); - ut_assert(str && !strcmp(str, propval)); + ut_asserteq_str(propval, str); + count++; } + ut_asserteq(expect_count, count); + + return 0; +} + +static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts) +{ + ut_assertok(check_prop_values(uts, ofnode_null(), "compatible", + "denx,u-boot-fdt-test", 11)); return 0; } DM_TEST(dm_test_ofnode_by_prop_value, UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_by_prop_value_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + + ut_assertok(check_prop_values(uts, oftree_root(otree), "str-prop", + "other", 2)); + + return 0; +} +DM_TEST(dm_test_ofnode_by_prop_value_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_fmap(struct unit_test_state *uts) { struct fmap_entry entry; @@ -108,6 +239,25 @@ static int dm_test_ofnode_read(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_read, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_read_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + const char *val; + ofnode node; + int size; + + node = oftree_path(otree, "/node/subnode"); + ut_assert(ofnode_valid(node)); + + val = ofnode_read_prop(node, "str-prop", &size); + ut_assertnonnull(val); + ut_asserteq_str("other", val); + ut_asserteq(6, size); + + return 0; +} +DM_TEST(dm_test_ofnode_read_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_phandle(struct unit_test_state *uts) { struct ofnode_phandle_args args; @@ -183,6 +333,34 @@ static int dm_test_ofnode_phandle(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_phandle_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + struct ofnode_phandle_args args; + ofnode node; + int ret; + + node = oftree_path(otree, "/node"); + + /* Test ofnode_count_phandle_with_args with cell name */ + ret = ofnode_count_phandle_with_args(node, "missing", "#gpio-cells", 0); + ut_asserteq(-ENOENT, ret); + ret = ofnode_count_phandle_with_args(node, "target", "#invalid", 0); + ut_asserteq(-EINVAL, ret); + ret = ofnode_count_phandle_with_args(node, "target", "#gpio-cells", 0); + ut_asserteq(1, ret); + + ret = ofnode_parse_phandle_with_args(node, "target", "#gpio-cells", 0, + 0, &args); + ut_assertok(ret); + ut_asserteq(2, args.args_count); + ut_asserteq(3, args.args[0]); + ut_asserteq(4, args.args[1]); + + return 0; +} +DM_TEST(dm_test_ofnode_phandle_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_read_chosen(struct unit_test_state *uts) { const char *str; @@ -255,6 +433,27 @@ static int dm_test_ofnode_get_child_count(struct unit_test_state *uts) DM_TEST(dm_test_ofnode_get_child_count, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_get_child_count_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node, child_node; + u32 val; + + node = oftree_path(otree, "/node"); + ut_assert(ofnode_valid(node)); + + val = ofnode_get_child_count(node); + ut_asserteq(2, val); + + child_node = ofnode_first_subnode(node); + ut_assert(ofnode_valid(child_node)); + val = ofnode_get_child_count(child_node); + ut_asserteq(0, val); + + return 0; +} +DM_TEST(dm_test_ofnode_get_child_count_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_is_enabled(struct unit_test_state *uts) { ofnode root_node = ofnode_path("/"); @@ -267,6 +466,19 @@ static int dm_test_ofnode_is_enabled(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_is_enabled, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_is_enabled_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode root_node = oftree_root(otree); + ofnode node = oftree_path(otree, "/target"); + + ut_assert(ofnode_is_enabled(root_node)); + ut_assert(!ofnode_is_enabled(node)); + + return 0; +} +DM_TEST(dm_test_ofnode_is_enabled_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_get_reg(struct unit_test_state *uts) { ofnode node; @@ -303,27 +515,59 @@ static int dm_test_ofnode_get_reg(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_get_reg, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_get_reg_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node = oftree_path(otree, "/target"); + fdt_addr_t addr; + + addr = ofnode_get_addr(node); + ut_asserteq(0x8000, addr); + + return 0; +} +DM_TEST(dm_test_ofnode_get_reg_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_get_path(struct unit_test_state *uts) { const char *path = "/translation-test@8000/noxlatebus@3,300/dev@42"; char buf[64]; ofnode node; - int res; node = ofnode_path(path); ut_assert(ofnode_valid(node)); - res = ofnode_get_path(node, buf, 64); - ut_asserteq(0, res); + ut_assertok(ofnode_get_path(node, buf, sizeof(buf))); ut_asserteq_str(path, buf); - res = ofnode_get_path(node, buf, 32); - ut_asserteq(-ENOSPC, res); + ut_asserteq(-ENOSPC, ofnode_get_path(node, buf, 32)); + + ut_assertok(ofnode_get_path(ofnode_root(), buf, 32)); + ut_asserteq_str("/", buf); return 0; } DM_TEST(dm_test_ofnode_get_path, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_get_path_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + const char *path = "/node/subnode"; + ofnode node = oftree_path(otree, path); + char buf[64]; + + ut_assert(ofnode_valid(node)); + + ut_assertok(ofnode_get_path(node, buf, sizeof(buf))); + ut_asserteq_str(path, buf); + + ut_assertok(ofnode_get_path(oftree_root(otree), buf, 32)); + ut_asserteq_str("/", buf); + + return 0; +} +DM_TEST(dm_test_ofnode_get_path_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_conf(struct unit_test_state *uts) { ut_assert(!ofnode_conf_read_bool("missing")); @@ -483,13 +727,17 @@ DM_TEST(dm_test_ofnode_get_phy, 0); * @uts: Test state * @fdt: Place to write FDT * @size: Maximum size of space for fdt + * @id: id value to add to the tree ('id' property in root node) */ -static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size) +static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size, + int id) { ut_assertok(fdt_create(fdt, size)); ut_assertok(fdt_finish_reservemap(fdt)); ut_assert(fdt_begin_node(fdt, "") >= 0); + ut_assertok(fdt_property_u32(fdt, "id", id)); + ut_assert(fdt_begin_node(fdt, "aliases") >= 0); ut_assertok(fdt_property_string(fdt, "mmc0", "/new-mmc")); ut_assertok(fdt_end_node(fdt)); @@ -505,37 +753,41 @@ static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size) static int dm_test_ofnode_root(struct unit_test_state *uts) { - struct device_node *root = NULL; char fdt[256]; oftree tree; ofnode node; + int ret; /* Check that aliases work on the control FDT */ node = ofnode_get_aliases_node("ethernet3"); ut_assert(ofnode_valid(node)); ut_asserteq_str("sbe5", ofnode_get_name(node)); - ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt))); - if (of_live_active()) { - ut_assertok(unflatten_device_tree(fdt, &root)); - tree.np = root; - } else { - tree.fdt = fdt; - } + ut_assert(!oftree_valid(oftree_null())); + + ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt), 0)); + ret = get_oftree(uts, fdt, &tree); + + /* skip the rest of this test if multiple FDTs are not supported */ + if (ret == -EOVERFLOW) + return 0; + + ut_assertok(ret); + ut_assert(oftree_valid(tree)); /* Make sure they don't work on this new tree */ - node = ofnode_path_root(tree, "mmc0"); + node = oftree_path(tree, "mmc0"); ut_assert(!ofnode_valid(node)); /* It should appear in the new tree */ - node = ofnode_path_root(tree, "/new-mmc"); + node = oftree_path(tree, "/new-mmc"); ut_assert(ofnode_valid(node)); /* ...and not in the control FDT */ - node = ofnode_path_root(oftree_default(), "/new-mmc"); + node = oftree_path(oftree_default(), "/new-mmc"); ut_assert(!ofnode_valid(node)); - free(root); + free_oftree(tree); return 0; } @@ -570,7 +822,8 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr(dev)); /* reg = 0x42, size = 0x100 */ ut_assertok(ofnode_write_prop(node, "reg", - "\x00\x00\x00\x42\x00\x00\x01\x00", 8)); + "\x00\x00\x00\x42\x00\x00\x01\x00", 8, + false)); ut_asserteq(0x42, dev_read_addr(dev)); /* Test disabling devices */ @@ -584,11 +837,71 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofnode_livetree_writing, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +static int check_write_prop(struct unit_test_state *uts, ofnode node) +{ + char prop[] = "middle-name"; + char name[10]; + int len; + + strcpy(name, "cecil"); + len = strlen(name) + 1; + ut_assertok(ofnode_write_prop(node, prop, name, len, false)); + ut_asserteq_str(name, ofnode_read_string(node, prop)); + + /* change the underlying value, this should mess up the live tree */ + strcpy(name, "tony"); + if (of_live_active()) { + ut_asserteq_str(name, ofnode_read_string(node, prop)); + } else { + ut_asserteq_str("cecil", ofnode_read_string(node, prop)); + } + + /* try again, this time copying the property */ + strcpy(name, "mary"); + ut_assertok(ofnode_write_prop(node, prop, name, len, true)); + ut_asserteq_str(name, ofnode_read_string(node, prop)); + strcpy(name, "leah"); + + /* both flattree and livetree behave the same */ + ut_asserteq_str("mary", ofnode_read_string(node, prop)); + + return 0; +} + +/* writing the tree with and without copying the property */ +static int dm_test_ofnode_write_copy(struct unit_test_state *uts) +{ + ofnode node; + + node = ofnode_path("/a-test"); + ut_assertok(check_write_prop(uts, node)); + + return 0; +} +DM_TEST(dm_test_ofnode_write_copy, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_write_copy_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node, check_node; + + node = oftree_path(otree, "/node"); + ut_assertok(check_write_prop(uts, node)); + + /* make sure the control FDT is not touched */ + check_node = ofnode_path("/node"); + ut_assertnull(ofnode_read_string(check_node, "middle-name")); + + return 0; +} +DM_TEST(dm_test_ofnode_write_copy_ot, UT_TESTF_OTHER_FDT); static int dm_test_ofnode_u32(struct unit_test_state *uts) { ofnode node; + u32 val; node = ofnode_path("/lcd"); ut_assert(ofnode_valid(node)); @@ -597,7 +910,328 @@ static int dm_test_ofnode_u32(struct unit_test_state *uts) ut_asserteq(1367, ofnode_read_u32_default(node, "xres", 123)); ut_assertok(ofnode_write_u32(node, "xres", 1366)); + node = ofnode_path("/backlight"); + ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 0, &val)); + ut_asserteq(0, val); + ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 1, &val)); + ut_asserteq(16, val); + ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 8, &val)); + ut_asserteq(255, val); + ut_asserteq(-EOVERFLOW, + ofnode_read_u32_index(node, "brightness-levels", 9, &val)); + ut_asserteq(-EINVAL, ofnode_read_u32_index(node, "missing", 0, &val)); + return 0; } -DM_TEST(dm_test_ofnode_u32, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); +DM_TEST(dm_test_ofnode_u32, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_u32_array(struct unit_test_state *uts) +{ + ofnode node; + u32 val[10]; + + node = ofnode_path("/a-test"); + ut_assert(ofnode_valid(node)); + ut_assertok(ofnode_read_u32_array(node, "int-value", val, 1)); + ut_asserteq(-EINVAL, ofnode_read_u32_array(node, "missing", val, 1)); + ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "bool-value", val, + 1)); + + memset(val, '\0', sizeof(val)); + ut_assertok(ofnode_read_u32_array(node, "int-array", val + 1, 3)); + ut_asserteq(0, val[0]); + ut_asserteq(5678, val[1]); + ut_asserteq(9123, val[2]); + ut_asserteq(4567, val[3]); + ut_asserteq(0, val[4]); + ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "int-array", val, + 4)); + + return 0; +} +DM_TEST(dm_test_ofnode_u32_array, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_u64(struct unit_test_state *uts) +{ + ofnode node; + u64 val; + + node = ofnode_path("/a-test"); + ut_assert(ofnode_valid(node)); + ut_assertok(ofnode_read_u64(node, "int64-value", &val)); + ut_asserteq_64(0x1111222233334444, val); + ut_asserteq(-EINVAL, ofnode_read_u64(node, "missing", &val)); + + return 0; +} +DM_TEST(dm_test_ofnode_u64, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_add_subnode(struct unit_test_state *uts) +{ + ofnode node, check, subnode; + char buf[128]; + + node = ofnode_path("/lcd"); + ut_assert(ofnode_valid(node)); + ut_assertok(ofnode_add_subnode(node, "edmund", &subnode)); + check = ofnode_path("/lcd/edmund"); + ut_asserteq(subnode.of_offset, check.of_offset); + ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf))); + ut_asserteq_str("/lcd/edmund", buf); + + if (of_live_active()) { + struct device_node *child; + + ut_assertok(of_add_subnode((void *)ofnode_to_np(node), "edmund", + 2, &child)); + ut_asserteq_str("ed", child->name); + ut_asserteq_str("/lcd/ed", child->full_name); + check = ofnode_path("/lcd/ed"); + ut_asserteq_ptr(child, check.np); + ut_assertok(ofnode_get_path(np_to_ofnode(child), buf, + sizeof(buf))); + ut_asserteq_str("/lcd/ed", buf); + } + + /* An existing node should be returned with -EEXIST */ + ut_asserteq(-EEXIST, ofnode_add_subnode(node, "edmund", &check)); + ut_asserteq(subnode.of_offset, check.of_offset); + + /* add a root node */ + node = ofnode_path("/"); + ut_assert(ofnode_valid(node)); + ut_assertok(ofnode_add_subnode(node, "lcd2", &subnode)); + check = ofnode_path("/lcd2"); + ut_asserteq(subnode.of_offset, check.of_offset); + ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf))); + ut_asserteq_str("/lcd2", buf); + + if (of_live_active()) { + ulong start; + int i; + + /* + * Make sure each of the three malloc()checks in + * of_add_subnode() work + */ + for (i = 0; i < 3; i++) { + malloc_enable_testing(i); + start = ut_check_free(); + ut_asserteq(-ENOMEM, ofnode_add_subnode(node, "anthony", + &check)); + ut_assertok(ut_check_delta(start)); + } + + /* This should pass since we allow 3 allocations */ + malloc_enable_testing(3); + ut_assertok(ofnode_add_subnode(node, "anthony", &check)); + malloc_disable_testing(); + } + + /* write to the empty node */ + ut_assertok(ofnode_write_string(subnode, "example", "text")); + + return 0; +} +DM_TEST(dm_test_ofnode_add_subnode, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_for_each_prop(struct unit_test_state *uts) +{ + ofnode node, subnode; + struct ofprop prop; + int count; + + node = ofnode_path("/buttons"); + count = 0; + + /* we expect "compatible" for each node */ + ofnode_for_each_prop(prop, node) + count++; + ut_asserteq(1, count); + + /* there are two nodes, each with 2 properties */ + ofnode_for_each_subnode(subnode, node) + ofnode_for_each_prop(prop, subnode) + count++; + ut_asserteq(5, count); + + return 0; +} +DM_TEST(dm_test_ofnode_for_each_prop, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_by_compatible(struct unit_test_state *uts) +{ + const char *compat = "denx,u-boot-fdt-test"; + ofnode node; + int count; + + count = 0; + for (node = ofnode_null(); + node = ofnode_by_compatible(node, compat), ofnode_valid(node);) + count++; + ut_asserteq(11, count); + + return 0; +} +DM_TEST(dm_test_ofnode_by_compatible, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_by_compatible_ot(struct unit_test_state *uts) +{ + const char *compat = "sandbox-other2"; + oftree otree = get_other_oftree(uts); + ofnode node; + int count; + + count = 0; + for (node = oftree_root(otree); + node = ofnode_by_compatible(node, compat), ofnode_valid(node);) + count++; + ut_asserteq(2, count); + + return 0; +} +DM_TEST(dm_test_ofnode_by_compatible_ot, UT_TESTF_OTHER_FDT); + +static int dm_test_ofnode_find_subnode(struct unit_test_state *uts) +{ + ofnode node, subnode; + + node = ofnode_path("/buttons"); + + subnode = ofnode_find_subnode(node, "btn1"); + ut_assert(ofnode_valid(subnode)); + ut_asserteq_str("btn1", ofnode_get_name(subnode)); + + subnode = ofnode_find_subnode(node, "btn"); + ut_assert(!ofnode_valid(subnode)); + + return 0; +} +DM_TEST(dm_test_ofnode_find_subnode, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_find_subnode_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node, subnode; + + node = oftree_path(otree, "/node"); + + subnode = ofnode_find_subnode(node, "subnode"); + ut_assert(ofnode_valid(subnode)); + ut_asserteq_str("subnode", ofnode_get_name(subnode)); + + subnode = ofnode_find_subnode(node, "btn"); + ut_assert(!ofnode_valid(subnode)); + + return 0; +} +DM_TEST(dm_test_ofnode_find_subnode_ot, UT_TESTF_OTHER_FDT); + +static int dm_test_ofnode_get_name(struct unit_test_state *uts) +{ + ofnode node; + + node = ofnode_path("/buttons"); + ut_assert(ofnode_valid(node)); + ut_asserteq_str("buttons", ofnode_get_name(node)); + ut_asserteq_str("", ofnode_get_name(ofnode_root())); + + return 0; +} +DM_TEST(dm_test_ofnode_get_name, UT_TESTF_SCAN_FDT); + +/* try to access more FDTs than is supported */ +static int dm_test_ofnode_too_many(struct unit_test_state *uts) +{ + const int max_trees = CONFIG_IS_ENABLED(OFNODE_MULTI_TREE, + (CONFIG_OFNODE_MULTI_TREE_MAX), (1)); + const int fdt_size = 256; + const int num_trees = max_trees + 1; + char fdt[num_trees][fdt_size]; + int i; + + for (i = 0; i < num_trees; i++) { + oftree tree; + int ret; + + ut_assertok(make_ofnode_fdt(uts, fdt[i], fdt_size, i)); + ret = get_oftree(uts, fdt[i], &tree); + + /* + * With flat tree we have the control FDT using one slot. Live + * tree has no limit since it uses pointers, not integer tree + * IDs + */ + if (of_live_active() || i < max_trees - 1) { + ut_assertok(ret); + } else { + /* + * tree should be invalid when we try to register too + * many trees + */ + ut_asserteq(-EOVERFLOW, ret); + } + } + + return 0; +} +DM_TEST(dm_test_ofnode_too_many, UT_TESTF_SCAN_FDT); + +static int check_copy_props(struct unit_test_state *uts, ofnode src, + ofnode dst) +{ + u32 reg[2], val; + + ut_assertok(ofnode_copy_props(src, dst)); + + ut_assertok(ofnode_read_u32(dst, "ping-expect", &val)); + ut_asserteq(3, val); + + ut_asserteq_str("denx,u-boot-fdt-test", + ofnode_read_string(dst, "compatible")); + + /* check that a property with the same name is overwritten */ + ut_assertok(ofnode_read_u32_array(dst, "reg", reg, ARRAY_SIZE(reg))); + ut_asserteq(3, reg[0]); + ut_asserteq(1, reg[1]); + + /* reset the compatible so the live tree does not change */ + ut_assertok(ofnode_write_string(dst, "compatible", "nothing")); + + return 0; +} + +static int dm_test_ofnode_copy_props(struct unit_test_state *uts) +{ + ofnode src, dst; + + /* + * These nodes are chosen so that the src node is before the destination + * node in the tree. This doesn't matter with livetree, but with + * flattree any attempt to insert a property earlier in the tree will + * mess up the offsets after it. + */ + src = ofnode_path("/b-test"); + dst = ofnode_path("/some-bus"); + + ut_assertok(check_copy_props(uts, src, dst)); + + /* check a property that is in the destination already */ + ut_asserteq_str("mux0", ofnode_read_string(dst, "mux-control-names")); + + return 0; +} +DM_TEST(dm_test_ofnode_copy_props, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_copy_props_ot(struct unit_test_state *uts) +{ + ofnode src, dst; + oftree otree = get_other_oftree(uts); + + src = ofnode_path("/b-test"); + dst = oftree_path(otree, "/node/subnode2"); + ut_assertok(check_copy_props(uts, src, dst)); + + return 0; +} +DM_TEST(dm_test_ofnode_copy_props_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT); diff --git a/test/dm/ofread.c b/test/dm/ofread.c index 8c7dd82513..3523860d2b 100644 --- a/test/dm/ofread.c +++ b/test/dm/ofread.c @@ -5,7 +5,7 @@ #include #include -static int dm_test_ofnode_get_property_by_prop(struct unit_test_state *uts) +static int dm_test_ofprop_get_property(struct unit_test_state *uts) { ofnode node; struct ofprop prop; @@ -14,10 +14,10 @@ static int dm_test_ofnode_get_property_by_prop(struct unit_test_state *uts) int res, len, count = 0; node = ofnode_path("/cros-ec/flash"); - for (res = ofnode_get_first_property(node, &prop); + for (res = ofnode_first_property(node, &prop); !res; - res = ofnode_get_next_property(&prop)) { - value = ofnode_get_property_by_prop(&prop, &propname, &len); + res = ofnode_next_property(&prop)) { + value = ofprop_get_property(&prop, &propname, &len); ut_assertnonnull(value); switch (count) { case 0: @@ -46,5 +46,4 @@ static int dm_test_ofnode_get_property_by_prop(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ofnode_get_property_by_prop, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +DM_TEST(dm_test_ofprop_get_property, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); diff --git a/test/dm/rtc.c b/test/dm/rtc.c index c7f9f8f0ce..bf97dbbd2f 100644 --- a/test/dm/rtc.c +++ b/test/dm/rtc.c @@ -60,16 +60,27 @@ static int dm_test_rtc_set_get(struct unit_test_state *uts) { struct rtc_time now, time, cmp; struct udevice *dev, *emul; - long offset, old_offset, old_base_time; + long offset, check_offset, old_offset, old_base_time; + int i; ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev)); - ut_assertok(dm_rtc_get(dev, &now)); ut_assertok(i2c_emul_find(dev, &emul)); - ut_assert(emul != NULL); + ut_assertnonnull(emul); + + /* Get the offset, putting the RTC into manual mode */ + i = 0; + do { + check_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); + ut_assertok(dm_rtc_get(dev, &now)); + + /* Tell the RTC to go into manual mode */ + old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); + + /* If the times changed in that period, read it again */ + } while (++i < 2 && check_offset != old_offset); + ut_asserteq(check_offset, old_offset); - /* Tell the RTC to go into manual mode */ - old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1); memset(&time, '\0', sizeof(time)); @@ -127,7 +138,8 @@ static int dm_test_rtc_set_get(struct unit_test_state *uts) ut_asserteq(now.tm_sec + 1, cmp.tm_sec); } - old_offset = sandbox_i2c_rtc_set_offset(emul, true, 0); + /* return RTC to normal mode */ + sandbox_i2c_rtc_set_offset(emul, true, 0); return 0; } @@ -161,7 +173,7 @@ static int dm_test_rtc_read_write(struct unit_test_state *uts) ut_asserteq(memcmp(buf, "at", 3), 0); ut_assertok(i2c_emul_find(dev, &emul)); - ut_assert(emul != NULL); + ut_assertnonnull(emul); old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); ut_assertok(dm_rtc_get(dev, &time)); @@ -240,20 +252,31 @@ static int dm_test_rtc_reset(struct unit_test_state *uts) struct rtc_time now; struct udevice *dev, *emul; long old_base_time, base_time; + int i; ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev)); ut_assertok(dm_rtc_get(dev, &now)); ut_assertok(i2c_emul_find(dev, &emul)); - ut_assert(emul != NULL); + ut_assertnonnull(emul); - old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, 0); + i = 0; + do { + old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, 0); - ut_asserteq(0, sandbox_i2c_rtc_get_set_base_time(emul, -1)); + ut_asserteq(0, sandbox_i2c_rtc_get_set_base_time(emul, -1)); - /* Resetting the RTC should put he base time back to normal */ - ut_assertok(dm_rtc_reset(dev)); - base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1); + ut_assertok(dm_rtc_reset(dev)); + base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1); + + /* + * Resetting the RTC should put the base time back to normal. + * Allow for a one-timeadjustment in case the time flips over + * while this test process is pre-empted (either by a second + * or a daylight-saving change), since reset_time() in + * i2c_rtc_emul.c reads the time from the OS. + */ + } while (++i < 2 && base_time != old_base_time); ut_asserteq(old_base_time, base_time); return 0; @@ -274,9 +297,9 @@ static int dm_test_rtc_dual(struct unit_test_state *uts) ut_assertok(dm_rtc_get(dev2, &now2)); ut_assertok(i2c_emul_find(dev1, &emul1)); - ut_assert(emul1 != NULL); + ut_assertnonnull(emul1); ut_assertok(i2c_emul_find(dev2, &emul2)); - ut_assert(emul2 != NULL); + ut_assertnonnull(emul2); offset = sandbox_i2c_rtc_set_offset(emul1, false, -1); sandbox_i2c_rtc_set_offset(emul2, false, offset + 1); diff --git a/test/dm/scsi.c b/test/dm/scsi.c new file mode 100644 index 0000000000..380cfc88ba --- /dev/null +++ b/test/dm/scsi.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2015 Google, Inc + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Test that sandbox SCSI works correctly */ +static int dm_test_scsi_base(struct unit_test_state *uts) +{ + const struct disk_partition *info; + const struct disk_part *part; + struct udevice *dev; + + ut_assertok(scsi_scan(false)); + + /* + * We expect some sort of partition on the disk image, created by + * test_ut_dm_init() + */ + ut_assertok(uclass_first_device_err(UCLASS_PARTITION, &dev)); + + part = dev_get_uclass_plat(dev); + ut_asserteq(1, part->partnum); + + info = &part->gpt_part_info; + ut_asserteq_str("sda1", info->name); + ut_asserteq_str("U-Boot", info->type); + ut_asserteq(0x83 /* linux */, info->sys_ind); + + return 0; +} +DM_TEST(dm_test_scsi_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); diff --git a/test/dm/test-dm.c b/test/dm/test-dm.c index f5cda81bbf..eb3581333b 100644 --- a/test/dm/test-dm.c +++ b/test/dm/test-dm.c @@ -29,13 +29,14 @@ DECLARE_GLOBAL_DATA_PTR; * "fdt_pre_reloc"), or NULL to run all * Return: 0 if all tests passed, 1 if not */ -static int dm_test_run(const char *test_name) +static int dm_test_run(const char *test_name, int runs_per_text) { struct unit_test *tests = UNIT_TEST_SUITE_START(dm_test); const int n_ents = UNIT_TEST_SUITE_COUNT(dm_test); int ret; - ret = ut_run_list("driver model", "dm_test_", tests, n_ents, test_name); + ret = ut_run_list("driver model", "dm_test_", tests, n_ents, test_name, + runs_per_text); return ret ? CMD_RET_FAILURE : 0; } @@ -43,9 +44,15 @@ static int dm_test_run(const char *test_name) int do_ut_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { const char *test_name = NULL; + int runs_per_text = 1; + if (argc > 1 && !strncmp("-r", argv[1], 2)) { + runs_per_text = dectoul(argv[1] + 2, NULL); + argv++; + argc++; + } if (argc > 1) test_name = argv[1]; - return dm_test_run(test_name); + return dm_test_run(test_name, runs_per_text); } diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 6118ad42ca..012f2f455f 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -815,6 +815,8 @@ DM_TEST(dm_test_first_child, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); static int dm_test_read_int(struct unit_test_state *uts) { struct udevice *dev; + u8 val8; + u16 val16; u32 val32; s32 sval; uint val; @@ -822,6 +824,23 @@ static int dm_test_read_int(struct unit_test_state *uts) ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev)); ut_asserteq_str("a-test", dev->name); + + ut_assertok(dev_read_u8(dev, "int8-value", &val8)); + ut_asserteq(0x12, val8); + + ut_asserteq(-EINVAL, dev_read_u8(dev, "missing", &val8)); + ut_asserteq(6, dev_read_u8_default(dev, "missing", 6)); + + ut_asserteq(0x12, dev_read_u8_default(dev, "int8-value", 6)); + + ut_assertok(dev_read_u16(dev, "int16-value", &val16)); + ut_asserteq(0x1234, val16); + + ut_asserteq(-EINVAL, dev_read_u16(dev, "missing", &val16)); + ut_asserteq(6, dev_read_u16_default(dev, "missing", 6)); + + ut_asserteq(0x1234, dev_read_u16_default(dev, "int16-value", 6)); + ut_assertok(dev_read_u32(dev, "int-value", &val32)); ut_asserteq(1234, val32); diff --git a/test/dm/wdt.c b/test/dm/wdt.c index 535f00a874..653d7b1c8b 100644 --- a/test/dm/wdt.c +++ b/test/dm/wdt.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -130,7 +131,7 @@ static int dm_test_wdt_watchdog_reset(struct unit_test_state *uts) /* Neither device should be "started", so watchdog_reset() should be a no-op. */ reset_count = state->wdt.reset_count; val = sandbox_gpio_get_value(gpio, offset); - watchdog_reset(); + cyclic_run(); ut_asserteq(reset_count, state->wdt.reset_count); ut_asserteq(val, sandbox_gpio_get_value(gpio, offset)); @@ -140,19 +141,19 @@ static int dm_test_wdt_watchdog_reset(struct unit_test_state *uts) /* Make sure both devices have just been pinged. */ timer_test_add_offset(100); - watchdog_reset(); + cyclic_run(); reset_count = state->wdt.reset_count; val = sandbox_gpio_get_value(gpio, offset); /* The gpio watchdog should be pinged, the sandbox one not. */ timer_test_add_offset(30); - watchdog_reset(); + cyclic_run(); ut_asserteq(reset_count, state->wdt.reset_count); ut_asserteq(!val, sandbox_gpio_get_value(gpio, offset)); /* After another ~30ms, both devices should get pinged. */ timer_test_add_offset(30); - watchdog_reset(); + cyclic_run(); ut_asserteq(reset_count + 1, state->wdt.reset_count); ut_asserteq(val, sandbox_gpio_get_value(gpio, offset)); diff --git a/test/image/spl_load.c b/test/image/spl_load.c index df389e26f9..4e27ff460a 100644 --- a/test/image/spl_load.c +++ b/test/image/spl_load.c @@ -49,7 +49,7 @@ int board_fit_config_name_match(const char *name) return 0; } -struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { return map_sysmem(0x100000, 0); } @@ -57,7 +57,7 @@ struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) static int spl_test_load(struct unit_test_state *uts) { struct spl_image_info image; - struct image_header *header; + struct legacy_img_hdr *header; struct text_ctx text_ctx; struct spl_load_info load; char fname[256]; diff --git a/test/lib/test_print.c b/test/lib/test_print.c index a60a5a51f1..79b67c7793 100644 --- a/test/lib/test_print.c +++ b/test/lib/test_print.c @@ -68,6 +68,9 @@ static int lib_test_print_size(struct unit_test_state *uts) ut_assertok(test_print_size(uts, 7654321, "7.3 MiB;")); ut_assertok(test_print_size(uts, 87654321, "83.6 MiB;")); ut_assertok(test_print_size(uts, 987654321, "941.9 MiB;")); + ut_assertok(test_print_size(uts, 1073689395, "1023.9 MiB;")); + ut_assertok(test_print_size(uts, 1073689396, "1 GiB;")); + ut_assertok(test_print_size(uts, 1073741824, "1 GiB;")); ut_assertok(test_print_size(uts, 1987654321, "1.9 GiB;")); ut_assertok(test_print_size(uts, 54321987654321, "49.4 TiB;")); return 0; diff --git a/test/nokia_rx51_test.sh b/test/nokia_rx51_test.sh index 28aa554ed8..a516ec2967 100755 --- a/test/nokia_rx51_test.sh +++ b/test/nokia_rx51_test.sh @@ -34,9 +34,20 @@ echo "========== Compiling U-Boot for Nokia RX-51 board ==========" echo "============================================================" echo -# First compile u-boot.bin binary for Nokia RX-51 board +# First compile u-boot-ubifs.bin binary with UBI/UBIFS support for Nokia RX-51 board according to doc/board/nokia/rx51.rst make nokia_rx51_config -make -j4 u-boot.bin ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- +cat >> .config << EOF +CONFIG_CMD_UBI=y +CONFIG_CMD_UBIFS=y +CONFIG_MTD_UBI_BEB_LIMIT=10 +EOF +make olddefconfig +make -j4 u-boot.bin CROSS_COMPILE=arm-linux-gnueabi- +mv u-boot.bin u-boot-ubifs.bin + +# Then compile standard u-boot.bin binary for Nokia RX-51 board +make nokia_rx51_config +make -j4 u-boot.bin CROSS_COMPILE=arm-linux-gnueabi- # And then do all stuff in temporary directory mkdir -p nokia_rx51_tmp @@ -44,6 +55,7 @@ cd nokia_rx51_tmp test -f mkimage || ln -s ../tools/mkimage . test -f u-boot.bin || ln -s ../u-boot.bin . +test -f u-boot-ubifs.bin || ln -s ../u-boot-ubifs.bin . echo echo "==========================================================================" @@ -99,6 +111,10 @@ echo "========== Generating images ==========" echo "=======================================" echo +# Generate kernel image in zImage and uImage format from FIASCO format +dd if=kernel_2.6.28/boot/zImage-2.6.28-20103103+0m5.fiasco of=zImage-2.6.28-omap1 skip=95 bs=1 +./mkimage -A arm -O linux -T kernel -C none -a 80008000 -e 80008000 -n zImage-2.6.28-omap1 -d zImage-2.6.28-omap1 uImage-2.6.28-omap1 + # Generate rootfs directory mkdir -p rootfs mkdir -p rootfs/dev/ @@ -123,20 +139,7 @@ echo EOF chmod +x rootfs/sbin/preinit -# Generate ubi config file for ubi rootfs image -cat > ubi.ini << EOF -[rootfs] -mode=ubi -image=ubifs.img -vol_id=0 -vol_size=160MiB -vol_type=dynamic -vol_name=rootfs -vol_alignment=1 -vol_flags=autoresize -EOF - -# Generate ubi rootfs image from rootfs directory +# Generate ubifs image from rootfs directory # NOTE: Character device on host filesystem can be created only by root # But we do not need it on host filesystem, just in ubifs image # So run mknod and mkfs.ubifs commands under fakeroot program @@ -149,8 +152,35 @@ fakeroot sh -c ' mknod rootfs/dev/console c 5 1; /usr/sbin/mkfs.ubifs -m 2048 -e 129024 -c 2047 -r rootfs ubifs.img; ' + +# Generate ubi image with rootfs on first volume +cat > ubi.ini << EOF +[rootfs] +mode=ubi +image=ubifs.img +vol_id=0 +vol_size=230MiB # 1870 LEBs +vol_type=dynamic +vol_name=rootfs +vol_alignment=1 +vol_flags=autoresize +EOF /usr/sbin/ubinize -o ubi.img -p 128KiB -m 2048 -s 512 ubi.ini +# Generate ubi image with rootfs on first volume and kernel in zImage format on second volume for UBI booting +cp ubi.ini ubi_with_kernel.ini +cat >> ubi_with_kernel.ini << EOF +[kernel] +mode=ubi +image=zImage-2.6.28-omap1 +vol_id=1 +vol_size=2MiB +vol_type=dynamic +vol_name=kernel +vol_alignment=1 +EOF +/usr/sbin/ubinize -o ubi_with_kernel.img -p 128KiB -m 2048 -s 512 ubi_with_kernel.ini + # Generate bootmenu for U-Boot serial console testing cat > bootmenu_uboot << EOF setenv bootmenu_0 'Serial console test=echo; echo "Testing serial console"; echo; echo "Successfully booted"; echo; poweroff'; @@ -178,15 +208,24 @@ setenv bootdelay 1; EOF ./mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n bootmenu_emmc2 -d bootmenu_emmc2 bootmenu_emmc2.scr -# Generate bootmenu for OneNAND booting +# Generate bootmenu for OneNAND booting (uImage) cat > bootmenu_nand << EOF -setenv bootmenu_0 'uImage-2.6.28-omap1 from OneNAND=mtd read initfs \${kernaddr}; setenv bootargs; setenv setup_omap_atag 1; bootm \${kernaddr}'; +setenv bootmenu_0 'uImage-2.6.28-omap1 from OneNAND=setenv bootargs; setenv setup_omap_atag 1; mtd read initfs \${kernaddr} && bootm \${kernaddr}'; setenv bootmenu_1; setenv bootmenu_delay 1; setenv bootdelay 1; EOF ./mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n bootmenu_nand -d bootmenu_nand bootmenu_nand.scr +# Generate bootmenu for UBI booting (zImage) +cat > bootmenu_ubi << EOF +setenv bootmenu_0 'zImage-2.6.28-omap1 from UBI=setenv bootargs; setenv setup_omap_atag 1; ubi part rootfs && ubi read \${kernaddr} kernel && bootz \${kernaddr}'; +setenv bootmenu_1; +setenv bootmenu_delay 1; +setenv bootdelay 1; +EOF +./mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n bootmenu_ubi -d bootmenu_ubi bootmenu_ubi.scr + # Generate bootmenu for default booting cat > bootmenu_default << EOF setenv bootmenu_delay 1; @@ -195,9 +234,7 @@ EOF ./mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n bootmenu_default -d bootmenu_default bootmenu_default.scr # Generate combined image from u-boot and Maemo fiasco kernel -dd if=kernel_2.6.28/boot/zImage-2.6.28-20103103+0m5.fiasco of=zImage-2.6.28-omap1 skip=95 bs=1 ./u-boot-gen-combined u-boot.bin zImage-2.6.28-omap1 combined_zimage.bin -./mkimage -A arm -O linux -T kernel -C none -a 80008000 -e 80008000 -n zImage-2.6.28-omap1 -d zImage-2.6.28-omap1 uImage-2.6.28-omap1 ./u-boot-gen-combined u-boot.bin uImage-2.6.28-omap1 combined_uimage.bin # Generate combined hack image from u-boot and Maemo fiasco kernel (kernel starts at 2MB offset and qflasher puts 2kB header before supplied image) @@ -221,11 +258,16 @@ mformat -m 0xf8 -F -h 4 -s 16 -c 1 -t $((50*1024*1024/(4*16*512))) :: -i emmc_em mcopy zImage-2.6.28-omap1 ::/zImage-2.6.28-omap1 -i emmc_emmc2.img mcopy bootmenu_emmc2.scr ::/bootmenu.scr -i emmc_emmc2.img -# Generate FAT32 eMMC image for OneNAND booting +# Generate FAT32 eMMC image for OneNAND booting (uImage) truncate -s 50MiB emmc_nand.img mformat -m 0xf8 -F -h 4 -s 16 -c 1 -t $((50*1024*1024/(4*16*512))) :: -i emmc_nand.img mcopy bootmenu_nand.scr ::/bootmenu.scr -i emmc_nand.img +# Generate FAT32 eMMC image for UBI booting (zImage) +truncate -s 50MiB emmc_ubi.img +mformat -m 0xf8 -F -h 4 -s 16 -c 1 -t $((50*1024*1024/(4*16*512))) :: -i emmc_ubi.img +mcopy bootmenu_ubi.scr ::/bootmenu.scr -i emmc_ubi.img + # Generate FAT32 eMMC image for default booting truncate -s 50MiB emmc_default.img mformat -m 0xf8 -F -h 4 -s 16 -c 1 -t $((50*1024*1024/(4*16*512))) :: -i emmc_default.img @@ -251,6 +293,10 @@ rm -f mtd_emmc.img rm -f mtd_nand.img ./qflasher -v -x xloader-qemu.bin -s secondary-qemu.bin -k combined_hack.bin -r ubi.img -m rx51 -p k=4094,i=2 -o mtd_nand.img +# Generate MTD image for UBI booting from bootloader nolo images, u-boot image with UBI/UBIFS support and rootfs image with kernel volume +rm -f mtd_ubi.img +./qflasher -v -x xloader-qemu.bin -s secondary-qemu.bin -k u-boot-ubifs.bin -r ubi_with_kernel.img -m rx51 -o mtd_ubi.img + echo echo "======================================================" echo "========== Running test images in n900 qemu ==========" @@ -329,6 +375,18 @@ wait -n $sleep_pid $qemu_pid || true kill -9 $tail_pid $sleep_pid $qemu_pid 2>/dev/null || true wait || true +# Run MTD image in qemu and wait for 300s if kernel from UBI is correctly booted +rm -f qemu_ubi.log +./qemu-system-arm -M n900 -mtdblock mtd_ubi.img -sd emmc_ubi.img -serial /dev/stdout -display none > qemu_ubi.log & +qemu_pid=$! +tail -F qemu_ubi.log & +tail_pid=$! +sleep 300 & +sleep_pid=$! +wait -n $sleep_pid $qemu_pid || true +kill -9 $tail_pid $sleep_pid $qemu_pid 2>/dev/null || true +wait || true + echo echo "=============================" echo "========== Results ==========" @@ -341,10 +399,11 @@ if grep -q 'Successfully booted' qemu_ram2.log; then echo "Kernel (zImage) was s if grep -q 'Successfully booted' qemu_emmc.log; then echo "Kernel (uImage) was successfully booted from eMMC"; else echo "Failed to boot kernel (uImage) from eMMC"; fi if grep -q 'Successfully booted' qemu_emmc2.log; then echo "Kernel (zImage) was successfully booted from eMMC"; else echo "Failed to boot kernel (zImage) from eMMC"; fi if grep -q 'Successfully booted' qemu_nand.log; then echo "Kernel (uImage) was successfully booted from OneNAND"; else echo "Failed to boot kernel (uImage) from OneNAND"; fi +if grep -q 'Successfully booted' qemu_ubi.log; then echo "Kernel (zImage) was successfully booted from UBI"; else echo "Failed to boot kernel (zImage) from UBI"; fi echo -if grep -q 'Successfully booted' qemu_uboot.log && grep -q 'Successfully booted' qemu_ram.log && grep -q 'Successfully booted' qemu_ram2.log && grep -q 'Successfully booted' qemu_emmc.log && grep -q 'Successfully booted' qemu_emmc2.log && grep -q 'Successfully booted' qemu_nand.log; then +if grep -q 'Successfully booted' qemu_uboot.log && grep -q 'Successfully booted' qemu_ram.log && grep -q 'Successfully booted' qemu_ram2.log && grep -q 'Successfully booted' qemu_emmc.log && grep -q 'Successfully booted' qemu_emmc2.log && grep -q 'Successfully booted' qemu_nand.log && grep -q 'Successfully booted' qemu_ubi.log; then echo "All tests passed" exit 0 else diff --git a/test/py/conftest.py b/test/py/conftest.py index 2ba34479e0..304e93164a 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -15,9 +15,11 @@ import atexit import configparser import errno +import filelock import io import os import os.path +from pathlib import Path import pytest import re from _pytest.runner import runtestprotocol @@ -27,6 +29,8 @@ import sys log = None console = None +TEST_PY_DIR = os.path.dirname(os.path.abspath(__file__)) + def mkdir_p(path): """Create a directory path. @@ -76,6 +80,53 @@ def pytest_addoption(parser): help='Run sandbox under gdbserver. The argument is the channel '+ 'over which gdbserver should communicate, e.g. localhost:1234') +def run_build(config, source_dir, build_dir, board_type, log): + """run_build: Build U-Boot + + Args: + config: The pytest configuration. + soruce_dir (str): Directory containing source code + build_dir (str): Directory to build in + board_type (str): board_type parameter (e.g. 'sandbox') + log (Logfile): Log file to use + """ + if config.getoption('buildman'): + if build_dir != source_dir: + dest_args = ['-o', build_dir, '-w'] + else: + dest_args = ['-i'] + cmds = (['buildman', '--board', board_type] + dest_args,) + name = 'buildman' + else: + if build_dir != source_dir: + o_opt = 'O=%s' % build_dir + else: + o_opt = '' + cmds = ( + ['make', o_opt, '-s', board_type + '_defconfig'], + ['make', o_opt, '-s', '-j{}'.format(os.cpu_count())], + ) + name = 'make' + + with log.section(name): + runner = log.get_runner(name, sys.stdout) + for cmd in cmds: + runner.run(cmd, cwd=source_dir) + runner.close() + log.status_pass('OK') + +def pytest_xdist_setupnodes(config, specs): + """Clear out any 'done' file from a previous build""" + global build_done_file + build_dir = config.getoption('build_dir') + board_type = config.getoption('board_type') + source_dir = os.path.dirname(os.path.dirname(TEST_PY_DIR)) + if not build_dir: + build_dir = source_dir + '/build-' + board_type + build_done_file = Path(build_dir) / 'build.done' + if build_done_file.exists(): + os.remove(build_done_file) + def pytest_configure(config): """pytest hook: Perform custom initialization at startup time. @@ -110,8 +161,7 @@ def pytest_configure(config): global console global ubconfig - test_py_dir = os.path.dirname(os.path.abspath(__file__)) - source_dir = os.path.dirname(os.path.dirname(test_py_dir)) + source_dir = os.path.dirname(os.path.dirname(TEST_PY_DIR)) board_type = config.getoption('board_type') board_type_filename = board_type.replace('-', '_') @@ -142,30 +192,13 @@ def pytest_configure(config): log = multiplexed_log.Logfile(result_dir + '/test-log.html') if config.getoption('build'): - if config.getoption('buildman'): - if build_dir != source_dir: - dest_args = ['-o', build_dir, '-w'] - else: - dest_args = ['-i'] - cmds = (['buildman', '--board', board_type] + dest_args,) - name = 'buildman' - else: - if build_dir != source_dir: - o_opt = 'O=%s' % build_dir - else: - o_opt = '' - cmds = ( - ['make', o_opt, '-s', board_type + '_defconfig'], - ['make', o_opt, '-s', '-j{}'.format(os.cpu_count())], - ) - name = 'make' - - with log.section(name): - runner = log.get_runner(name, sys.stdout) - for cmd in cmds: - runner.run(cmd, cwd=source_dir) - runner.close() - log.status_pass('OK') + worker_id = os.environ.get("PYTEST_XDIST_WORKER") + with filelock.FileLock(os.path.join(build_dir, 'build.lock')): + build_done_file = Path(build_dir) / 'build.done' + if (not worker_id or worker_id == 'master' or + not build_done_file.exists()): + run_build(config, source_dir, build_dir, board_type, log) + build_done_file.touch() class ArbitraryAttributeContainer(object): pass @@ -197,7 +230,7 @@ def pytest_configure(config): else: parse_config('include/autoconf.mk') - ubconfig.test_py_dir = test_py_dir + ubconfig.test_py_dir = TEST_PY_DIR ubconfig.source_dir = source_dir ubconfig.build_dir = build_dir ubconfig.result_dir = result_dir @@ -521,6 +554,22 @@ def setup_requiredtool(item): if not tool_is_in_path(tool): pytest.skip('tool "%s" not in $PATH' % tool) +def setup_singlethread(item): + """Process any 'singlethread' marker for a test. + + Skip this test if running in parallel. + + Args: + item: The pytest test item. + + Returns: + Nothing. + """ + for single in item.iter_markers('singlethread'): + worker_id = os.environ.get("PYTEST_XDIST_WORKER") + if worker_id and worker_id != 'master': + pytest.skip('must run single-threaded') + def start_test_section(item): anchors[item.name] = log.start_section(item.name) @@ -541,6 +590,7 @@ def pytest_runtest_setup(item): setup_boardspec(item) setup_buildconfigspec(item) setup_requiredtool(item) + setup_singlethread(item) def pytest_runtest_protocol(item, nextitem): """pytest hook: Called to execute a test. diff --git a/test/py/pytest.ini b/test/py/pytest.ini index e93d010f1f..26d83f83e0 100644 --- a/test/py/pytest.ini +++ b/test/py/pytest.ini @@ -11,3 +11,4 @@ markers = notbuildconfigspec: U-Boot: Describes required disabled Kconfig options. requiredtool: U-Boot: Required host tools for a test. slow: U-Boot: Specific test will run slowly. + singlethread: Cannot run in parallel diff --git a/test/py/requirements.txt b/test/py/requirements.txt index ead92ed8b4..1bf77b59d8 100644 --- a/test/py/requirements.txt +++ b/test/py/requirements.txt @@ -2,6 +2,7 @@ atomicwrites==1.4.1 attrs==19.3.0 coverage==4.5.4 extras==1.0.0 +filelock==3.0.12 fixtures==3.0.0 importlib-metadata==0.23 linecache2==1.0.0 @@ -15,6 +16,7 @@ pyelftools==0.27 pygit2==1.9.2 pyparsing==2.4.2 pytest==6.2.5 +pytest-xdist==2.5.0 python-mimeparse==1.6.0 python-subunit==1.3.0 requests==2.25.1 diff --git a/test/py/tests/test_bind.py b/test/py/tests/test_bind.py index c90c54d266..1376ab5ed2 100644 --- a/test/py/tests/test_bind.py +++ b/test/py/tests/test_bind.py @@ -119,6 +119,7 @@ def get_next_line(tree, name): @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_bind') +@pytest.mark.singlethread def test_bind_unbind_with_uclass(u_boot_console): #bind /bind-test response = u_boot_console.run_command('bind /bind-test simple_bus') diff --git a/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py b/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py index 75a6e7c962..1bb59d8fcf 100644 --- a/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py +++ b/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py @@ -7,6 +7,7 @@ import pytest @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_efidebug') @pytest.mark.buildconfigspec('cmd_bootefi_bootmgr') +@pytest.mark.singlethread def test_efi_bootmgr(u_boot_console, efi_bootmgr_data): """ Unit test for UEFI bootmanager The efidebug command is used to set up UEFI load options. diff --git a/test/py/tests/test_eficonfig/conftest.py b/test/py/tests/test_eficonfig/conftest.py new file mode 100644 index 0000000000..f289df0362 --- /dev/null +++ b/test/py/tests/test_eficonfig/conftest.py @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: GPL-2.0+ + +"""Fixture for UEFI eficonfig test +""" + +import os +import shutil +from subprocess import check_call +import pytest + +@pytest.fixture(scope='session') +def efi_eficonfig_data(u_boot_config): + """Set up a file system to be used in UEFI "eficonfig" command + tests + + Args: + u_boot_config -- U-boot configuration. + + Return: + A path to disk image to be used for testing + """ + mnt_point = u_boot_config.persistent_data_dir + '/test_efi_eficonfig' + image_path = u_boot_config.persistent_data_dir + '/efi_eficonfig.img' + + shutil.rmtree(mnt_point, ignore_errors=True) + os.mkdir(mnt_point, mode = 0o755) + + with open(mnt_point + '/initrd-1.img', 'w', encoding = 'ascii') as file: + file.write("initrd 1") + + with open(mnt_point + '/initrd-2.img', 'w', encoding = 'ascii') as file: + file.write("initrd 2") + + shutil.copyfile(u_boot_config.build_dir + '/lib/efi_loader/initrddump.efi', + mnt_point + '/initrddump.efi') + + check_call(f'virt-make-fs --partition=gpt --size=+1M --type=vfat {mnt_point} {image_path}', + shell=True) + + return image_path diff --git a/test/py/tests/test_eficonfig/test_eficonfig.py b/test/py/tests/test_eficonfig/test_eficonfig.py new file mode 100644 index 0000000000..99606d9c4b --- /dev/null +++ b/test/py/tests/test_eficonfig/test_eficonfig.py @@ -0,0 +1,354 @@ +# SPDX-License-Identifier: GPL-2.0+ +""" Unit test for UEFI menu-driven configuration +""" + +import pytest +import time + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('cmd_eficonfig') +@pytest.mark.buildconfigspec('cmd_bootefi_bootmgr') +def test_efi_eficonfig(u_boot_console, efi_eficonfig_data): + + def send_user_input_and_wait(user_str, expect_str): + time.sleep(0.1) # TODO: does not work correctly without sleep + u_boot_console.run_command(cmd=user_str, wait_for_prompt=False, + wait_for_echo=True, send_nl=False) + u_boot_console.run_command(cmd='\x0d', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + if expect_str is not None: + for i in expect_str: + u_boot_console.p.expect([i]) + + def press_up_down_enter_and_wait(up_count, down_count, enter, expect_str): + # press UP key + for i in range(up_count): + u_boot_console.run_command(cmd='\x1b\x5b\x41', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + # press DOWN key + for i in range(down_count): + u_boot_console.run_command(cmd='\x1b\x5b\x42', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + # press ENTER if requested + if enter: + u_boot_console.run_command(cmd='\x0d', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + # wait expected output + if expect_str is not None: + for i in expect_str: + u_boot_console.p.expect([i]) + + def press_escape_key(wait_prompt): + u_boot_console.run_command(cmd='\x1b', wait_for_prompt=wait_prompt, wait_for_echo=False, send_nl=False) + + def press_enter_key(wait_prompt): + u_boot_console.run_command(cmd='\x0d', wait_for_prompt=wait_prompt, + wait_for_echo=False, send_nl=False) + + def check_current_is_maintenance_menu(): + for i in ('UEFI Maintenance Menu', 'Add Boot Option', 'Edit Boot Option', + 'Change Boot Order', 'Delete Boot Option', 'Quit'): + u_boot_console.p.expect([i]) + + """ Unit test for "eficonfig" command + The menu-driven interface is used to set up UEFI load options. + The bootefi bootmgr loads initrddump.efi as a payload. + The crc32 of the loaded initrd.img is checked + + Args: + u_boot_console -- U-Boot console + efi__data -- Path to the disk image used for testing. + Test disk image has following files. + initrd-1.img + initrd-2.img + initrddump.efi + + """ + + # Restart the system to clean the previous state + u_boot_console.restart_uboot() + + with u_boot_console.temporary_timeout(500): + # + # Test Case 1: Check the menu is displayed + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + for i in ('UEFI Maintenance Menu', 'Add Boot Option', 'Edit Boot Option', + 'Change Boot Order', 'Delete Boot Option', 'Quit'): + u_boot_console.p.expect([i]) + # Select "Add Boot Option" + press_enter_key(False) + for i in ('Add Boot Option', 'Description:', 'File', 'Initrd File', 'Optional Data', + 'Save', 'Quit'): + u_boot_console.p.expect([i]) + press_escape_key(False) + check_current_is_maintenance_menu() + # return to U-Boot console + press_escape_key(True) + + # + # Test Case 2: check auto generated media device entry + # + + # bind the test disk image for succeeding tests + u_boot_console.run_command(cmd = f'host bind 0 {efi_eficonfig_data}') + + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + + # Change the Boot Order + press_up_down_enter_and_wait(0, 2, True, 'Quit') + for i in ('host 0:1', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + # disable auto generated boot option for succeeding test + u_boot_console.run_command(cmd=' ', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + # Save the BootOrder + press_up_down_enter_and_wait(0, 1, True, None) + check_current_is_maintenance_menu() + + # + # Test Case 3: Add first Boot Option and load it + # + + # Select 'Add Boot Option' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + + # Press the enter key to select 'Description:' entry, then enter Description + press_up_down_enter_and_wait(0, 0, True, 'enter description:') + # Send Description user input, press ENTER key to complete + send_user_input_and_wait('test 1', 'Quit') + + # Set EFI image(initrddump.efi) + press_up_down_enter_and_wait(0, 1, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'host 0:1') + # Select 'host 0:1' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + # Press down key to select "initrddump.efi" entry followed by the enter key + press_up_down_enter_and_wait(0, 2, True, 'Quit') + + # Set Initrd file(initrd-1.img) + press_up_down_enter_and_wait(0, 2, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'host 0:1') + # Select 'host 0:1' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + # Press down key to select "initrd-1.img" entry followed by the enter key + press_up_down_enter_and_wait(0, 0, True, 'Quit') + + # Set optional_data + press_up_down_enter_and_wait(0, 3, True, 'Optional Data:') + # Send Description user input, press ENTER key to complete + send_user_input_and_wait('nocolor', None) + for i in ('Description: test 1', 'File: host 0:1/initrddump.efi', + 'Initrd File: host 0:1/initrd-1.img', 'Optional Data: nocolor', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + + # Save the Boot Option + press_up_down_enter_and_wait(0, 4, True, None) + check_current_is_maintenance_menu() + + # Check the newly added Boot Option is handled correctly + # Return to U-Boot console + press_escape_key(True) + u_boot_console.run_command(cmd = 'bootefi bootmgr') + response = u_boot_console.run_command(cmd = 'load', wait_for_echo=False) + assert 'crc32: 0x181464af' in response + u_boot_console.run_command(cmd = 'exit', wait_for_echo=False) + + # + # Test Case 4: Add second Boot Option and load it + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + + # Select 'Add Boot Option' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + + # Press the enter key to select 'Description:' entry, then enter Description + press_up_down_enter_and_wait(0, 0, True, 'enter description:') + # Send Description user input, press ENTER key to complete + send_user_input_and_wait('test 2', 'Quit') + + # Set EFI image(initrddump.efi) + press_up_down_enter_and_wait(0, 1, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'host 0:1') + # Select 'host 0:1' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + # Press down key to select "initrddump.efi" entry followed by the enter key + press_up_down_enter_and_wait(0, 2, True, 'Quit') + + # Set Initrd file(initrd-2.img) + press_up_down_enter_and_wait(0, 2, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'host 0:1') + # Select 'host 0:1' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + # Press down key to select "initrd-2.img" entry followed by the enter key + press_up_down_enter_and_wait(0, 1, True, 'Quit') + + # Set optional_data + press_up_down_enter_and_wait(0, 3, True, 'Optional Data:') + # Send Description user input, press ENTER key to complete + send_user_input_and_wait('nocolor', None) + for i in ('Description: test 2', 'File: host 0:1/initrddump.efi', + 'Initrd File: host 0:1/initrd-2.img', 'Optional Data: nocolor', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + + # Save the Boot Option + press_up_down_enter_and_wait(0, 4, True, 'Quit') + + # Change the Boot Order + press_up_down_enter_and_wait(0, 2, True, 'Quit') + press_up_down_enter_and_wait(0, 1, False, 'Quit') + # move 'test 1' to the second entry + u_boot_console.run_command(cmd='+', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + for i in ('test 2', 'test 1', 'host 0:1', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + # Save the BootOrder + press_up_down_enter_and_wait(0, 3, True, None) + check_current_is_maintenance_menu() + + # Check the newly added Boot Option is handled correctly + # Return to U-Boot console + press_escape_key(True) + u_boot_console.run_command(cmd = 'bootefi bootmgr') + response = u_boot_console.run_command(cmd = 'load', wait_for_echo=False) + assert 'crc32: 0x811d3515' in response + u_boot_console.run_command(cmd = 'exit', wait_for_echo=False) + + # + # Test Case 5: Change BootOrder and load it + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + + # Change the Boot Order + press_up_down_enter_and_wait(0, 2, True, None) + # Check the curren BootOrder + for i in ('test 2', 'test 1', 'host 0:1', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + # move 'test 2' to the second entry + u_boot_console.run_command(cmd='-', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + for i in ('test 1', 'test 2', 'host 0:1', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + # Save the BootOrder + press_up_down_enter_and_wait(0, 2, True, None) + check_current_is_maintenance_menu() + + # Return to U-Boot console + press_escape_key(True) + u_boot_console.run_command(cmd = 'bootefi bootmgr') + response = u_boot_console.run_command(cmd = 'load', wait_for_echo=False) + assert 'crc32: 0x181464af' in response + u_boot_console.run_command(cmd = 'exit', wait_for_echo=False) + + # + # Test Case 6: Delete Boot Option(label:test 2) + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + + # Select 'Delete Boot Option' + press_up_down_enter_and_wait(0, 3, True, None) + # Check the current BootOrder + for i in ('test 1', 'test 2', 'Quit'): + u_boot_console.p.expect([i]) + + # Delete 'test 2' + press_up_down_enter_and_wait(0, 1, True, None) + for i in ('test 1', 'Quit'): + u_boot_console.p.expect([i]) + press_escape_key(False) + check_current_is_maintenance_menu() + # Return to U-Boot console + press_escape_key(True) + + # + # Test Case 7: Edit Boot Option + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + # Select 'Edit Boot Option' + press_up_down_enter_and_wait(0, 1, True, None) + # Check the curren BootOrder + for i in ('test 1', 'Quit'): + u_boot_console.p.expect([i]) + press_up_down_enter_and_wait(0, 0, True, None) + for i in ('Description: test 1', 'File: host 0:1/initrddump.efi', + 'Initrd File: host 0:1/initrd-1.img', 'Optional Data: nocolor', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + + # Press the enter key to select 'Description:' entry, then enter Description + press_up_down_enter_and_wait(0, 0, True, 'enter description:') + # Send Description user input, press ENTER key to complete + send_user_input_and_wait('test 3', 'Quit') + + # Set EFI image(initrddump.efi) + press_up_down_enter_and_wait(0, 1, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'host 0:1') + # Select 'host 0:1' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + # Press down key to select "initrddump.efi" entry followed by the enter key + press_up_down_enter_and_wait(0, 2, True, 'Quit') + + # Set Initrd file(initrd-2.img) + press_up_down_enter_and_wait(0, 2, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'host 0:1') + # Select 'host 0:1' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + # Press down key to select "initrd-1.img" entry followed by the enter key + press_up_down_enter_and_wait(0, 1, True, 'Quit') + + # Set optional_data + press_up_down_enter_and_wait(0, 3, True, 'Optional Data:') + # Send Description user input, press ENTER key to complete + send_user_input_and_wait('', None) + for i in ('Description: test 3', 'File: host 0:1/initrddump.efi', + 'Initrd File: host 0:1/initrd-2.img', 'Optional Data:', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + + # Save the Boot Option + press_up_down_enter_and_wait(0, 4, True, 'Quit') + press_escape_key(False) + check_current_is_maintenance_menu() + + # Check the updated Boot Option is handled correctly + # Return to U-Boot console + press_escape_key(True) + u_boot_console.run_command(cmd = 'bootefi bootmgr') + response = u_boot_console.run_command(cmd = 'load', wait_for_echo=False) + assert 'crc32: 0x811d3515' in response + u_boot_console.run_command(cmd = 'exit', wait_for_echo=False) + + # + # Test Case 8: Delete Boot Option(label:test 3) + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + + # Select 'Delete Boot Option' + press_up_down_enter_and_wait(0, 3, True, None) + # Check the curren BootOrder + for i in ('test 3', 'Quit'): + u_boot_console.p.expect([i]) + + # Delete 'test 3' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + press_escape_key(False) + check_current_is_maintenance_menu() + # Return to U-Boot console + press_escape_key(True) + + # remove the host device + u_boot_console.run_command(cmd = f'host bind -r 0') + + # + # Test Case 9: No block device found + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + + # Select 'Add Boot Option' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + + # Set EFI image + press_up_down_enter_and_wait(0, 1, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'No block device found!') + press_escape_key(False) + check_current_is_maintenance_menu() + # Return to U-Boot console + press_escape_key(True) diff --git a/test/py/tests/test_fit_ecdsa.py b/test/py/tests/test_fit_ecdsa.py index 87b6081222..cc6c0c4dc4 100644 --- a/test/py/tests/test_fit_ecdsa.py +++ b/test/py/tests/test_fit_ecdsa.py @@ -10,6 +10,7 @@ signature is then extracted, and verified against pyCryptodome. This test doesn't run the sandbox. It only checks the host tool 'mkimage' """ +import os import pytest import u_boot_utils as util from Cryptodome.Hash import SHA256 @@ -84,7 +85,8 @@ def test_fit_ecdsa(u_boot_console): cons = u_boot_console mkimage = cons.config.build_dir + '/tools/mkimage' datadir = cons.config.source_dir + '/test/py/tests/vboot/' - tempdir = cons.config.result_dir + tempdir = os.path.join(cons.config.result_dir, 'ecdsa') + os.makedirs(tempdir, exist_ok=True) key_file = f'{tempdir}/ecdsa-test-key.pem' fit_file = f'{tempdir}/test.fit' dtc('sandbox-kernel.dts') diff --git a/test/py/tests/test_fit_hashes.py b/test/py/tests/test_fit_hashes.py index e228ea96d3..4891e77ca2 100644 --- a/test/py/tests/test_fit_hashes.py +++ b/test/py/tests/test_fit_hashes.py @@ -10,6 +10,7 @@ output of a fixed data block with known good hashes. This test doesn't run the sandbox. It only checks the host tool 'mkimage' """ +import os import pytest import u_boot_utils as util @@ -93,7 +94,9 @@ def test_mkimage_hashes(u_boot_console): cons = u_boot_console mkimage = cons.config.build_dir + '/tools/mkimage' datadir = cons.config.source_dir + '/test/py/tests/vboot/' - tempdir = cons.config.result_dir + tempdir = os.path.join(cons.config.result_dir, 'hashes') + os.makedirs(tempdir, exist_ok=True) + fit_file = f'{tempdir}/test.fit' dtc('sandbox-kernel.dts') diff --git a/test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py b/test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py index 9eb00d6888..527a556ed8 100644 --- a/test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py +++ b/test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py @@ -105,6 +105,7 @@ def sqfs_run_all_ls_tests(u_boot_console): @pytest.mark.buildconfigspec('cmd_squashfs') @pytest.mark.buildconfigspec('fs_squashfs') @pytest.mark.requiredtool('mksquashfs') +@pytest.mark.singlethread def test_sqfs_ls(u_boot_console): """ Executes the sqfsls test suite. diff --git a/test/py/tests/test_gpio.py b/test/py/tests/test_gpio.py index fa0af5f82b..0af186f236 100644 --- a/test/py/tests/test_gpio.py +++ b/test/py/tests/test_gpio.py @@ -51,6 +51,7 @@ def test_gpio_exit_statuses(u_boot_console): def test_gpio_read(u_boot_console): """Test that gpio read correctly sets the variable to the value of a gpio pin.""" + u_boot_console.run_command('gpio clear 0') response = u_boot_console.run_command('gpio read var 0; echo val:$var,rc:$?') expected_response = 'val:0,rc:0' assert(expected_response in response) diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py index f707d9f253..cb44e1d789 100644 --- a/test/py/tests/test_gpt.py +++ b/test/py/tests/test_gpt.py @@ -13,6 +13,9 @@ These tests rely on a 4 MB disk image, which is automatically created by the test. """ +# Mark all tests here as slow +pytestmark = pytest.mark.slow + class GptTestDiskImage(object): """Disk Image used by the GPT tests.""" diff --git a/test/py/tests/test_pinmux.py b/test/py/tests/test_pinmux.py index b3ae2ab024..794994e12d 100644 --- a/test/py/tests/test_pinmux.py +++ b/test/py/tests/test_pinmux.py @@ -68,6 +68,7 @@ def test_pinmux_dev(u_boot_console): def test_pinmux_status(u_boot_console): """Test that 'pinmux status' displays selected pincontroller's pin muxing descriptions.""" + u_boot_console.run_command('pinmux dev pinctrl') output = u_boot_console.run_command('pinmux status') assert (not 'pinctrl-gpio:' in output) diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index 35fb393c1f..9d42390373 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -114,6 +114,15 @@ def test_ut_dm_init(u_boot_console): with open(fn, 'wb') as fh: fh.write(data) + # Create a file with a single partition + fn = u_boot_console.config.source_dir + '/scsi.img' + if not os.path.exists(fn): + data = b'\x00' * (2 * 1024 * 1024) + with open(fn, 'wb') as fh: + fh.write(data) + u_boot_utils.run_and_log( + u_boot_console, f'sfdisk {fn}', stdin=b'type=83') + @pytest.mark.buildconfigspec('cmd_bootflow') def test_ut_dm_init_bootstd(u_boot_console): """Initialise data for bootflow tests""" diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py index 040147d88b..e3e7ca4b21 100644 --- a/test/py/tests/test_vboot.py +++ b/test/py/tests/test_vboot.py @@ -42,7 +42,7 @@ import vboot_evil # Only run the full suite on a few combinations, since it doesn't add any more # test coverage. -TESTDATA = [ +TESTDATA_IN = [ ['sha1-basic', 'sha1', '', None, False, True, False, False], ['sha1-pad', 'sha1', '', '-E -p 0x10000', False, False, False, False], ['sha1-pss', 'sha1', '-pss', None, False, False, False, False], @@ -60,6 +60,10 @@ TESTDATA = [ ['sha256-global-sign-pss', 'sha256', '-pss', '', False, False, False, True], ] +# Mark all but the first test as slow, so they are not run with '-k not slow' +TESTDATA = [TESTDATA_IN[0]] +TESTDATA += [pytest.param(*v, marks=pytest.mark.slow) for v in TESTDATA_IN[1:]] + @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('fit_signature') @pytest.mark.requiredtool('dtc') diff --git a/test/run b/test/run index 869406cd8d..810b47e08d 100755 --- a/test/run +++ b/test/run @@ -13,25 +13,47 @@ run_test() { [ $? -ne 0 ] && failures=$((failures+1)) } -# SKip slow tests if requested -[ "$1" == "quick" ] && mark_expr="not slow" -[ "$1" == "quick" ] && skip=--skip-net-tests +# Select test attributes +ut_mark_expr=test_ut +if [ "$1" = "quick" ]; then + mark_expr="not slow" + ut_mark_expr="test_ut and not slow" + skip=--skip-net-tests +fi + [ "$1" == "tools" ] && tools_only=y +if [ "$1" = "parallel" ]; then + if ! echo 'import xdist' | python3 2>/dev/null; then + echo "Please install python3-pytest-xdist - see doc/develop/py_testing.rst" + exit 1 + fi + jobs="$(($(nproc) > 16 ? 16 : $(nproc)))" + para="-n${jobs} -q" + prompt="Building and..." + skip=--skip-net-tests + mark_expr="not slow and not bootstd and not spi_flash" + ut_mark_expr="test_ut and not slow and not bootstd and not spi_flash" + echo "Note: test log is garbled with parallel tests" +fi + failures=0 if [ -z "$tools_only" ]; then # Run all tests that the standard sandbox build can support - run_test "sandbox" ./test/py/test.py --bd sandbox --build \ - -m "${mark_expr}" + echo "${prompt}" + run_test "sandbox" ./test/py/test.py --bd sandbox --build ${para} \ + -k "${mark_expr}" fi # Run tests which require sandbox_spl -run_test "sandbox_spl" ./test/py/test.py --bd sandbox_spl --build \ +echo "${prompt}" +run_test "sandbox_spl" ./test/py/test.py --bd sandbox_spl --build ${para} \ -k 'test_ofplatdata or test_handoff or test_spl' # Run the sane tests with sandbox_noinst (i.e. without OF_PLATDATA_INST) -run_test "sandbox_spl" ./test/py/test.py --bd sandbox_noinst --build \ +echo "${prompt}" +run_test "sandbox_spl" ./test/py/test.py --bd sandbox_noinst --build ${para} \ -k 'test_ofplatdata or test_handoff or test_spl' if [ -z "$tools_only" ]; then @@ -39,8 +61,9 @@ if [ -z "$tools_only" ]; then # build which does not enable CONFIG_OF_LIVE for the live device tree, so we can # check that functionality is the same. The standard sandbox build (above) uses # CONFIG_OF_LIVE. + echo "${prompt}" run_test "sandbox_flattree" ./test/py/test.py --bd sandbox_flattree \ - --build -k test_ut + ${para} --build -k "${ut_mark_expr}" fi # Set up a path to dtc (device-tree compiler) and libfdt.py, a library it @@ -61,10 +84,14 @@ run_test "dtoc" ./tools/dtoc/dtoc -t # This needs you to set up Python test coverage tools. # To enable Python test coverage on Debian-type distributions (e.g. Ubuntu): # $ sudo apt-get install python-pytest python-coverage -export PATH=$PATH:${TOOLS_DIR} -run_test "binman code coverage" ./tools/binman/binman test -T -run_test "dtoc code coverage" ./tools/dtoc/dtoc -T -run_test "fdt code coverage" ./tools/dtoc/test_fdt -T + +# Code-coverage tests cannot run in parallel, so skip them in that case +if [ -z "${para}" ]; then + export PATH=$PATH:${TOOLS_DIR} + run_test "binman code coverage" ./tools/binman/binman test -T + run_test "dtoc code coverage" ./tools/dtoc/dtoc -T + run_test "fdt code coverage" ./tools/dtoc/test_fdt -T +fi if [ $failures == 0 ]; then echo "Tests passed!" diff --git a/test/test-main.c b/test/test-main.c index 31837e57a8..d74df297c4 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -6,16 +6,56 @@ #include #include +#include #include #include +#include +#include +#include #include #include #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; +/** + * enum fdtchk_t - what to do with the device tree (gd->fdt_blob) + * + * This affects what happens with the device tree before and after a test + * + * @FDTCHK_NONE: Do nothing + * @FDTCHK_CHECKSUM: Take a checksum of the FDT before the test runs and + * compare it afterwards to detect any changes + * @FDTCHK_COPY: Make a copy of the FDT and restore it afterwards + */ +enum fdtchk_t { + FDTCHK_NONE, + FDTCHK_CHECKSUM, + FDTCHK_COPY, +}; + +/** + * fdt_action() - get the required action for the FDT + * + * @return the action that should be taken for this build + */ +static enum fdtchk_t fdt_action(void) +{ + /* Do a copy for sandbox (but only the U-Boot build, not SPL) */ + if (CONFIG_IS_ENABLED(SANDBOX)) + return FDTCHK_COPY; + + /* For sandbox SPL builds, do nothing */ + if (IS_ENABLED(CONFIG_SANDBOX)) + return FDTCHK_NONE; + + /* For all other boards, do a checksum */ + return FDTCHK_CHECKSUM; +} + /* This is valid when a test is running, NULL otherwise */ static struct unit_test_state *cur_test_state; @@ -41,17 +81,26 @@ static int dm_test_pre_run(struct unit_test_state *uts) { bool of_live = uts->of_live; + if (of_live && (gd->flags & GD_FLG_FDT_CHANGED)) { + printf("Cannot run live tree test as device tree changed\n"); + return -EFAULT; + } uts->root = NULL; uts->testdev = NULL; uts->force_fail_alloc = false; uts->skip_post_probe = false; + if (fdt_action() == FDTCHK_CHECKSUM) + uts->fdt_chksum = crc8(0, gd->fdt_blob, + fdt_totalsize(gd->fdt_blob)); gd->dm_root = NULL; + malloc_disable_testing(); if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA)) memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); arch_reset_for_test(); /* Determine whether to make the live tree available */ gd_set_of_root(of_live ? uts->of_root : NULL); + oftree_reset(); ut_assertok(dm_init(of_live)); uts->root = dm_root(); @@ -62,6 +111,33 @@ static int dm_test_post_run(struct unit_test_state *uts) { int id; + if (gd->fdt_blob) { + switch (fdt_action()) { + case FDTCHK_COPY: + memcpy((void *)gd->fdt_blob, uts->fdt_copy, uts->fdt_size); + break; + case FDTCHK_CHECKSUM: { + uint chksum; + + chksum = crc8(0, gd->fdt_blob, fdt_totalsize(gd->fdt_blob)); + if (chksum != uts->fdt_chksum) { + /* + * We cannot run any more tests that need the + * live tree, since its strings point into the + * flat tree, which has changed. This likely + * means that at least some of the pointers from + * the live tree point to different things + */ + printf("Device tree changed: cannot run live tree tests\n"); + gd->flags |= GD_FLG_FDT_CHANGED; + } + break; + } + case FDTCHK_NONE: + break; + } + } + /* * With of-platdata-inst the uclasses are created at build time. If we * destroy them we cannot get them back since uclass_add() is not @@ -220,6 +296,7 @@ static int dm_test_restore(struct device_node *of_root) static int test_pre_run(struct unit_test_state *uts, struct unit_test *test) { ut_assertok(event_init()); + ut_assertok(cyclic_init()); if (test->flags & UT_TESTF_DM) ut_assertok(dm_test_pre_run(uts)); @@ -240,6 +317,20 @@ static int test_pre_run(struct unit_test_state *uts, struct unit_test *test) (test->flags & UT_TESTF_SCAN_FDT)) ut_assertok(dm_extended_scan(false)); + if (IS_ENABLED(CONFIG_SANDBOX) && (test->flags & UT_TESTF_OTHER_FDT)) { + /* make sure the other FDT is available */ + ut_assertok(test_load_other_fdt(uts)); + + /* + * create a new live tree with it for every test, in case a + * test modifies the tree + */ + if (of_live_active()) { + ut_assertok(unflatten_device_tree(uts->other_fdt, + &uts->of_other)); + } + } + if (test->flags & UT_TESTF_CONSOLE_REC) { int ret = console_record_reset_enable(); @@ -265,8 +356,12 @@ static int test_post_run(struct unit_test_state *uts, struct unit_test *test) ut_unsilence_console(uts); if (test->flags & UT_TESTF_DM) ut_assertok(dm_test_post_run(uts)); + ut_assertok(cyclic_uninit()); ut_assertok(event_uninit()); + free(uts->of_other); + uts->of_other = NULL; + return 0; } @@ -337,11 +432,13 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, { int runs; + if ((test->flags & UT_TESTF_OTHER_FDT) && !IS_ENABLED(CONFIG_SANDBOX)) + return -EAGAIN; + /* Run with the live tree if possible */ runs = 0; if (CONFIG_IS_ENABLED(OF_LIVE)) { - if (!(test->flags & - (UT_TESTF_FLAT_TREE | UT_TESTF_LIVE_OR_FLAT))) { + if (!(test->flags & UT_TESTF_FLAT_TREE)) { uts->of_live = true; ut_assertok(ut_run_test(uts, test, test->name)); runs++; @@ -349,11 +446,22 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, } /* - * Run with the flat tree if we couldn't run it with live tree, - * or it is a core test. + * Run with the flat tree if: + * - it is not marked for live tree only + * - it doesn't require the 'other' FDT when OFNODE_MULTI_TREE_MAX is + * not enabled (since flat tree can only support a single FDT in that + * case + * - we couldn't run it with live tree, + * - it is a core test (dm tests except video) + * - the FDT is still valid and has not been updated by an earlier test + * (for sandbox we handle this by copying the tree, but not for other + * boards) */ if (!(test->flags & UT_TESTF_LIVE_TREE) && - (!runs || ut_test_run_on_flattree(test))) { + (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) || + !(test->flags & UT_TESTF_OTHER_FDT)) && + (!runs || ut_test_run_on_flattree(test)) && + !(gd->flags & GD_FLG_FDT_CHANGED)) { uts->of_live = false; ut_assertok(ut_run_test(uts, test, test->name)); runs++; @@ -390,11 +498,17 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, for (test = tests; test < tests + count; test++) { const char *test_name = test->name; - int ret; + int ret, i, old_fail_count; if (!test_matches(prefix, test_name, select_name)) continue; - ret = ut_run_test_live_flat(uts, test, select_name); + old_fail_count = uts->fail_count; + for (i = 0; i < uts->runs_per_test; i++) + ret = ut_run_test_live_flat(uts, test, select_name); + if (uts->fail_count != old_fail_count) { + printf("Test %s failed %d times\n", select_name, + uts->fail_count - old_fail_count); + } found++; if (ret == -EAGAIN) continue; @@ -408,7 +522,8 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, } int ut_run_list(const char *category, const char *prefix, - struct unit_test *tests, int count, const char *select_name) + struct unit_test *tests, int count, const char *select_name, + int runs_per_test) { struct unit_test_state uts = { .fail_count = 0 }; bool has_dm_tests = false; @@ -432,8 +547,26 @@ int ut_run_list(const char *category, const char *prefix, printf("Running %d %s tests\n", count, category); uts.of_root = gd_of_root(); + uts.runs_per_test = runs_per_test; + if (fdt_action() == FDTCHK_COPY && gd->fdt_blob) { + uts.fdt_size = fdt_totalsize(gd->fdt_blob); + uts.fdt_copy = os_malloc(uts.fdt_size); + if (!uts.fdt_copy) { + printf("Out of memory for device tree copy\n"); + return -ENOMEM; + } + memcpy(uts.fdt_copy, gd->fdt_blob, uts.fdt_size); + } ret = ut_run_tests(&uts, prefix, tests, count, select_name); + /* Best efforts only...ignore errors */ + if (has_dm_tests) + dm_test_restore(uts.of_root); + if (IS_ENABLED(CONFIG_SANDBOX)) { + os_free(uts.fdt_copy); + os_free(uts.other_fdt); + } + if (ret == -ENOENT) printf("Test '%s' not found\n", select_name); else diff --git a/tools/Makefile b/tools/Makefile index 3626919633..34a1aa7a8b 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -147,6 +147,7 @@ dumpimage-mkimage-objs := aisimage.o \ gpimage.o \ gpimage-common.o \ mtk_image.o \ + mtk_nand_headers.o \ $(ECDSA_OBJS-y) \ $(RSA_OBJS-y) \ $(AES_OBJS-y) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index ecb3595603..261107b335 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -5782,7 +5782,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap # Check that the data appears in the file somewhere self.assertIn(U_BOOT_SPL_DATA, data) - # Get struct image_header -> ih_name + # Get struct legacy_img_hdr -> ih_name name = data[0x20:0x40] # Build the filename that we expect to be placed in there, by virtue of @@ -5799,7 +5799,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap # Check that the data appears in the file somewhere self.assertIn(U_BOOT_SPL_DATA, data) - # Get struct image_header -> ih_name + # Get struct legacy_img_hdr -> ih_name name = data[0x20:0x40] # Build the filename that we expect to be placed in there, by virtue of diff --git a/tools/default_image.c b/tools/default_image.c index e164c0c27d..4a067e6586 100644 --- a/tools/default_image.c +++ b/tools/default_image.c @@ -22,7 +22,7 @@ #include #include -static image_header_t header; +static struct legacy_img_hdr header; static int image_check_image_types(uint8_t type) { @@ -46,15 +46,15 @@ static int image_verify_header(unsigned char *ptr, int image_size, uint32_t len; const unsigned char *data; uint32_t checksum; - image_header_t header; - image_header_t *hdr = &header; + struct legacy_img_hdr header; + struct legacy_img_hdr *hdr = &header; /* * create copy of header so that we can blank out the * checksum field for checking - this can't be done * on the PROT_READ mapped data. */ - memcpy(hdr, ptr, sizeof(image_header_t)); + memcpy(hdr, ptr, sizeof(struct legacy_img_hdr)); if (be32_to_cpu(hdr->ih_magic) != IH_MAGIC) { debug("%s: Bad Magic Number: \"%s\" is no valid image\n", @@ -63,7 +63,7 @@ static int image_verify_header(unsigned char *ptr, int image_size, } data = (const unsigned char *)hdr; - len = sizeof(image_header_t); + len = sizeof(struct legacy_img_hdr); checksum = be32_to_cpu(hdr->ih_hcrc); hdr->ih_hcrc = cpu_to_be32(0); /* clear for re-calculation */ @@ -74,8 +74,8 @@ static int image_verify_header(unsigned char *ptr, int image_size, return -FDT_ERR_BADSTATE; } - data = (const unsigned char *)ptr + sizeof(image_header_t); - len = image_size - sizeof(image_header_t) ; + data = (const unsigned char *)ptr + sizeof(struct legacy_img_hdr); + len = image_size - sizeof(struct legacy_img_hdr); checksum = be32_to_cpu(hdr->ih_dcrc); if (crc32(0, data, len) != checksum) { @@ -94,13 +94,12 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd, uint32_t imagesize; uint32_t ep; uint32_t addr; - - image_header_t * hdr = (image_header_t *)ptr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; checksum = crc32(0, (const unsigned char *)(ptr + - sizeof(image_header_t)), - sbuf->st_size - sizeof(image_header_t)); + sizeof(struct legacy_img_hdr)), + sbuf->st_size - sizeof(struct legacy_img_hdr)); time = imagetool_get_source_date(params->cmdname, sbuf->st_mtime); ep = params->ep; @@ -108,11 +107,11 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd, if (params->type == IH_TYPE_FIRMWARE_IVT) /* Add size of CSF minus IVT */ - imagesize = sbuf->st_size - sizeof(image_header_t) + imagesize = sbuf->st_size - sizeof(struct legacy_img_hdr) + 0x2060 - sizeof(flash_header_v2_t); else - imagesize = sbuf->st_size - sizeof(image_header_t); + imagesize = sbuf->st_size - sizeof(struct legacy_img_hdr); if (params->os == IH_OS_TEE) { addr = optee_image_get_load_addr(hdr); @@ -134,14 +133,14 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd, image_set_name(hdr, params->imagename); checksum = crc32(0, (const unsigned char *)hdr, - sizeof(image_header_t)); + sizeof(struct legacy_img_hdr)); image_set_hcrc(hdr, checksum); } static int image_extract_subimage(void *ptr, struct image_tool_params *params) { - const image_header_t *hdr = (const image_header_t *)ptr; + const struct legacy_img_hdr *hdr = (const struct legacy_img_hdr *)ptr; ulong file_data; ulong file_len; @@ -175,7 +174,7 @@ static int image_extract_subimage(void *ptr, struct image_tool_params *params) U_BOOT_IMAGE_TYPE( defimage, "Default Image support", - sizeof(image_header_t), + sizeof(struct legacy_img_hdr), (void *)&header, image_check_params, image_verify_header, diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index 8a990b8bd7..a3e36ea363 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -851,4 +851,3 @@ def main(): if __name__ == '__main__': sys.exit(main()) -sys.exit(1) diff --git a/tools/fit_image.c b/tools/fit_image.c index 979f2411ee..923a9755b7 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -22,7 +22,7 @@ #include #include -static image_header_t header; +static struct legacy_img_hdr header; static int fit_add_file_data(struct image_tool_params *params, size_t size_inc, const char *tmpfile) @@ -915,7 +915,7 @@ static int fit_check_params(struct image_tool_params *params) U_BOOT_IMAGE_TYPE( fitimage, "FIT Image support", - sizeof(image_header_t), + sizeof(struct legacy_img_hdr), (void *)&header, fit_check_params, fit_verify_header, diff --git a/tools/imx8mimage.c b/tools/imx8mimage.c index a4699decf9..35d0a92bfd 100644 --- a/tools/imx8mimage.c +++ b/tools/imx8mimage.c @@ -318,7 +318,7 @@ err_mmap: static int generate_ivt_for_fit(int fd, int fit_offset, uint32_t ep, uint32_t *fit_load_addr) { - image_header_t image_header; + struct legacy_img_hdr image_header; int ret; uint32_t fit_size, load_addr; @@ -330,8 +330,8 @@ static int generate_ivt_for_fit(int fd, int fit_offset, uint32_t ep, exit(EXIT_FAILURE); } - if (read(fd, (char *)&image_header, sizeof(image_header_t)) != - sizeof(image_header_t)) { + if (read(fd, (char *)&image_header, sizeof(struct legacy_img_hdr)) != + sizeof(struct legacy_img_hdr)) { fprintf(stderr, "generate_ivt_for_fit read failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); @@ -600,7 +600,7 @@ void build_image(int ofd) close(sld_fd); file_off = sld_header_off; - file_off += sbuf.st_size + sizeof(image_header_t); + file_off += sbuf.st_size + sizeof(struct legacy_img_hdr); } } diff --git a/tools/mkimage.c b/tools/mkimage.c index 597cb3a5ce..30c6df7708 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -845,7 +845,7 @@ copy_file (int ifd, const char *datafile, int pad) if (params.xflag) { unsigned char *p = NULL; /* - * XIP: do not append the image_header_t at the + * XIP: do not append the struct legacy_img_hdr at the * beginning of the file, but consume the space * reserved for it. */ diff --git a/tools/mtk_image.c b/tools/mtk_image.c index de5ce4d964..5ef9334163 100644 --- a/tools/mtk_image.c +++ b/tools/mtk_image.c @@ -12,216 +12,7 @@ #include #include "imagetool.h" #include "mtk_image.h" - -/* NAND header for SPI-NAND with 2KB page + 64B spare */ -static const union nand_boot_header snand_hdr_2k_64_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00, - 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D, - 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7, - 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8, - 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00 - } -}; - -/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */ -static const union nand_boot_header snand_hdr_2k_128_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, - 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13, - 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3, - 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7, - 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00 - } -}; - -/* NAND header for SPI-NAND with 4KB page + 256B spare */ -static const union nand_boot_header snand_hdr_4k_256_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00, - 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3, - 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57, - 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F, - 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00 - } -}; - -/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */ -static const union nand_boot_header nand_hdr_1gb_2k_64_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, - 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12, - 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C, - 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82, - 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00 - } -}; - -/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */ -static const union nand_boot_header nand_hdr_2gb_2k_64_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, - 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D, - 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1, - 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95, - 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00 - } -}; - -/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */ -static const union nand_boot_header nand_hdr_4gb_2k_64_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, - 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32, - 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B, - 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87, - 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00 - } -}; - -/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */ -static const union nand_boot_header nand_hdr_2gb_2k_128_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, - 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A, - 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC, - 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0, - 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00 - } -}; - -/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */ -static const union nand_boot_header nand_hdr_4gb_2k_128_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, - 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45, - 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46, - 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2, - 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00 - } -}; - -static const struct nand_header_type { - const char *name; - const union nand_boot_header *data; -} nand_headers[] = { - { - .name = "2k+64", - .data = &snand_hdr_2k_64_data - }, { - .name = "2k+120", - .data = &snand_hdr_2k_128_data - }, { - .name = "2k+128", - .data = &snand_hdr_2k_128_data - }, { - .name = "4k+256", - .data = &snand_hdr_4k_256_data - }, { - .name = "1g:2k+64", - .data = &nand_hdr_1gb_2k_64_data - }, { - .name = "2g:2k+64", - .data = &nand_hdr_2gb_2k_64_data - }, { - .name = "4g:2k+64", - .data = &nand_hdr_4gb_2k_64_data - }, { - .name = "2g:2k+128", - .data = &nand_hdr_2gb_2k_128_data - }, { - .name = "4g:2k+128", - .data = &nand_hdr_4gb_2k_128_data - } -}; +#include "mtk_nand_headers.h" static const struct brom_img_type { const char *name; @@ -242,6 +33,9 @@ static const struct brom_img_type { }, { .name = "snand", .type = BRLYT_TYPE_SNAND + }, { + .name = "spim-nand", + .type = BRLYT_TYPE_SNAND } }; @@ -263,7 +57,8 @@ static char lk_name[32] = "U-Boot"; static uint32_t crc32tbl[256]; /* NAND header selected by user */ -static const union nand_boot_header *hdr_nand; +static const struct nand_header_type *hdr_nand; +static uint32_t hdr_nand_size; /* GFH header + 2 * 4KB pages of NAND */ static char hdr_tmp[sizeof(struct gfh_header) + 0x2000]; @@ -402,12 +197,7 @@ static int mtk_brom_parse_imagename(const char *imagename) } /* parse nand header type */ - for (i = 0; i < ARRAY_SIZE(nand_headers); i++) { - if (!strcmp(nand_headers[i].name, nandinfo)) { - hdr_nand = nand_headers[i].data; - break; - } - } + hdr_nand = mtk_nand_header_find(nandinfo); /* parse device header offset */ if (hdr_offs && hdr_offs[0]) @@ -432,6 +222,9 @@ static int mtk_brom_parse_imagename(const char *imagename) return -EINVAL; } + if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) + hdr_nand_size = mtk_nand_header_size(hdr_nand); + return 0; } @@ -468,7 +261,7 @@ static int mtk_image_vrec_header(struct image_tool_params *params, } if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) - tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize); + tparams->header_size = hdr_nand_size; else tparams->header_size = sizeof(struct gen_device_header); @@ -480,6 +273,25 @@ static int mtk_image_vrec_header(struct image_tool_params *params, return SHA256_SUM_LEN; } +static int mtk_image_verify_gfh(struct gfh_header *gfh, uint32_t type, int print) +{ + if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME)) + return -1; + + if (le32_to_cpu(gfh->file_info.flash_type) != type) + return -1; + + if (print) + printf("Load Address: %08x\n", + le32_to_cpu(gfh->file_info.load_addr) + + le32_to_cpu(gfh->file_info.jump_offset)); + + if (print) + printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); + + return 0; +} + static int mtk_image_verify_gen_header(const uint8_t *ptr, int print) { union gen_boot_header *gbh = (union gen_boot_header *)ptr; @@ -542,89 +354,57 @@ static int mtk_image_verify_gen_header(const uint8_t *ptr, int print) gfh = (struct gfh_header *)(ptr + gfh_offset); - if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME)) - return -1; - - if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN) - return -1; - - if (print) - printf("Load Address: %08x\n", - le32_to_cpu(gfh->file_info.load_addr) + - le32_to_cpu(gfh->file_info.jump_offset)); - - if (print) - printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); - - return 0; + return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_GEN, print); } static int mtk_image_verify_nand_header(const uint8_t *ptr, int print) { - union nand_boot_header *nh = (union nand_boot_header *)ptr; struct brom_layout_header *bh; + struct nand_header_info info; struct gfh_header *gfh; const char *bootmedia; + int ret; - if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) || - strcmp(nh->id, NAND_BOOT_ID)) - return -1; + ret = mtk_nand_header_info(ptr, &info); + if (ret < 0) + return ret; - bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize)); + if (!ret) { + bh = (struct brom_layout_header *)(ptr + info.page_size); - if (strcmp(bh->name, BRLYT_NAME)) - return -1; + if (strcmp(bh->name, BRLYT_NAME)) + return -1; + + if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) + return -1; - if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) { - return -1; - } else { if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) bootmedia = "Parallel NAND"; else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND) - bootmedia = "Serial NAND"; + bootmedia = "Serial NAND (SNFI/AP)"; else return -1; + } else { + if (info.snfi) + bootmedia = "Serial NAND (SNFI/HSM)"; + else + bootmedia = "Serial NAND (SPIM)"; } if (print) { - printf("Boot Media: %s\n", bootmedia); + printf("Boot Media: %s\n", bootmedia); - if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) { - uint64_t capacity = - (uint64_t)le16_to_cpu(nh->numblocks) * - (uint64_t)le16_to_cpu(nh->pages_of_block) * - (uint64_t)le16_to_cpu(nh->pagesize) * 8; - printf("Capacity: %dGb\n", - (uint32_t)(capacity >> 30)); - } - - if (le16_to_cpu(nh->pagesize) >= 1024) - printf("Page Size: %dKB\n", - le16_to_cpu(nh->pagesize) >> 10); + if (info.page_size >= 1024) + printf("Page Size: %dKB\n", info.page_size >> 10); else - printf("Page Size: %dB\n", - le16_to_cpu(nh->pagesize)); + printf("Page Size: %dB\n", info.page_size); - printf("Spare Size: %dB\n", le16_to_cpu(nh->oobsize)); + printf("Spare Size: %dB\n", info.spare_size); } - gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize)); + gfh = (struct gfh_header *)(ptr + info.gfh_offset); - if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME)) - return -1; - - if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND) - return -1; - - if (print) - printf("Load Address: %08x\n", - le32_to_cpu(gfh->file_info.load_addr) + - le32_to_cpu(gfh->file_info.jump_offset)); - - if (print) - printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); - - return 0; + return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_NAND, print); } static uint32_t crc32be_cal(const void *data, size_t length) @@ -647,10 +427,10 @@ static uint32_t crc32be_cal(const void *data, size_t length) static int mtk_image_verify_mt7621_header(const uint8_t *ptr, int print) { - const image_header_t *hdr = (const image_header_t *)ptr; + const struct legacy_img_hdr *hdr = (const struct legacy_img_hdr *)ptr; struct mt7621_nand_header *nhdr; uint32_t spl_size, crcval; - image_header_t header; + struct legacy_img_hdr header; int ret; spl_size = image_get_size(hdr); @@ -710,7 +490,7 @@ static int mtk_image_verify_mt7621_header(const uint8_t *ptr, int print) static int mtk_image_verify_header(unsigned char *ptr, int image_size, struct image_tool_params *params) { - image_header_t *hdr = (image_header_t *)ptr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; union lk_hdr *lk = (union lk_hdr *)ptr; /* nothing to verify for LK image header */ @@ -722,7 +502,7 @@ static int mtk_image_verify_header(unsigned char *ptr, int image_size, if (image_get_magic(hdr) == IH_MAGIC) return mtk_image_verify_mt7621_header(ptr, 0); - if (!strcmp((char *)ptr, NAND_BOOT_NAME)) + if (is_mtk_nand_header(ptr)) return mtk_image_verify_nand_header(ptr, 0); else return mtk_image_verify_gen_header(ptr, 0); @@ -732,7 +512,7 @@ static int mtk_image_verify_header(unsigned char *ptr, int image_size, static void mtk_image_print_header(const void *ptr) { - image_header_t *hdr = (image_header_t *)ptr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; union lk_hdr *lk = (union lk_hdr *)ptr; if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) { @@ -748,7 +528,7 @@ static void mtk_image_print_header(const void *ptr) return; } - if (!strcmp((char *)ptr, NAND_BOOT_NAME)) + if (is_mtk_nand_header(ptr)) mtk_image_verify_nand_header(ptr, 1); else mtk_image_verify_gen_header(ptr, 1); @@ -879,42 +659,39 @@ static void mtk_image_set_gen_header(void *ptr, off_t filesize, static void mtk_image_set_nand_header(void *ptr, off_t filesize, uint32_t loadaddr) { - union nand_boot_header *nh = (union nand_boot_header *)ptr; struct brom_layout_header *brlyt; struct gfh_header *gfh; - uint32_t payload_pages; - int i; + uint32_t payload_pages, nand_page_size; - /* NAND device header, repeat 4 times */ - for (i = 0; i < 4; i++) - memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header)); + /* NAND header */ + nand_page_size = mtk_nand_header_put(hdr_nand, ptr); - /* BRLYT header */ - payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) / - le16_to_cpu(hdr_nand->pagesize); - brlyt = (struct brom_layout_header *) - (ptr + le16_to_cpu(hdr_nand->pagesize)); - put_brom_layout_header(brlyt, hdr_media); - brlyt->header_size = cpu_to_le32(2); - brlyt->total_size = cpu_to_le32(payload_pages); - brlyt->header_size_2 = brlyt->header_size; - brlyt->total_size_2 = brlyt->total_size; - brlyt->unused = cpu_to_le32(1); + if (nand_page_size) { + /* BRLYT header */ + payload_pages = (filesize + nand_page_size - 1) / + nand_page_size; + brlyt = (struct brom_layout_header *)(ptr + nand_page_size); + put_brom_layout_header(brlyt, hdr_media); + brlyt->header_size = cpu_to_le32(2); + brlyt->total_size = cpu_to_le32(payload_pages); + brlyt->header_size_2 = brlyt->header_size; + brlyt->total_size_2 = brlyt->total_size; + brlyt->unused = cpu_to_le32(1); + } /* GFH header */ - gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize)); - put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize), - loadaddr, GFH_FLASH_TYPE_NAND); + gfh = (struct gfh_header *)(ptr + hdr_nand_size); + put_ghf_header(gfh, filesize, hdr_nand_size, loadaddr, + GFH_FLASH_TYPE_NAND); /* Generate SHA256 hash */ - put_hash((uint8_t *)gfh, - filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN); + put_hash((uint8_t *)gfh, filesize - hdr_nand_size - SHA256_SUM_LEN); } static void mtk_image_set_mt7621_header(void *ptr, off_t filesize, uint32_t loadaddr) { - image_header_t *hdr = (image_header_t *)ptr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; struct mt7621_stage1_header *shdr; struct mt7621_nand_header *nhdr; uint32_t datasize, crcval; diff --git a/tools/mtk_image.h b/tools/mtk_image.h index d868545a33..fad9372100 100644 --- a/tools/mtk_image.h +++ b/tools/mtk_image.h @@ -26,31 +26,6 @@ union gen_boot_header { #define SF_BOOT_NAME "SF_BOOT" #define SDMMC_BOOT_NAME "SDMMC_BOOT" -/* Header for NAND */ -union nand_boot_header { - struct { - char name[12]; - char version[4]; - char id[8]; - uint16_t ioif; - uint16_t pagesize; - uint16_t addrcycles; - uint16_t oobsize; - uint16_t pages_of_block; - uint16_t numblocks; - uint16_t writesize_shift; - uint16_t erasesize_shift; - uint8_t dummy[60]; - uint8_t ecc_parity[28]; - }; - - uint8_t data[0x80]; -}; - -#define NAND_BOOT_NAME "BOOTLOADER!" -#define NAND_BOOT_VERSION "V006" -#define NAND_BOOT_ID "NFIINFO" - /* BootROM layout header */ struct brom_layout_header { char name[8]; diff --git a/tools/mtk_nand_headers.c b/tools/mtk_nand_headers.c new file mode 100644 index 0000000000..2fa91e7af0 --- /dev/null +++ b/tools/mtk_nand_headers.c @@ -0,0 +1,668 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * MediaTek BootROM NAND header definitions + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Weijie Gao + */ + +#include +#include +#include "imagetool.h" +#include "mtk_image.h" +#include "mtk_nand_headers.h" + +/* NAND header for SPI-NAND with 2KB page + 64B spare */ +static const union nand_boot_header snand_hdr_2k_64_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00, + 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D, + 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7, + 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8, + 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00 + } +}; + +/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */ +static const union nand_boot_header snand_hdr_2k_128_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, + 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13, + 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3, + 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7, + 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00 + } +}; + +/* NAND header for SPI-NAND with 4KB page + 256B spare */ +static const union nand_boot_header snand_hdr_4k_256_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00, + 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3, + 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57, + 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F, + 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00 + } +}; + +/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */ +static const union nand_boot_header nand_hdr_1gb_2k_64_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, + 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12, + 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C, + 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82, + 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00 + } +}; + +/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */ +static const union nand_boot_header nand_hdr_2gb_2k_64_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, + 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D, + 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1, + 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95, + 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00 + } +}; + +/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */ +static const union nand_boot_header nand_hdr_4gb_2k_64_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, + 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32, + 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B, + 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87, + 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00 + } +}; + +/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */ +static const union nand_boot_header nand_hdr_2gb_2k_128_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, + 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A, + 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC, + 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0, + 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00 + } +}; + +/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */ +static const union nand_boot_header nand_hdr_4gb_2k_128_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, + 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45, + 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46, + 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2, + 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00 + } +}; + +/* HSM BROM NAND header for SPI NAND with 2KB page + 64B spare */ +static const union hsm_nand_boot_header hsm_nand_hdr_2k_64_data = { + .data = { + 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x21, 0xD2, 0xEE, 0xF6, + 0xAE, 0xDD, 0x5E, 0xC2, 0x82, 0x8E, 0x9A, 0x62, + 0x09, 0x8E, 0x80, 0xE2, 0x37, 0x0D, 0xC9, 0xFA, + 0xA9, 0xDD, 0xFC, 0x92, 0x34, 0x2A, 0xED, 0x51, + 0xA4, 0x1B, 0xF7, 0x63, 0xCC, 0x5A, 0xC7, 0xFB, + 0xED, 0x21, 0x02, 0x23, 0x51, 0x31 + } +}; + +/* HSM BROM NAND header for SPI NAND with 2KB page + 128B spare */ +static const union hsm_nand_boot_header hsm_nand_hdr_2k_128_data = { + .data = { + 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x71, 0x7f, 0x71, 0xAC, + 0x42, 0xD0, 0x5B, 0xD2, 0x12, 0x81, 0x15, 0x0A, + 0x0C, 0xD4, 0xF6, 0x32, 0x1E, 0x63, 0xE7, 0x81, + 0x8A, 0x7F, 0xDE, 0xF9, 0x4B, 0x91, 0xEC, 0xC2, + 0x70, 0x00, 0x7F, 0x57, 0xAF, 0xDC, 0xE4, 0x24, + 0x57, 0x09, 0xBC, 0xC5, 0x35, 0xDC + } +}; + +/* HSM BROM NAND header for SPI NAND with 4KB page + 256B spare */ +static const union hsm_nand_boot_header hsm_nand_hdr_4k_256_data = { + .data = { + 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x62, 0x04, 0xD6, 0x1F, + 0x2B, 0x57, 0x7A, 0x2D, 0xFE, 0xBB, 0x4A, 0x50, + 0xEC, 0xF8, 0x70, 0x1A, 0x44, 0x15, 0xF6, 0xA2, + 0x8E, 0xB0, 0xFD, 0xFA, 0xDC, 0xAA, 0x5A, 0x4E, + 0xCB, 0x8E, 0xC9, 0x72, 0x08, 0xDC, 0x20, 0xB9, + 0x98, 0xC8, 0x82, 0xD8, 0xBE, 0x44 + } +}; + +/* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 64B spare */ +static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_64_data = { + .data = { + 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5F, 0x4B, 0xB2, 0x5B, 0x8B, 0x1C, 0x35, 0xDA, + 0x83, 0xE6, 0x6C, 0xC3, 0xFB, 0x8C, 0x78, 0x23, + 0xD0, 0x89, 0x24, 0xD9, 0x6C, 0x35, 0x2C, 0x5D, + 0x8F, 0xBB, 0xFC, 0x10, 0xD0, 0xE2, 0x22, 0x7D, + 0xC8, 0x97, 0x9A, 0xEF, 0xC6, 0xB5, 0xA7, 0x4E, + 0x4E, 0x0E + } +}; + +/* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 128B spare */ +static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_128_data = { + .data = { + 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF8, 0x7E, 0xC1, 0x5D, 0x61, 0x54, 0xEA, 0x9F, + 0x5E, 0x66, 0x39, 0x66, 0x21, 0xFF, 0x8C, 0x3B, + 0xBE, 0xA7, 0x5A, 0x9E, 0xD7, 0xBD, 0x9E, 0x89, + 0xEE, 0x7E, 0x10, 0x31, 0x9A, 0x1D, 0x82, 0x49, + 0xA3, 0x4E, 0xD8, 0x47, 0xD7, 0x19, 0xF4, 0x2D, + 0x8E, 0x53 + } +}; + +/* HSM2.0 BROM NAND header for SPI NAND with 4KB page + 256B spare */ +static const union hsm20_nand_boot_header hsm20_nand_hdr_4k_256_data = { + .data = { + 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x79, 0x01, 0x1F, 0x86, 0x62, 0x6A, 0x43, 0xAE, + 0xE6, 0xF8, 0xDD, 0x5B, 0x29, 0xB7, 0xA2, 0x7F, + 0x29, 0x72, 0x54, 0x37, 0xBE, 0x50, 0xD4, 0x24, + 0xAB, 0x60, 0xF4, 0x44, 0x97, 0x3B, 0x65, 0x21, + 0x73, 0x24, 0x1F, 0x93, 0x0E, 0x9E, 0x96, 0x88, + 0x78, 0x6C + } +}; + +/* SPIM-NAND header for SPI NAND with 2KB page + 64B spare */ +static const union spim_nand_boot_header spim_nand_hdr_2k_64_data = { + .data = { + 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30, + 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + } +}; + +/* SPIM-NAND header for SPI NAND with 2KB page + 128B spare */ +static const union spim_nand_boot_header spim_nand_hdr_2k_128_data = { + .data = { + 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30, + 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + } +}; + +/* SPIM-NAND header for SPI NAND with 4KB page + 256B spare */ +static const union spim_nand_boot_header spim_nand_hdr_4k_256_data = { + .data = { + 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x30, + 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + } +}; + +struct nand_header_type { + const char *name; + enum nand_boot_header_type type; + union { + const union nand_boot_header *ap; + const union hsm_nand_boot_header *hsm; + const union hsm20_nand_boot_header *hsm20; + const union spim_nand_boot_header *spim; + }; +} nand_headers[] = { + { + .name = "2k+64", + .type = NAND_BOOT_AP_HEADER, + .ap = &snand_hdr_2k_64_data, + }, { + .name = "2k+120", + .type = NAND_BOOT_AP_HEADER, + .ap = &snand_hdr_2k_128_data, + }, { + .name = "2k+128", + .type = NAND_BOOT_AP_HEADER, + .ap = &snand_hdr_2k_128_data, + }, { + .name = "4k+256", + .type = NAND_BOOT_AP_HEADER, + .ap = &snand_hdr_4k_256_data, + }, { + .name = "1g:2k+64", + .type = NAND_BOOT_AP_HEADER, + .ap = &nand_hdr_1gb_2k_64_data, + }, { + .name = "2g:2k+64", + .type = NAND_BOOT_AP_HEADER, + .ap = &nand_hdr_2gb_2k_64_data, + }, { + .name = "4g:2k+64", + .type = NAND_BOOT_AP_HEADER, + .ap = &nand_hdr_4gb_2k_64_data, + }, { + .name = "2g:2k+128", + .type = NAND_BOOT_AP_HEADER, + .ap = &nand_hdr_2gb_2k_128_data, + }, { + .name = "4g:2k+128", + .type = NAND_BOOT_AP_HEADER, + .ap = &nand_hdr_4gb_2k_128_data, + }, { + .name = "hsm:2k+64", + .type = NAND_BOOT_HSM_HEADER, + .hsm = &hsm_nand_hdr_2k_64_data, + }, { + .name = "hsm:2k+128", + .type = NAND_BOOT_HSM_HEADER, + .hsm = &hsm_nand_hdr_2k_128_data, + }, { + .name = "hsm:4k+256", + .type = NAND_BOOT_HSM_HEADER, + .hsm = &hsm_nand_hdr_4k_256_data, + }, { + .name = "hsm20:2k+64", + .type = NAND_BOOT_HSM20_HEADER, + .hsm20 = &hsm20_nand_hdr_2k_64_data, + }, { + .name = "hsm20:2k+128", + .type = NAND_BOOT_HSM20_HEADER, + .hsm20 = &hsm20_nand_hdr_2k_128_data, + }, { + .name = "hsm20:4k+256", + .type = NAND_BOOT_HSM20_HEADER, + .hsm20 = &hsm20_nand_hdr_4k_256_data, + }, { + .name = "spim:2k+64", + .type = NAND_BOOT_SPIM_HEADER, + .spim = &spim_nand_hdr_2k_64_data, + }, { + .name = "spim:2k+128", + .type = NAND_BOOT_SPIM_HEADER, + .spim = &spim_nand_hdr_2k_128_data, + }, { + .name = "spim:4k+256", + .type = NAND_BOOT_SPIM_HEADER, + .spim = &spim_nand_hdr_4k_256_data, + } +}; + +const struct nand_header_type *mtk_nand_header_find(const char *name) +{ + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(nand_headers); i++) { + if (!strcmp(nand_headers[i].name, name)) + return &nand_headers[i]; + } + + return NULL; +} + +uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand) +{ + switch (hdr_nand->type) { + case NAND_BOOT_HSM_HEADER: + return le32_to_cpu(hdr_nand->hsm->page_size); + + case NAND_BOOT_HSM20_HEADER: + return le32_to_cpu(hdr_nand->hsm20->page_size); + + case NAND_BOOT_SPIM_HEADER: + return le32_to_cpu(hdr_nand->spim->page_size); + + default: + return 2 * le16_to_cpu(hdr_nand->ap->pagesize); + } +} + +static int mtk_nand_header_ap_info(const void *ptr, + struct nand_header_info *info) +{ + union nand_boot_header *nh = (union nand_boot_header *)ptr; + + if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) || + strcmp(nh->id, NAND_BOOT_ID)) + return -1; + + info->page_size = le16_to_cpu(nh->pagesize); + info->spare_size = le16_to_cpu(nh->oobsize); + info->gfh_offset = 2 * info->page_size; + info->snfi = true; + + return 0; +} + +static int mtk_nand_header_hsm_info(const void *ptr, + struct nand_header_info *info) +{ + union hsm_nand_boot_header *nh = (union hsm_nand_boot_header *)ptr; + + info->page_size = le16_to_cpu(nh->page_size); + info->spare_size = le16_to_cpu(nh->spare_size); + info->gfh_offset = info->page_size; + info->snfi = true; + + return 1; +} + +static int mtk_nand_header_spim_info(const void *ptr, + struct nand_header_info *info) +{ + union spim_nand_boot_header *nh = (union spim_nand_boot_header *)ptr; + + info->page_size = le16_to_cpu(nh->page_size); + info->spare_size = le16_to_cpu(nh->spare_size); + info->gfh_offset = info->page_size; + info->snfi = false; + + return 1; +} + +int mtk_nand_header_info(const void *ptr, struct nand_header_info *info) +{ + if (!strcmp((char *)ptr, NAND_BOOT_NAME)) + return mtk_nand_header_ap_info(ptr, info); + else if (!strncmp((char *)ptr, HSM_NAND_BOOT_NAME, 8)) + return mtk_nand_header_hsm_info(ptr, info); + else if (!strncmp((char *)ptr, SPIM_NAND_BOOT_NAME, 8)) + return mtk_nand_header_spim_info(ptr, info); + + return -1; +} + +bool is_mtk_nand_header(const void *ptr) +{ + struct nand_header_info info; + + if (mtk_nand_header_info(ptr, &info) >= 0) + return true; + + return false; +} + +static uint16_t crc16(const uint8_t *p, uint32_t len) +{ + uint16_t crc = 0x4f4e; + uint32_t i; + + while (len--) { + crc ^= *p++ << 8; + for (i = 0; i < 8; i++) + crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0); + } + + return crc; +} + +static uint32_t mtk_nand_header_put_ap(const struct nand_header_type *hdr_nand, + void *ptr) +{ + int i; + + /* NAND device header, repeat 4 times */ + for (i = 0; i < 4; i++) { + memcpy(ptr, hdr_nand->ap, sizeof(*hdr_nand->ap)); + ptr += sizeof(*hdr_nand->ap); + } + + return le16_to_cpu(hdr_nand->ap->pagesize); +} + +static uint32_t mtk_nand_header_put_hsm(const struct nand_header_type *hdr_nand, + void *ptr) +{ + memcpy(ptr, hdr_nand->hsm, sizeof(*hdr_nand->hsm)); + return 0; +} + +static uint32_t mtk_nand_header_put_hsm20(const struct nand_header_type *hdr_nand, + void *ptr) +{ + memcpy(ptr, hdr_nand->hsm20, sizeof(*hdr_nand->hsm20)); + return 0; +} + +static uint32_t mtk_nand_header_put_spim(const struct nand_header_type *hdr_nand, + void *ptr) +{ + uint16_t crc; + + memcpy(ptr, hdr_nand->spim, sizeof(*hdr_nand->spim)); + + crc = crc16(ptr, 0x4e); + memcpy(ptr + 0x4e, &crc, sizeof(uint16_t)); + + return 0; +} + +uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand, void *ptr) +{ + switch (hdr_nand->type) { + case NAND_BOOT_HSM_HEADER: + return mtk_nand_header_put_hsm(hdr_nand, ptr); + + case NAND_BOOT_HSM20_HEADER: + return mtk_nand_header_put_hsm20(hdr_nand, ptr); + + case NAND_BOOT_SPIM_HEADER: + return mtk_nand_header_put_spim(hdr_nand, ptr); + + default: + return mtk_nand_header_put_ap(hdr_nand, ptr); + } +} diff --git a/tools/mtk_nand_headers.h b/tools/mtk_nand_headers.h new file mode 100644 index 0000000000..9b1c4bab11 --- /dev/null +++ b/tools/mtk_nand_headers.h @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * MediaTek BootROM NAND header definitions + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Weijie Gao + */ + +#ifndef _MTK_NAND_HEADERS_H +#define _MTK_NAND_HEADERS_H + +#include +#include + +struct nand_header_info { + uint32_t page_size; + uint32_t spare_size; + uint32_t gfh_offset; + bool snfi; +}; + +/* AP BROM Header for NAND */ +union nand_boot_header { + struct { + char name[12]; + char version[4]; + char id[8]; + uint16_t ioif; /* I/O interface */ + uint16_t pagesize; /* NAND page size */ + uint16_t addrcycles; /* Address cycles */ + uint16_t oobsize; /* NAND page spare size */ + uint16_t pages_of_block; /* Pages of one block */ + uint16_t numblocks; /* Total blocks of NAND chip */ + uint16_t writesize_shift; + uint16_t erasesize_shift; + uint8_t dummy[60]; + uint8_t ecc_parity[28]; /* ECC parity of this header */ + }; + + uint8_t data[0x80]; +}; + +/* HSM BROM Header for NAND */ +union hsm_nand_boot_header { + struct { + char id[8]; + uint32_t version; /* Header version */ + uint32_t config; /* Header config */ + uint32_t sector_size; /* ECC step size */ + uint32_t fdm_size; /* User OOB size of a step */ + uint32_t fdm_ecc_size; /* ECC parity size of a step */ + uint32_t lbs; + uint32_t page_size; /* NAND page size */ + uint32_t spare_size; /* NAND page spare size */ + uint32_t page_per_block; /* Pages of one block */ + uint32_t blocks; /* Total blocks of NAND chip */ + uint32_t plane_sel_position; /* Plane bit position */ + uint32_t pll; /* Value of pll reg */ + uint32_t acccon; /* Value of access timing reg */ + uint32_t strobe_sel; /* Value of DQS selection reg*/ + uint32_t acccon1; /* Value of access timing reg */ + uint32_t dqs_mux; /* Value of DQS mux reg */ + uint32_t dqs_ctrl; /* Value of DQS control reg */ + uint32_t delay_ctrl; /* Value of delay ctrl reg */ + uint32_t latch_lat; /* Value of latch latency reg */ + uint32_t sample_delay; /* Value of sample delay reg */ + uint32_t driving; /* Value of driving reg */ + uint32_t bl_start; /* Bootloader start addr */ + uint32_t bl_end; /* Bootloader end addr */ + uint8_t ecc_parity[42]; /* ECC parity of this header */ + }; + + uint8_t data[0x8E]; +}; + +/* HSM2.0 BROM Header for NAND */ +union hsm20_nand_boot_header { + struct { + char id[8]; + uint32_t version; /* Header version */ + uint32_t config; /* Header config */ + uint32_t sector_size; /* ECC step size */ + uint32_t fdm_size; /* User OOB size of a step */ + uint32_t fdm_ecc_size; /* ECC parity size of a step */ + uint32_t lbs; + uint32_t page_size; /* NAND page size */ + uint32_t spare_size; /* NAND page spare size */ + uint32_t page_per_block; /* Pages of one block */ + uint32_t blocks; /* Total blocks of NAND chip */ + uint32_t plane_sel_position; /* Plane bit position */ + uint32_t pll; /* Value of pll reg */ + uint32_t acccon; /* Value of access timing reg */ + uint32_t strobe_sel; /* Value of DQS selection reg*/ + uint32_t acccon1; /* Value of access timing reg */ + uint32_t dqs_mux; /* Value of DQS mux reg */ + uint32_t dqs_ctrl; /* Value of DQS control reg */ + uint32_t delay_ctrl; /* Value of delay ctrl reg */ + uint32_t latch_lat; /* Value of latch latency reg */ + uint32_t sample_delay; /* Value of sample delay reg */ + uint32_t driving; /* Value of driving reg */ + uint32_t reserved; + uint32_t bl0_start; /* Bootloader start addr */ + uint32_t bl0_end; /* Bootloader end addr */ + uint32_t bl0_type; /* Bootloader type */ + uint8_t bl_reserve[84]; + uint8_t ecc_parity[42]; /* ECC parity of this header */ + }; + + uint8_t data[0xEA]; +}; + +/* SPIM BROM Header for SPI-NAND */ +union spim_nand_boot_header { + struct { + char id[8]; + uint32_t version; /* Header version */ + uint32_t config; /* Header config */ + uint32_t page_size; /* NAND page size */ + uint32_t spare_size; /* NAND page spare size */ + uint16_t page_per_block; /* Pages of one block */ + uint16_t plane_sel_position; /* Plane bit position */ + uint16_t reserve_reg; + uint16_t reserve_val; + uint16_t ecc_error; /* ECC error reg addr */ + uint16_t ecc_mask; /* ECC error bit mask */ + uint32_t bl_start; /* Bootloader start addr */ + uint32_t bl_end; /* Bootloader end addr */ + uint8_t ecc_parity[32]; /* ECC parity of this header */ + uint32_t integrity_crc; /* CRC of this header */ + }; + + uint8_t data[0x50]; +}; + +enum nand_boot_header_type { + NAND_BOOT_AP_HEADER, + NAND_BOOT_HSM_HEADER, + NAND_BOOT_HSM20_HEADER, + NAND_BOOT_SPIM_HEADER +}; + +#define NAND_BOOT_NAME "BOOTLOADER!" +#define NAND_BOOT_VERSION "V006" +#define NAND_BOOT_ID "NFIINFO" + +#define HSM_NAND_BOOT_NAME "NANDCFG!" +#define SPIM_NAND_BOOT_NAME "SPINAND!" + +/* Find nand header data by name */ +const struct nand_header_type *mtk_nand_header_find(const char *name); + +/* Device header size using this nand header */ +uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand); + +/* Get nand info from nand header (page size, spare size, ...) */ +int mtk_nand_header_info(const void *ptr, struct nand_header_info *info); + +/* Whether given header data is valid */ +bool is_mtk_nand_header(const void *ptr); + +/* Generate Device header using give nand header */ +uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand, + void *ptr); + +#endif /* _MTK_NAND_HEADERS_H */